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:
@@ -7,14 +7,16 @@ import { Reveal } from "@/components/ui/Reveal";
|
||||
import { DayCard } from "./schedule/DayCard";
|
||||
import { ScheduleFilters } from "./schedule/ScheduleFilters";
|
||||
import { MobileSchedule } from "./schedule/MobileSchedule";
|
||||
import { buildTypeDots } from "./schedule/constants";
|
||||
import type { StatusFilter } from "./schedule/constants";
|
||||
import type { SiteContent } from "@/types/content";
|
||||
|
||||
interface ScheduleProps {
|
||||
data: SiteContent["schedule"];
|
||||
classItems?: { name: string; color?: string }[];
|
||||
}
|
||||
|
||||
export function Schedule({ data: schedule }: ScheduleProps) {
|
||||
export function Schedule({ data: schedule, classItems }: ScheduleProps) {
|
||||
const [locationIndex, setLocationIndex] = useState(0);
|
||||
const [filterTrainer, setFilterTrainer] = useState<string | null>(null);
|
||||
const [filterType, setFilterType] = useState<string | null>(null);
|
||||
@@ -22,6 +24,8 @@ export function Schedule({ data: schedule }: ScheduleProps) {
|
||||
const [showTrainers, setShowTrainers] = useState(false);
|
||||
const location = schedule.locations[locationIndex];
|
||||
|
||||
const typeDots = useMemo(() => buildTypeDots(classItems), [classItems]);
|
||||
|
||||
const { trainers, types, hasAnySlots, hasAnyRecruiting } = useMemo(() => {
|
||||
const trainerSet = new Set<string>();
|
||||
const typeSet = new Set<string>();
|
||||
@@ -108,6 +112,7 @@ export function Schedule({ data: schedule }: ScheduleProps) {
|
||||
{/* Compact filters — desktop only */}
|
||||
<Reveal>
|
||||
<ScheduleFilters
|
||||
typeDots={typeDots}
|
||||
types={types}
|
||||
trainers={trainers}
|
||||
hasAnySlots={hasAnySlots}
|
||||
@@ -129,6 +134,7 @@ export function Schedule({ data: schedule }: ScheduleProps) {
|
||||
{/* Mobile: compact agenda list with tap-to-filter */}
|
||||
<Reveal>
|
||||
<MobileSchedule
|
||||
typeDots={typeDots}
|
||||
filteredDays={filteredDays}
|
||||
filterType={filterType}
|
||||
setFilterType={setFilterType}
|
||||
@@ -151,7 +157,7 @@ export function Schedule({ data: schedule }: ScheduleProps) {
|
||||
key={day.day}
|
||||
className={filteredDays.length === 1 ? "w-full max-w-[340px]" : ""}
|
||||
>
|
||||
<DayCard day={day} />
|
||||
<DayCard day={day} typeDots={typeDots} />
|
||||
</div>
|
||||
))}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user