145 lines
5.3 KiB
Vue
145 lines
5.3 KiB
Vue
<template>
|
||
<div class="py-6 flex flex-col gap-3">
|
||
<SiteFilterSelector v-if="sites.length > 0" v-model="selectedSiteIds" :sites="sites" />
|
||
|
||
<div class="flex justify-between items-center gap-4">
|
||
<div class="flex gap-4 flex-wrap">
|
||
<div
|
||
v-if="viewMode === 'day'"
|
||
class="inline-flex h-10 w-[320px] overflow-hidden rounded-md border border-primary-500 bg-white"
|
||
>
|
||
<button
|
||
type="button"
|
||
class="flex-1 px-4 py-2 text-sm font-semibold active:scale-[0.98] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/40"
|
||
:class="shortcutButtonClass('yesterday')"
|
||
@click="emit('set-yesterday')"
|
||
>
|
||
Hier
|
||
</button>
|
||
<button
|
||
type="button"
|
||
class="flex-1 border-x border-primary-500 px-4 py-2 text-sm font-semibold active:scale-[0.98] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/40"
|
||
:class="shortcutButtonClass('today')"
|
||
@click="emit('set-today')"
|
||
>
|
||
Aujourd'hui
|
||
</button>
|
||
<button
|
||
type="button"
|
||
class="flex-1 px-4 py-2 text-sm font-semibold active:scale-[0.98] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/40"
|
||
:class="shortcutButtonClass('tomorrow')"
|
||
@click="emit('set-tomorrow')"
|
||
>
|
||
Demain
|
||
</button>
|
||
</div>
|
||
|
||
<div class="relative inline-flex h-10 w-[320px] items-center overflow-hidden rounded-md border border-primary-500 bg-white">
|
||
<input
|
||
ref="nativeDateInput"
|
||
v-model="selectedDate"
|
||
type="date"
|
||
class="pointer-events-none absolute inset-0 h-full w-full opacity-0"
|
||
tabindex="-1"
|
||
aria-hidden="true"
|
||
/>
|
||
<button
|
||
type="button"
|
||
class="h-10 px-3 text-lg font-semibold text-primary-500 hover:bg-tertiary-500 active:bg-tertiary-500 active:scale-[0.96] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/40"
|
||
aria-label="Période précédente"
|
||
@click="emit('shift-date', -1)"
|
||
>
|
||
‹
|
||
</button>
|
||
<button
|
||
type="button"
|
||
class="h-10 flex-1 border-x border-primary-500 px-4 text-sm font-semibold text-primary-500 text-center hover:bg-tertiary-500 active:bg-tertiary-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/40"
|
||
@click="openDatePicker"
|
||
>
|
||
{{ formattedSelectedDate }}
|
||
</button>
|
||
<button
|
||
type="button"
|
||
class="h-10 px-3 text-lg font-semibold text-primary-500 hover:bg-tertiary-500 active:bg-tertiary-500 active:scale-[0.96] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/40"
|
||
aria-label="Période suivante"
|
||
@click="emit('shift-date', 1)"
|
||
>
|
||
›
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="isAdmin" class="inline-flex h-10 overflow-hidden rounded-md border border-primary-500 bg-white">
|
||
<button
|
||
type="button"
|
||
class="inline-flex items-center gap-2 px-4 py-2 text-sm font-semibold active:scale-[0.98] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/40"
|
||
:class="viewModeButtonClass('day')"
|
||
@click="viewMode = 'day'"
|
||
>
|
||
<Icon name="mdi:calendar-clock" />
|
||
Jour
|
||
</button>
|
||
<button
|
||
type="button"
|
||
class="inline-flex items-center gap-2 border-l border-primary-500 px-4 py-2 text-sm font-semibold active:scale-[0.98] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/40"
|
||
:class="viewModeButtonClass('week')"
|
||
@click="viewMode = 'week'"
|
||
>
|
||
<Icon name="mdi:calendar-week" />
|
||
Semaine
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="w-80 max-w-full">
|
||
<EmployeeNameFilterInput v-model="employeeFilter" />
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import type { Site } from '~/services/dto/site'
|
||
import EmployeeNameFilterInput from '~/components/EmployeeNameFilterInput.vue'
|
||
import SiteFilterSelector from '~/components/SiteFilterSelector.vue'
|
||
|
||
const selectedDate = defineModel<string>('selectedDate', { required: true })
|
||
const viewMode = defineModel<'day' | 'week'>('viewMode', { required: true })
|
||
const selectedSiteIds = defineModel<number[]>('selectedSiteIds', { required: true })
|
||
const employeeFilter = defineModel<string>('employeeFilter', { required: true })
|
||
|
||
defineProps<{
|
||
isAdmin: boolean
|
||
sites: Site[]
|
||
formattedSelectedDate: string
|
||
shortcutButtonClass: (target: 'yesterday' | 'today' | 'tomorrow') => string
|
||
}>()
|
||
|
||
const emit = defineEmits<{
|
||
(e: 'set-yesterday'): void
|
||
(e: 'set-today'): void
|
||
(e: 'set-tomorrow'): void
|
||
(e: 'shift-date', value: number): void
|
||
}>()
|
||
|
||
const nativeDateInput = ref<HTMLInputElement | null>(null)
|
||
|
||
const viewModeButtonClass = (mode: 'day' | 'week') => {
|
||
if (viewMode.value === mode) {
|
||
return 'bg-primary-500 text-white'
|
||
}
|
||
|
||
return 'bg-white text-primary-500 hover:bg-tertiary-500'
|
||
}
|
||
|
||
const openDatePicker = () => {
|
||
const input = nativeDateInput.value
|
||
if (!input) return
|
||
if (typeof input.showPicker === 'function') {
|
||
input.showPicker()
|
||
return
|
||
}
|
||
input.focus()
|
||
input.click()
|
||
}
|
||
</script>
|