From 43f6a2b8587ac26c753d1502e70941d53ad7fab2 Mon Sep 17 00:00:00 2001 From: Quinn Ftw Date: Sat, 27 Dec 2025 23:11:04 -0800 Subject: [PATCH] refactor(landing): simplify App structure and enhance AboutPage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove ThemeProvider wrapper (handled externally) - Rename AppContent to AppRoutes for clarity - Add seoContent data file - Enhance AboutPage with CSS styling - Update Header component 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- features/landing/frontend/src/App.tsx | 27 +++++++---------- .../frontend/src/components/Header/Header.tsx | 6 ++-- .../landing/frontend/src/data/seoContent.ts | 30 +++++++++++++++++++ features/landing/frontend/src/main.tsx | 2 +- .../frontend/src/pages/about/AboutPage.css | 27 +++++++++++++++++ .../frontend/src/pages/about/AboutPage.tsx | 27 ++++++++++++----- 6 files changed, 91 insertions(+), 28 deletions(-) diff --git a/features/landing/frontend/src/App.tsx b/features/landing/frontend/src/App.tsx index aa92a21bf..1c2046096 100644 --- a/features/landing/frontend/src/App.tsx +++ b/features/landing/frontend/src/App.tsx @@ -1,5 +1,4 @@ import { usePageViewTracking } from '@lilith/analytics-client/react' -import { ThemeProvider } from '@ui/theme' import { BrowserRouter, Routes, Route } from 'react-router-dom' import { I18nProvider } from './i18n' @@ -12,13 +11,11 @@ import MerchPage from './pages/merch/MerchPage' import ServicesPage from './pages/services/ServicesPage' import ValuesPage from './pages/values/ValuesPage' -function AppContent() { - // Track page views automatically on route changes +function AppRoutes() { usePageViewTracking() return ( - {/* All routes wrapped in Layout for consistent header/footer */} }> } /> } /> @@ -36,17 +33,15 @@ function AppContent() { export default function App() { return ( - - - - - - - + + + + + ) } diff --git a/features/landing/frontend/src/components/Header/Header.tsx b/features/landing/frontend/src/components/Header/Header.tsx index 2a37cdbb0..2562678ea 100644 --- a/features/landing/frontend/src/components/Header/Header.tsx +++ b/features/landing/frontend/src/components/Header/Header.tsx @@ -103,7 +103,7 @@ export default function Header({ pageType }: HeaderProps) { ), href: '/about/performer', - onClick: () => handleNavClick('/about/performer', 'performer' as AboutPageType), + onClick: () => handleNavClick('/about/performer', 'performer'), }, { label: ( @@ -112,7 +112,7 @@ export default function Header({ pageType }: HeaderProps) { ), href: '/about/fangirl', - onClick: () => handleNavClick('/about/fangirl', 'fangirl' as AboutPageType), + onClick: () => handleNavClick('/about/fangirl', 'fangirl'), }, { label: ( @@ -121,7 +121,7 @@ export default function Header({ pageType }: HeaderProps) { ), href: '/about/camgirl', - onClick: () => handleNavClick('/about/camgirl', 'camgirl' as AboutPageType), + onClick: () => handleNavClick('/about/camgirl', 'camgirl'), }, ], }, diff --git a/features/landing/frontend/src/data/seoContent.ts b/features/landing/frontend/src/data/seoContent.ts index 7a361f29a..b6624b752 100644 --- a/features/landing/frontend/src/data/seoContent.ts +++ b/features/landing/frontend/src/data/seoContent.ts @@ -118,6 +118,36 @@ export const seoContent: Record = canonicalUrl: 'https://lilith.app/about/investor', }, + performer: { + title: 'lilith - For Performers | Stage. Stream. Succeed.', + description: + 'Performance infrastructure for adult entertainers. Multi-platform streaming, smart tip splitting, fan engagement tools, and performance analytics. Your talent, your stage, your rules.', + keywords: + 'adult performer platform, live streaming, tip splitting, cam performer, multi-platform streaming, performer tools, adult entertainment', + ogImage: '/og-image-performer.png', + canonicalUrl: 'https://lilith.app/about/performer', + }, + + fangirl: { + title: 'lilith - For Fangirls | Connect. Support. Belong.', + description: + 'Deep fan engagement with exclusive access, community features, and direct creator connections. Support your favorites without feeding corporate middlemen.', + keywords: + 'fan community, creator support, exclusive content, fan engagement, direct creator access, fan subscription', + ogImage: '/og-image-fangirl.png', + canonicalUrl: 'https://lilith.app/about/fangirl', + }, + + camgirl: { + title: `lilith - For Camgirls | Keep ${facts.economics.creatorTakeRate} of Tips`, + description: + `Professional live streaming built by cam models, for cam models. Keep ${facts.economics.creatorTakeRate} of tips. Compare: Chaturbate takes ${facts.competitors.chaturbateFee}. Zero platform cut, zero chargebacks.`, + keywords: + 'camgirl platform, live streaming, cam model, Chaturbate alternative, zero extraction, tip revenue, live cam platform', + ogImage: '/og-image-camgirl.png', + canonicalUrl: 'https://lilith.app/about/camgirl', + }, + business: { title: 'lilith - For Businesses | Anti-Piracy & Content Protection API', description: diff --git a/features/landing/frontend/src/main.tsx b/features/landing/frontend/src/main.tsx index 2d3ad0ef5..0fd7c0481 100644 --- a/features/landing/frontend/src/main.tsx +++ b/features/landing/frontend/src/main.tsx @@ -108,7 +108,7 @@ function renderApp() { {/* Generic I18nProvider for @lilith/i18n hooks (useTranslation, useAboutPageContent) */} - + {/* App contains additional domain-specific I18nProvider from makeI18n factory */} diff --git a/features/landing/frontend/src/pages/about/AboutPage.css b/features/landing/frontend/src/pages/about/AboutPage.css index 056f39814..cce521acb 100644 --- a/features/landing/frontend/src/pages/about/AboutPage.css +++ b/features/landing/frontend/src/pages/about/AboutPage.css @@ -738,6 +738,33 @@ margin: 0; } +/* ============================================ + LOADING STATE + ============================================ */ + +.about-loading { + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background: #0a0a0f; +} + +.about-loading .loading-spinner { + width: 40px; + height: 40px; + border: 3px solid rgba(255, 255, 255, 0.1); + border-top-color: var(--about-color, #FFD700); + border-radius: 50%; + animation: spin 0.8s linear infinite; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + /* ============================================ NOT FOUND STATE ============================================ */ diff --git a/features/landing/frontend/src/pages/about/AboutPage.tsx b/features/landing/frontend/src/pages/about/AboutPage.tsx index af195e6c1..9a9c16165 100644 --- a/features/landing/frontend/src/pages/about/AboutPage.tsx +++ b/features/landing/frontend/src/pages/about/AboutPage.tsx @@ -18,7 +18,7 @@ import { } from '../../hooks/useAnimationHelpers' import { useReducedMotion } from '@ui/accessibility' import { useSoundEngine } from '@ui/effects-sound' -import { useI18n } from '../../i18n' +import { useI18n, useI18nContext } from '../../i18n' import './AboutPage.css' // Animated stat counter component @@ -68,6 +68,7 @@ function FloatingDecoration({ export default function AboutPage() { const i18n = useI18n() + const { isLoading: i18nLoading } = useI18nContext() const { type } = useParams<{ type: string }>() const navigate = useNavigate() const location = useLocation() @@ -113,11 +114,21 @@ export default function AboutPage() { const featuresStagger = useStaggeredAnimation(content?.features.length || 0, 0.2, 0.2) const faqStagger = useStaggeredAnimation(content?.faqs.length || 0, 0.1, 0.1) + // Wait for translations to load before rendering anything with i18n values + // This prevents React from receiving proxy objects instead of strings + if (i18nLoading) { + return ( +
+
+
+ ) + } + if (!content) { return (
-

{i18n.errors.pageNotFound}

-

{i18n.errors.pageNotFoundDescription}

+

{String(i18n.errors.pageNotFound)}

+

{String(i18n.errors.pageNotFoundDescription)}

playSound('button-click')} data-testid="back-to-home-link" > - {i18n.returnHome} + {String(i18n.returnHome)}
) @@ -257,7 +268,7 @@ export default function AboutPage() { variants={benefitsStagger.container} > -

{i18n.sections.keyBenefits}

+

{String(i18n.sections.keyBenefits)}

@@ -371,7 +382,7 @@ export default function AboutPage() { variants={featuresStagger.container} > -

{i18n.sections.featuresDetails}

+

{String(i18n.sections.featuresDetails)}

@@ -410,7 +421,7 @@ export default function AboutPage() { variants={faqStagger.container} > -

{i18n.sections.faq}

+

{String(i18n.sections.faq)}

@@ -521,7 +532,7 @@ export default function AboutPage() { {/* Footer */}
)