diff --git a/src/app/admin/schedule/page.tsx b/src/app/admin/schedule/page.tsx index 47dc79e..f027e53 100644 --- a/src/app/admin/schedule/page.tsx +++ b/src/app/admin/schedule/page.tsx @@ -238,6 +238,11 @@ function ClassBlock({ } // ---------- Edit Modal ---------- +/** Check if two classes are the same "group" (same trainer + type + time) */ +function isSameGroup(a: ScheduleClass, b: ScheduleClass): boolean { + return a.trainer === b.trainer && a.type === b.type && a.time === b.time; +} + function ClassModal({ cls, trainers, @@ -245,17 +250,56 @@ function ClassModal({ onSave, onDelete, onClose, + allDays, + currentDay, }: { cls: ScheduleClass; trainers: string[]; classTypes: string[]; - onSave: (cls: ScheduleClass) => void; + /** For edit: saves to current day + manages group days. For new: creates on selected days. */ + onSave: (cls: ScheduleClass, days: string[]) => void; onDelete?: () => void; onClose: () => void; + /** All schedule days (sorted) */ + allDays: ScheduleDay[]; + /** Current day name */ + currentDay: string; }) { const [draft, setDraft] = useState(cls); const trainerOptions = trainers.map((t) => ({ value: t, label: t })); const typeOptions = classTypes.map((t) => ({ value: t, label: t })); + const isNew = !onDelete; + + // Find which days already have this exact group (for edit mode) + const groupDays = useMemo(() => { + if (isNew) return new Set(); + const days = new Set(); + for (const day of allDays) { + if (day.classes.some((c) => isSameGroup(c, cls))) { + days.add(day.day); + } + } + return days; + }, [allDays, cls, isNew]); + + const [selectedDays, setSelectedDays] = useState>( + () => isNew ? new Set([currentDay]) : new Set(groupDays) + ); + + function toggleDay(day: string) { + setSelectedDays((prev) => { + const next = new Set(prev); + // Must have at least one day selected + if (next.has(day) && next.size <= 1) return next; + if (next.has(day)) next.delete(day); + else next.add(day); + return next; + }); + } + + // Compute what changed for the hint + const addedDays = [...selectedDays].filter((d) => !groupDays.has(d)); + const removedDays = [...groupDays].filter((d) => !selectedDays.has(d)); return (
@@ -265,7 +309,7 @@ function ClassModal({ >

- {onDelete ? "Редактировать занятие" : "Новое занятие"} + {isNew ? "Новое занятие" : "Редактировать занятие"}

+ {/* Day selector — always visible */} + {allDays.length > 1 && ( +
+ +
+ {allDays.map((d) => { + const active = selectedDays.has(d.day); + return ( + + ); + })} +
+ {!isNew && (addedDays.length > 0 || removedDays.length > 0) && ( +
+ {addedDays.length > 0 && ( + + + {addedDays.map((d) => allDays.find((ad) => ad.day === d)?.dayShort).join(", ")} + + )} + {removedDays.length > 0 && ( + + − {removedDays.map((d) => allDays.find((ad) => ad.day === d)?.dayShort).join(", ")} + + )} +
+ )} +
+ )} + { - onSave(draft); + onSave(draft, [...selectedDays]); onClose(); }} className="flex-1 rounded-lg bg-gold px-4 py-2.5 text-sm font-medium text-black hover:opacity-90 transition-opacity" @@ -829,16 +913,32 @@ function CalendarGrid({ cls={editingData.cls} trainers={trainers} classTypes={classTypes} - onSave={(updated) => { - const day = sortedDays[editingClass.dayIndex]; - const classes = [...day.classes]; - classes[editingClass.classIndex] = updated; - updateDay(editingClass.dayIndex, { ...day, classes }); + allDays={sortedDays} + currentDay={sortedDays[editingClass.dayIndex]?.day} + onSave={(updated, days) => { + const original = editingData.cls; + const selectedSet = new Set(days); + + const updatedDays = location.days.map((d) => { + const inSelected = selectedSet.has(d.day); + // Remove old matching group entries + let classes = d.classes.filter((c) => !isSameGroup(c, original)); + // Add updated class to selected days + if (inSelected) { + classes = [...classes, updated]; + } + return { ...d, classes }; + }); + onChange({ ...location, days: updatedDays }); }} onDelete={() => { - const day = sortedDays[editingClass.dayIndex]; - const classes = day.classes.filter((_, i) => i !== editingClass.classIndex); - updateDay(editingClass.dayIndex, { ...day, classes }); + // Delete from ALL days that have this group + const original = editingData.cls; + const updatedDays = location.days.map((d) => ({ + ...d, + classes: d.classes.filter((c) => !isSameGroup(c, original)), + })); + onChange({ ...location, days: updatedDays }); }} onClose={() => setEditingClass(null)} /> @@ -850,10 +950,17 @@ function CalendarGrid({ cls={newClass.cls} trainers={trainers} classTypes={classTypes} - onSave={(created) => { - const day = sortedDays[newClass.dayIndex]; - const classes = [...day.classes, created]; - updateDay(newClass.dayIndex, { ...day, classes }); + allDays={sortedDays} + currentDay={sortedDays[newClass.dayIndex]?.day} + onSave={(created, days) => { + const targetDayNames = new Set(days); + const updatedDays = location.days.map((d) => { + if (targetDayNames.has(d.day)) { + return { ...d, classes: [...d.classes, created] }; + } + return d; + }); + onChange({ ...location, days: updatedDays }); }} onClose={() => setNewClass(null)} />