feat: unified badges, filter UI overhaul, trainer bio link
- ScheduleBadge: shared gold badge component for all status/level tags - Replace hardcoded emerald/sky/rose badge colors with unified gold style - DayCard, GroupCard, MobileSchedule all use ScheduleBadge - Location tag moved before status badges, gold styling - GroupCard: flex-col with mt-auto button alignment - TeamProfile: pass hasSlots/status to GroupCard Filter modal redesign: - Status: horizontal Airbnb-style toggle cards with ? info tips - Experience: vertical radio list with gold dots - When: days + time inputs on single row - Click-to-toggle InfoTip replacing hover tooltips - Gold speech bubble tooltip design Schedule cards: - Trainer name click opens bio instead of filtering - DayCard location header: gold background, no duplicate address
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { MapPin } from "lucide-react";
|
||||
import { shortAddress } from "@/components/sections/schedule/constants";
|
||||
import { ScheduleBadge } from "@/components/ui/ScheduleBadge";
|
||||
|
||||
export interface GroupCardSlot {
|
||||
days: string[];
|
||||
@@ -50,14 +51,11 @@ export function GroupCard({
|
||||
const typeCls = compact ? "text-xs" : "text-sm";
|
||||
const dayPad = compact ? "px-1.5 py-px text-[10px] min-w-[40px]" : "px-2 py-0.5 text-[11px] min-w-[52px]";
|
||||
const timeCls = compact ? "text-xs" : "text-sm font-medium";
|
||||
const badgeSize = compact ? "px-2 py-0.5 text-[9px]" : "px-2.5 py-0.5 text-[10px]";
|
||||
const locSize = compact ? "px-2 py-0.5 text-[9px]" : "px-2.5 py-0.5 text-[10px]";
|
||||
const locIcon = compact ? 8 : 9;
|
||||
|
||||
const levelBadge = level ? (
|
||||
<span className={`shrink-0 rounded-full bg-rose-500/15 border border-rose-500/25 ${badgeSize} font-semibold text-rose-400`}>
|
||||
{level}
|
||||
</span>
|
||||
<ScheduleBadge size={compact ? "sm" : "md"}>{level}</ScheduleBadge>
|
||||
) : null;
|
||||
|
||||
const typeContent = (
|
||||
@@ -69,7 +67,7 @@ export function GroupCard({
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="space-y-1.5">
|
||||
<div className="flex flex-col flex-1 gap-1.5">
|
||||
{/* Type + level + status badges + extras */}
|
||||
<div className="flex items-center gap-1.5 flex-wrap">
|
||||
{onTypeClick ? (
|
||||
@@ -79,27 +77,17 @@ export function GroupCard({
|
||||
) : (
|
||||
<span className="inline-flex items-center gap-1.5">{typeContent}</span>
|
||||
)}
|
||||
{hasSlots && (
|
||||
<span className={`rounded-full bg-emerald-500/15 border border-emerald-500/25 ${badgeSize} font-semibold text-emerald-400`}>
|
||||
есть места
|
||||
</span>
|
||||
)}
|
||||
{recruiting && (
|
||||
<span className={`rounded-full bg-sky-500/15 border border-sky-500/25 ${badgeSize} font-semibold text-sky-400`}>
|
||||
набор
|
||||
</span>
|
||||
)}
|
||||
{status && status !== "hasSlots" && status !== "recruiting" && (
|
||||
<span className={`rounded-full bg-gold/15 border border-gold/25 ${badgeSize} font-semibold text-gold`}>
|
||||
{statusLabel || status}
|
||||
</span>
|
||||
)}
|
||||
{showLocation && (address || location) && (
|
||||
<span className={`inline-flex items-center gap-1 rounded-full bg-white/[0.04] border border-white/[0.08] ${locSize} font-medium text-white/40`}>
|
||||
<MapPin size={locIcon} />
|
||||
<span className={`inline-flex items-center gap-1 rounded-full bg-gold/15 border border-gold/25 ${locSize} font-medium text-white`}>
|
||||
<MapPin size={locIcon} className="text-gold" />
|
||||
{shortAddress(address || location || "")}
|
||||
</span>
|
||||
)}
|
||||
{hasSlots && <ScheduleBadge size={compact ? "sm" : "md"}>есть места</ScheduleBadge>}
|
||||
{recruiting && <ScheduleBadge size={compact ? "sm" : "md"}>набор</ScheduleBadge>}
|
||||
{status && status !== "hasSlots" && status !== "recruiting" && (
|
||||
<ScheduleBadge size={compact ? "sm" : "md"}>{statusLabel || status}</ScheduleBadge>
|
||||
)}
|
||||
{extraBadges}
|
||||
</div>
|
||||
|
||||
@@ -122,7 +110,7 @@ export function GroupCard({
|
||||
compact ? (
|
||||
<button
|
||||
onClick={onBook}
|
||||
className="w-full rounded-lg bg-gold/15 border border-gold/25 py-1.5 text-[11px] font-semibold text-gold hover:bg-gold/25 transition-colors cursor-pointer"
|
||||
className="w-full mt-auto rounded-lg bg-gold/15 border border-gold/25 py-1.5 text-[11px] font-semibold text-gold hover:bg-gold/25 transition-colors cursor-pointer"
|
||||
>
|
||||
Записаться
|
||||
</button>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
interface ScheduleBadgeProps {
|
||||
children: React.ReactNode;
|
||||
size?: "sm" | "md";
|
||||
}
|
||||
|
||||
/**
|
||||
* Unified badge for schedule status and level tags.
|
||||
* Single gold style used consistently across DayCard, GroupCard, MobileSchedule.
|
||||
*/
|
||||
export function ScheduleBadge({ children, size = "md" }: ScheduleBadgeProps) {
|
||||
const sizeClass = size === "sm"
|
||||
? "px-1.5 py-px text-[9px]"
|
||||
: "px-2.5 py-0.5 text-[10px]";
|
||||
|
||||
return (
|
||||
<span className={`shrink-0 rounded-full bg-gold/15 border border-gold/25 ${sizeClass} font-semibold text-gold`}>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user