#99 - ui changes

This commit is contained in:
Adrian Hopek
2022-03-30 14:24:10 +02:00
parent 08421b8a69
commit fe1d86789d
21 changed files with 336 additions and 276 deletions

View File

@@ -3,28 +3,28 @@
<div class="bg-white shadow-md">
<div class="flex justify-between items-center p-4 sm:px-6">
<div class="flex items-center">
<h2 class="text-lg leading-6 font-medium text-gray-900">
<h2 class="text-lg leading-6 text-center font-medium text-gray-900">
Kalendarz urlopów
</h2>
<div class="ml-5 flex items-center rounded-md shadow-sm md:items-stretch">
<div class="ml-3 flex items-center rounded-md shadow-sm md:items-stretch">
<InertiaLink
v-if="previousMonth"
as="button"
:href="`/vacation/calendar/${previousMonth.value}`"
class="flex items-center justify-center rounded-l-md border border-r-0 border-gray-300 bg-white py-2 pl-3 pr-4 text-gray-400 hover:text-gray-500 focus:relative md:w-9 md:px-2 md:hover:bg-gray-50"
class="flex items-center justify-center rounded-l-md border border-r-0 border-gray-300 bg-white py-2 px-2 text-gray-400 hover:text-gray-500 focus:relative md:w-9 md:px-2 md:hover:bg-gray-50"
>
<ChevronLeftIcon class="h-5 w-5" />
</InertiaLink>
<span
v-else
class="flex items-center justify-center rounded-l-md border border-r-0 border-gray-300 bg-white py-2 pl-3 pr-4 text-gray-400 hover:text-gray-500 focus:relative md:w-9 md:px-2 md:hover:bg-gray-50"
class="flex items-center justify-center rounded-l-md border border-r-0 border-gray-300 bg-white py-2 px-2 text-gray-400 hover:text-gray-500 focus:relative md:w-9 md:px-2 md:hover:bg-gray-50"
>
<ChevronLeftIcon class="h-5 w-5" />
</span>
<InertiaLink
as="button"
:href="`/vacation/calendar/${currentMonth.value}`"
class="hidden border-t border-b border-gray-300 bg-white px-3.5 text-sm font-medium flex items-center text-gray-700 hover:bg-gray-50 hover:text-gray-900 focus:relative md:block"
class="hidden border-t border-b border-gray-300 bg-white px-2 text-sm font-medium flex items-center text-gray-700 hover:bg-gray-50 hover:text-gray-900 focus:relative md:block"
>
Dzisiaj
</InertiaLink>
@@ -32,13 +32,13 @@
v-if="nextMonth"
as="button"
:href="`/vacation/calendar/${nextMonth.value}`"
class="flex items-center justify-center rounded-r-md border border-l-0 border-gray-300 bg-white py-2 pl-4 pr-3 text-gray-400 hover:text-gray-500 focus:relative md:w-9 md:px-2 md:hover:bg-gray-50"
class="flex items-center justify-center rounded-r-md border border-l-0 border-gray-300 bg-white py-2 px-2 text-gray-400 hover:text-gray-500 focus:relative md:w-9 md:px-2 md:hover:bg-gray-50"
>
<ChevronRightIcon class="h-5 w-5" />
</InertiaLink>
<span
v-else
class="flex items-center justify-center rounded-r-md border border-l-0 border-gray-300 bg-white py-2 pl-4 pr-3 text-gray-400 hover:text-gray-500 focus:relative md:w-9 md:px-2 md:hover:bg-gray-50"
class="flex items-center justify-center rounded-r-md border border-l-0 border-gray-300 bg-white py-2 px-2 text-gray-400 hover:text-gray-500 focus:relative md:w-9 md:px-2 md:hover:bg-gray-50"
>
<ChevronRightIcon class="h-5 w-5" />
</span>
@@ -47,7 +47,7 @@
<div v-if="can.generateTimesheet">
<a
:href="`/vacation/timesheet/${selectedMonth.value}`"
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"
class="block text-center ml-3 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"
>
Pobierz plik Excel
</a>

View File

@@ -1,7 +1,7 @@
<template>
<InertiaHead title="Strona główna" />
<div class="grid grid-cols-1 gap-4 items-start lg:grid-cols-3 lg:gap-8">
<div class="grid grid-cols-1 gap-4 lg:col-span-2">
<div class="grid grid-cols-1 gap-4 items-start xl:grid-cols-3 xl:gap-8">
<div class="grid grid-cols-1 gap-4 xl:col-span-2">
<Welcome :user="auth.user" />
<VacationStats :stats="stats" />
</div>

View File

@@ -5,9 +5,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"

View File

@@ -5,9 +5,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"

View File

@@ -6,16 +6,13 @@
<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 v-if="can.manageHolidays">
<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
Dodaj dzień
</InertiaLink>
</div>
</div>
@@ -26,25 +23,25 @@
<tr>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Nazwa
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Data
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Dzień tygodnia
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
/>
</tr>
</thead>

View File

@@ -5,9 +5,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"
@@ -116,7 +113,7 @@
<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 }"
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.role, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.role }"
>
<span class="block truncate">{{ form.role.label }}</span>
<span class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">

View File

@@ -5,9 +5,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"

View File

@@ -4,16 +4,13 @@
<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
Użytkownicy
</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"
class="inline-flex items-center text-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>
@@ -39,37 +36,37 @@
<tr>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Imię i nazwisko
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Rola
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Stanowisko
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Forma zatrudnienia
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Data rozpoczęcia
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
/>
</tr>
</thead>

View File

@@ -6,44 +6,41 @@
<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 dostępnymi 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">
<form @submit.prevent="submitVacationDays">
<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 border-b">
<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"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Imię i nazwisko
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Forma zatrudnienia
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Posiada urlop?
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Pozostałe dni z poprzedniego roku
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Dostępne dni w roku
</th>
@@ -120,16 +117,16 @@
</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 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>
</template>

View File

@@ -1,7 +1,7 @@
<template>
<InertiaHead title="Złóż wniosek urlopowy" />
<div class="grid grid-cols-1 gap-4 items-start lg:grid-cols-3 lg:gap-8">
<div class="lg:col-span-2 h-full bg-white shadow-md flex flex-col">
<div class="grid grid-cols-1 gap-4 items-start xl:grid-cols-3 xl:gap-8">
<div class="xl:col-span-2 h-full bg-white shadow-md flex flex-col">
<div class="p-4 sm:px-6">
<h2 class="text-lg leading-6 font-medium text-gray-900">
Złóż wniosek urlopowy
@@ -43,7 +43,7 @@
<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.type, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.type }"
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.user, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.user }"
>
<span class="flex items-center">
<img
@@ -129,44 +129,39 @@
</div>
</div>
<Listbox
v-model="form.type"
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
Rodzaj urlopu
</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.type, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.type }"
>
<span class="block truncate">{{ form.type.label }}</span>
<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"
>
<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="type in vacationTypes"
:key="type.value"
v-for="vacationType in vacationTypes"
:key="vacationType.value"
v-slot="{ active, selected }"
as="template"
:value="type"
:value="vacationType"
>
<li
:class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']"
>
<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']">
{{ type.label }}
{{ vacationType.label }}
</span>
<span
@@ -271,7 +266,7 @@
>
Natychmiastowo zatwierdź wniosek
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<div class="mt-2 sm:mt-0 sm:col-span-2">
<Switch
id="flowSkipped"
v-model="form.flowSkipped"
@@ -346,7 +341,7 @@ const form = useForm({
: props.auth.user,
from: null,
to: null,
type: props.vacationTypes[0],
vacationType: props.vacationTypes[0],
comment: null,
flowSkipped: false,
})
@@ -385,7 +380,7 @@ function createForm() {
form
.transform(data => ({
...data,
type: data.type.value,
type: data.vacationType.value,
user: data.user.id,
}))
.post('/vacation/requests')
@@ -418,20 +413,20 @@ function resetForm() {
async function refreshEstimatedDays(from, to) {
if (from && to) {
const res = await axios.post('/api/calculate-vacation/days', { from, to })
const res = await axios.post('/api/vacation/calculate-days', { from, to })
estimatedDays.value = res.data
}
}
async function refreshVacationStats(user) {
const res = await axios.post('/api/calculate-vacation/stats', { user: user.id })
const res = await axios.post('/api/vacation/calculate-stats', { user: user.id })
stats.value = res.data
}
async function refreshUnavailableDays(user) {
const res = await axios.post('/api/calculate-unavailable-days', { user: user.id })
const res = await axios.post('/api/vacation/calculate-unavailable-days', { user: user.id })
const unavailableDays = res.data
fromInputConfig.disable = [

View File

@@ -2,11 +2,9 @@
<InertiaHead title="Moje wnioski urlopowe" />
<div class="bg-white 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">
Moje wnioski urlopowe
</h2>
</div>
<h2 class="text-lg leading-6 font-medium text-gray-900">
Moje wnioski urlopowe
</h2>
<div>
<InertiaLink
href="/vacation/requests/create"
@@ -16,13 +14,13 @@
</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
<div class="border-t border-gray-200">
<div class="hidden md:flex relative shadow divide-x divide-gray-200">
<button
v-for="(status, index) in statuses"
:key="index"
:data="{ status: status.value }"
:class="[status.value === filters.status ? 'text-blumilk-600 font-semibold' : 'hover:bg-blumilk-25 text-gray-700 focus:z-10', 'group relative min-w-0 flex-1 overflow-hidden bg-white py-4 px-4 text-sm font-medium text-center']"
@click="form.status = status"
>
<span>{{ status.name }}</span>
<span
@@ -31,45 +29,102 @@
>
{{ stats[status.value] }}
</span>
<span :class="[status.value === filters.status ? 'bg-blumilk-500' : 'bg-transparent', 'absolute inset-x-0 bottom-0 h-0.5']" />
</InertiaLink>
</nav>
<span
:class="[status.value === filters.status ? 'bg-blumilk-500' : 'bg-transparent', 'absolute inset-x-0 bottom-0 h-0.5']"
/>
</button>
</div>
<div class="md:hidden px-4 py-4 grid grid-cols-1 md:grid-cols-2 gap-2 md:gap-4">
<Listbox
v-model="form.status"
as="div"
>
<ListboxLabel class="block text-sm font-medium text-gray-700 mb-2">
Status
</ListboxLabel>
<div class="mt-1 relative sm:mt-0">
<ListboxButton
class="bg-white relative w-full h-10 max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:outline-none focus:ring-1 focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300"
>
<span class="flex items-center">
{{ form.status.name }}
</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="status in statuses"
:key="status.value"
v-slot="{ active, selected }"
as="template"
:value="status"
>
<li
:class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default truncate select-none relative py-2 pl-3 pr-9']"
>
{{ status.name }}
<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>
</div>
</Listbox>
</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-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Numer
</th>
<th
scope="col"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Rodzaj urlopu
</th>
<th
scope="col"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Od
</th>
<th
scope="col"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Do
</th>
<th
scope="col"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Dni urlopu
</th>
<th
scope="col"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Status
</th>
@@ -134,12 +189,16 @@
</template>
<script setup>
import { ChevronRightIcon } from '@heroicons/vue/solid'
import { ChevronRightIcon, SelectorIcon, CheckIcon } from '@heroicons/vue/solid'
import Status from '@/Shared/Status'
import VacationType from '@/Shared/VacationType'
import Pagination from '@/Shared/Pagination'
import { Listbox, ListboxButton, ListboxLabel, ListboxOption, ListboxOptions } from '@headlessui/vue'
import { reactive, watch } from 'vue'
import { debounce } from 'lodash'
import { Inertia } from '@inertiajs/inertia'
defineProps({
const props = defineProps({
requests: Object,
stats: Object,
filters: Object,
@@ -163,4 +222,16 @@ const statuses = [
value: 'failed',
},
]
const form = reactive({
status: statuses.find(status => status.value === props.filters.status) ?? statuses[0],
})
watch(form, debounce(() => {
Inertia.get('/vacation/requests/me', { status: form.status.value }, {
preserveState: true,
replace: false,
})
}, 300))
</script>

View File

@@ -16,200 +16,194 @@
</InertiaLink>
</div>
</div>
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
<div class="border-t border-gray-200">
<div class="px-4 grid grid-cols-2 gap-4">
<div>
<Listbox
v-model="form.user"
as="div"
class="py-4 items-center"
<div class="border-t border-gray-200">
<div class="px-4 py-4 grid grid-cols-1 md:grid-cols-2 gap-2 md:gap-4">
<Listbox
v-model="form.user"
as="div"
>
<ListboxLabel class="block text-sm font-medium text-gray-700 mb-2">
Pracownik
</ListboxLabel>
<div class="mt-1 relative sm:mt-0">
<ListboxButton
class="bg-white relative w-full h-10 max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:outline-none focus:ring-1 focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300"
>
<ListboxLabel class="block text-sm font-medium text-gray-700 mb-2">
Pracownik
</ListboxLabel>
<div class="mt-1 relative sm:mt-0">
<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 focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300"
<span v-if="form.user === null">
Wszyscy
</span>
<span
v-else
class="flex items-center"
>
<img
:src="form.user.avatar"
class="flex-shrink-0 h-6 w-6 rounded-full"
>
<span v-if="form.user === null">
Wszyscy
</span>
<span
v-else
class="flex items-center"
>
<img
:src="form.user.avatar"
class="flex-shrink-0 h-6 w-6 rounded-full"
>
<span class="ml-3 block truncate">{{ form.user.name }}</span>
</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>
<span class="ml-3 block truncate">{{ form.user.name }}</span>
</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-slot="{ active }"
as="template"
:value="null"
>
<li
:class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']"
>
<div class="flex items-center">
Wszyscy pracownicy
</div>
<span
v-if="form.user === null"
: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>
<ListboxOption
v-for="user in users.data"
:key="user.id"
v-slot="{ active }"
as="template"
:value="user"
>
<li
:class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']"
>
<div class="flex items-center">
<img
:src="user.avatar"
class="flex-shrink-0 h-6 w-6 rounded-full"
>
<span
:class="[form.user?.id === user.id ? 'font-semibold' : 'font-normal', 'ml-3 block truncate']"
>
{{ user.name }}
</span>
</div>
<span
v-if="form.user?.id === user.id"
: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>
</div>
</Listbox>
</div>
<div>
<Listbox
v-model="form.status"
as="div"
class="py-4 items-center"
<transition
leave-active-class="transition ease-in duration-100"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<ListboxLabel class="block text-sm font-medium text-gray-700 mb-2">
Status
</ListboxLabel>
<div class="mt-1 relative sm:mt-0">
<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 focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300"
<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-slot="{ active }"
as="template"
:value="null"
>
<span class="flex items-center">
{{ form.status.name }}
</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"
<li
:class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']"
>
<ListboxOption
v-for="status in statuses"
:key="status.value"
v-slot="{ active, selected }"
as="template"
:value="status"
>
<li
:class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']"
>
{{ status.name }}
<div class="flex items-center">
Wszyscy
</div>
<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>
</div>
</Listbox>
<span
v-if="form.user === null"
: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>
<ListboxOption
v-for="user in users.data"
:key="user.id"
v-slot="{ active }"
as="template"
:value="user"
>
<li
:class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']"
>
<div class="flex items-center">
<img
:src="user.avatar"
class="flex-shrink-0 h-6 w-6 rounded-full"
>
<span
:class="[form.user?.id === user.id ? 'font-semibold' : 'font-normal', 'ml-3 block truncate']"
>
{{ user.name }}
</span>
</div>
<span
v-if="form.user?.id === user.id"
: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>
</div>
</div>
</Listbox>
<Listbox
v-model="form.status"
as="div"
>
<ListboxLabel class="block text-sm font-medium text-gray-700 mb-2">
Status
</ListboxLabel>
<div class="mt-1 relative sm:mt-0">
<ListboxButton
class="bg-white relative w-full h-10 max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:outline-none focus:ring-1 focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300"
>
<span class="flex items-center">
{{ form.status.name }}
</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="status in statuses"
:key="status.value"
v-slot="{ active, selected }"
as="template"
:value="status"
>
<li
:class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default truncate select-none relative py-2 pl-3 pr-9']"
>
{{ status.name }}
<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>
</div>
</Listbox>
</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-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Numer
</th>
<th
scope="col"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Pracownik
</th>
<th
scope="col"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Rodzaj urlopu
</th>
<th
scope="col"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Od
</th>
<th
scope="col"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Do
</th>
<th
scope="col"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Dni urlopu
</th>
<th
scope="col"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider"
class="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider whitespace-nowrap"
>
Status
</th>
@@ -232,10 +226,9 @@
</td>
<td class="px-4 py-4 whitespace-nowrap text-sm font-medium text-gray-500">
<div class="flex">
<img
class="h-10 w-10 rounded-full"
:src="request.user.avatar"
>
<div class="h-10 w-10 rounded-full">
<img :src="request.user.avatar">
</div>
<div class="ml-3">
<p class="text-sm font-medium text-gray-900">
{{ request.user.name }}

View File

@@ -5,7 +5,7 @@
:years="years"
/>
<main class="lg:ml-64 flex flex-col flex-1 py-8">
<div class="px-4">
<div class="lg:px-4">
<slot />
</div>
</main>

View File

@@ -49,11 +49,13 @@
</div>
</TransitionChild>
<div class="flex-shrink-0 flex items-center px-4">
<InertiaLink href="/">
<InertiaLink
href="/"
@click="sidebarOpen = false;"
>
<img
class="h-8 w-auto"
src="/img/logo-white.png"
alt="Workflow"
src="/img/logo-white.svg"
>
</InertiaLink>
</div>
@@ -61,7 +63,8 @@
<div class="px-2 space-y-1">
<InertiaLink
href="/"
:class="[$page.component === 'Dashboard' ? 'bg-blumilk-800 text-white' : 'text-blumilk-100 hover:text-white hover:bg-blumilk-600', 'group flex items-center px-2 py-2 text-sm leading-6 font-medium rounded-md']"
:class="[$page.component === 'Dashboard' ? 'bg-blumilk-800 text-white' : 'text-blumilk-100 hover:text-white hover:bg-blumilk-600', 'group flex items-center px-2 py-2 text-base leading-6 font-medium rounded-md']"
@click="sidebarOpen = false;"
>
<HomeIcon class="mr-4 flex-shrink-0 h-6 w-6 text-blumilk-200" />
Strona główna
@@ -74,6 +77,7 @@
:key="item.name"
:href="item.href"
:class="[$page.component === item.component ? 'bg-blumilk-800 text-white' : 'text-blumilk-100 hover:text-white hover:bg-blumilk-600', 'group flex items-center px-2 py-2 text-base font-medium rounded-md']"
@click="sidebarOpen = false;"
>
<component
:is="item.icon"
@@ -95,9 +99,8 @@
<div class="flex items-center flex-shrink-0 px-4">
<InertiaLink href="/">
<img
class="h-8 w-auto"
src="/img/logo-white.png"
alt="Workflow"
src="/img/logo-white.svg"
class="w-auto h-10 text-red-600 fil-red-600"
>
</InertiaLink>
</div>

View File

@@ -1,6 +1,6 @@
<template>
<section class="grid grid-cols-2 gap-4">
<div class="bg-white shadow-md p-4">
<section class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="hidden md:block bg-white shadow-md p-4">
<VacationChart :stats="stats" />
</div>
<div class="h-full">

View File

@@ -41,5 +41,6 @@ Flatpickr.setDefaults({
enableTime: false,
altFormat: 'd.m.Y',
altInput: true,
disableMobile: true,
})