feat: UI improvements — scrollbar, multi-filters, pricing fix, routing, modals
- Global page scrollbar styled with gold theme - Schedule: multi-select for class types and status tags - Pricing: fix tab switch blink (display toggle vs conditional render) - OpenDay: trainer name more prominent, section divider added - Team: browser back button closes trainer bio (history API) - Modals: block scroll + compensate scrollbar width to prevent layout shift - Header: remove booking button from desktop nav
This commit is contained in:
@@ -8,8 +8,8 @@ interface DayCardProps {
|
||||
showLocation?: boolean;
|
||||
filterTrainer: string | null;
|
||||
setFilterTrainer: (trainer: string | null) => void;
|
||||
filterType: string | null;
|
||||
setFilterType: (type: string | null) => void;
|
||||
filterTypes: Set<string>;
|
||||
toggleFilterType: (type: string) => void;
|
||||
}
|
||||
|
||||
function ClassRow({
|
||||
@@ -17,15 +17,15 @@ function ClassRow({
|
||||
typeDots,
|
||||
filterTrainer,
|
||||
setFilterTrainer,
|
||||
filterType,
|
||||
setFilterType,
|
||||
filterTypes,
|
||||
toggleFilterType,
|
||||
}: {
|
||||
cls: ScheduleClassWithLocation;
|
||||
typeDots: Record<string, string>;
|
||||
filterTrainer: string | null;
|
||||
setFilterTrainer: (trainer: string | null) => void;
|
||||
filterType: string | null;
|
||||
setFilterType: (type: string | null) => void;
|
||||
filterTypes: Set<string>;
|
||||
toggleFilterType: (type: string) => void;
|
||||
}) {
|
||||
return (
|
||||
<div className={`px-5 py-3.5 ${cls.hasSlots ? "bg-emerald-500/5" : cls.recruiting ? "bg-sky-500/5" : ""}`}>
|
||||
@@ -58,12 +58,12 @@ function ClassRow({
|
||||
</button>
|
||||
<div className="mt-2 flex items-center gap-2 flex-wrap">
|
||||
<button
|
||||
onClick={() => setFilterType(filterType === cls.type ? null : cls.type)}
|
||||
onClick={() => toggleFilterType(cls.type)}
|
||||
className="flex items-center gap-2 cursor-pointer active:opacity-60"
|
||||
>
|
||||
<span className={`h-2 w-2 shrink-0 rounded-full ${typeDots[cls.type] ?? "bg-white/30"}`} />
|
||||
<span className={`text-xs ${
|
||||
filterType === cls.type
|
||||
filterTypes.has(cls.type)
|
||||
? "text-gold underline underline-offset-2"
|
||||
: "text-neutral-500 dark:text-white/40"
|
||||
}`}>{cls.type}</span>
|
||||
@@ -78,7 +78,7 @@ function ClassRow({
|
||||
);
|
||||
}
|
||||
|
||||
export function DayCard({ day, typeDots, showLocation, filterTrainer, setFilterTrainer, filterType, setFilterType }: DayCardProps) {
|
||||
export function DayCard({ day, typeDots, showLocation, filterTrainer, setFilterTrainer, filterTypes, toggleFilterType }: DayCardProps) {
|
||||
// Group classes by location when showLocation is true
|
||||
const locationGroups = showLocation
|
||||
? Array.from(
|
||||
@@ -123,7 +123,7 @@ export function DayCard({ day, typeDots, showLocation, filterTrainer, setFilterT
|
||||
</div>
|
||||
<div className="divide-y divide-neutral-100 dark:divide-white/[0.04]">
|
||||
{classes.map((cls, i) => (
|
||||
<ClassRow key={i} cls={cls} typeDots={typeDots} filterTrainer={filterTrainer} setFilterTrainer={setFilterTrainer} filterType={filterType} setFilterType={setFilterType} />
|
||||
<ClassRow key={i} cls={cls} typeDots={typeDots} filterTrainer={filterTrainer} setFilterTrainer={setFilterTrainer} filterTypes={filterTypes} toggleFilterType={toggleFilterType} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
@@ -133,7 +133,7 @@ export function DayCard({ day, typeDots, showLocation, filterTrainer, setFilterT
|
||||
// Single location — no sub-headers
|
||||
<div className="divide-y divide-neutral-100 dark:divide-white/[0.04]">
|
||||
{day.classes.map((cls, i) => (
|
||||
<ClassRow key={i} cls={cls} typeDots={typeDots} filterTrainer={filterTrainer} setFilterTrainer={setFilterTrainer} filterType={filterType} setFilterType={setFilterType} />
|
||||
<ClassRow key={i} cls={cls} typeDots={typeDots} filterTrainer={filterTrainer} setFilterTrainer={setFilterTrainer} filterTypes={filterTypes} toggleFilterType={toggleFilterType} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user