SkateSpots/src/components/SkaterDirectoryCard.tsx

90 lines
3.9 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Link } from 'react-router-dom';
import { PersonStanding, ChevronRight, Sparkles, Check } from 'lucide-react';
import { useCurrentUser } from '@/hooks/useCurrentUser';
import { useUserSkaterProfile } from '@/hooks/useSkaters';
import { useTranslation } from '@/contexts/language';
import { SKATER_STYLES, SKATER_LEVELS } from '@/lib/types';
/**
* Settings/profile companion card that surfaces the user's SkateSpots "skater
* layer" (kind 35000) right next to their kind-0 profile — the reverse of the
* cross-link on the Become-Skater page. Shows status + a link to edit, or a
* nudge to join the directory if they haven't yet.
*/
export function SkaterDirectoryCard() {
const { user } = useCurrentUser();
const { t } = useTranslation();
const { data: skater, isLoading } = useUserSkaterProfile(user?.pubkey);
if (!user || isLoading) return null;
// Not in the directory yet — gentle nudge.
if (!skater) {
return (
<Link
to="/become/skater"
className="group flex items-center gap-3 p-4 rounded-2xl border-2 border-dashed border-[#ff0040]/30 bg-[#ff0040]/5 hover:border-[#ff0040]/60 hover:bg-[#ff0040]/10 transition-all"
>
<div className="flex-shrink-0 w-10 h-10 rounded-xl bg-[#ff0040]/15 flex items-center justify-center group-hover:bg-[#ff0040]/25 transition-colors">
<PersonStanding className="h-5 w-5 text-[#ff0040]" />
</div>
<div className="min-w-0 flex-1">
<p className="font-bold text-sm leading-tight">{t('labUi.skaterCard.joinTitle')}</p>
<p className="text-xs text-muted-foreground mt-0.5">
{t('labUi.skaterCard.joinDesc')}
</p>
</div>
<Sparkles className="h-4 w-4 text-[#ff0040] flex-shrink-0" />
</Link>
);
}
// Already in the directory — show a compact summary + edit affordance.
const level = skater.level ? SKATER_LEVELS[skater.level] : undefined;
return (
<Link
to="/become/skater"
className="group flex items-center gap-3 p-4 rounded-2xl border border-[#ff0040]/30 bg-gradient-to-r from-[#ff0040]/10 via-transparent to-transparent hover:border-[#ff0040]/50 transition-all"
>
<div className="flex-shrink-0 w-10 h-10 rounded-xl bg-[#ff0040]/15 flex items-center justify-center">
<PersonStanding className="h-5 w-5 text-[#ff0040]" />
</div>
<div className="min-w-0 flex-1">
<p className="font-bold text-sm leading-tight flex items-center gap-1.5">
<Check className="h-3.5 w-3.5 text-[#ccff00]" />
{t('labUi.skaterCard.inDirectory')}
</p>
<div className="flex flex-wrap items-center gap-1.5 mt-1.5">
{level ? (
<span
className="text-[10px] font-black uppercase tracking-wide px-2 py-0.5 rounded-full text-black"
style={{ backgroundColor: level.color }}
>
{level.emoji} {t(level.labelKey)}
</span>
) : skater.customLevel ? (
<span className="text-[10px] font-black uppercase tracking-wide px-2 py-0.5 rounded-full bg-[#ccff00] text-black">
✏️ {skater.customLevel}
</span>
) : null}
{skater.styles.slice(0, 3).map((s) => (
<span
key={s}
className="text-[10px] font-bold px-2 py-0.5 rounded-full bg-muted text-muted-foreground border border-border"
>
{SKATER_STYLES[s].emoji} {t(SKATER_STYLES[s].labelKey)}
</span>
))}
{skater.styles.length > 3 && (
<span className="text-[10px] font-bold text-muted-foreground">+{skater.styles.length - 3}</span>
)}
</div>
</div>
<span className="flex items-center gap-0.5 text-xs font-bold uppercase tracking-wider text-[#ff0040] flex-shrink-0">
{t('common.edit')}
<ChevronRight className="h-4 w-4" />
</span>
</Link>
);
}