chore(ridercard): delete the unused AwardBadgeDialog

showAwardDialog was never set true, so the dialog could never open; the inline
AwardBadgeInline form is the live flow. Removes ~142 lines plus its now-unused
Dialog imports, state and helper.
This commit is contained in:
SkateSpots 2026-09-26 19:14:21 +07:00
parent bf7fdbd621
commit 10ab45383d

View file

@ -28,9 +28,6 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
import { Switch } from '@/components/ui/switch'; import { Switch } from '@/components/ui/switch';
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'; import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import {
Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription,
} from '@/components/ui/dialog';
import { useCurrentUser } from '@/hooks/useCurrentUser'; import { useCurrentUser } from '@/hooks/useCurrentUser';
import { useAuthor } from '@/hooks/useAuthor'; import { useAuthor } from '@/hooks/useAuthor';
@ -874,148 +871,6 @@ function RiderCardFront({ d, printRef }: { d: CardData; printRef?: React.RefObje
); );
} }
// ─── Award Badge Dialog ───────────────────────────────────────────────────────
interface AwardBadgeDialogProps {
open: boolean;
onClose: () => void;
issuerPubkey: string;
}
function AwardBadgeDialog({ open, onClose, issuerPubkey }: AwardBadgeDialogProps) {
const { mutate: publishEvent, isPending } = useNostrPublish();
const { toast } = useToast();
const [recipientNpub, setRecipientNpub] = useState('');
const [selectedSkills, setSelectedSkills] = useState<string[]>([]);
const [spotName, setSpotName] = useState('');
const toggleSkill = (id: string) =>
setSelectedSkills(prev =>
prev.includes(id) ? prev.filter(s => s !== id) : [...prev, id]
);
const handleAward = () => {
if (!recipientNpub.trim() || selectedSkills.length === 0) {
toast({ title: 'Fill in rider npub + at least one skill', variant: 'destructive' });
return;
}
let recipientHex = '';
try {
const decoded = nip19.decode(recipientNpub.trim());
if (decoded.type !== 'npub') throw new Error('not npub');
recipientHex = decoded.data;
} catch {
toast({ title: 'Invalid npub', description: 'Paste a valid npub1… address', variant: 'destructive' });
return;
}
const tags: string[][] = [
['p', recipientHex],
['t', 'skill-badge'],
['alt', `Skill badge awarded: ${selectedSkills.join(', ')}`],
...selectedSkills.map(s => ['skill', s]),
];
if (spotName.trim()) tags.push(['spot', spotName.trim()]);
publishEvent(
{ kind: SKILL_BADGE_KIND, content: '', tags },
{
onSuccess: () => {
toast({ title: '🏅 Badge awarded!', description: `${selectedSkills.join(', ')} sent to rider.` });
setRecipientNpub('');
setSelectedSkills([]);
setSpotName('');
onClose();
},
onError: (e) => toast({ title: 'Failed', description: String(e), variant: 'destructive' }),
},
);
};
return (
<Dialog open={open} onOpenChange={(v) => !v && onClose()}>
<DialogContent className="bg-black border-gray-800 max-w-md">
<DialogHeader>
<DialogTitle className="text-white flex items-center gap-2">
<Award className="h-5 w-5 text-yellow-400" />
Award a Skill Badge
</DialogTitle>
<DialogDescription className="text-gray-400">
You saw it happen. Sign the proof on Nostr — it becomes part of their permanent record.
</DialogDescription>
</DialogHeader>
<div className="space-y-4 pt-2">
{/* Recipient */}
<div>
<Label className="text-xs uppercase tracking-widest text-gray-500 mb-1.5 block">
Rider's Nostr Address (npub)
</Label>
<Input
value={recipientNpub}
onChange={e => setRecipientNpub(e.target.value)}
placeholder="npub1…"
className="bg-black/50 border-gray-700 font-mono text-xs"
/>
</div>
{/* Skills */}
<div>
<Label className="text-xs uppercase tracking-widest text-gray-500 mb-2 block">
Skills you witnessed
</Label>
<div className="flex flex-wrap gap-1.5">
{SKILL_OPTIONS.map(s => (
<button
key={s.id}
onClick={() => toggleSkill(s.id)}
className={cn(
'px-2 py-1 rounded-full text-[11px] font-bold border transition-all',
selectedSkills.includes(s.id)
? 'bg-yellow-500/20 border-yellow-400 text-yellow-300'
: 'bg-black/40 border-gray-700 text-gray-400 hover:border-gray-500'
)}
>
{s.icon} {s.label}
</button>
))}
</div>
</div>
{/* Spot name */}
<div>
<Label className="text-xs uppercase tracking-widest text-gray-500 mb-1.5 block">
Where did you witness it? (optional)
</Label>
<Input
value={spotName}
onChange={e => setSpotName(e.target.value)}
placeholder="e.g. MACBA, The Berrics, Burnside…"
className="bg-black/50 border-gray-700 text-sm"
/>
</div>
<div className="p-3 rounded-xl bg-yellow-500/5 border border-yellow-500/20 text-xs text-gray-400">
<span className="font-bold text-yellow-400">🔐 Signed proof.</span>{' '}
This badge is a signed message on the Nostr network — cryptographically tied to your key.
The rider can show it with your name as witness, and anyone can verify it's real.
</div>
<Button
onClick={handleAward}
disabled={isPending || selectedSkills.length === 0 || !recipientNpub.trim()}
className="w-full bg-yellow-500 hover:bg-yellow-400 text-black font-black uppercase gap-2"
>
<Award className="h-4 w-4" />
{isPending ? 'Signing…' : 'Award Badge'}
</Button>
</div>
</DialogContent>
</Dialog>
);
}
// ─── Received badges panel ──────────────────────────────────────────────────── // ─── Received badges panel ────────────────────────────────────────────────────
function ReceivedBadgesPanel({ pubkey }: { pubkey: string }) { function ReceivedBadgesPanel({ pubkey }: { pubkey: string }) {
const { data: badgeEvents = [] } = useReceivedBadges(pubkey); const { data: badgeEvents = [] } = useReceivedBadges(pubkey);
@ -1126,7 +981,6 @@ export default function RiderCardPage() {
const [cardType, setCardType] = useState<'rider' | 'park'>('rider'); const [cardType, setCardType] = useState<'rider' | 'park'>('rider');
const [theme, setTheme] = useState<ThemeId>('thug'); const [theme, setTheme] = useState<ThemeId>('thug');
const [holographic, setHolographic] = useState(true); const [holographic, setHolographic] = useState(true);
const [showAwardDialog, setShowAwardDialog] = useState(false);
// Rider fields // Rider fields
const [style, setStyle] = useState('Street'); const [style, setStyle] = useState('Street');
@ -1636,13 +1490,7 @@ export default function RiderCardPage() {
</div> </div>
</div> </div>
<AwardBadgeDialog {/* Inline award form — the dialog was removed as dead code */}
open={showAwardDialog}
onClose={() => setShowAwardDialog(false)}
issuerPubkey={user.pubkey}
/>
{/* Inline award form — replaces the dialog on this tab */}
<AwardBadgeInline issuerPubkey={user.pubkey} onSuccess={() => setPageTab('badges')} /> <AwardBadgeInline issuerPubkey={user.pubkey} onSuccess={() => setPageTab('badges')} />
</div> </div>
)} )}