From ba5fd9bf856c89d2dfafe727046e50a1ddf6e586 Mon Sep 17 00:00:00 2001 From: Louis Mazin Date: Sun, 20 Sep 2026 04:41:44 +0200 Subject: [PATCH] nice --- frontend/src/pages/TimeClockPage.jsx | 268 ++++++++++++++--------- frontend/src/pages/WeeklySummaryPage.jsx | 59 +---- 2 files changed, 167 insertions(+), 160 deletions(-) diff --git a/frontend/src/pages/TimeClockPage.jsx b/frontend/src/pages/TimeClockPage.jsx index 93909d0..473edb5 100644 --- a/frontend/src/pages/TimeClockPage.jsx +++ b/frontend/src/pages/TimeClockPage.jsx @@ -12,7 +12,7 @@ import { import { Label } from '@/components/ui/label'; import { Button } from '@/components/ui/button'; - +import { Input } from '@/components/ui/input'; import { Alert, AlertDescription, @@ -334,54 +334,106 @@ const TimePicker = ({ onChange, placeholder = 'Choisir une heure', }) => { - const [open, setOpen] = - useState(false); + const [open, setOpen] = useState(false); - const [ - hours = '', - minutes = '', - ] = value + const [hours = '', minutes = ''] = value ? value.split(':') : []; - const setTimePart = ( - part, - nextValue, + const hourOptions = Array.from( + { length: 24 }, + (_, i) => String(i).padStart(2, '0'), + ); + + const minuteOptions = Array.from( + { length: 60 }, + (_, i) => String(i).padStart(2, '0'), + ); + + const updateTime = ( + nextHours, + nextMinutes, ) => { - const nextHours = - part === 'hours' - ? nextValue - : hours || '00'; - - const nextMinutes = - part === 'minutes' - ? nextValue - : minutes || '00'; - onChange( - `${nextHours}:${nextMinutes}`, + `${String(nextHours).padStart(2, '0')}:${String( + nextMinutes, + ).padStart(2, '0')}`, ); }; - const hourOptions = - Array.from( - { length: 24 }, - (_, index) => - String(index).padStart( - 2, - '0', - ), + const changeHour = (direction) => { + const currentHour = Number(hours || 0); + const currentMinute = Number( + minutes || 0, ); - const minuteOptions = - Array.from( - { length: 60 }, - (_, index) => - String(index).padStart( - 2, - '0', - ), + let nextHour = + currentHour + direction; + + if (nextHour < 0) nextHour = 23; + if (nextHour > 23) nextHour = 0; + + updateTime( + nextHour, + currentMinute, ); + }; + + const changeMinute = (direction) => { + const currentHour = Number(hours || 0); + const currentMinute = Number( + minutes || 0, + ); + + let nextMinute = + currentMinute + direction; + + let nextHour = currentHour; + + if (nextMinute < 0) { + nextMinute = 59; + nextHour = + currentHour === 0 + ? 23 + : currentHour - 1; + } + + if (nextMinute > 59) { + nextMinute = 0; + nextHour = + currentHour === 23 + ? 0 + : currentHour + 1; + } + + updateTime( + nextHour, + nextMinute, + ); + }; + + const handleWheel = ( + event, + type, + ) => { + event.preventDefault(); + event.stopPropagation(); + + // Un événement de molette = une seule unité + const direction = + event.deltaY > 0 ? 1 : -1; + + if (type === 'hours') { + changeHour(direction); + } else { + changeMinute(direction); + } + }; + + const clearTime = () => { + onChange(''); + setOpen(false); + }; return ( @@ -411,102 +463,106 @@ const TimePicker = ({ -
+
Choisir une heure - + {value || '--:--'}
-
+
+ {/* Sélection centrale */} +
{/* HEURES */} +
+ handleWheel( + event, + 'hours', + ) + } + > +
+ + {hourOptions[ + (Number(hours || 0) + 23) % + 24 + ]} + -
-

- Heure -

+ + {hours || '00'} + -
- {hourOptions.map( - (hour) => ( - - ), - )} + + {hourOptions[ + (Number(hours || 0) + 1) % + 24 + ]} +
+ {/* : */} +
+ + : + +
{/* MINUTES */} +
+ handleWheel( + event, + 'minutes', + ) + } + > +
+ + {minuteOptions[ + (Number(minutes || 0) + + 59) % + 60 + ]} + -
-

- Minutes -

+ + {minutes || '00'} + -
- {minuteOptions.map( - (minute) => ( - - ), - )} + + {minuteOptions[ + (Number(minutes || 0) + 1) % + 60 + ]} +
-
-
+

+ Molette pour modifier +

+ +
diff --git a/frontend/src/pages/WeeklySummaryPage.jsx b/frontend/src/pages/WeeklySummaryPage.jsx index bf090d6..8d2c683 100644 --- a/frontend/src/pages/WeeklySummaryPage.jsx +++ b/frontend/src/pages/WeeklySummaryPage.jsx @@ -42,16 +42,6 @@ const MOBILE_TIME_COLUMN_WIDTH = 64; const MOBILE_USER_COLUMN_WIDTH = 40; const MOBILE_DEFAULT_CONTENT_WIDTH = 236; -const USER_COLORS = [ - '#c56a3d', - '#3d7c8c', - '#8a5a9e', - '#5d8b55', - '#c08a32', - '#b04f66', - '#4772a8', -]; - const expandOvernightAttendances = (entries) => { return entries.map((entry) => { if (entry.start_time && !entry.end_time) { @@ -241,41 +231,6 @@ const WeeklySummaryPage = ({ userId }) => { }; }; - const getUserColor = (user) => { - if (user?.color) { - return user.color; - } - - const id = getUserId(user); - - if (id) { - const numericId = Number(id); - - if (!Number.isNaN(numericId)) { - return USER_COLORS[ - numericId % USER_COLORS.length - ]; - } - } - - const name = - user?.first_name || - user?.firstName || - user?.username || - user?.name || - ''; - - const hash = [...String(name)].reduce( - (total, character) => - total + character.charCodeAt(0), - 0, - ); - - return USER_COLORS[ - hash % USER_COLORS.length - ]; - }; - const loadAttendances = async () => { try { setLoading(true); @@ -1214,7 +1169,7 @@ const WeeklySummaryPage = ({ userId }) => { ).map((user) => ({ id: getUserId(user), label: getUserLabel(user), - color: getUserColor(user), + color: user.color, })); return ( @@ -1599,10 +1554,7 @@ const WeeklySummaryPage = ({ userId }) => { user, ); - const color = - getUserColor( - user, - ); + const color = user.color; return (
{ style={ style } + title={`${formatSegmentTime(start)} - ${formatSegmentTime(end)}`} >
{formatSegmentTime( @@ -1873,10 +1826,7 @@ const WeeklySummaryPage = ({ userId }) => { user, ); - const color = - getUserColor( - user, - ); + const color = user.color; return (
{ style={ style } + title={`${formatSegmentTime(start)} - ${formatSegmentTime(end)}`} >