Add a Settings → Pro & Support hub
One discoverable home for every paid extra, so the pricing model is legible instead of scattered across the Sasquatch panel and each offer form: - components/ProSupportScreen.tsx (Settings ?section=pro + a menu row): honest "prepaid, not a subscription" framing; Sasquatch Pro status (days left) + PRO_TIERS with per-day sats and a Go Pro / Extend button; Featured placement (PLATFORM_FEES x DURATION_TIERS with per-day + best-value); your currently featured Lab listings (featuredUntil); and the free paths (PoW listing, free AI FAQ). - Distinct naming in copy: Sasquatch Pro (AI) vs Featured placement (visibility). - Smoke test now walks /settings?section=pro.
This commit is contained in:
parent
8cdc41cc15
commit
4cad201716
6 changed files with 230 additions and 3 deletions
11
AGENTS.md
11
AGENTS.md
|
|
@ -542,6 +542,17 @@ session with **no other memory of this project**. So:
|
||||||
Pro access (`useSasquatchPro`) is granted by a provider-authored zap receipt,
|
Pro access (`useSasquatchPro`) is granted by a provider-authored zap receipt,
|
||||||
and its **expiry is derived from the paid amount → tier**, never the
|
and its **expiry is derived from the paid amount → tier**, never the
|
||||||
user-signed `pro-expiry` tag.
|
user-signed `pro-expiry` tag.
|
||||||
|
**Pro & Support hub (2026-10-04):** all paid extras now have one home —
|
||||||
|
**Settings → Pro & Support** (`?section=pro`, `components/ProSupportScreen.tsx`,
|
||||||
|
menu row + section in `SettingsPage`). It shows the honest "prepaid, not a
|
||||||
|
subscription" framing, **Sasquatch Pro** status (days left) + `PRO_TIERS` with
|
||||||
|
per-day sats + a "Go Pro / Extend" button (opens `SasquatchProDialog`), the
|
||||||
|
**Featured placement** types (`PLATFORM_FEES` × `DURATION_TIERS`, per-day +
|
||||||
|
best-value), **your currently-featured Lab listings** (`featuredUntil`), and
|
||||||
|
the **free paths** (PoW listing, free AI FAQ). Distinct naming is enforced in
|
||||||
|
copy: **Sasquatch Pro** (AI) vs **Featured placement** (visibility) — don't
|
||||||
|
call both "Pro". Not done: an actual discounted bundle SKU (would be a single
|
||||||
|
combined zap, no new rails). `/settings?section=pro` is in the smoke list.
|
||||||
- **Pro proofs STACK (fixed 2026-09-28).** `useSasquatchPro` now collects ALL
|
- **Pro proofs STACK (fixed 2026-09-28).** `useSasquatchPro` now collects ALL
|
||||||
valid proofs and accumulates `expiry = max(expiry, proofTime) + tierDays`
|
valid proofs and accumulates `expiry = max(expiry, proofTime) + tierDays`
|
||||||
(renewal semantics) — before, it took the **max** of
|
(renewal semantics) — before, it took the **max** of
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,7 @@ const ROUTES = [
|
||||||
'/settings',
|
'/settings',
|
||||||
'/settings?section=profile',
|
'/settings?section=profile',
|
||||||
'/settings?section=coordinator',
|
'/settings?section=coordinator',
|
||||||
|
'/settings?section=pro',
|
||||||
'/npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx',
|
'/npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx',
|
||||||
'/stash',
|
'/stash',
|
||||||
'/collections',
|
'/collections',
|
||||||
|
|
|
||||||
158
src/components/ProSupportScreen.tsx
Normal file
158
src/components/ProSupportScreen.tsx
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import { ChevronLeft, Crown, CheckCircle2, Sparkles, Cpu } from 'lucide-react';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { useTranslation } from '@/contexts/language';
|
||||||
|
import { useSasquatchPro } from '@/hooks/useSasquatchPro';
|
||||||
|
import { PRO_TIERS } from '@/lib/sasquatchPro';
|
||||||
|
import { DURATION_TIERS, PLATFORM_FEES, FEE_META, tierPriceSats, tierPerDaySats, type FeeType } from '@/hooks/usePlatformFee';
|
||||||
|
import { SasquatchProDialog } from '@/components/SasquatchProDialog';
|
||||||
|
import { useLabProfiles } from '@/hooks/useLabProfiles';
|
||||||
|
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
||||||
|
import { labProfilePath } from '@/lib/labRoutes';
|
||||||
|
import { dateLocaleCode } from '@/lib/dateFnsI18n';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings → Pro & Support.
|
||||||
|
*
|
||||||
|
* One honest home for every paid extra: what it does, the duration tiers and
|
||||||
|
* effective per-day price, your current status, and the free alternatives.
|
||||||
|
* Nothing here holds funds — each purchase is a one-off Lightning payment.
|
||||||
|
*/
|
||||||
|
export function ProSupportScreen({ onBack }: { onBack: () => void }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { isPro, expiresAt } = useSasquatchPro();
|
||||||
|
const { user } = useCurrentUser();
|
||||||
|
const { data: profiles } = useLabProfiles(100);
|
||||||
|
const [proOpen, setProOpen] = useState(false);
|
||||||
|
|
||||||
|
const now = Math.floor(Date.now() / 1000);
|
||||||
|
const daysLeft = isPro && expiresAt ? Math.max(0, Math.ceil((expiresAt - now) / 86400)) : 0;
|
||||||
|
const fmt = (secs: number) => new Date(secs * 1000).toLocaleDateString(dateLocaleCode(), { month: 'short', day: 'numeric', year: 'numeric' });
|
||||||
|
|
||||||
|
const featured = (profiles ?? []).filter((p) => p.pubkey === user?.pubkey && p.featuredUntil && p.featuredUntil > now);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center gap-3 mb-5">
|
||||||
|
<button
|
||||||
|
onClick={onBack}
|
||||||
|
aria-label={t('common.back')}
|
||||||
|
className="flex items-center justify-center w-8 h-8 rounded-xl bg-white/5 hover:bg-white/10 active:scale-95 transition-all"
|
||||||
|
>
|
||||||
|
<ChevronLeft className="h-4 w-4 text-white" />
|
||||||
|
</button>
|
||||||
|
<h2 className="text-lg font-black uppercase tracking-wide text-white">{t('settingsUi.proSupport.title')}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-4">
|
||||||
|
{/* Honest framing */}
|
||||||
|
<div className="rounded-2xl border border-[#ccff00]/20 bg-[#ccff00]/5 p-4">
|
||||||
|
<p className="flex items-center gap-2 text-sm font-bold text-[#ccff00]">
|
||||||
|
<CheckCircle2 className="h-4 w-4" /> {t('settingsUi.proSupport.prepaidTitle')}
|
||||||
|
</p>
|
||||||
|
<p className="mt-1 text-xs text-muted-foreground leading-relaxed">{t('settingsUi.proSupport.prepaidBody')}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Sasquatch Pro */}
|
||||||
|
<div className="rounded-2xl border border-white/8 p-4 bg-white/2">
|
||||||
|
<div className="flex items-start gap-3">
|
||||||
|
<div className="flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-xl bg-emerald-500/15">
|
||||||
|
<Sparkles className="h-4 w-4 text-emerald-400" />
|
||||||
|
</div>
|
||||||
|
<div className="min-w-0 flex-1">
|
||||||
|
<p className="text-sm font-black uppercase tracking-wide text-white">{t('settingsUi.proSupport.sasquatchTitle')}</p>
|
||||||
|
<p className="mt-0.5 text-xs text-muted-foreground leading-relaxed">{t('settingsUi.proSupport.sasquatchBenefit')}</p>
|
||||||
|
<p className={cn('mt-1 text-xs font-bold', isPro ? 'text-emerald-400' : 'text-gray-500')}>
|
||||||
|
{isPro
|
||||||
|
? expiresAt
|
||||||
|
? `${t('settingsUi.proSupport.activeUntil', { date: fmt(expiresAt) })} · ${t('settingsUi.proSupport.daysLeft', { count: daysLeft })}`
|
||||||
|
: t('settingsUi.proSupport.active')
|
||||||
|
: t('settingsUi.proSupport.notActive')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-3 grid grid-cols-2 gap-2 sm:grid-cols-4">
|
||||||
|
{PRO_TIERS.map((tier) => (
|
||||||
|
<div key={tier.id} className={cn('rounded-xl border p-2.5 text-center', tier.popular ? 'border-emerald-500/50 bg-emerald-500/10' : 'border-white/10')}>
|
||||||
|
<p className="text-xs font-bold text-white">{t(tier.labelKey)}</p>
|
||||||
|
<p className="mt-1 text-sm font-black text-white">{tier.sats.toLocaleString()}</p>
|
||||||
|
<p className="text-[10px] text-muted-foreground">{t('common.sats')} · {Math.round(tier.sats / tier.days)}/{t('settingsUi.proSupport.day')}</p>
|
||||||
|
{tier.badgeKey && <p className="mt-1 text-[10px] font-bold text-emerald-400">{t(tier.badgeKey)}</p>}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Button onClick={() => setProOpen(true)} className="mt-3 w-full gap-2 bg-[#ccff00] font-black uppercase text-black hover:bg-[#ccff00]/90">
|
||||||
|
<Crown className="h-4 w-4" /> {isPro ? t('settingsUi.proSupport.extend') : t('settingsUi.proSupport.goPro')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Featured placement */}
|
||||||
|
<div className="rounded-2xl border border-white/8 p-4 bg-white/2">
|
||||||
|
<div className="flex items-start gap-3">
|
||||||
|
<div className="flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-xl bg-amber-500/15">
|
||||||
|
<Cpu className="h-4 w-4 text-amber-400" />
|
||||||
|
</div>
|
||||||
|
<div className="min-w-0 flex-1">
|
||||||
|
<p className="text-sm font-black uppercase tracking-wide text-white">{t('settingsUi.proSupport.featuredTitle')}</p>
|
||||||
|
<p className="mt-0.5 text-xs text-muted-foreground leading-relaxed">{t('settingsUi.proSupport.featuredBenefit')}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-3 space-y-3">
|
||||||
|
{(Object.keys(PLATFORM_FEES) as FeeType[]).map((type) => (
|
||||||
|
<div key={type}>
|
||||||
|
<p className="text-xs font-bold text-gray-300">
|
||||||
|
<span className="mr-1">{FEE_META[type].emoji}</span>{FEE_META[type].label}
|
||||||
|
<span className="ml-2 font-normal text-muted-foreground">{FEE_META[type].benefit}</span>
|
||||||
|
</p>
|
||||||
|
<div className="mt-1.5 grid grid-cols-2 gap-1.5 sm:grid-cols-4">
|
||||||
|
{DURATION_TIERS.map((tier) => (
|
||||||
|
<div key={tier.id} className={cn('rounded-lg border p-2 text-center', tier.bestValue ? 'border-[#ccff00]/40 bg-[#ccff00]/5' : 'border-white/10')}>
|
||||||
|
<p className="text-[11px] font-bold text-white">{tier.label}</p>
|
||||||
|
<p className="text-xs font-black text-white">{tierPriceSats(type, tier).toLocaleString()}</p>
|
||||||
|
<p className="text-[10px] text-muted-foreground">{tierPerDaySats(type, tier).toLocaleString()}/{t('settingsUi.proSupport.day')}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<p className="mt-3 text-xs text-muted-foreground">{t('settingsUi.proSupport.featuredHow')}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Your featured listings */}
|
||||||
|
<div className="rounded-2xl border border-white/8 p-4 bg-white/2">
|
||||||
|
<p className="text-sm font-black uppercase tracking-wide text-white">{t('settingsUi.proSupport.yourFeatured')}</p>
|
||||||
|
{featured.length === 0 ? (
|
||||||
|
<p className="mt-1 text-xs text-muted-foreground">{t('settingsUi.proSupport.noneFeatured')}</p>
|
||||||
|
) : (
|
||||||
|
<div className="mt-2 space-y-1.5">
|
||||||
|
{featured.map((p) => (
|
||||||
|
<Link
|
||||||
|
key={p.id}
|
||||||
|
to={labProfilePath(p.profileType, p.pubkey, p.identifier)}
|
||||||
|
className="flex items-center justify-between gap-2 rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-xs font-bold text-gray-200 hover:bg-white/10"
|
||||||
|
>
|
||||||
|
<span className="truncate">{p.title}</span>
|
||||||
|
<span className="flex-shrink-0 text-amber-400">{t('settingsUi.proSupport.featuredUntil', { date: fmt(p.featuredUntil!) })}</span>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Free paths */}
|
||||||
|
<div className="rounded-2xl border border-white/8 p-4 bg-white/2">
|
||||||
|
<p className="text-sm font-black uppercase tracking-wide text-white">{t('settingsUi.proSupport.freeTitle')}</p>
|
||||||
|
<p className="mt-1 text-xs text-muted-foreground leading-relaxed">{t('settingsUi.proSupport.freeBody')}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<SasquatchProDialog open={proOpen} onOpenChange={setProOpen} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -4307,6 +4307,29 @@ socialUi: {
|
||||||
},
|
},
|
||||||
|
|
||||||
settingsUi: {
|
settingsUi: {
|
||||||
|
proSupport: {
|
||||||
|
title: 'Pro & Support',
|
||||||
|
subtitle: 'Optional extras that keep SkateSpots free',
|
||||||
|
prepaidTitle: 'Prepaid, not a subscription',
|
||||||
|
prepaidBody: 'Every purchase is a one-off Bitcoin/Lightning payment — no account, no recurring charge, no custody. Paying again extends your time.',
|
||||||
|
sasquatchTitle: 'Sasquatch Pro',
|
||||||
|
sasquatchBenefit: 'Unlocks the personal AI assistant — it can read your own Stash, crews and listings — and helps fund the project.',
|
||||||
|
active: 'Active',
|
||||||
|
activeUntil: 'Active until {{date}}',
|
||||||
|
daysLeft: '{{count}} days left',
|
||||||
|
notActive: 'Not active',
|
||||||
|
goPro: 'Go Pro',
|
||||||
|
extend: 'Extend Pro',
|
||||||
|
day: 'day',
|
||||||
|
featuredTitle: 'Featured placement',
|
||||||
|
featuredBenefit: 'Push a listing to the top with a Pro badge — for Lab profiles, events, shops and tours.',
|
||||||
|
featuredHow: 'Duration tiers apply to every type; longer commitments cost less per day. You feature a listing when you create or edit it.',
|
||||||
|
featuredUntil: 'Until {{date}}',
|
||||||
|
yourFeatured: 'Your featured listings',
|
||||||
|
noneFeatured: 'No active featured placements.',
|
||||||
|
freeTitle: 'Free paths',
|
||||||
|
freeBody: 'The AI FAQ and local search are always free, and you can publish a marketplace listing with a free proof-of-work instead of the sats fee.',
|
||||||
|
},
|
||||||
notFound: {
|
notFound: {
|
||||||
seoTitle: '404 - Page Not Found',
|
seoTitle: '404 - Page Not Found',
|
||||||
seoDescription: 'The page you are looking for could not be found. Return to the home page to continue browsing.',
|
seoDescription: 'The page you are looking for could not be found. Return to the home page to continue browsing.',
|
||||||
|
|
|
||||||
|
|
@ -4307,6 +4307,29 @@ socialUi: {
|
||||||
},
|
},
|
||||||
|
|
||||||
settingsUi: {
|
settingsUi: {
|
||||||
|
proSupport: {
|
||||||
|
title: 'Pro y apoyo',
|
||||||
|
subtitle: 'Extras opcionales que mantienen SkateSpots gratis',
|
||||||
|
prepaidTitle: 'Pago por adelantado, no suscripción',
|
||||||
|
prepaidBody: 'Cada compra es un pago único en Bitcoin/Lightning — sin cuenta, sin cargo recurrente y sin custodia. Pagar de nuevo amplía tu tiempo.',
|
||||||
|
sasquatchTitle: 'Sasquatch Pro',
|
||||||
|
sasquatchBenefit: 'Desbloquea el asistente personal con IA — puede leer tu Stash, crews y anuncios — y ayuda a financiar el proyecto.',
|
||||||
|
active: 'Activo',
|
||||||
|
activeUntil: 'Activo hasta {{date}}',
|
||||||
|
daysLeft: 'Quedan {{count}} días',
|
||||||
|
notActive: 'No activo',
|
||||||
|
goPro: 'Hazte Pro',
|
||||||
|
extend: 'Ampliar Pro',
|
||||||
|
day: 'día',
|
||||||
|
featuredTitle: 'Posición destacada',
|
||||||
|
featuredBenefit: 'Lleva un anuncio arriba con un distintivo Pro — para perfiles del Lab, eventos, tiendas y tours.',
|
||||||
|
featuredHow: 'Los tramos de duración se aplican a cada tipo; los compromisos más largos cuestan menos por día. Destacas un anuncio al crearlo o editarlo.',
|
||||||
|
featuredUntil: 'Hasta {{date}}',
|
||||||
|
yourFeatured: 'Tus anuncios destacados',
|
||||||
|
noneFeatured: 'No hay destacados activos.',
|
||||||
|
freeTitle: 'Opciones gratis',
|
||||||
|
freeBody: 'El FAQ de IA y la búsqueda local son siempre gratis, y puedes publicar un anuncio con prueba de trabajo en vez de la tarifa en sats.',
|
||||||
|
},
|
||||||
notFound: {
|
notFound: {
|
||||||
seoTitle: '404 - Página no encontrada',
|
seoTitle: '404 - Página no encontrada',
|
||||||
seoDescription: 'La página que buscas no se pudo encontrar. Vuelve a la página de inicio para seguir navegando.',
|
seoDescription: 'La página que buscas no se pudo encontrar. Vuelve a la página de inicio para seguir navegando.',
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import { RelatrSettings } from '@/components/RelatrSettings';
|
||||||
import { CVMHealthCheck } from '@/components/CVMHealthCheck';
|
import { CVMHealthCheck } from '@/components/CVMHealthCheck';
|
||||||
import { SasquatchAiStatusCard } from '@/components/SasquatchAiStatusCard';
|
import { SasquatchAiStatusCard } from '@/components/SasquatchAiStatusCard';
|
||||||
import { GrantProCard } from '@/components/GrantProCard';
|
import { GrantProCard } from '@/components/GrantProCard';
|
||||||
|
import { ProSupportScreen } from '@/components/ProSupportScreen';
|
||||||
import { AdminReviewCard } from '@/components/AdminReviewCard';
|
import { AdminReviewCard } from '@/components/AdminReviewCard';
|
||||||
import { RegionBackfillCard } from '@/components/RegionBackfillCard';
|
import { RegionBackfillCard } from '@/components/RegionBackfillCard';
|
||||||
import { NotificationSettingsCard } from '@/components/NotificationSettingsCard';
|
import { NotificationSettingsCard } from '@/components/NotificationSettingsCard';
|
||||||
|
|
@ -34,7 +35,7 @@ import { cn } from '@/lib/utils';
|
||||||
import { NIP05_PROVIDERS } from '@/lib/nip05Providers';
|
import { NIP05_PROVIDERS } from '@/lib/nip05Providers';
|
||||||
import { SKATE_NIP05_DOMAIN } from '@/lib/skateNip05';
|
import { SKATE_NIP05_DOMAIN } from '@/lib/skateNip05';
|
||||||
import { useTranslation } from '@/contexts/language';
|
import { useTranslation } from '@/contexts/language';
|
||||||
import { User, Radio, Wallet, Wrench, RotateCcw, Shield, ExternalLink, Languages, RefreshCw, AlertCircle, Database, Package, ChevronRight, ChevronLeft, Smartphone, Download, Zap, WifiOff, Bell, Server } from 'lucide-react';
|
import { User, Radio, Wallet, Wrench, RotateCcw, Shield, ExternalLink, Languages, RefreshCw, AlertCircle, Database, Package, ChevronRight, ChevronLeft, Smartphone, Download, Zap, WifiOff, Bell, Server, Crown } from 'lucide-react';
|
||||||
|
|
||||||
// ─── Types ────────────────────────────────────────────────────────────────────
|
// ─── Types ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -52,7 +53,8 @@ type Section =
|
||||||
| 'stash'
|
| 'stash'
|
||||||
| 'notifications'
|
| 'notifications'
|
||||||
| 'coordinator'
|
| 'coordinator'
|
||||||
| 'advanced';
|
| 'advanced'
|
||||||
|
| 'pro';
|
||||||
|
|
||||||
// ─── Back header ──────────────────────────────────────────────────────────────
|
// ─── Back header ──────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -818,6 +820,14 @@ function SettingsMenu({ onNavigate }: { onNavigate: (s: Section) => void }) {
|
||||||
iconBg="bg-pink-500/15"
|
iconBg="bg-pink-500/15"
|
||||||
onClick={() => onNavigate('appearance')}
|
onClick={() => onNavigate('appearance')}
|
||||||
/>
|
/>
|
||||||
|
<MenuRow
|
||||||
|
icon={Crown}
|
||||||
|
label={t('settingsUi.proSupport.title')}
|
||||||
|
sublabel={t('settingsUi.proSupport.subtitle')}
|
||||||
|
iconColor="text-[#ccff00]"
|
||||||
|
iconBg="bg-[#ccff00]/15"
|
||||||
|
onClick={() => onNavigate('pro')}
|
||||||
|
/>
|
||||||
<MenuRow
|
<MenuRow
|
||||||
icon={Bell}
|
icon={Bell}
|
||||||
label={t('settingsUi.settingsPage.notifications')}
|
label={t('settingsUi.settingsPage.notifications')}
|
||||||
|
|
@ -882,7 +892,7 @@ export default function SettingsPage() {
|
||||||
// stale bookmark to ?section=language) falls back to the menu rather than a
|
// stale bookmark to ?section=language) falls back to the menu rather than a
|
||||||
// blank screen with no way back.
|
// blank screen with no way back.
|
||||||
const RENDERABLE_SECTIONS: Section[] = [
|
const RENDERABLE_SECTIONS: Section[] = [
|
||||||
'profile', 'security', 'nip05', 'mydata', 'relays', 'appearance', 'wallet', 'notifications', 'coordinator', 'advanced',
|
'profile', 'security', 'nip05', 'mydata', 'relays', 'appearance', 'wallet', 'notifications', 'coordinator', 'advanced', 'pro',
|
||||||
];
|
];
|
||||||
const requestedSection = searchParams.get('section') as Section;
|
const requestedSection = searchParams.get('section') as Section;
|
||||||
const initialSection =
|
const initialSection =
|
||||||
|
|
@ -922,6 +932,7 @@ export default function SettingsPage() {
|
||||||
)}
|
)}
|
||||||
{section === 'relays' && <RelaysScreen onBack={handleBack} />}
|
{section === 'relays' && <RelaysScreen onBack={handleBack} />}
|
||||||
{section === 'appearance' && <AppearanceScreen onBack={handleBack} />}
|
{section === 'appearance' && <AppearanceScreen onBack={handleBack} />}
|
||||||
|
{section === 'pro' && <ProSupportScreen onBack={handleBack} />}
|
||||||
{section === 'wallet' && <WalletScreen onBack={handleBack} />}
|
{section === 'wallet' && <WalletScreen onBack={handleBack} />}
|
||||||
{section === 'notifications' && (
|
{section === 'notifications' && (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue