diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 384c3e73..c10c3e5c 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -28,6 +28,7 @@ import { RaspberryPiSimulatorPage } from './pages/RaspberryPiSimulatorPage'; import { Velxio2Page } from './pages/Velxio2Page'; import { Velxio25Page } from './pages/Velxio25Page'; import { AboutPage } from './pages/AboutPage'; +import { PricingPlaceholder } from './pages/PricingPlaceholder'; import { useAuthStore } from './store/useAuthStore'; import './App.css'; @@ -68,6 +69,8 @@ function App() { } /> } /> } /> + {/* Pricing — placeholder by default; private overlays portal-inject the real page */} + } /> {/* Canonical project URL by ID */} } /> {/* Legacy slug route — redirects to /project/:id */} diff --git a/frontend/src/pages/PricingPlaceholder.tsx b/frontend/src/pages/PricingPlaceholder.tsx new file mode 100644 index 00000000..a5e33556 --- /dev/null +++ b/frontend/src/pages/PricingPlaceholder.tsx @@ -0,0 +1,69 @@ +/** + * PricingPlaceholder — the route at /pricing. + * + * In the open-source build this renders a minimal heading + slot div. It + * exists so that: + * 1. Private overlays can portal-inject a real PricingPage into the slot + * (data-velxio-slot="pricing-page") without forking this file. + * 2. Self-hosters who navigate to /pricing get a polite "this image + * doesn't sell anything" page rather than a 404. + * + * The route is registered in App.tsx. The slot pattern is the same as + * data-velxio-slot="user-menu" / "admin-tabs" / "admin-tab-content". + */ + +import { useEffect } from 'react'; +import { AppHeader } from '../components/layout/AppHeader'; + +export const PricingPlaceholder = () => { + useEffect(() => { + document.title = 'Pricing — Velxio'; + }, []); + + return ( +
+ +
+ {/* Default content — only visible if no overlay is mounted (i.e. + self-hosted OSS image without a private pricing overlay). */} +
+

Pricing

+

+ This Velxio instance is self-hosted from the open-source image — + all features are free for everyone using it. +

+

+ The hosted version at{' '} + + velxio.dev + {' '} + offers an optional Pro tier that helps fund development. +

+

+ Source code is{' '} + + MIT-licensed on GitHub + + . +

+
+
+
+ ); +}; + +export default PricingPlaceholder; diff --git a/frontend/src/store/useAuthStore.ts b/frontend/src/store/useAuthStore.ts index a346e23f..ee3e30b6 100644 --- a/frontend/src/store/useAuthStore.ts +++ b/frontend/src/store/useAuthStore.ts @@ -9,6 +9,12 @@ export interface UserResponse { avatar_url: string | null; is_admin: boolean; created_at: string; + // Subscription state — populated by deployments that wire an external + // billing system (e.g. velxio.dev). Self-hosted OSS images leave these + // at the safe defaults (no paid features unlock). + is_paid_subscriber?: boolean; + subscription_status?: string | null; + subscription_period_end?: string | null; } interface AuthState {