feat: unique color picker for class types in schedule editor

- Add clickable color picker in schedule legend (16 distinct colors)
- Two-pass smart assignment: explicit colors first, then unused palette slots
- Hide already-used colors from the picker (both explicit and fallback)
- Colors saved to classes section and flow to public site schedule dots
- Expanded palette: rose, orange, amber, yellow, lime, emerald, teal, cyan,
  sky, blue, indigo, violet, purple, fuchsia, pink, red

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 20:16:26 +03:00
parent 85c61cfacd
commit 5c23b622f9
9 changed files with 240 additions and 40 deletions

View File

@@ -2,9 +2,9 @@
import { User, X } from "lucide-react";
import type { ScheduleDay } from "@/types/content";
import { TYPE_DOT } from "./constants";
interface MobileScheduleProps {
typeDots: Record<string, string>;
filteredDays: ScheduleDay[];
filterType: string | null;
setFilterType: (type: string | null) => void;
@@ -15,6 +15,7 @@ interface MobileScheduleProps {
}
export function MobileSchedule({
typeDots,
filteredDays,
filterType,
setFilterType,
@@ -37,7 +38,7 @@ export function MobileSchedule({
)}
{filterType && (
<span className="flex items-center gap-1">
<span className={`h-1.5 w-1.5 rounded-full ${TYPE_DOT[filterType] ?? "bg-white/30"}`} />
<span className={`h-1.5 w-1.5 rounded-full ${typeDots[filterType] ?? "bg-white/30"}`} />
{filterType}
</span>
)}
@@ -107,7 +108,7 @@ export function MobileSchedule({
onClick={() => setFilterType(filterType === cls.type ? null : cls.type)}
className={`mt-0.5 flex items-center gap-1.5 active:opacity-60 ${filterType === cls.type ? "opacity-100" : ""}`}
>
<span className={`h-1.5 w-1.5 shrink-0 rounded-full ${TYPE_DOT[cls.type] ?? "bg-white/30"}`} />
<span className={`h-1.5 w-1.5 shrink-0 rounded-full ${typeDots[cls.type] ?? "bg-white/30"}`} />
<span className={`text-[11px] ${filterType === cls.type ? "text-gold underline underline-offset-2" : "text-neutral-400 dark:text-white/30"}`}>{cls.type}</span>
</button>
</div>