fix : redirection après login + écran des heures chauffeurs
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
This commit is contained in:
@@ -9,9 +9,11 @@
|
||||
<span class="pl-2">Absence</span>
|
||||
<span class="pl-4">Heure de jour</span>
|
||||
<span class="pl-2">Heure de nuit</span>
|
||||
<span class="pl-2">Heure atelier</span>
|
||||
<span class="pl-2">Total</span>
|
||||
<span>Petit déj.</span>
|
||||
<span>Déjeuner</span>
|
||||
<span>Dîner</span>
|
||||
<span>Nuitée</span>
|
||||
<span v-if="isAdmin" class="flex justify-between items-center">
|
||||
<span>Valider</span>
|
||||
@@ -96,6 +98,12 @@
|
||||
:disabled="!hasContractAtSelectedDate(employee.id) || isRowLocked(employee.id)"
|
||||
/>
|
||||
</div>
|
||||
<div class="pl-2">
|
||||
<TimeSelect
|
||||
v-model="rows[employee.id].workshopHours"
|
||||
:disabled="!hasContractAtSelectedDate(employee.id) || isRowLocked(employee.id)"
|
||||
/>
|
||||
</div>
|
||||
<div class="pl-2 text-sm font-semibold">
|
||||
{{ formatMinutes(getRowMetrics(employee.id).totalMinutes) }}
|
||||
</div>
|
||||
@@ -115,6 +123,14 @@
|
||||
:disabled="!hasContractAtSelectedDate(employee.id) || isRowLocked(employee.id)"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<input
|
||||
v-model="rows[employee.id].hasDinner"
|
||||
type="checkbox"
|
||||
class="cursor-pointer h-4 w-4"
|
||||
:disabled="!hasContractAtSelectedDate(employee.id) || isRowLocked(employee.id)"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<input
|
||||
v-model="rows[employee.id].hasOvernight"
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
:style="{ gridTemplateColumns: weekGridCols }"
|
||||
>
|
||||
<span>Nom</span>
|
||||
<span v-for="day in weekDayHeaders" :key="day.date" class="text-left">{{ day.label }}</span>
|
||||
<span v-for="day in weekDayHeaders" :key="day.date" class="text-left">{{ day.weekday }}<br>{{ day.dayDate }}</span>
|
||||
<span>Jour/Nuit <br>sem.</span>
|
||||
<span>Atelier <br>sem.</span>
|
||||
<span>Total <br>sem.</span>
|
||||
<span>Total <br>h. supp.</span>
|
||||
<span>+25%</span>
|
||||
@@ -16,7 +17,8 @@
|
||||
<span>Total <br>récup.</span>
|
||||
<span>Petit <br>déj.</span>
|
||||
<span>Déj.</span>
|
||||
<span>Nuitée</span>
|
||||
<span>Dîner</span>
|
||||
<span>Nuit.</span>
|
||||
</div>
|
||||
|
||||
<div class="border-x border-b border-primary-500 rounded-b-md">
|
||||
@@ -44,9 +46,11 @@
|
||||
>
|
||||
<div>J {{ formatMinutes(daily.dayMinutes) }}</div>
|
||||
<div>N {{ formatMinutes(daily.nightMinutes) }}</div>
|
||||
<div v-if="daily.hasBreakfast || daily.hasLunch || daily.hasOvernight" class="text-[10px] flex gap-1 mt-0.5">
|
||||
<div v-if="daily.workshopMinutes">A {{ formatMinutes(daily.workshopMinutes) }}</div>
|
||||
<div v-if="daily.hasBreakfast || daily.hasLunch || daily.hasDinner || daily.hasOvernight" class="text-[10px] flex gap-1 mt-0.5">
|
||||
<span v-if="daily.hasBreakfast" title="Petit déjeuner">PD</span>
|
||||
<span v-if="daily.hasLunch" title="Déjeuner">DJ</span>
|
||||
<span v-if="daily.hasDinner" title="Dîner">DI</span>
|
||||
<span v-if="daily.hasOvernight" title="Nuitée">NU</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,6 +59,9 @@
|
||||
<div>J {{ formatMinutes(row.weeklyDayMinutes) }}</div>
|
||||
<div>N {{ formatMinutes(row.weeklyNightMinutes) }}</div>
|
||||
</div>
|
||||
<div class="font-semibold">
|
||||
{{ formatMinutes(row.weeklyWorkshopMinutes ?? 0) }}
|
||||
</div>
|
||||
<div class="font-semibold">
|
||||
{{ formatMinutes(row.weeklyTotalMinutes) }}
|
||||
</div>
|
||||
@@ -72,6 +79,7 @@
|
||||
</div>
|
||||
<div class="font-semibold">{{ row.weeklyBreakfastCount ?? 0 }}</div>
|
||||
<div class="font-semibold">{{ row.weeklyLunchCount ?? 0 }}</div>
|
||||
<div class="font-semibold">{{ row.weeklyDinnerCount ?? 0 }}</div>
|
||||
<div class="font-semibold">{{ row.weeklyOvernightCount ?? 0 }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -94,7 +102,7 @@ defineProps<{
|
||||
isWeekLoading: boolean
|
||||
weekGridCols: string
|
||||
weeklySummary: WeeklyWorkHourSummary | null
|
||||
weekDayHeaders: Array<{ date: string; label: string }>
|
||||
weekDayHeaders: Array<{ date: string; weekday: string; dayDate: string }>
|
||||
formatMinutes: (minutes: number) => string
|
||||
}>()
|
||||
</script>
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
} from '~/services/work-hours'
|
||||
import {
|
||||
formatDateLongFr,
|
||||
formatWeekDayHeaderFr,
|
||||
formatWeekRangeFr,
|
||||
getIsoWeekNumber,
|
||||
getOffsetFromTodayYmd,
|
||||
@@ -73,10 +72,10 @@ export const useDriverHoursPage = () => {
|
||||
const dayGridCols = computed(() => {
|
||||
const metricCol = '0.4fr'
|
||||
const validationCols = isAdmin.value ? `${metricCol}` : `${metricCol} ${metricCol}`
|
||||
return `1.2fr 0.6fr 0.8fr 0.8fr ${metricCol} ${metricCol} ${metricCol} ${metricCol} ${validationCols}`
|
||||
return `1.2fr 0.6fr 0.8fr 0.8fr 0.8fr ${metricCol} ${metricCol} ${metricCol} ${metricCol} ${metricCol} ${validationCols}`
|
||||
})
|
||||
|
||||
const weekGridCols = '1.6fr repeat(7, 1fr) repeat(6, 0.6fr) repeat(3, 0.4fr)'
|
||||
const weekGridCols = '1.6fr repeat(7, 0.6fr) repeat(7, 0.6fr) repeat(4, 0.4fr)'
|
||||
|
||||
const sites = computed<Site[]>(() => {
|
||||
const siteMap = new Map<number, Site>()
|
||||
@@ -265,7 +264,13 @@ export const useDriverHoursPage = () => {
|
||||
|
||||
const weekDayHeaders = computed(() => {
|
||||
const days = weeklySummary.value?.days ?? []
|
||||
return days.map((date) => ({ date, label: formatWeekDayHeaderFr(date) }))
|
||||
return days.map((date) => {
|
||||
const parsed = parseYmd(date)
|
||||
if (!parsed) return { date, weekday: '', dayDate: '' }
|
||||
const weekday = new Intl.DateTimeFormat('fr-FR', { weekday: 'short' }).format(parsed)
|
||||
const dayDate = new Intl.DateTimeFormat('fr-FR', { day: '2-digit', month: '2-digit' }).format(parsed)
|
||||
return { date, weekday, dayDate }
|
||||
})
|
||||
})
|
||||
|
||||
const shiftDate = (steps: number) => {
|
||||
@@ -331,8 +336,10 @@ export const useDriverHoursPage = () => {
|
||||
workHourId: null,
|
||||
dayHours: '',
|
||||
nightHours: '',
|
||||
workshopHours: '',
|
||||
hasBreakfast: false,
|
||||
hasLunch: false,
|
||||
hasDinner: false,
|
||||
hasOvernight: false,
|
||||
isSiteValid: false,
|
||||
isValid: false,
|
||||
@@ -357,8 +364,9 @@ export const useDriverHoursPage = () => {
|
||||
const row = rows.value[employeeId] ?? emptyRow()
|
||||
const dayMinutes = toMinutes(row.dayHours)
|
||||
const nightMinutes = toMinutes(row.nightHours)
|
||||
const totalMinutes = dayMinutes + nightMinutes
|
||||
return { dayMinutes, nightMinutes, totalMinutes }
|
||||
const workshopMinutes = toMinutes(row.workshopHours)
|
||||
const totalMinutes = dayMinutes + nightMinutes + workshopMinutes
|
||||
return { dayMinutes, nightMinutes, workshopMinutes, totalMinutes }
|
||||
}
|
||||
|
||||
const getRowAbsenceLabel = (employeeId: number) => {
|
||||
@@ -412,8 +420,10 @@ export const useDriverHoursPage = () => {
|
||||
workHourId: workHour?.id ?? null,
|
||||
dayHours: minutesToTimeString(workHour?.dayHoursMinutes),
|
||||
nightHours: minutesToTimeString(workHour?.nightHoursMinutes),
|
||||
workshopHours: minutesToTimeString(workHour?.workshopHoursMinutes),
|
||||
hasBreakfast: workHour?.hasBreakfast ?? false,
|
||||
hasLunch: workHour?.hasLunch ?? false,
|
||||
hasDinner: workHour?.hasDinner ?? false,
|
||||
hasOvernight: workHour?.hasOvernight ?? false,
|
||||
isSiteValid: workHour?.isSiteValid ?? false,
|
||||
isValid: workHour?.isValid ?? false,
|
||||
@@ -556,8 +566,10 @@ export const useDriverHoursPage = () => {
|
||||
isPresentAfternoon: false,
|
||||
dayHoursMinutes: null,
|
||||
nightHoursMinutes: null,
|
||||
workshopHoursMinutes: null,
|
||||
hasBreakfast: false,
|
||||
hasLunch: false,
|
||||
hasDinner: false,
|
||||
hasOvernight: false
|
||||
})
|
||||
|
||||
@@ -859,6 +871,7 @@ export const useDriverHoursPage = () => {
|
||||
const row = rows.value[employeeId] ?? emptyRow()
|
||||
const dayMin = toMinutes(row.dayHours)
|
||||
const nightMin = toMinutes(row.nightHours)
|
||||
const workshopMin = toMinutes(row.workshopHours)
|
||||
|
||||
return {
|
||||
employeeId,
|
||||
@@ -872,8 +885,10 @@ export const useDriverHoursPage = () => {
|
||||
isPresentAfternoon: false,
|
||||
dayHoursMinutes: dayMin || null,
|
||||
nightHoursMinutes: nightMin || null,
|
||||
workshopHoursMinutes: workshopMin || null,
|
||||
hasBreakfast: row.hasBreakfast,
|
||||
hasLunch: row.hasLunch,
|
||||
hasDinner: row.hasDinner,
|
||||
hasOvernight: row.hasOvernight
|
||||
}
|
||||
})
|
||||
|
||||
@@ -21,14 +21,16 @@
|
||||
<NuxtLink
|
||||
to="/hours"
|
||||
class="flex items-center gap-2 py-2 text-md text-black hover:bg-tertiary-500 hover:text-primary-500"
|
||||
:class="route.path.startsWith('/hours')
|
||||
? 'bg-tertiary-500 text-primary-500 font-bold'
|
||||
: ''"
|
||||
:class="[
|
||||
route.path.startsWith('/hours') ? 'bg-tertiary-500 text-primary-500 font-bold' : '',
|
||||
!isAdmin ? 'border-t border-secondary-500 pt-3' : ''
|
||||
]"
|
||||
>
|
||||
<Icon name="mdi:clock-time-four-outline" size="24"/>
|
||||
<p>Heures</p>
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
v-if="isAdmin"
|
||||
to="/driver-hours"
|
||||
class="flex items-center gap-2 py-2 text-md text-black hover:bg-tertiary-500 hover:text-primary-500"
|
||||
:class="route.path.startsWith('/driver-hours')
|
||||
|
||||
@@ -68,7 +68,8 @@ const handleSubmit = async () => {
|
||||
try {
|
||||
await auth.login(username.value, password.value)
|
||||
|
||||
await router.push('/calendar')
|
||||
const isAdmin = auth.user?.roles?.includes('ROLE_ADMIN')
|
||||
await router.push(isAdmin ? '/calendar' : '/hours')
|
||||
} finally {
|
||||
isSubmitting.value = false
|
||||
}
|
||||
|
||||
@@ -15,8 +15,10 @@ export type WorkHour = {
|
||||
isPresentAfternoon?: boolean
|
||||
dayHoursMinutes?: number | null
|
||||
nightHoursMinutes?: number | null
|
||||
workshopHoursMinutes?: number | null
|
||||
hasBreakfast?: boolean
|
||||
hasLunch?: boolean
|
||||
hasDinner?: boolean
|
||||
hasOvernight?: boolean
|
||||
isSiteValid?: boolean
|
||||
isValid?: boolean
|
||||
@@ -35,8 +37,10 @@ export type WorkHourEntryPayload = {
|
||||
isPresentAfternoon?: boolean
|
||||
dayHoursMinutes?: number | null
|
||||
nightHoursMinutes?: number | null
|
||||
workshopHoursMinutes?: number | null
|
||||
hasBreakfast?: boolean
|
||||
hasLunch?: boolean
|
||||
hasDinner?: boolean
|
||||
hasOvernight?: boolean
|
||||
}
|
||||
|
||||
@@ -44,6 +48,7 @@ export type WeeklyWorkHourDailySummary = {
|
||||
date: string
|
||||
dayMinutes: number
|
||||
nightMinutes: number
|
||||
workshopMinutes?: number
|
||||
totalMinutes: number
|
||||
present?: number | null
|
||||
hasAbsence?: boolean
|
||||
@@ -51,6 +56,7 @@ export type WeeklyWorkHourDailySummary = {
|
||||
absenceColor?: string | null
|
||||
hasBreakfast?: boolean
|
||||
hasLunch?: boolean
|
||||
hasDinner?: boolean
|
||||
hasOvernight?: boolean
|
||||
}
|
||||
|
||||
@@ -65,6 +71,7 @@ export type WeeklyWorkHourRowSummary = {
|
||||
daily: WeeklyWorkHourDailySummary[]
|
||||
weeklyDayMinutes: number
|
||||
weeklyNightMinutes: number
|
||||
weeklyWorkshopMinutes?: number
|
||||
weeklyTotalMinutes: number
|
||||
weeklyPresenceCount?: number
|
||||
weeklyOvertimeTotalMinutes?: number
|
||||
@@ -74,6 +81,7 @@ export type WeeklyWorkHourRowSummary = {
|
||||
isDriver?: boolean
|
||||
weeklyBreakfastCount?: number
|
||||
weeklyLunchCount?: number
|
||||
weeklyDinnerCount?: number
|
||||
weeklyOvernightCount?: number
|
||||
}
|
||||
|
||||
@@ -106,8 +114,10 @@ export type DriverHourRow = {
|
||||
workHourId: number | null
|
||||
dayHours: string
|
||||
nightHours: string
|
||||
workshopHours: string
|
||||
hasBreakfast: boolean
|
||||
hasLunch: boolean
|
||||
hasDinner: boolean
|
||||
hasOvernight: boolean
|
||||
isSiteValid: boolean
|
||||
isValid: boolean
|
||||
|
||||
Reference in New Issue
Block a user