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:
parent
bf7fdbd621
commit
10ab45383d
1 changed files with 1 additions and 153 deletions
|
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue