add platform pages

This commit is contained in:
JCEEE
2026-08-23 15:12:19 +01:00
parent 762fbab4b6
commit bb2b1759dc
11 changed files with 1044 additions and 245 deletions
+139 -44
View File
@@ -3,7 +3,8 @@
import { enhance } from '$app/forms';
import { PUBLIC_STRIPE_PUBLISHABLE_KEY } from '$app/env/public';
import { loadStripe, type StripeEmbeddedCheckout } from '@stripe/stripe-js';
import { ViewHeader, CardGrid, Card, Button, PricingPlans } from '$lib/components';
import { Button, PricingPlans } from '$lib/components';
import Footer from '$lib/components/Footer.svelte';
let { data, form } = $props();
@@ -45,55 +46,149 @@
}
</script>
<ViewHeader title="Pricing" subtitle="Choose a plan for your family" hero />
<svelte:head><title>Pricing — FamChore</title></svelte:head>
{#if !showCheckout}
<PricingPlans
action="?/choose"
selected=""
error={form?.error}
onsubmit={handleChoose}
/>
{:else}
<CardGrid>
<Card title={`Checkout — ${checkoutTitle}`} accent="#059669">
<div class="checkout-actions">
<Button variant="ghost" size="sm" onclick={resetCheckout}>← Back to plans</Button>
<div class="shell">
<header class="topbar">
<a class="brand" href="/"><span class="brand-icon">🏠</span> <strong>FamChore</strong></a>
<nav>
<a href="/login" class="nav-link">Log in</a>
<a href="/signup" class="nav-cta">Get started</a>
</nav>
</header>
<main>
{#if !showCheckout}
<div class="head">
<h1>Simple pricing for every family</h1>
<p>One price, the whole family. Start free — upgrade whenever you're ready.</p>
</div>
<div bind:this={checkoutEl} class="checkout-host"></div>
<p class="hint" style="margin-top: 1rem;">
You can close and go to your dashboard any time — access unlocks once payment completes.
</p>
<a href={data.famSlug ? `/${data.famSlug}` : '/'} class="btn-primary" style="margin-top: 1rem; display: inline-block;">Go to dashboard</a>
</Card>
</CardGrid>
{/if}
<PricingPlans action="?/choose" selected="" error={form?.error} onsubmit={handleChoose} />
{:else}
<div class="checkout-wrap">
<div class="checkout-card">
<div class="checkout-head">
<h2>Checkout — {checkoutTitle}</h2>
<Button variant="ghost" size="sm" onclick={resetCheckout}>← Back to plans</Button>
</div>
<div bind:this={checkoutEl} class="checkout-host"></div>
<p class="hint">
You can close and go to your dashboard any time — access unlocks once payment completes.
</p>
<a href={data.famSlug ? `/${data.famSlug}` : '/'} class="dash-link">Go to dashboard →</a>
</div>
</div>
{/if}
</main>
<Footer />
</div>
<style>
.hint {
font-size: 0.85rem;
color: #9ca3af;
line-height: 1.4;
/* Full-height shell: topbar / centered content / footer — no scroll on desktop. */
.shell {
min-height: 100vh;
display: grid;
grid-template-rows: auto 1fr auto;
background:
radial-gradient(60rem 30rem at 50% -10rem, #eef2ff 0%, transparent 65%),
#fafafa;
}
.checkout-actions {
margin-bottom: 0.75rem;
.topbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.8rem 2rem;
border-bottom: 1px solid #f3f4f6;
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(6px);
}
.checkout-host {
min-height: 480px;
}
.checkout-host :global(iframe) {
width: 100%;
}
.btn-primary {
display: inline-block;
text-align: center;
background: #4338ca;
color: #fff;
border-radius: 8px;
padding: 0.75rem 1.5rem;
font-size: 1rem;
font-weight: 600;
.brand {
display: inline-flex;
align-items: center;
gap: 0.45rem;
font-size: 1.05rem;
color: #111827;
text-decoration: none;
}
.btn-primary:hover { background: #3730a3; }
.nav {
display: flex;
align-items: center;
gap: 1rem;
}
.topbar nav { display: flex; align-items: center; gap: 1rem; }
.nav-link {
font-size: 0.9rem;
color: #4b5563;
text-decoration: none;
}
.nav-link:hover { color: #111827; }
.nav-cta {
font-size: 0.88rem;
font-weight: 600;
color: #fff;
text-decoration: none;
background: linear-gradient(135deg, #4338ca, #6366f1);
padding: 0.45rem 1rem;
border-radius: 999px;
}
.nav-cta:hover { background: linear-gradient(135deg, #3730a3, #4f46e5); }
main {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1.75rem;
padding: 1.5rem 2rem;
width: 100%;
max-width: 1040px;
margin: 0 auto;
}
.head { text-align: center; }
.head h1 {
margin: 0 0 0.35rem;
font-size: clamp(1.5rem, 3vw, 2.1rem);
font-weight: 800;
color: #111827;
letter-spacing: -0.02em;
}
.head p {
margin: 0;
font-size: 0.95rem;
color: #6b7280;
}
.checkout-wrap { width: 100%; max-width: 720px; }
.checkout-card {
background: #fff;
border: 1px solid #e5e7eb;
border-radius: 16px;
padding: 1.25rem 1.5rem 1.5rem;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}
.checkout-head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0.75rem;
}
.checkout-head h2 { margin: 0; font-size: 1.05rem; color: #111827; }
.checkout-host { min-height: 420px; }
.checkout-host :global(iframe) { width: 100%; }
.hint { font-size: 0.82rem; color: #9ca3af; margin: 0.75rem 0 0; }
.dash-link {
display: inline-block;
margin-top: 0.5rem;
color: #4338ca;
font-weight: 600;
font-size: 0.9rem;
text-decoration: none;
}
.dash-link:hover { text-decoration: underline; }
@media (max-height: 760px) {
main { gap: 1rem; padding-top: 0.75rem; padding-bottom: 0.75rem; }
.head h1 { font-size: 1.35rem; }
}
</style>