/** * RegionBackfillCard — admin-only: backfill missing `city`/`country` tags on the * logged-in user's own legacy spots & shops. * * Why: spots created before reverse geocoding existed have coordinates (so they * appear on the map) but no region tags (so `/stats` can only call them * "Uncategorised", under-counting the country vs the map). This re-derives the * tags from each pin and republishes the addressable event. * * Renders nothing for non-admins, so it can sit in Settings → Advanced beside the * other owner cards. */ import { useState } from 'react'; import { MapPin, Loader2 } from 'lucide-react'; import { Card, CardContent } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import { useRegionBackfill, type BackfillResult } from '@/hooks/useRegionBackfill'; import { isAdminPubkey } from '@/lib/admins'; import { toast } from '@/hooks/useToast'; export function RegionBackfillCard() { const { user } = useCurrentUser(); const isAdmin = isAdminPubkey(user?.pubkey); const { candidates, isLoading, backfill, progress, isRunning } = useRegionBackfill(isAdmin); const [summary, setSummary] = useState(null); if (!isAdmin) return null; const count = candidates.length; const run = async () => { setSummary(null); try { const result = await backfill(); setSummary(result); if (result.updated > 0) { toast({ title: `Tagged ${result.updated} location${result.updated === 1 ? '' : 's'}`, description: result.skipped > 0 ? `${result.skipped} skipped (no coordinates or no geocoder match).` : 'Region tags written to the community relay.', }); } else { toast({ title: 'Nothing to tag', description: 'No pins could be geocoded. Try again later.', variant: 'destructive', }); } } catch (err) { toast({ title: 'Backfill failed', description: err instanceof Error ? err.message : 'Try again.', variant: 'destructive', }); } }; return (

Backfill region tags Admin

Pins made before geocoding existed have coordinates but no city/country tag, so the map draws them while Community Stats can only say “Uncategorised”. This re-derives the tags from each pin and republishes your own untagged spots & shops.

{isLoading ? (

Scanning your spots…

) : count === 0 ? (

Every spot & shop you own already has a region tag. 🎉 Any remaining “Uncategorised” pins belong to other mappers — only their own keys can tag them.

) : ( <>

{count} of your spot{count === 1 ? '' : 's'}/shops have no region tag. Your signer may ask to approve each one.

{summary && ( {summary.updated} updated · {summary.skipped} skipped · {summary.failed} failed )}
)}
); }