import { dateLocaleCode } from '@/lib/dateFnsI18n'; import { useEffect, useRef, useState } from 'react'; import { useSeoMeta } from '@unhead/react'; import { nip19 } from 'nostr-tools'; import { ImageWithFallback } from '@/components/ImageWithFallback'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Textarea } from '@/components/ui/textarea'; import { Link } from 'react-router-dom'; import { Skeleton } from '@/components/ui/skeleton'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from '@/components/ui/dialog'; import { Zap, MapPin, Shield, Layers, Crown, Radio, ArrowRight, Share2, CheckCircle2, Users, Store, Calendar, GraduationCap, Route, Eye, Send, } from 'lucide-react'; import { useAuthor } from '@/hooks/useAuthor'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import { useNostrPublish } from '@/hooks/useNostrPublish'; import { useGrowthStats } from '@/hooks/useGrowthStats'; import { useToast } from '@/hooks/useToast'; import { useTranslation } from '@/contexts/language'; import { genUserName } from '@/lib/genUserName'; import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'; import { NewsletterSubscribeButton } from '@/components/NewsletterSubscribeButton'; import { NewsletterComposer } from '@/components/NewsletterComposer'; import { NewsletterBackfillPanel } from '@/components/NewsletterBackfillPanel'; import { useNewsletterIssues } from '@/hooks/useNewsletterIssues'; import { useNewsletterSubscriberCount } from '@/hooks/useNewsletterSubscriberCount'; import { useNewsletterRead } from '@/hooks/useNewsletterRead'; import { NEWSLETTER_KIND, type SkateNewsletterIssue } from '@/lib/types'; // ─── Admin pubkeys allowed to publish newsletter as kind 1 ─────────────────── import { isAdminPubkey } from '@/lib/admins'; // ─── Newsletter issue structure ─────────────────────────────────────────────── // import { NEWSLETTER_ISSUES, type NewsletterUpdate, type SpotOfTheWeek, type NewsletterIssue } from '@/lib/newsletterIssues'; // ─── Nostr post preview + publish ──────────────────────────────────────────── function NostrPreviewModal({ issue, open, onClose, onConfirm, isPending, }: { issue: NewsletterIssue; open: boolean; onClose: () => void; onConfirm: (text: string) => void; isPending: boolean; }) { const { t } = useTranslation(); const { user } = useCurrentUser(); const author = useAuthor(user?.pubkey ?? ''); const metadata = author.data?.metadata; const displayName = metadata?.name ?? genUserName(user?.pubkey ?? ''); const avatar = metadata?.picture; const now = new Date(); const timeStr = now.toLocaleTimeString(dateLocaleCode(), { hour: 'numeric', minute: '2-digit' }); const [editing, setEditing] = useState(false); const [editedText, setEditedText] = useState(issue.nostrText); const currentText = editing ? editedText : issue.nostrText; const renderPreviewText = (text: string) => { return text.split('\n').map((line, i) => { const parts = line.split(/(\s+)/).map((word, j) => { if (word.startsWith('#')) return {word}; if (word.startsWith('https://')) return {word}; return {word}; }); return

{parts}

; }); }; return ( {editing ? t('common.edit') : t('walletUi.newsletter.previewLabel')} — {t('walletUi.newsletter.dropNumber', { number: `#${String(issue.number).padStart(3, '0')}` })} {editing ? t('walletUi.newsletter.editNoteDesc') : t('walletUi.newsletter.previewNoteDesc')} {editing ? ( /* ── Edit mode ── */