feat: auto-focus and scroll to newly created class in Open Day schedule
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState, useEffect, useMemo, useCallback } from "react";
|
import { useState, useEffect, useMemo, useCallback, useRef } from "react";
|
||||||
import {
|
import {
|
||||||
Plus, X, Loader2, Calendar, Trash2, Ban, CheckCircle2, RotateCcw, Sparkles,
|
Plus, X, Loader2, Calendar, Trash2, Ban, CheckCircle2, RotateCcw, Sparkles,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
@@ -186,6 +186,7 @@ function ClassCell({
|
|||||||
minBookings,
|
minBookings,
|
||||||
trainers,
|
trainers,
|
||||||
styles,
|
styles,
|
||||||
|
autoEdit,
|
||||||
onUpdate,
|
onUpdate,
|
||||||
onDelete,
|
onDelete,
|
||||||
onCancel,
|
onCancel,
|
||||||
@@ -194,13 +195,21 @@ function ClassCell({
|
|||||||
minBookings: number;
|
minBookings: number;
|
||||||
trainers: string[];
|
trainers: string[];
|
||||||
styles: string[];
|
styles: string[];
|
||||||
|
autoEdit?: boolean;
|
||||||
onUpdate: (id: number, data: Partial<OpenDayClass>) => void;
|
onUpdate: (id: number, data: Partial<OpenDayClass>) => void;
|
||||||
onDelete: (id: number) => void;
|
onDelete: (id: number) => void;
|
||||||
onCancel: (id: number) => void;
|
onCancel: (id: number) => void;
|
||||||
}) {
|
}) {
|
||||||
const [editing, setEditing] = useState(false);
|
const [editing, setEditing] = useState(!!autoEdit);
|
||||||
const [trainer, setTrainer] = useState(cls.trainer);
|
const [trainer, setTrainer] = useState(cls.trainer);
|
||||||
const [style, setStyle] = useState(cls.style);
|
const [style, setStyle] = useState(cls.style);
|
||||||
|
const cellRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (autoEdit && cellRef.current) {
|
||||||
|
cellRef.current.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||||
|
}
|
||||||
|
}, [autoEdit]);
|
||||||
const [endTime, setEndTime] = useState(cls.endTime);
|
const [endTime, setEndTime] = useState(cls.endTime);
|
||||||
|
|
||||||
const atRisk = cls.bookingCount < minBookings && !cls.cancelled;
|
const atRisk = cls.bookingCount < minBookings && !cls.cancelled;
|
||||||
@@ -216,7 +225,7 @@ function ClassCell({
|
|||||||
|
|
||||||
if (editing) {
|
if (editing) {
|
||||||
return (
|
return (
|
||||||
<div className="p-2 space-y-1.5">
|
<div ref={cellRef} className="p-2 space-y-1.5 ring-1 ring-gold/30 rounded-lg">
|
||||||
<select value={style} onChange={(e) => setStyle(e.target.value)} className={selectCls}>
|
<select value={style} onChange={(e) => setStyle(e.target.value)} className={selectCls}>
|
||||||
<option value="">Стиль...</option>
|
<option value="">Стиль...</option>
|
||||||
{styles.map((s) => <option key={s} value={s}>{s}</option>)}
|
{styles.map((s) => <option key={s} value={s}>{s}</option>)}
|
||||||
@@ -332,6 +341,8 @@ function ScheduleGrid({
|
|||||||
return counts;
|
return counts;
|
||||||
}, [classes, halls]);
|
}, [classes, halls]);
|
||||||
|
|
||||||
|
const [newClassTime, setNewClassTime] = useState<string | null>(null);
|
||||||
|
|
||||||
async function addClass(startTime: string) {
|
async function addClass(startTime: string) {
|
||||||
const endTime = addHour(startTime);
|
const endTime = addHour(startTime);
|
||||||
await adminFetch("/api/admin/open-day/classes", {
|
await adminFetch("/api/admin/open-day/classes", {
|
||||||
@@ -339,6 +350,7 @@ function ScheduleGrid({
|
|||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ eventId, hall: selectedHall, startTime, endTime, trainer: "—", style: "—" }),
|
body: JSON.stringify({ eventId, hall: selectedHall, startTime, endTime, trainer: "—", style: "—" }),
|
||||||
});
|
});
|
||||||
|
setNewClassTime(startTime);
|
||||||
onClassesChange();
|
onClassesChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,7 +418,8 @@ function ScheduleGrid({
|
|||||||
minBookings={minBookings}
|
minBookings={minBookings}
|
||||||
trainers={trainers}
|
trainers={trainers}
|
||||||
styles={styles}
|
styles={styles}
|
||||||
onUpdate={updateClass}
|
autoEdit={cls.startTime === newClassTime}
|
||||||
|
onUpdate={(id, data) => { setNewClassTime(null); updateClass(id, data); }}
|
||||||
onDelete={deleteClass}
|
onDelete={deleteClass}
|
||||||
onCancel={cancelClass}
|
onCancel={cancelClass}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user