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:
@@ -7,8 +7,8 @@ import type { ScheduleDayMerged, ScheduleClassWithLocation } from "./constants";
|
||||
interface MobileScheduleProps {
|
||||
typeDots: Record<string, string>;
|
||||
filteredDays: ScheduleDayMerged[];
|
||||
filterType: string | null;
|
||||
setFilterType: (type: string | null) => void;
|
||||
filterTypes: Set<string>;
|
||||
toggleFilterType: (type: string) => void;
|
||||
filterTrainer: string | null;
|
||||
setFilterTrainer: (trainer: string | null) => void;
|
||||
hasActiveFilter: boolean;
|
||||
@@ -19,16 +19,16 @@ interface MobileScheduleProps {
|
||||
function ClassRow({
|
||||
cls,
|
||||
typeDots,
|
||||
filterType,
|
||||
setFilterType,
|
||||
filterTypes,
|
||||
toggleFilterType,
|
||||
filterTrainer,
|
||||
setFilterTrainer,
|
||||
showLocation,
|
||||
}: {
|
||||
cls: ScheduleClassWithLocation;
|
||||
typeDots: Record<string, string>;
|
||||
filterType: string | null;
|
||||
setFilterType: (type: string | null) => void;
|
||||
filterTypes: Set<string>;
|
||||
toggleFilterType: (type: string) => void;
|
||||
filterTrainer: string | null;
|
||||
setFilterTrainer: (trainer: string | null) => void;
|
||||
showLocation?: boolean;
|
||||
@@ -69,11 +69,11 @@ function ClassRow({
|
||||
</div>
|
||||
<div className="mt-0.5 flex items-center gap-2">
|
||||
<button
|
||||
onClick={() => setFilterType(filterType === cls.type ? null : cls.type)}
|
||||
className={`flex items-center gap-1.5 active:opacity-60 ${filterType === cls.type ? "opacity-100" : ""}`}
|
||||
onClick={() => toggleFilterType(cls.type)}
|
||||
className={`flex items-center gap-1.5 active:opacity-60 ${filterTypes.has(cls.type) ? "opacity-100" : ""}`}
|
||||
>
|
||||
<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>
|
||||
<span className={`text-[11px] ${filterTypes.has(cls.type) ? "text-gold underline underline-offset-2" : "text-neutral-400 dark:text-white/30"}`}>{cls.type}</span>
|
||||
</button>
|
||||
{showLocation && cls.locationName && (
|
||||
<span className="flex items-center gap-0.5 text-[10px] text-neutral-400 dark:text-white/20">
|
||||
@@ -90,8 +90,8 @@ function ClassRow({
|
||||
export function MobileSchedule({
|
||||
typeDots,
|
||||
filteredDays,
|
||||
filterType,
|
||||
setFilterType,
|
||||
filterTypes,
|
||||
toggleFilterType,
|
||||
filterTrainer,
|
||||
setFilterTrainer,
|
||||
hasActiveFilter,
|
||||
@@ -110,12 +110,12 @@ export function MobileSchedule({
|
||||
{filterTrainer}
|
||||
</span>
|
||||
)}
|
||||
{filterType && (
|
||||
<span className="flex items-center gap-1">
|
||||
<span className={`h-1.5 w-1.5 rounded-full ${typeDots[filterType] ?? "bg-white/30"}`} />
|
||||
{filterType}
|
||||
{filterTypes.size > 0 && Array.from(filterTypes).map((type) => (
|
||||
<span key={type} className="flex items-center gap-1">
|
||||
<span className={`h-1.5 w-1.5 rounded-full ${typeDots[type] ?? "bg-white/30"}`} />
|
||||
{type}
|
||||
</span>
|
||||
)}
|
||||
))}
|
||||
</div>
|
||||
<button
|
||||
onClick={clearFilters}
|
||||
@@ -175,8 +175,8 @@ export function MobileSchedule({
|
||||
key={i}
|
||||
cls={cls}
|
||||
typeDots={typeDots}
|
||||
filterType={filterType}
|
||||
setFilterType={setFilterType}
|
||||
filterTypes={filterTypes}
|
||||
toggleFilterType={toggleFilterType}
|
||||
filterTrainer={filterTrainer}
|
||||
setFilterTrainer={setFilterTrainer}
|
||||
/>
|
||||
@@ -190,8 +190,8 @@ export function MobileSchedule({
|
||||
key={i}
|
||||
cls={cls}
|
||||
typeDots={typeDots}
|
||||
filterType={filterType}
|
||||
setFilterType={setFilterType}
|
||||
filterTypes={filterTypes}
|
||||
toggleFilterType={toggleFilterType}
|
||||
filterTrainer={filterTrainer}
|
||||
setFilterTrainer={setFilterTrainer}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user