From fc523b2045abf22be54dd7a9ba5846721c2411c8 Mon Sep 17 00:00:00 2001 From: "diana.dolgolyova" Date: Thu, 12 Mar 2026 13:52:59 +0300 Subject: [PATCH] feat: same-time checkbox for multi-day class groups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - "Одинаковое время" checkbox (default on) syncs time across all days - Uncheck to set per-day times (e.g., Mon 12:00, Fri 18:00) - Checkbox only appears when 2+ days selected - Single day: just shows one time field, no checkbox - Unified day selector for both new and edit modes Co-Authored-By: Claude Opus 4.6 --- src/app/admin/schedule/page.tsx | 164 ++++++++++++++++++-------------- 1 file changed, 95 insertions(+), 69 deletions(-) diff --git a/src/app/admin/schedule/page.tsx b/src/app/admin/schedule/page.tsx index 97d8406..8a3a4df 100644 --- a/src/app/admin/schedule/page.tsx +++ b/src/app/admin/schedule/page.tsx @@ -254,6 +254,13 @@ function ClassModal({ const [dayTimes, setDayTimes] = useState>(initialDayTimes); + // "Same time for all days" — default true if all existing times match + const allTimesMatch = useMemo(() => { + const vals = Object.values(initialDayTimes); + return vals.length <= 1 || vals.every((t) => t === vals[0]); + }, [initialDayTimes]); + const [sameTime, setSameTime] = useState(allTimesMatch); + const selectedDays = new Set(Object.keys(dayTimes)); function toggleDay(day: string) { @@ -265,13 +272,34 @@ function ClassModal({ delete next[day]; return next; } - // New day gets time from current day - return { ...prev, [day]: prev[currentDay] || cls.time }; + // New day gets time from current day or first existing + const refTime = sameTime + ? (Object.values(prev)[0] || cls.time) + : (prev[currentDay] || cls.time); + return { ...prev, [day]: refTime }; }); } function updateDayTime(day: string, time: string) { - setDayTimes((prev) => ({ ...prev, [day]: time })); + if (sameTime) { + // Update all days at once + setDayTimes((prev) => { + const next: Record = {}; + for (const d of Object.keys(prev)) next[d] = time; + return next; + }); + } else { + setDayTimes((prev) => ({ ...prev, [day]: time })); + } + } + + function updateSharedTime(time: string) { + setDraft({ ...draft, time }); + setDayTimes((prev) => { + const next: Record = {}; + for (const d of Object.keys(prev)) next[d] = time; + return next; + }); } // Compute what changed for the hint (edit mode only) @@ -300,61 +328,25 @@ function ClassModal({
- {/* Selected days with per-day time (edit mode) or simple buttons (new mode) */} - {!isNew && selectedDays.size > 0 && ( -
- {allDays.filter((d) => selectedDays.has(d.day)).map((d) => ( -
- -
- updateDayTime(d.day, v)} - /> -
-
- ))} -
- )} - - {/* Unselected days — toggle buttons */} + {/* Day toggle buttons */}
- {isNew - ? allDays.map((d) => { - const active = selectedDays.has(d.day); - return ( - - ); - }) - : allDays.filter((d) => !selectedDays.has(d.day)).map((d) => ( - - )) - } + {allDays.map((d) => { + const active = selectedDays.has(d.day); + return ( + + ); + })}
{!isNew && (addedDays.length > 0 || removedDays.length > 0) && ( @@ -374,21 +366,55 @@ function ClassModal({
)} - {/* Time — only for new class (edit mode has per-day times above) */} - {isNew && ( + {/* Same time checkbox + time fields */} + {selectedDays.size > 1 && ( + + )} + + {sameTime || selectedDays.size <= 1 ? ( { - setDraft({ ...draft, time: v }); - // Update all selected day times - setDayTimes((prev) => { - const next: Record = {}; - for (const day of Object.keys(prev)) next[day] = v; - return next; - }); - }} + value={Object.values(dayTimes)[0] || draft.time} + onChange={updateSharedTime} /> + ) : ( +
+ + {allDays.filter((d) => selectedDays.has(d.day)).map((d) => ( +
+ + {d.dayShort} + +
+ updateDayTime(d.day, v)} + /> +
+
+ ))} +
)}