Merge branch 'main' into #22-vacation-calendar
# Conflicts: # resources/js/Pages/Dashboard.vue # resources/js/Shared/Layout/AppLayout.vue # resources/js/Shared/MainMenu.vue # routes/web.php
This commit is contained in:
@@ -1,106 +1,106 @@
|
||||
<template>
|
||||
<InertiaHead title="Dodaj dzień wolny" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="p-4 sm:px-6">
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Dodaj dzień wolny
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Użytkownik nie będzie miał możliwości wzięcia urlopu w dzień wolny.
|
||||
</p>
|
||||
</div>
|
||||
<form
|
||||
class="border-t border-gray-200 px-6"
|
||||
@submit.prevent="createHoliday"
|
||||
>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="name"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Nazwa
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="name"
|
||||
v-model="form.name"
|
||||
type="text"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.name, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.name }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.name"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.name }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="date"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Data
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<FlatPickr
|
||||
id="date"
|
||||
v-model="form.date"
|
||||
placeholder="Wybierz datę"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.date, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.date }"
|
||||
/>
|
||||
<p
|
||||
v-if="form.errors.date"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.date }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end py-3">
|
||||
<div class="space-x-3">
|
||||
<InertiaLink
|
||||
href="/holidays"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Anuluj
|
||||
</InertiaLink>
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="form.processing"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Zapisz
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<InertiaHead title="Dodaj dzień wolny" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="p-4 sm:px-6">
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Dodaj dzień wolny
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Użytkownik nie będzie miał możliwości wzięcia urlopu w dzień wolny.
|
||||
</p>
|
||||
</div>
|
||||
<form
|
||||
class="border-t border-gray-200 px-6"
|
||||
@submit.prevent="createHoliday"
|
||||
>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="name"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Nazwa
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="name"
|
||||
v-model="form.name"
|
||||
type="text"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.name, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.name }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.name"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.name }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="date"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Data
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<FlatPickr
|
||||
id="date"
|
||||
v-model="form.date"
|
||||
placeholder="Wybierz datę"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.date, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.date }"
|
||||
/>
|
||||
<p
|
||||
v-if="form.errors.date"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.date }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end py-3">
|
||||
<div class="space-x-3">
|
||||
<InertiaLink
|
||||
href="/holidays"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Anuluj
|
||||
</InertiaLink>
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="form.processing"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Zapisz
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useForm } from '@inertiajs/inertia-vue3';
|
||||
import FlatPickr from 'vue-flatpickr-component';
|
||||
import { useForm } from '@inertiajs/inertia-vue3'
|
||||
import FlatPickr from 'vue-flatpickr-component'
|
||||
|
||||
export default {
|
||||
name: 'HolidayCreate',
|
||||
components: {
|
||||
FlatPickr,
|
||||
},
|
||||
setup() {
|
||||
const form = useForm({
|
||||
name: null,
|
||||
date: null,
|
||||
});
|
||||
name: 'HolidayCreate',
|
||||
components: {
|
||||
FlatPickr,
|
||||
},
|
||||
setup() {
|
||||
const form = useForm({
|
||||
name: null,
|
||||
date: null,
|
||||
})
|
||||
|
||||
return { form };
|
||||
return { form }
|
||||
},
|
||||
methods: {
|
||||
createHoliday() {
|
||||
this.form.post('/holidays')
|
||||
},
|
||||
methods: {
|
||||
createHoliday() {
|
||||
this.form.post('/holidays');
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@@ -1,113 +1,113 @@
|
||||
<template>
|
||||
<InertiaHead title="Edytuj dzień wolny" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="p-4 sm:px-6">
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Edytuj dzień wolny
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Użytkownik nie będzie miał możliwości wzięcia urlopu w dzień wolny.
|
||||
</p>
|
||||
</div>
|
||||
<form
|
||||
class="border-t border-gray-200 px-6"
|
||||
@submit.prevent="editHoliday"
|
||||
>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="name"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Nazwa
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="name"
|
||||
v-model="form.name"
|
||||
type="text"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.name, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.name }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.name"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.name }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="date"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Data
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<FlatPickr
|
||||
id="date"
|
||||
v-model="form.date"
|
||||
placeholder="Wybierz datę"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.date, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.date }"
|
||||
/>
|
||||
<p
|
||||
v-if="form.errors.date"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.date }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end py-3">
|
||||
<div class="space-x-3">
|
||||
<InertiaLink
|
||||
href="/holidays"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Anuluj
|
||||
</InertiaLink>
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="form.processing"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Zapisz
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<InertiaHead title="Edytuj dzień wolny" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="p-4 sm:px-6">
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Edytuj dzień wolny
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Użytkownik nie będzie miał możliwości wzięcia urlopu w dzień wolny.
|
||||
</p>
|
||||
</div>
|
||||
<form
|
||||
class="border-t border-gray-200 px-6"
|
||||
@submit.prevent="editHoliday"
|
||||
>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="name"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Nazwa
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="name"
|
||||
v-model="form.name"
|
||||
type="text"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.name, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.name }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.name"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.name }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="date"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Data
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<FlatPickr
|
||||
id="date"
|
||||
v-model="form.date"
|
||||
placeholder="Wybierz datę"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.date, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.date }"
|
||||
/>
|
||||
<p
|
||||
v-if="form.errors.date"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.date }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end py-3">
|
||||
<div class="space-x-3">
|
||||
<InertiaLink
|
||||
href="/holidays"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Anuluj
|
||||
</InertiaLink>
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="form.processing"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Zapisz
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useForm } from '@inertiajs/inertia-vue3';
|
||||
import FlatPickr from 'vue-flatpickr-component';
|
||||
import { useForm } from '@inertiajs/inertia-vue3'
|
||||
import FlatPickr from 'vue-flatpickr-component'
|
||||
|
||||
export default {
|
||||
name: 'HolidayEdit',
|
||||
components: {
|
||||
FlatPickr,
|
||||
name: 'HolidayEdit',
|
||||
components: {
|
||||
FlatPickr,
|
||||
},
|
||||
props: {
|
||||
holiday: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
props: {
|
||||
holiday: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const form = useForm({
|
||||
name: props.holiday.name,
|
||||
date: props.holiday.date,
|
||||
});
|
||||
},
|
||||
setup(props) {
|
||||
const form = useForm({
|
||||
name: props.holiday.name,
|
||||
date: props.holiday.date,
|
||||
})
|
||||
|
||||
return { form };
|
||||
return { form }
|
||||
},
|
||||
methods: {
|
||||
editHoliday() {
|
||||
this.form
|
||||
.put(`/holidays/${this.holiday.id}`)
|
||||
},
|
||||
methods: {
|
||||
editHoliday() {
|
||||
this.form
|
||||
.put(`/holidays/${this.holiday.id}`);
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@@ -1,167 +1,167 @@
|
||||
<template>
|
||||
<InertiaHead title="Dni wolne od pracy" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="flex justify-between items-center p-4 sm:px-6">
|
||||
<div>
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Dni wolne od pracy
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Lista dni wolnych od pracy w danym roku
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<InertiaLink
|
||||
href="holidays/create"
|
||||
class="inline-flex items-center px-4 py-3 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Dodaj dzień wolny
|
||||
</InertiaLink>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-200">
|
||||
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-100">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Nazwa
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Data
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Dzień tygodnia
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
/>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-100">
|
||||
<tr
|
||||
v-for="holiday in holidays.data"
|
||||
:key="holiday.id"
|
||||
class="hover:bg-blumilk-25"
|
||||
>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500 font-semibold capitalize">
|
||||
{{ holiday.name }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ holiday.displayDate }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ holiday.dayOfWeek }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500 text-right">
|
||||
<Menu
|
||||
as="div"
|
||||
class="relative inline-block text-left"
|
||||
>
|
||||
<MenuButton class="rounded-full flex items-center text-gray-400 hover:text-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-blumilk-500">
|
||||
<DotsVerticalIcon
|
||||
class="h-5 w-5"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</MenuButton>
|
||||
|
||||
<transition
|
||||
enter-active-class="transition ease-out duration-100"
|
||||
enter-from-class="transform opacity-0 scale-95"
|
||||
enter-to-class="transform opacity-100 scale-100"
|
||||
leave-active-class="transition ease-in duration-75"
|
||||
leave-from-class="transform opacity-100 scale-100"
|
||||
leave-to-class="transform opacity-0 scale-95"
|
||||
>
|
||||
<MenuItems class="origin-top-right absolute right-0 mt-2 w-56 z-10 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none">
|
||||
<div class="py-1">
|
||||
<MenuItem
|
||||
v-slot="{ active }"
|
||||
class="flex"
|
||||
>
|
||||
<InertiaLink
|
||||
:href="`/holidays/${holiday.id}/edit`"
|
||||
:class="[active ? 'bg-gray-100 text-gray-900' : 'text-gray-700', 'font-medium block px-4 py-2 text-sm']"
|
||||
>
|
||||
<PencilIcon
|
||||
class="mr-2 h-5 w-5 text-blue-500"
|
||||
aria-hidden="true"
|
||||
/> Edytuj
|
||||
</InertiaLink>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
v-slot="{ active }"
|
||||
class="flex"
|
||||
>
|
||||
<InertiaLink
|
||||
as="button"
|
||||
method="delete"
|
||||
:preserve-scroll="true"
|
||||
:href="`/holidays/${holiday.id}`"
|
||||
:class="[active ? 'bg-gray-100 text-gray-900' : 'text-gray-700', 'block w-full text-left font-medium px-4 py-2 text-sm']"
|
||||
>
|
||||
<TrashIcon
|
||||
class="mr-2 h-5 w-5 text-red-500"
|
||||
aria-hidden="true"
|
||||
/> Usuń
|
||||
</InertiaLink>
|
||||
</MenuItem>
|
||||
</div>
|
||||
</MenuItems>
|
||||
</transition>
|
||||
</Menu>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-if="!holidays.data.length"
|
||||
>
|
||||
<td
|
||||
colspan="100%"
|
||||
class="text-center py-4 text-xl leading-5 text-gray-700"
|
||||
>
|
||||
Brak danych
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<InertiaHead title="Dni wolne od pracy" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="flex justify-between items-center p-4 sm:px-6">
|
||||
<div>
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Dni wolne od pracy
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Lista dni wolnych od pracy w danym roku
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<InertiaLink
|
||||
href="holidays/create"
|
||||
class="inline-flex items-center px-4 py-3 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Dodaj dzień wolny
|
||||
</InertiaLink>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-200">
|
||||
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-100">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Nazwa
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Data
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Dzień tygodnia
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
/>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-100">
|
||||
<tr
|
||||
v-for="holiday in holidays.data"
|
||||
:key="holiday.id"
|
||||
class="hover:bg-blumilk-25"
|
||||
>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500 font-semibold capitalize">
|
||||
{{ holiday.name }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ holiday.displayDate }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ holiday.dayOfWeek }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500 text-right">
|
||||
<Menu
|
||||
as="div"
|
||||
class="relative inline-block text-left"
|
||||
>
|
||||
<MenuButton class="rounded-full flex items-center text-gray-400 hover:text-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-blumilk-500">
|
||||
<DotsVerticalIcon
|
||||
class="h-5 w-5"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</MenuButton>
|
||||
|
||||
<transition
|
||||
enter-active-class="transition ease-out duration-100"
|
||||
enter-from-class="transform opacity-0 scale-95"
|
||||
enter-to-class="transform opacity-100 scale-100"
|
||||
leave-active-class="transition ease-in duration-75"
|
||||
leave-from-class="transform opacity-100 scale-100"
|
||||
leave-to-class="transform opacity-0 scale-95"
|
||||
>
|
||||
<MenuItems class="origin-top-right absolute right-0 mt-2 w-56 z-10 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none">
|
||||
<div class="py-1">
|
||||
<MenuItem
|
||||
v-slot="{ active }"
|
||||
class="flex"
|
||||
>
|
||||
<InertiaLink
|
||||
:href="`/holidays/${holiday.id}/edit`"
|
||||
:class="[active ? 'bg-gray-100 text-gray-900' : 'text-gray-700', 'font-medium block px-4 py-2 text-sm']"
|
||||
>
|
||||
<PencilIcon
|
||||
class="mr-2 h-5 w-5 text-blue-500"
|
||||
aria-hidden="true"
|
||||
/> Edytuj
|
||||
</InertiaLink>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
v-slot="{ active }"
|
||||
class="flex"
|
||||
>
|
||||
<InertiaLink
|
||||
as="button"
|
||||
method="delete"
|
||||
:preserve-scroll="true"
|
||||
:href="`/holidays/${holiday.id}`"
|
||||
:class="[active ? 'bg-gray-100 text-gray-900' : 'text-gray-700', 'block w-full text-left font-medium px-4 py-2 text-sm']"
|
||||
>
|
||||
<TrashIcon
|
||||
class="mr-2 h-5 w-5 text-red-500"
|
||||
aria-hidden="true"
|
||||
/> Usuń
|
||||
</InertiaLink>
|
||||
</MenuItem>
|
||||
</div>
|
||||
</MenuItems>
|
||||
</transition>
|
||||
</Menu>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-if="!holidays.data.length"
|
||||
>
|
||||
<td
|
||||
colspan="100%"
|
||||
class="text-center py-4 text-xl leading-5 text-gray-700"
|
||||
>
|
||||
Brak danych
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DotsVerticalIcon, PencilIcon, TrashIcon } from '@heroicons/vue/solid';
|
||||
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue';
|
||||
import { DotsVerticalIcon, PencilIcon, TrashIcon } from '@heroicons/vue/solid'
|
||||
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue'
|
||||
|
||||
export default {
|
||||
name: 'HolidayINdex',
|
||||
components: {
|
||||
DotsVerticalIcon,
|
||||
PencilIcon,
|
||||
TrashIcon,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuItem,
|
||||
MenuItems,
|
||||
name: 'HolidayINdex',
|
||||
components: {
|
||||
DotsVerticalIcon,
|
||||
PencilIcon,
|
||||
TrashIcon,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuItem,
|
||||
MenuItems,
|
||||
},
|
||||
props: {
|
||||
holidays: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
props: {
|
||||
holidays: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
};
|
||||
},
|
||||
setup() {
|
||||
return {}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@@ -1,86 +1,86 @@
|
||||
<template>
|
||||
<InertiaHead title="Zaloguj się" />
|
||||
<transition
|
||||
enter-active-class="transform ease-out duration-300 transition"
|
||||
enter-from-class="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
|
||||
enter-to-class="translate-y-0 opacity-100 sm:translate-x-0"
|
||||
leave-active-class="transition ease-in duration-100"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0"
|
||||
>
|
||||
<div
|
||||
v-if="errors.oauth"
|
||||
class="absolute inset-x-2 top-2 sm:mx-auto sm:w-full sm:max-w-md bg-red-500 shadow-lg rounded-lg pointer-events-auto ring-1 ring-black ring-opacity-5 overflow-hidden"
|
||||
>
|
||||
<div class="p-4">
|
||||
<div class="flex items-center">
|
||||
<div class="w-0 flex-1 flex justify-between">
|
||||
<ExclamationIcon class="h-5 w-5 text-white" />
|
||||
<p class="w-0 flex-1 text-sm font-medium text-white">
|
||||
{{ errors.oauth }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="ml-4 flex-shrink-0 flex">
|
||||
<button
|
||||
class="bg-red-500 rounded-md inline-flex text-red-100 hover:text-red-400 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-600"
|
||||
@click="delete errors.oauth"
|
||||
>
|
||||
<span class="sr-only">Close</span>
|
||||
<XIcon
|
||||
class="h-5 w-5"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
<InertiaHead title="Zaloguj się" />
|
||||
<transition
|
||||
enter-active-class="transform ease-out duration-300 transition"
|
||||
enter-from-class="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
|
||||
enter-to-class="translate-y-0 opacity-100 sm:translate-x-0"
|
||||
leave-active-class="transition ease-in duration-100"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0"
|
||||
>
|
||||
<div
|
||||
class="sm:mx-auto sm:w-full sm:max-w-md text-white space-y-4 flex flex-col items-center rounded-lg px-4 py-8"
|
||||
dusk="login-link"
|
||||
v-if="errors.oauth"
|
||||
class="absolute inset-x-2 top-2 sm:mx-auto sm:w-full sm:max-w-md bg-red-500 shadow-lg rounded-lg pointer-events-auto ring-1 ring-black ring-opacity-5 overflow-hidden"
|
||||
>
|
||||
<img
|
||||
class="mx-auto h-50 w-auto"
|
||||
src="img/logo.png"
|
||||
alt="Blumilk"
|
||||
>
|
||||
<a
|
||||
href="/login/google/start"
|
||||
class="inline-flex justify-center py-2 px-6 rounded-md shadow-sm bg-blumilk-500 text-md font-medium text-white hover:bg-blumilk-700"
|
||||
>
|
||||
Zaloguj się za pomocą Google
|
||||
<svg
|
||||
class="w-5 h-5 ml-2"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
<div class="p-4">
|
||||
<div class="flex items-center">
|
||||
<div class="w-0 flex-1 flex justify-between">
|
||||
<ExclamationIcon class="h-5 w-5 text-white" />
|
||||
<p class="w-0 flex-1 text-sm font-medium text-white">
|
||||
{{ errors.oauth }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="ml-4 flex-shrink-0 flex">
|
||||
<button
|
||||
class="bg-red-500 rounded-md inline-flex text-red-100 hover:text-red-400 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-600"
|
||||
@click="delete errors.oauth"
|
||||
>
|
||||
<path
|
||||
d="M6 12C6 15.3137 8.68629 18 12 18C14.6124 18 16.8349 16.3304 17.6586 14H12V10H21.8047V14H21.8C20.8734 18.5645 16.8379 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C15.445 2 18.4831 3.742 20.2815 6.39318L17.0039 8.68815C15.9296 7.06812 14.0895 6 12 6C8.68629 6 6 8.68629 6 12Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
<span class="sr-only">Close</span>
|
||||
<XIcon
|
||||
class="h-5 w-5"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
<div
|
||||
class="sm:mx-auto sm:w-full sm:max-w-md text-white space-y-4 flex flex-col items-center rounded-lg px-4 py-8"
|
||||
dusk="login-link"
|
||||
>
|
||||
<img
|
||||
class="mx-auto h-50 w-auto"
|
||||
src="img/logo.png"
|
||||
alt="Blumilk"
|
||||
>
|
||||
<a
|
||||
href="/login/google/start"
|
||||
class="inline-flex justify-center py-2 px-6 rounded-md shadow-sm bg-blumilk-500 text-md font-medium text-white hover:bg-blumilk-700"
|
||||
>
|
||||
Zaloguj się za pomocą Google
|
||||
<svg
|
||||
class="w-5 h-5 ml-2"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M6 12C6 15.3137 8.68629 18 12 18C14.6124 18 16.8349 16.3304 17.6586 14H12V10H21.8047V14H21.8C20.8734 18.5645 16.8379 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C15.445 2 18.4831 3.742 20.2815 6.39318L17.0039 8.68815C15.9296 7.06812 14.0895 6 12 6C8.68629 6 6 8.68629 6 12Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GuestLayout from '@/Shared/Layout/GuestLayout';
|
||||
import {XIcon} from '@heroicons/vue/solid';
|
||||
import {ExclamationIcon} from '@heroicons/vue/solid';
|
||||
import GuestLayout from '@/Shared/Layout/GuestLayout'
|
||||
import {XIcon} from '@heroicons/vue/solid'
|
||||
import {ExclamationIcon} from '@heroicons/vue/solid'
|
||||
|
||||
export default {
|
||||
name: 'Login',
|
||||
components: {
|
||||
XIcon,
|
||||
ExclamationIcon,
|
||||
name: 'LoginPage',
|
||||
components: {
|
||||
XIcon,
|
||||
ExclamationIcon,
|
||||
},
|
||||
layout: GuestLayout,
|
||||
props: {
|
||||
errors: {
|
||||
type: Object,
|
||||
default: () => ({oauth: null}),
|
||||
},
|
||||
layout: GuestLayout,
|
||||
props: {
|
||||
errors: {
|
||||
type: Object,
|
||||
default: () => ({oauth: null}),
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@@ -1,230 +1,290 @@
|
||||
<template>
|
||||
<InertiaHead title="Dodawanie użytkownika" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="p-4 sm:px-6">
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Dodaj użytkownika
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Tylko dodani użytkownicy będą mogli zalogować się do aplikacji.
|
||||
</p>
|
||||
</div>
|
||||
<form
|
||||
class="border-t border-gray-200 px-6"
|
||||
@submit.prevent="createUser"
|
||||
>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="firstName"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Imię
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="firstName"
|
||||
v-model="form.firstName"
|
||||
type="text"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.firstName, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.firstName }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.firstName"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.firstName }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="lastName"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Nazwisko
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="lastName"
|
||||
v-model="form.lastName"
|
||||
type="text"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.lastName, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.lastName }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.lastName"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.lastName }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="email"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Adres e-mail
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="email"
|
||||
v-model="form.email"
|
||||
type="email"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.email, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.email }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.email"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.email }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Listbox
|
||||
v-model="form.employmentForm"
|
||||
as="div"
|
||||
class="sm:grid sm:grid-cols-3 py-4 items-center"
|
||||
>
|
||||
<ListboxLabel class="block text-sm font-medium text-gray-700">
|
||||
Forma zatrudnienia
|
||||
</ListboxLabel>
|
||||
<div class="mt-1 relative sm:mt-0 sm:col-span-2">
|
||||
<ListboxButton
|
||||
class="bg-white relative w-full max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:ring-1"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.employmentForm, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.employmentForm }"
|
||||
>
|
||||
<span class="block truncate">{{ form.employmentForm.label }}</span>
|
||||
<span class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
||||
<SelectorIcon class="h-5 w-5 text-gray-400" />
|
||||
</span>
|
||||
</ListboxButton>
|
||||
|
||||
<transition
|
||||
leave-active-class="transition ease-in duration-100"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0"
|
||||
>
|
||||
<ListboxOptions class="absolute z-10 mt-1 w-full max-w-lg bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm">
|
||||
<ListboxOption
|
||||
v-for="employmentForm in employmentForms"
|
||||
:key="employmentForm.value"
|
||||
v-slot="{ active, selected }"
|
||||
as="template"
|
||||
:value="employmentForm"
|
||||
>
|
||||
<li :class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']">
|
||||
<span :class="[selected ? 'font-semibold' : 'font-normal', 'block truncate']">
|
||||
{{ employmentForm.label }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="selected"
|
||||
:class="[active ? 'text-white' : 'text-blumilk-600', 'absolute inset-y-0 right-0 flex items-center pr-4']"
|
||||
>
|
||||
<CheckIcon class="h-5 w-5" />
|
||||
</span>
|
||||
</li>
|
||||
</ListboxOption>
|
||||
</ListboxOptions>
|
||||
</transition>
|
||||
<p
|
||||
v-if="form.errors.employmentForm"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.employmentForm }}
|
||||
</p>
|
||||
</div>
|
||||
</Listbox>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="employment_date"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Data zatrudnienia
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<FlatPickr
|
||||
id="employment_date"
|
||||
v-model="form.employmentDate"
|
||||
placeholder="Wybierz datę"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.employmentDate, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.employmentDate }"
|
||||
/>
|
||||
<p
|
||||
v-if="form.errors.employmentDate"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.employmentDate }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end py-3">
|
||||
<div class="space-x-3">
|
||||
<InertiaLink
|
||||
href="/users"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Anuluj
|
||||
</InertiaLink>
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="form.processing"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Zapisz
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<InertiaHead title="Dodawanie użytkownika" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="p-4 sm:px-6">
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Dodaj użytkownika
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Tylko dodani użytkownicy będą mogli zalogować się do aplikacji.
|
||||
</p>
|
||||
</div>
|
||||
<form
|
||||
class="border-t border-gray-200 px-6"
|
||||
@submit.prevent="createUser"
|
||||
>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="firstName"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Imię
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="firstName"
|
||||
v-model="form.firstName"
|
||||
type="text"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.firstName, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.firstName }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.firstName"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.firstName }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="lastName"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Nazwisko
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="lastName"
|
||||
v-model="form.lastName"
|
||||
type="text"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.lastName, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.lastName }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.lastName"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.lastName }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="email"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Adres e-mail
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="email"
|
||||
v-model="form.email"
|
||||
type="email"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.email, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.email }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.email"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.email }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Listbox
|
||||
v-model="form.role"
|
||||
as="div"
|
||||
class="sm:grid sm:grid-cols-3 py-4 items-center"
|
||||
>
|
||||
<ListboxLabel class="block text-sm font-medium text-gray-700">
|
||||
Rola
|
||||
</ListboxLabel>
|
||||
<div class="mt-1 relative sm:mt-0 sm:col-span-2">
|
||||
<ListboxButton
|
||||
class="bg-white relative w-full max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:ring-1"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.employmentForm, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.employmentForm }"
|
||||
>
|
||||
<span class="block truncate">{{ form.role.label }}</span>
|
||||
<span class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
||||
<SelectorIcon class="h-5 w-5 text-gray-400" />
|
||||
</span>
|
||||
</ListboxButton>
|
||||
<transition
|
||||
leave-active-class="transition ease-in duration-100"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0"
|
||||
>
|
||||
<ListboxOptions class="absolute z-10 mt-1 w-full max-w-lg bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm">
|
||||
<ListboxOption
|
||||
v-for="role in roles"
|
||||
:key="role.value"
|
||||
v-slot="{ active, selected }"
|
||||
as="template"
|
||||
:value="role"
|
||||
>
|
||||
<li :class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']">
|
||||
<span :class="[selected ? 'font-semibold' : 'font-normal', 'block truncate']">
|
||||
{{ role.label }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="selected"
|
||||
:class="[active ? 'text-white' : 'text-blumilk-600', 'absolute inset-y-0 right-0 flex items-center pr-4']"
|
||||
>
|
||||
<CheckIcon class="h-5 w-5" />
|
||||
</span>
|
||||
</li>
|
||||
</ListboxOption>
|
||||
</ListboxOptions>
|
||||
</transition>
|
||||
<p
|
||||
v-if="form.errors.role"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.role }}
|
||||
</p>
|
||||
</div>
|
||||
</Listbox>
|
||||
<Listbox
|
||||
v-model="form.employmentForm"
|
||||
as="div"
|
||||
class="sm:grid sm:grid-cols-3 py-4 items-center"
|
||||
>
|
||||
<ListboxLabel class="block text-sm font-medium text-gray-700">
|
||||
Forma zatrudnienia
|
||||
</ListboxLabel>
|
||||
<div class="mt-1 relative sm:mt-0 sm:col-span-2">
|
||||
<ListboxButton
|
||||
class="bg-white relative w-full max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:ring-1"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.employmentForm, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.employmentForm }"
|
||||
>
|
||||
<span class="block truncate">{{ form.employmentForm.label }}</span>
|
||||
<span class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
||||
<SelectorIcon class="h-5 w-5 text-gray-400" />
|
||||
</span>
|
||||
</ListboxButton>
|
||||
|
||||
<transition
|
||||
leave-active-class="transition ease-in duration-100"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0"
|
||||
>
|
||||
<ListboxOptions class="absolute z-10 mt-1 w-full max-w-lg bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm">
|
||||
<ListboxOption
|
||||
v-for="employmentForm in employmentForms"
|
||||
:key="employmentForm.value"
|
||||
v-slot="{ active, selected }"
|
||||
as="template"
|
||||
:value="employmentForm"
|
||||
>
|
||||
<li :class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']">
|
||||
<span :class="[selected ? 'font-semibold' : 'font-normal', 'block truncate']">
|
||||
{{ employmentForm.label }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="selected"
|
||||
:class="[active ? 'text-white' : 'text-blumilk-600', 'absolute inset-y-0 right-0 flex items-center pr-4']"
|
||||
>
|
||||
<CheckIcon class="h-5 w-5" />
|
||||
</span>
|
||||
</li>
|
||||
</ListboxOption>
|
||||
</ListboxOptions>
|
||||
</transition>
|
||||
<p
|
||||
v-if="form.errors.employmentForm"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.employmentForm }}
|
||||
</p>
|
||||
</div>
|
||||
</Listbox>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="employment_date"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Data zatrudnienia
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<FlatPickr
|
||||
id="employment_date"
|
||||
v-model="form.employmentDate"
|
||||
placeholder="Wybierz datę"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.employmentDate, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.employmentDate }"
|
||||
/>
|
||||
<p
|
||||
v-if="form.errors.employmentDate"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.employmentDate }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end py-3">
|
||||
<div class="space-x-3">
|
||||
<InertiaLink
|
||||
href="/users"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Anuluj
|
||||
</InertiaLink>
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="form.processing"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Zapisz
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useForm } from '@inertiajs/inertia-vue3';
|
||||
import FlatPickr from 'vue-flatpickr-component';
|
||||
import { Listbox, ListboxButton, ListboxLabel, ListboxOption, ListboxOptions } from '@headlessui/vue';
|
||||
import { CheckIcon, SelectorIcon } from '@heroicons/vue/solid';
|
||||
import { useForm } from '@inertiajs/inertia-vue3'
|
||||
import FlatPickr from 'vue-flatpickr-component'
|
||||
import { Listbox, ListboxButton, ListboxLabel, ListboxOption, ListboxOptions } from '@headlessui/vue'
|
||||
import { CheckIcon, SelectorIcon } from '@heroicons/vue/solid'
|
||||
|
||||
export default {
|
||||
employmentDate: 'UserCreate',
|
||||
components: {
|
||||
FlatPickr,
|
||||
Listbox,
|
||||
ListboxButton,
|
||||
ListboxLabel,
|
||||
ListboxOption,
|
||||
ListboxOptions,
|
||||
CheckIcon,
|
||||
SelectorIcon,
|
||||
name: 'UserCreate',
|
||||
components: {
|
||||
FlatPickr,
|
||||
Listbox,
|
||||
ListboxButton,
|
||||
ListboxLabel,
|
||||
ListboxOption,
|
||||
ListboxOptions,
|
||||
CheckIcon,
|
||||
SelectorIcon,
|
||||
},
|
||||
props: {
|
||||
employmentForms: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
props: {
|
||||
employmentForms: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
roles: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
setup(props) {
|
||||
const form = useForm({
|
||||
firstName: null,
|
||||
lastName: null,
|
||||
email: null,
|
||||
employmentForm: props.employmentForms[0],
|
||||
employmentDate: null,
|
||||
});
|
||||
},
|
||||
setup(props) {
|
||||
const form = useForm({
|
||||
firstName: null,
|
||||
lastName: null,
|
||||
email: null,
|
||||
employmentForm: props.employmentForms[0],
|
||||
role: props.roles[0],
|
||||
employmentDate: null,
|
||||
})
|
||||
|
||||
return { form };
|
||||
return { form }
|
||||
},
|
||||
methods: {
|
||||
createUser() {
|
||||
this.form
|
||||
.transform(data => ({
|
||||
...data,
|
||||
employmentForm: data.employmentForm.value,
|
||||
role: data.role.value,
|
||||
}))
|
||||
.post('/users')
|
||||
},
|
||||
methods: {
|
||||
createUser() {
|
||||
this.form
|
||||
.transform(data => ({
|
||||
...data,
|
||||
employmentForm: data.employmentForm.value,
|
||||
}))
|
||||
.post('/users');
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@@ -1,234 +1,293 @@
|
||||
<template>
|
||||
<InertiaHead title="Edycja użytkownika" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="p-4 sm:px-6">
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Edytuj użytkownika
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Edytuj dane użytkownika, takie jak e-mail czy formę zatrudnienia.
|
||||
</p>
|
||||
</div>
|
||||
<form
|
||||
class="border-t border-gray-200 px-6"
|
||||
@submit.prevent="editUser"
|
||||
>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="firstName"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Imię
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="firstName"
|
||||
v-model="form.firstName"
|
||||
type="text"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.firstName, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.firstName }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.firstName"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.firstName }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="lastName"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Nazwisko
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="lastName"
|
||||
v-model="form.lastName"
|
||||
type="text"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.lastName, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.lastName }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.lastName"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.lastName }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="email"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Adres e-mail
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="email"
|
||||
v-model="form.email"
|
||||
type="email"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.email, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.email }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.email"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.email }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Listbox
|
||||
v-model="form.employmentForm"
|
||||
as="div"
|
||||
class="sm:grid sm:grid-cols-3 py-4 items-center"
|
||||
>
|
||||
<ListboxLabel class="block text-sm font-medium text-gray-700">
|
||||
Forma zatrudnienia
|
||||
</ListboxLabel>
|
||||
<div class="mt-1 relative sm:mt-0 sm:col-span-2">
|
||||
<ListboxButton
|
||||
class="bg-white relative w-full max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:ring-1"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.employmentForm, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.employmentForm }"
|
||||
>
|
||||
<span class="block truncate">{{ form.employmentForm.label }}</span>
|
||||
<span class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
||||
<SelectorIcon class="h-5 w-5 text-gray-400" />
|
||||
</span>
|
||||
</ListboxButton>
|
||||
|
||||
<transition
|
||||
leave-active-class="transition ease-in duration-100"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0"
|
||||
>
|
||||
<ListboxOptions class="absolute z-10 mt-1 w-full max-w-lg bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm">
|
||||
<ListboxOption
|
||||
v-for="employmentForm in employmentForms"
|
||||
:key="employmentForm.value"
|
||||
v-slot="{ active, selected }"
|
||||
as="template"
|
||||
:value="employmentForm"
|
||||
>
|
||||
<li :class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']">
|
||||
<span :class="[selected ? 'font-semibold' : 'font-normal', 'block truncate']">
|
||||
{{ employmentForm.label }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="selected"
|
||||
:class="[active ? 'text-white' : 'text-blumilk-600', 'absolute inset-y-0 right-0 flex items-center pr-4']"
|
||||
>
|
||||
<CheckIcon class="h-5 w-5" />
|
||||
</span>
|
||||
</li>
|
||||
</ListboxOption>
|
||||
</ListboxOptions>
|
||||
</transition>
|
||||
<p
|
||||
v-if="form.errors.employmentForm"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.employmentForm }}
|
||||
</p>
|
||||
</div>
|
||||
</Listbox>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="employment_date"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Data zatrudnienia
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<FlatPickr
|
||||
id="employment_date"
|
||||
v-model="form.employmentDate"
|
||||
placeholder="Wybierz datę"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.employmentDate, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.employmentDate }"
|
||||
/>
|
||||
<p
|
||||
v-if="form.errors.employmentDate"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.employmentDate }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end py-3">
|
||||
<div class="space-x-3">
|
||||
<InertiaLink
|
||||
href="/users"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Anuluj
|
||||
</InertiaLink>
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="form.processing"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Zapisz
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<InertiaHead title="Edycja użytkownika" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="p-4 sm:px-6">
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Edytuj użytkownika
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Edytuj dane użytkownika, takie jak e-mail czy formę zatrudnienia.
|
||||
</p>
|
||||
</div>
|
||||
<form
|
||||
class="border-t border-gray-200 px-6"
|
||||
@submit.prevent="editUser"
|
||||
>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="firstName"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Imię
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="firstName"
|
||||
v-model="form.firstName"
|
||||
type="text"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.firstName, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.firstName }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.firstName"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.firstName }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="lastName"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Nazwisko
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="lastName"
|
||||
v-model="form.lastName"
|
||||
type="text"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.lastName, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.lastName }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.lastName"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.lastName }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="email"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Adres e-mail
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
id="email"
|
||||
v-model="form.email"
|
||||
type="email"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.email, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.email }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors.email"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.email }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Listbox
|
||||
v-model="form.role"
|
||||
as="div"
|
||||
class="sm:grid sm:grid-cols-3 py-4 items-center"
|
||||
>
|
||||
<ListboxLabel class="block text-sm font-medium text-gray-700">
|
||||
Rola
|
||||
</ListboxLabel>
|
||||
<div class="mt-1 relative sm:mt-0 sm:col-span-2">
|
||||
<ListboxButton
|
||||
class="bg-white relative w-full max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:ring-1"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.employmentForm, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.employmentForm }"
|
||||
>
|
||||
<span class="block truncate">{{ form.role.label }}</span>
|
||||
<span class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
||||
<SelectorIcon class="h-5 w-5 text-gray-400" />
|
||||
</span>
|
||||
</ListboxButton>
|
||||
<transition
|
||||
leave-active-class="transition ease-in duration-100"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0"
|
||||
>
|
||||
<ListboxOptions class="absolute z-10 mt-1 w-full max-w-lg bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm">
|
||||
<ListboxOption
|
||||
v-for="role in roles"
|
||||
:key="role.value"
|
||||
v-slot="{ active, selected }"
|
||||
as="template"
|
||||
:value="role"
|
||||
>
|
||||
<li :class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']">
|
||||
<span :class="[selected ? 'font-semibold' : 'font-normal', 'block truncate']">
|
||||
{{ role.label }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="selected"
|
||||
:class="[active ? 'text-white' : 'text-blumilk-600', 'absolute inset-y-0 right-0 flex items-center pr-4']"
|
||||
>
|
||||
<CheckIcon class="h-5 w-5" />
|
||||
</span>
|
||||
</li>
|
||||
</ListboxOption>
|
||||
</ListboxOptions>
|
||||
</transition>
|
||||
<p
|
||||
v-if="form.errors.role"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.role }}
|
||||
</p>
|
||||
</div>
|
||||
</Listbox>
|
||||
<Listbox
|
||||
v-model="form.employmentForm"
|
||||
as="div"
|
||||
class="sm:grid sm:grid-cols-3 py-4 items-center"
|
||||
>
|
||||
<ListboxLabel class="block text-sm font-medium text-gray-700">
|
||||
Forma zatrudnienia
|
||||
</ListboxLabel>
|
||||
<div class="mt-1 relative sm:mt-0 sm:col-span-2">
|
||||
<ListboxButton
|
||||
class="bg-white relative w-full max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:ring-1"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.employmentForm, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.employmentForm }"
|
||||
>
|
||||
<span class="block truncate">{{ form.employmentForm.label }}</span>
|
||||
<span class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
||||
<SelectorIcon class="h-5 w-5 text-gray-400" />
|
||||
</span>
|
||||
</ListboxButton>
|
||||
<transition
|
||||
leave-active-class="transition ease-in duration-100"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0"
|
||||
>
|
||||
<ListboxOptions class="absolute z-10 mt-1 w-full max-w-lg bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm">
|
||||
<ListboxOption
|
||||
v-for="employmentForm in employmentForms"
|
||||
:key="employmentForm.value"
|
||||
v-slot="{ active, selected }"
|
||||
as="template"
|
||||
:value="employmentForm"
|
||||
>
|
||||
<li :class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']">
|
||||
<span :class="[selected ? 'font-semibold' : 'font-normal', 'block truncate']">
|
||||
{{ employmentForm.label }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="selected"
|
||||
:class="[active ? 'text-white' : 'text-blumilk-600', 'absolute inset-y-0 right-0 flex items-center pr-4']"
|
||||
>
|
||||
<CheckIcon class="h-5 w-5" />
|
||||
</span>
|
||||
</li>
|
||||
</ListboxOption>
|
||||
</ListboxOptions>
|
||||
</transition>
|
||||
<p
|
||||
v-if="form.errors.employmentForm"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.employmentForm }}
|
||||
</p>
|
||||
</div>
|
||||
</Listbox>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="employment_date"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Data zatrudnienia
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<FlatPickr
|
||||
id="employment_date"
|
||||
v-model="form.employmentDate"
|
||||
placeholder="Wybierz datę"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.employmentDate, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.employmentDate }"
|
||||
/>
|
||||
<p
|
||||
v-if="form.errors.employmentDate"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.employmentDate }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end py-3">
|
||||
<div class="space-x-3">
|
||||
<InertiaLink
|
||||
href="/users"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Anuluj
|
||||
</InertiaLink>
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="form.processing"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Zapisz
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {useForm} from '@inertiajs/inertia-vue3';
|
||||
import FlatPickr from 'vue-flatpickr-component';
|
||||
import {Listbox, ListboxButton, ListboxLabel, ListboxOption, ListboxOptions} from '@headlessui/vue';
|
||||
import {CheckIcon, SelectorIcon} from '@heroicons/vue/solid';
|
||||
import {useForm} from '@inertiajs/inertia-vue3'
|
||||
import FlatPickr from 'vue-flatpickr-component'
|
||||
import {Listbox, ListboxButton, ListboxLabel, ListboxOption, ListboxOptions} from '@headlessui/vue'
|
||||
import {CheckIcon, SelectorIcon} from '@heroicons/vue/solid'
|
||||
|
||||
export default {
|
||||
employmentDate: 'UserEdit',
|
||||
components: {
|
||||
FlatPickr,
|
||||
Listbox,
|
||||
ListboxButton,
|
||||
ListboxLabel,
|
||||
ListboxOption,
|
||||
ListboxOptions,
|
||||
CheckIcon,
|
||||
SelectorIcon,
|
||||
name: 'UserEdit',
|
||||
components: {
|
||||
FlatPickr,
|
||||
Listbox,
|
||||
ListboxButton,
|
||||
ListboxLabel,
|
||||
ListboxOption,
|
||||
ListboxOptions,
|
||||
CheckIcon,
|
||||
SelectorIcon,
|
||||
},
|
||||
props: {
|
||||
employmentForms: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
props: {
|
||||
employmentForms: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
user: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
roles: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
setup(props) {
|
||||
const form = useForm({
|
||||
firstName: props.user.firstName,
|
||||
lastName: props.user.lastName,
|
||||
email: props.user.email,
|
||||
employmentForm: props.employmentForms.find(form => form.value === props.user.employmentForm),
|
||||
employmentDate: props.user.employmentDate,
|
||||
});
|
||||
user: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const form = useForm({
|
||||
firstName: props.user.firstName,
|
||||
lastName: props.user.lastName,
|
||||
email: props.user.email,
|
||||
role: props.roles.find(role => role.value === props.user.role),
|
||||
employmentForm: props.employmentForms.find(form => form.value === props.user.employmentForm),
|
||||
employmentDate: props.user.employmentDate,
|
||||
})
|
||||
|
||||
return { form };
|
||||
return { form }
|
||||
},
|
||||
methods: {
|
||||
editUser() {
|
||||
this.form
|
||||
.transform(data => ({
|
||||
...data,
|
||||
employmentForm: data.employmentForm.value,
|
||||
role: data.role.value,
|
||||
}))
|
||||
.put(`/users/${this.user.id}`)
|
||||
},
|
||||
methods: {
|
||||
editUser() {
|
||||
this.form
|
||||
.transform(data => ({
|
||||
...data,
|
||||
employmentForm: data.employmentForm.value,
|
||||
}))
|
||||
.put(`/users/${this.user.id}`);
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@@ -1,300 +1,300 @@
|
||||
<template>
|
||||
<InertiaHead title="Użytkownicy" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="flex justify-between items-center p-4 sm:px-6">
|
||||
<div>
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Użytkownicy w organizacji
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Lista użytkowników w organizacji.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<InertiaLink
|
||||
href="users/create"
|
||||
class="inline-flex items-center px-4 py-3 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Dodaj użytkownika
|
||||
</InertiaLink>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-200">
|
||||
<div class="px-4 py-3">
|
||||
<div class="relative max-w-md">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<SearchIcon class="h-5 w-5 text-gray-400" />
|
||||
</div>
|
||||
<input
|
||||
v-model.trim="search"
|
||||
type="search"
|
||||
class="block w-full bg-white border border-gray-300 rounded-md py-2 pl-10 pr-3 text-sm placeholder-gray-500 focus:outline-none focus:text-gray-900 focus:placeholder-gray-400 focus:ring-1 focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm mt-1"
|
||||
placeholder="Szukaj"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Imię i nazwisko
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Rola
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Forma zatrudnienia
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Data rozpoczęcia
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
/>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-100">
|
||||
<tr
|
||||
v-for="user in users.data"
|
||||
:key="user.id"
|
||||
:class="{ 'bg-red-50': user.deleted, 'hover:bg-blumilk-25': !user.deleted }"
|
||||
>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<div class="flex">
|
||||
<span
|
||||
class="inline-flex items-center justify-center h-10 w-10 rounded-full"
|
||||
>
|
||||
<img
|
||||
class="h-10 w-10 rounded-full"
|
||||
:src="user.avatar"
|
||||
alt=""
|
||||
>
|
||||
</span>
|
||||
<div class="ml-3">
|
||||
<p class="text-sm font-medium break-all text-gray-900">
|
||||
{{ user.name }}
|
||||
</p>
|
||||
<p class="text-sm break-all text-gray-500">
|
||||
{{ user.email }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ user.role }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ user.employmentForm }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ user.employmentDate }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500 text-right">
|
||||
<Menu
|
||||
as="div"
|
||||
class="relative inline-block text-left"
|
||||
>
|
||||
<MenuButton class="rounded-full flex items-center text-gray-400 hover:text-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-blumilk-500">
|
||||
<DotsVerticalIcon
|
||||
class="h-5 w-5"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</MenuButton>
|
||||
|
||||
<transition
|
||||
enter-active-class="transition ease-out duration-100"
|
||||
enter-from-class="transform opacity-0 scale-95"
|
||||
enter-to-class="transform opacity-100 scale-100"
|
||||
leave-active-class="transition ease-in duration-75"
|
||||
leave-from-class="transform opacity-100 scale-100"
|
||||
leave-to-class="transform opacity-0 scale-95"
|
||||
>
|
||||
<MenuItems class="origin-top-right absolute right-0 mt-2 w-56 z-10 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none">
|
||||
<div
|
||||
v-if="!user.deleted"
|
||||
class="py-1"
|
||||
>
|
||||
<MenuItem
|
||||
v-slot="{ active }"
|
||||
class="flex"
|
||||
>
|
||||
<InertiaLink
|
||||
:href="`/users/${user.id}/edit`"
|
||||
:class="[active ? 'bg-gray-100 text-gray-900' : 'text-gray-700', 'font-medium block px-4 py-2 text-sm']"
|
||||
>
|
||||
<PencilIcon
|
||||
class="mr-2 h-5 w-5 text-blue-500"
|
||||
aria-hidden="true"
|
||||
/> Edytuj
|
||||
</InertiaLink>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
v-slot="{ active }"
|
||||
class="flex"
|
||||
>
|
||||
<InertiaLink
|
||||
as="button"
|
||||
method="delete"
|
||||
:preserve-scroll="true"
|
||||
:href="`/users/${user.id}`"
|
||||
:class="[active ? 'bg-gray-100 text-gray-900' : 'text-gray-700', 'block w-full text-left font-medium px-4 py-2 text-sm']"
|
||||
>
|
||||
<TrashIcon
|
||||
class="mr-2 h-5 w-5 text-red-500"
|
||||
aria-hidden="true"
|
||||
/> Usuń
|
||||
</InertiaLink>
|
||||
</MenuItem>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="py-1"
|
||||
>
|
||||
<MenuItem
|
||||
v-slot="{ active }"
|
||||
class="flex"
|
||||
>
|
||||
<InertiaLink
|
||||
as="button"
|
||||
method="post"
|
||||
:preserve-scroll="true"
|
||||
:href="`/users/${user.id}/restore`"
|
||||
:class="[active ? 'bg-gray-100 text-gray-900' : 'text-gray-700', 'block w-full text-left font-medium px-4 py-2 text-sm']"
|
||||
>
|
||||
<RefreshIcon
|
||||
class="mr-2 h-5 w-5 text-green-500"
|
||||
aria-hidden="true"
|
||||
/> Przywróć
|
||||
</InertiaLink>
|
||||
</MenuItem>
|
||||
</div>
|
||||
</MenuItems>
|
||||
</transition>
|
||||
</Menu>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-if="! users.data.length"
|
||||
>
|
||||
<td
|
||||
colspan="100%"
|
||||
class="text-center py-4 text-xl leading-5 text-gray-700"
|
||||
>
|
||||
Brak danych
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div
|
||||
v-if="users.data.length && users.meta.last_page !== 1"
|
||||
class="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6 rounded-b-lg"
|
||||
>
|
||||
<div class="flex-1 flex justify-between sm:hidden">
|
||||
<InertiaLink
|
||||
:is="users.links.prev ? 'InertiaLink': 'span'"
|
||||
:href="users.links.prev"
|
||||
class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
|
||||
>
|
||||
Poprzednia
|
||||
</InertiaLink>
|
||||
<Component
|
||||
:is="users.links.next ? 'InertiaLink': 'span'"
|
||||
:href="users.links.next"
|
||||
class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
|
||||
>
|
||||
Następna
|
||||
</Component>
|
||||
</div>
|
||||
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
|
||||
<div class="text-sm text-gray-700">
|
||||
Wyświetlanie
|
||||
<span class="font-medium">{{ users.meta.from }}</span>
|
||||
od
|
||||
<span class="font-medium">{{ users.meta.to }}</span>
|
||||
do
|
||||
<span class="font-medium">{{ users.meta.total }}</span>
|
||||
wyników
|
||||
</div>
|
||||
<nav class="relative z-0 inline-flex space-x-1">
|
||||
<template
|
||||
v-for="(link, index) in users.meta.links"
|
||||
:key="index"
|
||||
>
|
||||
<Component
|
||||
:is="link.url ? 'InertiaLink' : 'span'"
|
||||
:href="link.url"
|
||||
:preserve-scroll="true"
|
||||
class="relative inline-flex items-center px-4 py-2 border rounded-md text-sm font-medium"
|
||||
:class="{ 'z-10 bg-blumilk-25 border-blumilk-500 text-blumilk-600': link.active, 'bg-white border-gray-300 text-gray-500': !link.active, 'hover:bg-blumilk-25': link.url, 'border-none': !link.url}"
|
||||
v-text="link.label"
|
||||
/>
|
||||
</template>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<InertiaHead title="Użytkownicy" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="flex justify-between items-center p-4 sm:px-6">
|
||||
<div>
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Użytkownicy w organizacji
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Lista użytkowników w organizacji.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<InertiaLink
|
||||
href="users/create"
|
||||
class="inline-flex items-center px-4 py-3 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Dodaj użytkownika
|
||||
</InertiaLink>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-200">
|
||||
<div class="px-4 py-3">
|
||||
<div class="relative max-w-md">
|
||||
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<SearchIcon class="h-5 w-5 text-gray-400" />
|
||||
</div>
|
||||
<input
|
||||
v-model.trim="search"
|
||||
type="search"
|
||||
class="block w-full bg-white border border-gray-300 rounded-md py-2 pl-10 pr-3 text-sm placeholder-gray-500 focus:outline-none focus:text-gray-900 focus:placeholder-gray-400 focus:ring-1 focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm mt-1"
|
||||
placeholder="Szukaj"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Imię i nazwisko
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Rola
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Forma zatrudnienia
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Data rozpoczęcia
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
/>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-100">
|
||||
<tr
|
||||
v-for="user in users.data"
|
||||
:key="user.id"
|
||||
:class="{ 'bg-red-50': user.deleted, 'hover:bg-blumilk-25': !user.deleted }"
|
||||
>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<div class="flex">
|
||||
<span
|
||||
class="inline-flex items-center justify-center h-10 w-10 rounded-full"
|
||||
>
|
||||
<img
|
||||
class="h-10 w-10 rounded-full"
|
||||
:src="user.avatar"
|
||||
alt=""
|
||||
>
|
||||
</span>
|
||||
<div class="ml-3">
|
||||
<p class="text-sm font-medium break-all text-gray-900">
|
||||
{{ user.name }}
|
||||
</p>
|
||||
<p class="text-sm break-all text-gray-500">
|
||||
{{ user.email }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ user.role }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ user.employmentForm }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ user.employmentDate }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500 text-right">
|
||||
<Menu
|
||||
as="div"
|
||||
class="relative inline-block text-left"
|
||||
>
|
||||
<MenuButton class="rounded-full flex items-center text-gray-400 hover:text-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-blumilk-500">
|
||||
<DotsVerticalIcon
|
||||
class="h-5 w-5"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</MenuButton>
|
||||
|
||||
<transition
|
||||
enter-active-class="transition ease-out duration-100"
|
||||
enter-from-class="transform opacity-0 scale-95"
|
||||
enter-to-class="transform opacity-100 scale-100"
|
||||
leave-active-class="transition ease-in duration-75"
|
||||
leave-from-class="transform opacity-100 scale-100"
|
||||
leave-to-class="transform opacity-0 scale-95"
|
||||
>
|
||||
<MenuItems class="origin-top-right absolute right-0 mt-2 w-56 z-10 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none">
|
||||
<div
|
||||
v-if="!user.deleted"
|
||||
class="py-1"
|
||||
>
|
||||
<MenuItem
|
||||
v-slot="{ active }"
|
||||
class="flex"
|
||||
>
|
||||
<InertiaLink
|
||||
:href="`/users/${user.id}/edit`"
|
||||
:class="[active ? 'bg-gray-100 text-gray-900' : 'text-gray-700', 'font-medium block px-4 py-2 text-sm']"
|
||||
>
|
||||
<PencilIcon
|
||||
class="mr-2 h-5 w-5 text-blue-500"
|
||||
aria-hidden="true"
|
||||
/> Edytuj
|
||||
</InertiaLink>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
v-slot="{ active }"
|
||||
class="flex"
|
||||
>
|
||||
<InertiaLink
|
||||
as="button"
|
||||
method="delete"
|
||||
:preserve-scroll="true"
|
||||
:href="`/users/${user.id}`"
|
||||
:class="[active ? 'bg-gray-100 text-gray-900' : 'text-gray-700', 'block w-full text-left font-medium px-4 py-2 text-sm']"
|
||||
>
|
||||
<TrashIcon
|
||||
class="mr-2 h-5 w-5 text-red-500"
|
||||
aria-hidden="true"
|
||||
/> Usuń
|
||||
</InertiaLink>
|
||||
</MenuItem>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="py-1"
|
||||
>
|
||||
<MenuItem
|
||||
v-slot="{ active }"
|
||||
class="flex"
|
||||
>
|
||||
<InertiaLink
|
||||
as="button"
|
||||
method="post"
|
||||
:preserve-scroll="true"
|
||||
:href="`/users/${user.id}/restore`"
|
||||
:class="[active ? 'bg-gray-100 text-gray-900' : 'text-gray-700', 'block w-full text-left font-medium px-4 py-2 text-sm']"
|
||||
>
|
||||
<RefreshIcon
|
||||
class="mr-2 h-5 w-5 text-green-500"
|
||||
aria-hidden="true"
|
||||
/> Przywróć
|
||||
</InertiaLink>
|
||||
</MenuItem>
|
||||
</div>
|
||||
</MenuItems>
|
||||
</transition>
|
||||
</Menu>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-if="! users.data.length"
|
||||
>
|
||||
<td
|
||||
colspan="100%"
|
||||
class="text-center py-4 text-xl leading-5 text-gray-700"
|
||||
>
|
||||
Brak danych
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div
|
||||
v-if="users.data.length && users.meta.last_page !== 1"
|
||||
class="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6 rounded-b-lg"
|
||||
>
|
||||
<div class="flex-1 flex justify-between sm:hidden">
|
||||
<InertiaLink
|
||||
:is="users.links.prev ? 'InertiaLink': 'span'"
|
||||
:href="users.links.prev"
|
||||
class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
|
||||
>
|
||||
Poprzednia
|
||||
</InertiaLink>
|
||||
<Component
|
||||
:is="users.links.next ? 'InertiaLink': 'span'"
|
||||
:href="users.links.next"
|
||||
class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
|
||||
>
|
||||
Następna
|
||||
</Component>
|
||||
</div>
|
||||
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
|
||||
<div class="text-sm text-gray-700">
|
||||
Wyświetlanie
|
||||
<span class="font-medium">{{ users.meta.from }}</span>
|
||||
od
|
||||
<span class="font-medium">{{ users.meta.to }}</span>
|
||||
do
|
||||
<span class="font-medium">{{ users.meta.total }}</span>
|
||||
wyników
|
||||
</div>
|
||||
<nav class="relative z-0 inline-flex space-x-1">
|
||||
<template
|
||||
v-for="(link, index) in users.meta.links"
|
||||
:key="index"
|
||||
>
|
||||
<Component
|
||||
:is="link.url ? 'InertiaLink' : 'span'"
|
||||
:href="link.url"
|
||||
:preserve-scroll="true"
|
||||
class="relative inline-flex items-center px-4 py-2 border rounded-md text-sm font-medium"
|
||||
:class="{ 'z-10 bg-blumilk-25 border-blumilk-500 text-blumilk-600': link.active, 'bg-white border-gray-300 text-gray-500': !link.active, 'hover:bg-blumilk-25': link.url, 'border-none': !link.url}"
|
||||
v-text="link.label"
|
||||
/>
|
||||
</template>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, watch } from 'vue';
|
||||
import { Inertia } from '@inertiajs/inertia';
|
||||
import { debounce } from 'lodash';
|
||||
import { SearchIcon } from '@heroicons/vue/outline';
|
||||
import { DotsVerticalIcon, PencilIcon, TrashIcon, RefreshIcon } from '@heroicons/vue/solid';
|
||||
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue';
|
||||
import { ref, watch } from 'vue'
|
||||
import { Inertia } from '@inertiajs/inertia'
|
||||
import { debounce } from 'lodash'
|
||||
import { SearchIcon } from '@heroicons/vue/outline'
|
||||
import { DotsVerticalIcon, PencilIcon, TrashIcon, RefreshIcon } from '@heroicons/vue/solid'
|
||||
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue'
|
||||
|
||||
export default {
|
||||
name: 'UserIndex',
|
||||
components: {
|
||||
SearchIcon,
|
||||
DotsVerticalIcon,
|
||||
PencilIcon,
|
||||
TrashIcon,
|
||||
RefreshIcon,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuItem,
|
||||
MenuItems,
|
||||
name: 'UserIndex',
|
||||
components: {
|
||||
SearchIcon,
|
||||
DotsVerticalIcon,
|
||||
PencilIcon,
|
||||
TrashIcon,
|
||||
RefreshIcon,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuItem,
|
||||
MenuItems,
|
||||
},
|
||||
props: {
|
||||
users: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
props: {
|
||||
users: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
filters: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
filters: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
setup(props) {
|
||||
let search = ref(props.filters.search);
|
||||
},
|
||||
setup(props) {
|
||||
let search = ref(props.filters.search)
|
||||
|
||||
watch(search, debounce(value => {
|
||||
Inertia.get('/users', value ? { search: value} : {}, {
|
||||
preserveState: true,
|
||||
replace: true,
|
||||
});
|
||||
}, 300));
|
||||
watch(search, debounce(value => {
|
||||
Inertia.get('/users', value ? { search: value} : {}, {
|
||||
preserveState: true,
|
||||
replace: true,
|
||||
})
|
||||
}, 300))
|
||||
|
||||
return {
|
||||
search,
|
||||
};
|
||||
},
|
||||
};
|
||||
return {
|
||||
search,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@@ -1,175 +1,175 @@
|
||||
<template>
|
||||
<InertiaHead title="Użytkownicy" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="flex justify-between items-center p-4 sm:px-6">
|
||||
<div>
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Dostępne dni urlopu dla użytkowników
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Zarządzaj dostepnymi dniami urlopów dla użytkowników.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-200">
|
||||
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
|
||||
<form @submit.prevent="submitVacationDays">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Imię i nazwisko
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Forma zatrudnienia
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Posiada urlop?
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Dostępne dni w roku
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-100">
|
||||
<tr
|
||||
v-for="(item, index) in form.items"
|
||||
:key="item.id"
|
||||
class="hover:bg-blumilk-25"
|
||||
>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<div class="flex">
|
||||
<span
|
||||
class="inline-flex items-center justify-center h-10 w-10 rounded-full"
|
||||
>
|
||||
<img
|
||||
class="h-10 w-10 rounded-full"
|
||||
:src="item.user.avatar"
|
||||
alt=""
|
||||
>
|
||||
</span>
|
||||
<div class="ml-3">
|
||||
<p class="text-sm font-medium break-all text-gray-900">
|
||||
{{ item.user.name }}
|
||||
</p>
|
||||
<p class="text-sm break-all text-gray-500">
|
||||
{{ item.user.email }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ item.user.employmentForm }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<Switch
|
||||
v-model="item.hasVacation"
|
||||
:class="[item.hasVacation ? 'bg-blumilk-500' : 'bg-gray-200', 'relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500']"
|
||||
>
|
||||
<span
|
||||
:class="[item.hasVacation ? 'translate-x-5' : 'translate-x-0', 'pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200']"
|
||||
/>
|
||||
</Switch>
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
v-model="item.days"
|
||||
type="number"
|
||||
min="0"
|
||||
class="block w-full shadow-sm rounded-md sm:text-sm disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none disabled:cursor-not-allowed"
|
||||
:disabled="!item.hasVacation"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`items.${index}.days`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`items.${index}.days`] }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors[`items.${index}.days`]"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors[`items.${index}.days`] }}
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-if="!form.items.length"
|
||||
>
|
||||
<td
|
||||
colspan="100%"
|
||||
class="text-center py-4 text-xl leading-5 text-gray-700"
|
||||
>
|
||||
Brak danych
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="flex justify-end py-3 px-4">
|
||||
<button
|
||||
type="submit"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Zapisz
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<InertiaHead title="Użytkownicy" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="flex justify-between items-center p-4 sm:px-6">
|
||||
<div>
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Dostępne dni urlopu dla użytkowników
|
||||
</h2>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
Zarządzaj dostepnymi dniami urlopów dla użytkowników.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-200">
|
||||
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
|
||||
<form @submit.prevent="submitVacationDays">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Imię i nazwisko
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Forma zatrudnienia
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Posiada urlop?
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Dostępne dni w roku
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-100">
|
||||
<tr
|
||||
v-for="(item, index) in form.items"
|
||||
:key="item.id"
|
||||
class="hover:bg-blumilk-25"
|
||||
>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<div class="flex">
|
||||
<span
|
||||
class="inline-flex items-center justify-center h-10 w-10 rounded-full"
|
||||
>
|
||||
<img
|
||||
class="h-10 w-10 rounded-full"
|
||||
:src="item.user.avatar"
|
||||
alt=""
|
||||
>
|
||||
</span>
|
||||
<div class="ml-3">
|
||||
<p class="text-sm font-medium break-all text-gray-900">
|
||||
{{ item.user.name }}
|
||||
</p>
|
||||
<p class="text-sm break-all text-gray-500">
|
||||
{{ item.user.email }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ item.user.employmentForm }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<Switch
|
||||
v-model="item.hasVacation"
|
||||
:class="[item.hasVacation ? 'bg-blumilk-500' : 'bg-gray-200', 'relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500']"
|
||||
>
|
||||
<span
|
||||
:class="[item.hasVacation ? 'translate-x-5' : 'translate-x-0', 'pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200']"
|
||||
/>
|
||||
</Switch>
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<input
|
||||
v-model="item.days"
|
||||
type="number"
|
||||
min="0"
|
||||
class="block w-full shadow-sm rounded-md sm:text-sm disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none disabled:cursor-not-allowed"
|
||||
:disabled="!item.hasVacation"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors[`items.${index}.days`], 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors[`items.${index}.days`] }"
|
||||
>
|
||||
<p
|
||||
v-if="form.errors[`items.${index}.days`]"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors[`items.${index}.days`] }}
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-if="!form.items.length"
|
||||
>
|
||||
<td
|
||||
colspan="100%"
|
||||
class="text-center py-4 text-xl leading-5 text-gray-700"
|
||||
>
|
||||
Brak danych
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="flex justify-end py-3 px-4">
|
||||
<button
|
||||
type="submit"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Zapisz
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {Switch} from '@headlessui/vue';
|
||||
import {useForm} from '@inertiajs/inertia-vue3';
|
||||
import {Switch} from '@headlessui/vue'
|
||||
import {useForm} from '@inertiajs/inertia-vue3'
|
||||
|
||||
export default {
|
||||
name: 'VacationLimits',
|
||||
components: {
|
||||
Switch,
|
||||
name: 'VacationLimits',
|
||||
components: {
|
||||
Switch,
|
||||
},
|
||||
props: {
|
||||
limits: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
props: {
|
||||
limits: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
years: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
years: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
setup(props) {
|
||||
const form = useForm({
|
||||
items: props.limits.data,
|
||||
});
|
||||
},
|
||||
setup(props) {
|
||||
const form = useForm({
|
||||
items: props.limits.data,
|
||||
})
|
||||
|
||||
return {
|
||||
form,
|
||||
};
|
||||
return {
|
||||
form,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitVacationDays() {
|
||||
this.form
|
||||
.transform(data => ({
|
||||
items: data.items.map(item => ({
|
||||
id: item.id,
|
||||
days: item.hasVacation ? item.days : null,
|
||||
})),
|
||||
}))
|
||||
.put('/vacation-limits', {
|
||||
preserveState: (page) => Object.keys(page.props.errors).length,
|
||||
preserveScroll: true,
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
submitVacationDays() {
|
||||
this.form
|
||||
.transform(data => ({
|
||||
items: data.items.map(item => ({
|
||||
id: item.id,
|
||||
days: item.hasVacation ? item.days : null,
|
||||
})),
|
||||
}))
|
||||
.put('/vacation-limits', {
|
||||
preserveState: (page) => Object.keys(page.props.errors).length,
|
||||
preserveScroll: true,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
240
resources/js/Pages/VacationRequest/Create.vue
Normal file
240
resources/js/Pages/VacationRequest/Create.vue
Normal file
@@ -0,0 +1,240 @@
|
||||
<template>
|
||||
<InertiaHead title="Złóż wniosek urlopowy" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="p-4 sm:px-6">
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Złóż wniosek urlopowy
|
||||
</h2>
|
||||
</div>
|
||||
<form
|
||||
class="border-t border-gray-200 px-6"
|
||||
@submit.prevent="createForm"
|
||||
>
|
||||
<Listbox
|
||||
v-model="form.vacationType"
|
||||
as="div"
|
||||
class="sm:grid sm:grid-cols-3 py-4 items-center"
|
||||
>
|
||||
<ListboxLabel class="block text-sm font-medium text-gray-700">
|
||||
Rodzaj wniosku
|
||||
</ListboxLabel>
|
||||
<div class="mt-1 relative sm:mt-0 sm:col-span-2">
|
||||
<ListboxButton
|
||||
class="bg-white relative w-full max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:ring-1"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.vacationType, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.vacationType }"
|
||||
>
|
||||
<span class="block truncate">{{ form.vacationType.label }}</span>
|
||||
<span class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
||||
<SelectorIcon class="h-5 w-5 text-gray-400" />
|
||||
</span>
|
||||
</ListboxButton>
|
||||
|
||||
<transition
|
||||
leave-active-class="transition ease-in duration-100"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0"
|
||||
>
|
||||
<ListboxOptions
|
||||
class="absolute z-10 mt-1 w-full max-w-lg bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm"
|
||||
>
|
||||
<ListboxOption
|
||||
v-for="vacationType in vacationTypes"
|
||||
:key="vacationType.value"
|
||||
v-slot="{ active, selected }"
|
||||
as="template"
|
||||
:value="vacationType"
|
||||
>
|
||||
<li :class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']">
|
||||
<span :class="[selected ? 'font-semibold' : 'font-normal', 'block truncate']">
|
||||
{{ vacationType.label }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="selected"
|
||||
:class="[active ? 'text-white' : 'text-blumilk-600', 'absolute inset-y-0 right-0 flex items-center pr-4']"
|
||||
>
|
||||
<CheckIcon class="h-5 w-5" />
|
||||
</span>
|
||||
</li>
|
||||
</ListboxOption>
|
||||
</ListboxOptions>
|
||||
</transition>
|
||||
<p
|
||||
v-if="form.errors.vacationType"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.vacationType }}
|
||||
</p>
|
||||
</div>
|
||||
</Listbox>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="date_from"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Planowany urlop od
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<FlatPickr
|
||||
id="date_from"
|
||||
v-model="form.dateFrom"
|
||||
:config="fromInputConfig"
|
||||
placeholder="Wybierz datę"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.dateFrom, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.dateFrom }"
|
||||
@on-change="onFromChange"
|
||||
/>
|
||||
<p
|
||||
v-if="form.errors.dateFrom"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.dateFrom }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="date_from"
|
||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||
>
|
||||
Planowany urlop do
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<FlatPickr
|
||||
id="date_to"
|
||||
v-model="form.dateTo"
|
||||
:config="toInputConfig"
|
||||
placeholder="Wybierz datę"
|
||||
class="block w-full max-w-lg shadow-sm rounded-md sm:text-sm"
|
||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.dateTo, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.dateTo }"
|
||||
@on-change="onToChange"
|
||||
/>
|
||||
<p
|
||||
v-if="form.errors.dateTo"
|
||||
class="mt-2 text-sm text-red-600"
|
||||
>
|
||||
{{ form.errors.dateTo }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<span class="block text-sm font-medium text-gray-700 sm:mt-px">Liczba dni urlopu</span>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2 w-full max-w-lg bg-gray-50 border border-gray-300 rounded-md px-4 py-2 inline-flex items-center text-gray-500 sm:text-sm">
|
||||
1
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
|
||||
<label
|
||||
for="comment"
|
||||
class="block text-sm font-medium text-gray-700"
|
||||
>
|
||||
Komentarz
|
||||
</label>
|
||||
<div class="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<textarea
|
||||
id="comment"
|
||||
v-model="form.comment"
|
||||
rows="4"
|
||||
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full max-w-lg sm:text-sm border-gray-300 rounded-md"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end py-3">
|
||||
<div class="space-x-3">
|
||||
<InertiaLink
|
||||
href="/vacation-requests"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Anuluj
|
||||
</InertiaLink>
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="form.processing"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Zapisz
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {useForm} from '@inertiajs/inertia-vue3'
|
||||
import FlatPickr from 'vue-flatpickr-component'
|
||||
import {Listbox, ListboxButton, ListboxLabel, ListboxOption, ListboxOptions} from '@headlessui/vue'
|
||||
import {CheckIcon, SelectorIcon} from '@heroicons/vue/solid'
|
||||
import {reactive} from 'vue'
|
||||
|
||||
export default {
|
||||
name: 'VacationRequestCreate',
|
||||
components: {
|
||||
FlatPickr,
|
||||
Listbox,
|
||||
ListboxButton,
|
||||
ListboxLabel,
|
||||
ListboxOption,
|
||||
ListboxOptions,
|
||||
CheckIcon,
|
||||
SelectorIcon,
|
||||
},
|
||||
props: {
|
||||
vacationTypes: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
holidays: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const form = useForm({
|
||||
dateFrom: null,
|
||||
dateTo: null,
|
||||
vacationType: props.vacationTypes[0],
|
||||
comment: null,
|
||||
})
|
||||
|
||||
const disableDates = [
|
||||
date => (date.getDay() === 0 || date.getDay() === 6),
|
||||
]
|
||||
|
||||
const fromInputConfig = reactive({
|
||||
maxDate: null,
|
||||
disable: disableDates,
|
||||
})
|
||||
|
||||
const toInputConfig = reactive({
|
||||
minDate: null,
|
||||
disable: disableDates,
|
||||
})
|
||||
|
||||
return {
|
||||
form,
|
||||
fromInputConfig,
|
||||
toInputConfig,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
createForm() {
|
||||
this.form
|
||||
.transform(data => ({
|
||||
from: data.dateFrom,
|
||||
to: data.dateTo,
|
||||
type: data.vacationType.value,
|
||||
comment: data.comment,
|
||||
}))
|
||||
.post('/vacation-requests')
|
||||
},
|
||||
onFromChange(selectedDates, dateStr) {
|
||||
this.toInputConfig.minDate = dateStr
|
||||
},
|
||||
onToChange(selectedDates, dateStr) {
|
||||
this.fromInputConfig.maxDate = dateStr
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
217
resources/js/Pages/VacationRequest/Index.vue
Normal file
217
resources/js/Pages/VacationRequest/Index.vue
Normal file
@@ -0,0 +1,217 @@
|
||||
<template>
|
||||
<InertiaHead title="Twoje wnioski urlopowe" />
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="flex justify-between items-center p-4 sm:px-6">
|
||||
<div>
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Twoje wnioski urlopowe
|
||||
</h2>
|
||||
</div>
|
||||
<div>
|
||||
<InertiaLink
|
||||
href="vacation-requests/create"
|
||||
class="inline-flex items-center px-4 py-3 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Dodaj wniosek
|
||||
</InertiaLink>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
|
||||
<nav class="relative shadow flex divide-x divide-gray-200 border-t border-gray-200">
|
||||
<InertiaLink
|
||||
v-for="(status, index) in statuses"
|
||||
:key="index"
|
||||
:data="{ status: status.value }"
|
||||
:class="[status.value === filters.status ? 'text-gray-900' : '', 'text-gray-500 hover:text-gray-700 group relative min-w-0 flex-1 overflow-hidden bg-white py-4 px-4 text-sm font-medium text-center hover:bg-gray-50 focus:z-10']"
|
||||
>
|
||||
<span>{{ status.name }}</span>
|
||||
<span :class="[status.value === filters.status ? 'bg-blumilk-500' : 'bg-transparent', 'absolute inset-x-0 bottom-0 h-0.5']" />
|
||||
</InertiaLink>
|
||||
</nav>
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Numer
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Rodzaj urlopu
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Status
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Od
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Do
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
Dni urlopu
|
||||
</th>
|
||||
<th scope="col" />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-100">
|
||||
<tr
|
||||
v-for="request in requests.data"
|
||||
:key="request.id"
|
||||
class="hover:bg-blumilk-25"
|
||||
>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<InertiaLink
|
||||
:href="`/vacation-requests/${request.id}`"
|
||||
class="font-semibold text-blumilk-600 hover:text-blumilk-500 hover:underline"
|
||||
>
|
||||
{{ request.name }}
|
||||
</InertiaLink>
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ request.type }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ request.state }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ request.from }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ request.to }}
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
X
|
||||
</td>
|
||||
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<InertiaLink :href="`/vacation-requests/${request.id}`">
|
||||
<ChevronRightIcon class="block w-6 h-6 fill-gray-400" />
|
||||
</InertiaLink>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-if="! requests.data.length"
|
||||
>
|
||||
<td
|
||||
colspan="100%"
|
||||
class="text-center py-4 text-xl leading-5 text-gray-700"
|
||||
>
|
||||
Brak danych
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div
|
||||
v-if="requests.data.length && requests.meta.last_page !== 1"
|
||||
class="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6 rounded-b-lg"
|
||||
>
|
||||
<div class="flex-1 flex justify-between sm:hidden">
|
||||
<InertiaLink
|
||||
:is="requests.links.prev ? 'InertiaLink': 'span'"
|
||||
:href="requests.links.prev"
|
||||
class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
|
||||
>
|
||||
Poprzednia
|
||||
</InertiaLink>
|
||||
<Component
|
||||
:is="requests.links.next ? 'InertiaLink': 'span'"
|
||||
:href="requests.links.next"
|
||||
class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
|
||||
>
|
||||
Następna
|
||||
</Component>
|
||||
</div>
|
||||
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
|
||||
<div class="text-sm text-gray-700">
|
||||
Wyświetlanie
|
||||
<span class="font-medium">{{ requests.meta.from }}</span>
|
||||
od
|
||||
<span class="font-medium">{{ requests.meta.to }}</span>
|
||||
do
|
||||
<span class="font-medium">{{ requests.meta.total }}</span>
|
||||
wyników
|
||||
</div>
|
||||
<nav class="relative z-0 inline-flex space-x-1">
|
||||
<template
|
||||
v-for="(link, index) in requests.meta.links"
|
||||
:key="index"
|
||||
>
|
||||
<Component
|
||||
:is="link.url ? 'InertiaLink' : 'span'"
|
||||
:href="link.url"
|
||||
:preserve-scroll="true"
|
||||
class="relative inline-flex items-center px-4 py-2 border rounded-md text-sm font-medium"
|
||||
:class="{ 'z-10 bg-blumilk-25 border-blumilk-500 text-blumilk-600': link.active, 'bg-white border-gray-300 text-gray-500': !link.active, 'hover:bg-blumilk-25': link.url, 'border-none': !link.url}"
|
||||
v-text="link.label"
|
||||
/>
|
||||
</template>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {ChevronRightIcon, DotsVerticalIcon, PencilIcon, TrashIcon} from '@heroicons/vue/solid'
|
||||
|
||||
export default {
|
||||
name: 'VacationRequestIndex',
|
||||
components: {
|
||||
DotsVerticalIcon,
|
||||
PencilIcon,
|
||||
TrashIcon,
|
||||
ChevronRightIcon,
|
||||
},
|
||||
props: {
|
||||
requests: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
filters: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const statuses = [
|
||||
{
|
||||
name: 'Wszystkie',
|
||||
value: 'all',
|
||||
},
|
||||
{
|
||||
name: 'W trakcie',
|
||||
value: 'pending',
|
||||
},
|
||||
{
|
||||
name: 'Zatwierdzone',
|
||||
value: 'success',
|
||||
},
|
||||
{
|
||||
name: 'Odrzucone/anulowane',
|
||||
value: 'failed',
|
||||
},
|
||||
]
|
||||
|
||||
return {
|
||||
statuses,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
216
resources/js/Pages/VacationRequest/Show.vue
Normal file
216
resources/js/Pages/VacationRequest/Show.vue
Normal file
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<InertiaHead :title="`Wniosek ${request.name}`" />
|
||||
<div class="grid grid-cols-1 gap-6 xl:grid-flow-col-dense xl:grid-cols-3">
|
||||
<div class="space-y-6 xl:col-start-1 xl:col-span-2">
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Informacje na temat wniosku
|
||||
</h3>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 px-4 py-5 sm:p-0">
|
||||
<dl class="sm:divide-y sm:divide-gray-200">
|
||||
<div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||
<dt class="text-sm font-medium text-gray-500">
|
||||
Nr wniosku
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{ request.name }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||
<dt class="text-sm font-medium text-gray-500">
|
||||
Rodzaj urlopu
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{ request.type }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||
<dt class="text-sm font-medium text-gray-500">
|
||||
Urlop od
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{ request.from }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||
<dt class="text-sm font-medium text-gray-500">
|
||||
Urlop do
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{ request.to }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||
<dt class="text-sm font-medium text-gray-500">
|
||||
Dni
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
x
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||
<dt class="text-sm font-medium text-gray-500">
|
||||
Komentarz
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{ request.comment }}
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white shadow sm:rounded-lg">
|
||||
<div class="px-4 py-5 sm:p-6">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Zaakceptuj wniosek jako osoba techniczna
|
||||
</h3>
|
||||
<div class="mt-2 max-w-xl text-sm text-gray-500">
|
||||
<p>
|
||||
W zależności od typu wniosku, zostanie on zatwierdzony lub osoba administracyjna będzie musiała go zaakceptować.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-5">
|
||||
<InertiaLink
|
||||
:href="`/vacation-requests/${request.id}/accept-as-technical`"
|
||||
method="post"
|
||||
as="button"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Zaakceptuj wniosek
|
||||
</InertiaLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white shadow sm:rounded-lg">
|
||||
<div class="px-4 py-5 sm:p-6">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Zaakceptuj wniosek jako osoba administracyjna
|
||||
</h3>
|
||||
<div class="mt-2 max-w-xl text-sm text-gray-500">
|
||||
<p>
|
||||
Po akceptacji przez osobę administracyjną, wniosek zostanie zatwierdzony.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-5">
|
||||
<InertiaLink
|
||||
:href="`/vacation-requests/${request.id}/accept-as-administrative`"
|
||||
method="post"
|
||||
as="button"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
|
||||
>
|
||||
Zaakceptuj wniosek
|
||||
</InertiaLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white shadow sm:rounded-lg">
|
||||
<div class="px-4 py-5 sm:p-6">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Odrzuć wniosek
|
||||
</h3>
|
||||
<div class="mt-2 max-w-xl text-sm text-gray-500">
|
||||
<p>
|
||||
Odrzuconego wniosku nie można przywracać - należy zrobić nowy.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-5">
|
||||
<InertiaLink
|
||||
:href="`/vacation-requests/${request.id}/reject`"
|
||||
method="post"
|
||||
as="button"
|
||||
class="inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:text-sm"
|
||||
>
|
||||
Odrzuć wniosek
|
||||
</InertiaLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white shadow sm:rounded-lg border border-red-500">
|
||||
<div class="px-4 py-5 sm:p-6">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Anuluj wniosek
|
||||
</h3>
|
||||
<div class="mt-2 max-w-xl text-sm text-gray-500">
|
||||
<p>
|
||||
Wniosek można anulować w każdej chwili - nawet jeśli był już zatwierdzony.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-5">
|
||||
<InertiaLink
|
||||
:href="`/vacation-requests/${request.id}/cancel`"
|
||||
method="post"
|
||||
as="button"
|
||||
class="inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:text-sm"
|
||||
>
|
||||
Anuluj wniosek
|
||||
</InertiaLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="xl:col-start-3 xl:col-span-1 space-y-6">
|
||||
<div class="bg-white sm:rounded-lg shadow-md">
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Historia wniosku
|
||||
</h3>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 px-4 py-4">
|
||||
<ul>
|
||||
<li
|
||||
v-for="(activity, index) in activities.data"
|
||||
:key="activity.id"
|
||||
>
|
||||
<div :class="{'relative pb-8': index !== activities.data.length - 1}">
|
||||
<span
|
||||
v-if="(index !== activities.data.length - 1)"
|
||||
class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200"
|
||||
/>
|
||||
<div class="relative flex space-x-3">
|
||||
<div>
|
||||
<span class="bg-blumilk-500 h-8 w-8 rounded-full flex items-center justify-center ring-8 ring-white">
|
||||
<ThumbUpIcon class="w-5 h-5 text-white" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
|
||||
<div>
|
||||
<p class="text-sm text-gray-500">
|
||||
{{ activity.to }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-right text-sm whitespace-nowrap text-gray-500">
|
||||
<time>{{ activity.date }}</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ThumbUpIcon } from '@heroicons/vue/outline'
|
||||
|
||||
export default {
|
||||
name: 'VacationRequestShow',
|
||||
components: {
|
||||
ThumbUpIcon,
|
||||
},
|
||||
props: {
|
||||
request: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
activities: {
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
Reference in New Issue
Block a user