SkateSpots/src/components/ZapButton.tsx
SkateSpots 0b796440f1 feat(i18n): Spanish batch 2 — nav/chrome, events/shops/tours, crews/DMs, settings/auth, wallet/stash/newsletter/stats
~3,470 new keys (5,770 total, EN=ES), ~115 more files wired.
- nav + chromeUi: header, More menu, burger menu, footer, map toolbar widgets
  (sort/trust/weather), spot-type label helper.
- placesUi: events, shops, tours, food. socialUi: crews, DMs, notifications,
  collectives, crew chat/coordinator. settingsUi: settings, auth/signup,
  onboarding, profile edit, legal. walletUi: wallet/Cashu, stash, mints,
  app shop, newsletter, community stats, leaderboards, profile.
- Fixed 738 usages where an agent dropped the socialUi. prefix (caught by check:i18n).
2026-10-02 10:11:06 +07:00

83 lines
No EOL
2.6 KiB
TypeScript

import { ZapDialog } from '@/components/ZapDialog';
import { useZaps } from '@/hooks/useZaps';
import { useWallet } from '@/hooks/useWallet';
import { useCurrentUser } from '@/hooks/useCurrentUser';
import { useAuthor } from '@/hooks/useAuthor';
import { useTranslation } from '@/contexts/language';
import { Zap } from 'lucide-react';
import type { Event } from 'nostr-tools';
interface ZapButtonProps {
target: Event;
className?: string;
showCount?: boolean;
zapData?: { count: number; totalSats: number; isLoading?: boolean };
}
export function ZapButton({
target,
className = "text-xs ml-1",
showCount = true,
zapData: externalZapData
}: ZapButtonProps) {
const { t } = useTranslation();
const { user } = useCurrentUser();
const { data: author } = useAuthor(target?.pubkey || '');
const { webln, activeNWC } = useWallet();
// Only fetch data if not provided externally
const { totalSats: fetchedTotalSats, zapCount: fetchedZapCount, isLoading } = useZaps(
externalZapData ? [] : target ?? [], // Empty array prevents fetching if external data provided
webln,
activeNWC
);
if (!target) {
return null;
}
// Use external data if provided, otherwise use fetched data
const totalSats = externalZapData?.totalSats ?? fetchedTotalSats;
const zapCount = externalZapData?.count ?? fetchedZapCount;
const showLoading = externalZapData?.isLoading || isLoading;
const hasLightning = !!(author?.metadata?.lud16 || author?.metadata?.lud06);
const canZap = !!user && user.pubkey !== target.pubkey && hasLightning;
/**
* Read-only total. Zaps are social proof, so the count is shown to EVERYONE —
* logged-out visitors included — not just to people who can zap. This costs
* no extra network work: `useZaps` already runs above regardless of login.
*/
if (!canZap) {
if (!showCount || showLoading || totalSats <= 0) {
return null;
}
return (
<span
className={`flex items-center gap-1 ${className}`}
title={t('walletUi.zap.count', { count: zapCount.toLocaleString() })}
>
<Zap className="h-4 w-4" />
<span className="text-xs">{totalSats.toLocaleString()}</span>
</span>
);
}
return (
<ZapDialog target={target}>
<div className={`flex items-center gap-1 ${className}`}>
<Zap className="h-4 w-4" />
<span className="text-xs">
{showLoading ? (
'...'
) : showCount && totalSats > 0 ? (
`${totalSats.toLocaleString()}`
) : (
t('zaps.zapButton')
)}
</span>
</div>
</ZapDialog>
);
}