[#SIRH-25] Version mobile (#16)
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
| Numéro du ticket | Titre du ticket | |------------------|-----------------| | | | ## Description de la PR ## Modification du .env ## Check list - [ ] Pas de régression - [ ] TU/TI/TF rédigée - [ ] TU/TI/TF OK - [ ] CHANGELOG modifié Reviewed-on: #16 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #16.
This commit is contained in:
@@ -1,6 +1,174 @@
|
||||
<template>
|
||||
<div class="bg-white overflow-hidden flex min-h-0 flex-col">
|
||||
<div class="overflow-y-auto min-h-0">
|
||||
<!-- Mobile card layout -->
|
||||
<div class="overflow-y-auto min-h-0 space-y-3 lg:hidden">
|
||||
<div
|
||||
v-for="employee in employees"
|
||||
:key="'m-' + employee.id"
|
||||
class="rounded-md border border-primary-500 bg-white p-4"
|
||||
>
|
||||
<!-- Employee name + site -->
|
||||
<div class="mb-3">
|
||||
<p class="text-md font-bold text-primary-500 truncate">
|
||||
{{ employee.firstName }} {{ employee.lastName }}
|
||||
<span class="font-normal text-neutral-600 text-sm">({{ contractLabel(employee) }})</span>
|
||||
</p>
|
||||
<p class="text-sm text-neutral-500 truncate">
|
||||
{{ employee.site?.name ?? 'Sans site' }}<span v-if="employee.currentContractNature"> — {{ contractNatureLabel(employee.currentContractNature) }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Absence / Holiday / Formation pills -->
|
||||
<div class="mb-3 flex flex-col gap-1">
|
||||
<p
|
||||
v-if="getRowAbsenceLabel(employee.id)"
|
||||
class="rounded-md px-2 py-1 text-xs text-white truncate"
|
||||
:style="getRowAbsenceStyle(employee.id)"
|
||||
>
|
||||
{{ getRowAbsenceLabel(employee.id) }}
|
||||
</p>
|
||||
<p
|
||||
v-else
|
||||
class="text-xs text-neutral-400"
|
||||
>
|
||||
Aucune absence
|
||||
</p>
|
||||
<p
|
||||
v-if="isHoliday"
|
||||
class="rounded-md px-2 py-1 text-xs text-sky-900 inline-flex items-center gap-1"
|
||||
style="background-color: #b3e5fc"
|
||||
>
|
||||
<Icon name="mdi:calendar-star" size="14" class="shrink-0"/>
|
||||
<span class="truncate">{{ holidayLabel || 'Férié' }}</span>
|
||||
</p>
|
||||
<p
|
||||
v-if="hasRowFormation(employee.id)"
|
||||
class="rounded-md px-2 py-1 text-xs text-white bg-indigo-500 inline-flex items-center gap-1"
|
||||
>
|
||||
<Icon name="mdi:school-outline" size="14" class="shrink-0"/>
|
||||
<span class="truncate">{{ getRowFormationLabel(employee.id) }}</span>
|
||||
</p>
|
||||
<button
|
||||
v-if="!hasRowFormation(employee.id)"
|
||||
type="button"
|
||||
class="self-start text-xs font-semibold underline"
|
||||
:class="isRowLocked(employee.id) || !hasContractAtSelectedDate(employee.id) ? 'text-neutral-400 cursor-not-allowed' : 'text-primary-500 cursor-pointer'"
|
||||
:disabled="isRowLocked(employee.id) || !hasContractAtSelectedDate(employee.id)"
|
||||
@click="onAbsenceClick(employee.id)"
|
||||
>
|
||||
Modifier
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Time inputs (TIME tracking) -->
|
||||
<div v-if="isTimeTracking(employee)" class="space-y-2">
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<label class="text-xs text-neutral-500">Début matin</label>
|
||||
<TimeSelect
|
||||
v-model="rows[employee.id].morningFrom"
|
||||
:disabled="!hasContractAtSelectedDate(employee.id) || isRowLocked(employee.id) || (!isAdmin && isHalfLockedByAbsence(employee.id, 'AM'))"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-neutral-500">Fin matin</label>
|
||||
<TimeSelect
|
||||
v-model="rows[employee.id].morningTo"
|
||||
:disabled="!hasContractAtSelectedDate(employee.id) || isRowLocked(employee.id) || (!isAdmin && isHalfLockedByAbsence(employee.id, 'AM'))"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<label class="text-xs text-neutral-500">Début après-midi</label>
|
||||
<TimeSelect
|
||||
v-model="rows[employee.id].afternoonFrom"
|
||||
:disabled="!hasContractAtSelectedDate(employee.id) || isRowLocked(employee.id) || (!isAdmin && isHalfLockedByAbsence(employee.id, 'PM'))"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-neutral-500">Fin après-midi</label>
|
||||
<TimeSelect
|
||||
v-model="rows[employee.id].afternoonTo"
|
||||
:disabled="!hasContractAtSelectedDate(employee.id) || isRowLocked(employee.id) || (!isAdmin && isHalfLockedByAbsence(employee.id, 'PM'))"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<label class="text-xs text-neutral-500">Début soir</label>
|
||||
<TimeSelect
|
||||
v-model="rows[employee.id].eveningFrom"
|
||||
:disabled="!hasContractAtSelectedDate(employee.id) || isRowLocked(employee.id) || (!isAdmin && isEveningLockedByAbsence(employee.id))"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-neutral-500">Fin soir</label>
|
||||
<TimeSelect
|
||||
v-model="rows[employee.id].eveningTo"
|
||||
:disabled="!hasContractAtSelectedDate(employee.id) || isRowLocked(employee.id) || (!isAdmin && isEveningLockedByAbsence(employee.id))"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-4 pt-1 text-sm font-semibold text-primary-500">
|
||||
<span>Jour : {{ formatMinutes(getRowMetrics(employee.id).dayMinutes) }}</span>
|
||||
<span>Nuit : {{ formatMinutes(getRowMetrics(employee.id).nightMinutes) }}</span>
|
||||
<span>Total : {{ formatMinutes(getRowMetrics(employee.id).totalMinutes) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Presence tracking -->
|
||||
<div v-else-if="isPresenceTracking(employee)" class="space-y-2">
|
||||
<div class="flex items-center gap-4">
|
||||
<label class="flex items-center gap-2 text-sm">
|
||||
<input
|
||||
v-model="rows[employee.id].isPresentMorning"
|
||||
type="checkbox"
|
||||
class="h-4 w-4 cursor-pointer"
|
||||
:disabled="!hasContractAtSelectedDate(employee.id) || isRowLocked(employee.id) || (!isAdmin && isHalfLockedByAbsence(employee.id, 'AM'))"
|
||||
/>
|
||||
Matin
|
||||
</label>
|
||||
<label class="flex items-center gap-2 text-sm">
|
||||
<input
|
||||
v-model="rows[employee.id].isPresentAfternoon"
|
||||
type="checkbox"
|
||||
class="h-4 w-4 cursor-pointer"
|
||||
:disabled="!hasContractAtSelectedDate(employee.id) || isRowLocked(employee.id) || (!isAdmin && isHalfLockedByAbsence(employee.id, 'PM'))"
|
||||
/>
|
||||
Après-midi
|
||||
</label>
|
||||
</div>
|
||||
<p class="text-sm font-semibold text-primary-500">Total : {{ getPresenceDayValue(employee.id) }}</p>
|
||||
</div>
|
||||
|
||||
<!-- Validation status (non-admin) -->
|
||||
<div v-if="!isAdmin" class="mt-3 flex gap-4 text-xs border-t border-neutral-200 pt-2">
|
||||
<span v-if="!isSiteManager" class="flex items-center gap-1">
|
||||
<Icon name="mdi:check-circle-outline" size="14" :class="rows[employee.id]?.isSiteValid ? 'text-green-600' : 'text-neutral-400'"/>
|
||||
Validation site : <span :class="rows[employee.id]?.isSiteValid ? 'font-semibold text-green-600' : 'text-neutral-500'">{{ rows[employee.id]?.isSiteValid ? 'Validé' : 'En attente' }}</span>
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<Icon name="mdi:check-circle-outline" size="14" :class="rows[employee.id]?.isValid ? 'text-green-600' : 'text-neutral-400'"/>
|
||||
Validation RH : <span :class="rows[employee.id]?.isValid ? 'font-semibold text-green-600' : 'text-neutral-500'">{{ rows[employee.id]?.isValid ? 'Validé' : 'En attente' }}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Validation checkbox (admin) -->
|
||||
<div v-if="isAdmin" class="mt-3 flex items-center gap-2 text-sm">
|
||||
<input
|
||||
:checked="rows[employee.id]?.isValid ?? false"
|
||||
type="checkbox"
|
||||
class="h-4 w-4 cursor-pointer"
|
||||
@change="onToggleValidation(employee.id, ($event.target as HTMLInputElement).checked)"
|
||||
/>
|
||||
<span class="text-neutral-700 font-semibold">Valider</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Desktop table layout -->
|
||||
<div class="overflow-y-auto min-h-0 hidden lg:block">
|
||||
<div
|
||||
class="grid w-full min-w-0 gap-1 border border-black bg-tertiary-500 px-4 py-3 text-sm font-semibold text-black rounded-t-md sticky top-0 z-10"
|
||||
:style="{ gridTemplateColumns: dayGridCols }"
|
||||
|
||||
Reference in New Issue
Block a user