This commit is contained in:
Louis Mazin 2026-09-20 00:40:52 +02:00
parent db61ec30e1
commit 448dc573ee

View File

@ -822,8 +822,9 @@ const WeeklySummaryPage = ({ userId }) => {
attendance,
) === userId,
)
.map((attendance) => ({
.map((attendance, index) => ({
attendance,
index,
start: getMinutes(
getTimeValue(
attendance,
@ -845,33 +846,75 @@ const WeeklySummaryPage = ({ userId }) => {
);
};
const getUserDayBounds = (
dayAttendances,
user,
/*
* ------------------------------------------------------------
* NOUVEAU :
* Utilisateurs actifs sur une période
*
* Desktop -> toute la semaine
* Mobile -> journée sélectionnée
* ------------------------------------------------------------
*/
const getUsersWithAttendances = (
entries,
) => {
const schedules =
getUserScheduleForDay(
dayAttendances,
user,
const activeUserIds = new Set();
entries.forEach((entry) => {
const userId =
getEntryUserId(entry);
if (userId) {
activeUserIds.add(
String(userId),
);
}
});
return users.filter((user) =>
activeUserIds.has(
String(getUserId(user)),
),
);
};
const getWeekActiveUsers = () => {
const weekDateKeys =
new Set(
weekDays.map(
formatDateKey,
),
);
if (!schedules.length) {
return null;
const weekAttendances =
expandOvernightAttendances(
attendances,
).filter(
(attendance) =>
weekDateKeys.has(
String(
attendance.date,
).slice(0, 10),
),
);
return getUsersWithAttendances(
weekAttendances,
);
};
const getDayActiveUsers = () => {
const day =
weekDays[selectedDayIndex];
if (!day) {
return [];
}
return {
start: Math.min(
...schedules.map(
({ start }) => start,
),
),
end: Math.max(
...schedules.map(
({ end }) => end,
),
),
};
return getUsersWithAttendances(
getAttendancesForDay(day),
);
};
/*
@ -977,12 +1020,36 @@ const WeeklySummaryPage = ({ userId }) => {
/*
* ------------------------------------------------------------
* Mobile : largeur des colonnes utilisateurs
* Utilisateurs réellement affichés
*
* Desktop : actifs sur la semaine
* Mobile : actifs sur le jour
* ------------------------------------------------------------
*/
const desktopActiveUsers =
getWeekActiveUsers();
const mobileActiveUsers =
getDayActiveUsers();
const desktopUserCount =
Math.max(
desktopActiveUsers.length,
1,
);
const mobileUserCount =
Math.max(users.length, 1);
Math.max(
mobileActiveUsers.length,
1,
);
/*
* ------------------------------------------------------------
* Largeur mobile
* ------------------------------------------------------------
*/
const mobileUsersWidth =
isAdmin && showAllUsers
@ -1365,7 +1432,7 @@ const WeeklySummaryPage = ({ userId }) => {
{/* ==================================================
ADMIN + TOUS LES UTILISATEURS
1 utilisateur = 1 colonne
1 utilisateur actif = 1 colonne
================================================== */}
{isAdmin &&
@ -1376,10 +1443,10 @@ const WeeklySummaryPage = ({ userId }) => {
gridTemplateColumns: `repeat(${mobileUserCount}, minmax(${MOBILE_USER_COLUMN_WIDTH}px, 1fr))`,
}}
>
{users.map(
{mobileActiveUsers.map(
(user) => {
const bounds =
getUserDayBounds(
const schedules =
getUserScheduleForDay(
getAttendancesForDay(
weekDays[
selectedDayIndex
@ -1400,34 +1467,46 @@ const WeeklySummaryPage = ({ userId }) => {
)}
className="relative border-r border-border/30 last:border-r-0"
title={
bounds
? `${getUserLabel(
user,
)} : ${formatSegmentTime(
bounds.start,
)} - ${formatSegmentTime(
bounds.end,
)}`
: getUserLabel(
user,
)
getUserLabel(
user,
)
}
>
{bounds && (
<div
className="absolute left-1/2 w-2 -translate-x-1/2 rounded-full"
style={{
...getAttendanceStyle(
bounds.start,
bounds.end,
startHour,
endHour,
hourHeight,
),
backgroundColor:
color,
}}
/>
{schedules.map(
({
attendance,
start,
end,
index,
}) => (
<div
key={
attendance.id ??
`${getUserId(
user,
)}-${start}-${end}-${index}`
}
className="absolute left-1/2 w-2 -translate-x-1/2 rounded-full"
style={{
...getAttendanceStyle(
start,
end,
startHour,
endHour,
hourHeight,
),
backgroundColor:
color,
}}
title={`${getUserLabel(
user,
)} : ${formatSegmentTime(
start,
)} - ${formatSegmentTime(
end,
)}`}
/>
),
)}
</div>
);
@ -1447,8 +1526,9 @@ const WeeklySummaryPage = ({ userId }) => {
),
)
.map(
(attendance) => ({
(attendance, index) => ({
attendance,
index,
start: getMinutes(
getTimeValue(
attendance,
@ -1474,8 +1554,10 @@ const WeeklySummaryPage = ({ userId }) => {
)
.map(
({
attendance,
start,
end,
index,
}) => {
const style =
getAttendanceStyle(
@ -1488,11 +1570,14 @@ const WeeklySummaryPage = ({ userId }) => {
return (
<div
key={`${formatDateKey(
weekDays[
selectedDayIndex
],
)}-${start}-${end}`}
key={
attendance.id ??
`${formatDateKey(
weekDays[
selectedDayIndex
],
)}-${start}-${end}-${index}`
}
className="absolute left-0 right-0 overflow-hidden rounded-sm border border-blue-600/30 bg-blue-500/80"
style={
style
@ -1636,16 +1721,26 @@ const WeeklySummaryPage = ({ userId }) => {
{/* ==================================================
ADMIN : TOUS LES UTILISATEURS
1 utilisateur = 1 colonne
1 utilisateur ayant pointé dans la semaine
= 1 colonne
IMPORTANT :
on ne fait plus getUserDayBounds().
Chaque pointage est affiché séparément.
================================================== */}
{isAdmin &&
showAllUsers ? (
<div className="absolute inset-0 grid grid-cols-[repeat(auto-fit,minmax(0,1fr))]">
{users.map(
<div
className="absolute inset-0 grid"
style={{
gridTemplateColumns: `repeat(${desktopUserCount}, minmax(0, 1fr))`,
}}
>
{desktopActiveUsers.map(
(user) => {
const bounds =
getUserDayBounds(
const schedules =
getUserScheduleForDay(
dayAttendances,
user,
);
@ -1661,35 +1756,47 @@ const WeeklySummaryPage = ({ userId }) => {
user,
)}
className="relative min-w-0 border-r border-border/30 last:border-r-0"
title={
bounds
? `${getUserLabel(
title={getUserLabel(
user,
)}
>
{schedules.map(
({
attendance,
start,
end,
index,
}) => (
<div
key={
attendance.id ??
`${getUserId(
user,
)}-${formatDateKey(
day,
)}-${start}-${end}-${index}`
}
className="absolute left-1/2 w-2 -translate-x-1/2 rounded-full"
style={{
...getAttendanceStyle(
start,
end,
startHour,
endHour,
hourHeight,
),
backgroundColor:
color,
}}
title={`${getUserLabel(
user,
)} : ${formatSegmentTime(
bounds.start,
start,
)} - ${formatSegmentTime(
bounds.end,
)}`
: getUserLabel(
user,
)
}
>
{bounds && (
<div
className="absolute left-1/2 w-2 -translate-x-1/2 rounded-full"
style={{
...getAttendanceStyle(
bounds.start,
bounds.end,
startHour,
endHour,
hourHeight,
),
backgroundColor:
color,
}}
/>
end,
)}`}
/>
),
)}
</div>
);
@ -1704,8 +1811,12 @@ const WeeklySummaryPage = ({ userId }) => {
dayAttendances,
)
.map(
(attendance) => ({
(
attendance,
index,
) => ({
attendance,
index,
start: getMinutes(
getTimeValue(
attendance,
@ -1731,8 +1842,10 @@ const WeeklySummaryPage = ({ userId }) => {
)
.map(
({
attendance,
start,
end,
index,
}) => {
const style =
getAttendanceStyle(
@ -1745,9 +1858,12 @@ const WeeklySummaryPage = ({ userId }) => {
return (
<div
key={`${formatDateKey(
day,
)}-${start}-${end}`}
key={
attendance.id ??
`${formatDateKey(
day,
)}-${start}-${end}-${index}`
}
className="absolute left-2 right-2 overflow-hidden rounded-md border border-blue-600/30 bg-blue-500/80"
style={
style