feat: shared GroupCard component, admin status select, schedule level filter

- Extract shared GroupCard component used by both Schedule GroupView and TeamProfile
- Admin schedule: replace hasSlots/recruiting toggles with single Status select
- User schedule: add level filter pills (Начинающий/Без опыта, Продвинутый)
- Consistent group card styling across schedule and trainer bio views
This commit is contained in:
2026-03-26 23:38:51 +03:00
parent c4c3a7ab0d
commit 035f68776a
6 changed files with 219 additions and 107 deletions
+18 -13
View File
@@ -2,7 +2,7 @@
import { useState, useEffect, useRef, useCallback, useMemo } from "react";
import { SectionEditor } from "../_components/SectionEditor";
import { InputField, SelectField, TimeRangeField, ToggleField } from "../_components/FormField";
import { InputField, SelectField, TimeRangeField } from "../_components/FormField";
import { Plus, X, Trash2 } from "lucide-react";
import { adminFetch } from "@/lib/csrf";
import type { ScheduleLocation, ScheduleDay, ScheduleClass } from "@/types/content";
@@ -32,6 +32,13 @@ const LEVELS = [
{ value: "Продвинутый", label: "Продвинутый" },
];
const STATUS_OPTIONS = [
{ value: "", label: "Без статуса" },
{ value: "hasSlots", label: "Есть места" },
{ value: "recruiting", label: "Набор открыт" },
{ value: "both", label: "Есть места + Набор" },
];
const GROUP_PALETTE = [
"bg-rose-500/80 border-rose-400",
"bg-orange-500/80 border-orange-400",
@@ -477,18 +484,16 @@ function ClassModal({
onChange={(v) => setDraft({ ...draft, level: v || undefined })}
options={LEVELS}
/>
<div className="flex gap-6">
<ToggleField
label="Есть места"
checked={draft.hasSlots ?? false}
onChange={(v) => setDraft({ ...draft, hasSlots: v })}
/>
<ToggleField
label="Набор открыт"
checked={draft.recruiting ?? false}
onChange={(v) => setDraft({ ...draft, recruiting: v })}
/>
</div>
<SelectField
label="Статус"
value={draft.hasSlots && draft.recruiting ? "both" : draft.recruiting ? "recruiting" : draft.hasSlots ? "hasSlots" : ""}
onChange={(v) => setDraft({
...draft,
hasSlots: v === "hasSlots" || v === "both",
recruiting: v === "recruiting" || v === "both",
})}
options={STATUS_OPTIONS}
/>
</div>
{/* Overlap warning */}