999c4b65ef
Implements the M3-frontend slice of the §22 multi-project track, per docs/superpowers/specs/2026-06-03-m3-frontend-design.md (design merged in #10). Completes the runtime-config cut 0.33.0 (M3-backend Plan A) began. Frontend: - DeploymentProvider boots GET /api/deployment → {name, tagline, defaultProjectId, projects}; brandTitle() neutral 'RFC' pre-fetch fallback. - /p/:projectId/* routing with generic /e/<slug> segment. ProjectLayout fetches /api/projects/:id, applies per-project theme (reset on switch), provides ProjectContext, guards the corpus (served only for the default; others get NotServedPlaceholder — decouples this slice from Plan B). - Directory at / (2+ projects) with N=1 redirect into the single project; ProjectSwitcher in deployment chrome; entry-noun by project type. - VITE_APP_NAME hard cut: removed from vite.config + index.html; the 6 brand reads now use deployment.name via context; static <title>RFC</title> + JS document.title. Internal /rfc·/proposals links → /p/<project>/e|proposals via lib/entryPaths. Backend: - GET /api/deployment returns default_project_id (the guard contract). - Server-side 308s: /rfc/<slug>, /rfc/<slug>/pr/<n>, /proposals/<n> → /p/<default>/… . nginx (testing + prod) routes /rfc/ and /proposals/ to the backend. Tests: 3 new backend redirect/deployment tests (438 pass); Vitest unit for DeploymentProvider, ProjectLayout (theme/guard/404), Directory (11 pass); clean build with no VITE_APP_NAME. Playwright e2e deferred until Tier-1 seeds a registry (see CHANGELOG 0.35.0 step 5). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
129 lines
4.3 KiB
React
129 lines
4.3 KiB
React
// Cookies.jsx — v0.13.0 / roadmap item #11 / SPEC §14.6.
|
|
//
|
|
// Lists the framework's cookies, by category, with each cookie's
|
|
// purpose. Deployments override via `VITE_COOKIES_POLICY_URL` (linked
|
|
// below the framework's stub list, same shape as the privacy page).
|
|
//
|
|
// Keeping the list in source makes the framework self-documenting:
|
|
// when a future framework release adds or removes a cookie, this page
|
|
// is the change-record. Item #13's analytics SDK will add its own row
|
|
// to the analytics-category list in v0.15.0.
|
|
|
|
import { useNavigate, Link } from 'react-router-dom'
|
|
import { useDeployment } from '../context/DeploymentProvider'
|
|
|
|
const COOKIES = [
|
|
{
|
|
name: 'rfc_session',
|
|
category: 'Essential',
|
|
purpose: "Signed session cookie that remembers who you're signed in as. itsdangerous-signed; HttpOnly; SameSite=Lax.",
|
|
lifetime: 'Session (cleared on sign-out).',
|
|
},
|
|
{
|
|
name: 'rfc-app.cookie-consent.v1',
|
|
category: 'Essential',
|
|
purpose: 'localStorage entry (not a cookie strictly, but tracked here for symmetry) that remembers your consent choice on this device. Cleared on browser data reset.',
|
|
lifetime: 'Until cleared.',
|
|
},
|
|
]
|
|
|
|
export default function Cookies() {
|
|
const navigate = useNavigate()
|
|
const deploymentUrl = (import.meta.env.VITE_COOKIES_POLICY_URL || '').trim()
|
|
// §22.9: deployment name from runtime config (was VITE_APP_NAME).
|
|
const { name } = useDeployment()
|
|
const appName = name || 'this deployment'
|
|
|
|
return (
|
|
<div className="policy-page">
|
|
<header className="policy-header">
|
|
<button
|
|
className="policy-back"
|
|
onClick={() => (history.length > 1 ? navigate(-1) : navigate('/'))}
|
|
>
|
|
← Back
|
|
</button>
|
|
<span className="policy-title">Cookies policy</span>
|
|
</header>
|
|
<article className="policy-body">
|
|
<h1>Cookies policy</h1>
|
|
<p className="policy-subtitle">
|
|
What {appName} stores in your browser, by category.
|
|
</p>
|
|
|
|
<h2>Categories</h2>
|
|
<ul>
|
|
<li>
|
|
<strong>Essential</strong> — required for the app to keep
|
|
you signed in, protect submissions, and remember your
|
|
consent choice. Cannot be switched off (without these the
|
|
app cannot function).
|
|
</li>
|
|
<li>
|
|
<strong>Analytics</strong> — optional anonymous usage
|
|
telemetry. Off by default; opt-in via the consent banner.
|
|
As of v0.13.0 no analytics SDK ships; roadmap item #13
|
|
(v0.15.0) adds one behind this gate.
|
|
</li>
|
|
<li>
|
|
<strong>Other</strong> — third-party embeds, social
|
|
widgets, or anything else the deployment chooses to enable.
|
|
Off by default; opt-in via the consent banner. The
|
|
framework ships no such cookies by default.
|
|
</li>
|
|
</ul>
|
|
|
|
<h2>Current cookies set by the framework</h2>
|
|
<table className="policy-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Category</th>
|
|
<th>Purpose</th>
|
|
<th>Lifetime</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{COOKIES.map(c => (
|
|
<tr key={c.name}>
|
|
<td><code>{c.name}</code></td>
|
|
<td>{c.category}</td>
|
|
<td>{c.purpose}</td>
|
|
<td>{c.lifetime}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
|
|
<h2>Manage your choice</h2>
|
|
<p>
|
|
Change your consent any time from{' '}
|
|
<Link to="/settings/notifications">
|
|
Settings → Privacy & cookies
|
|
</Link>. The "Change" affordance re-opens the consent banner
|
|
with your current selection pre-loaded.
|
|
</p>
|
|
|
|
{deploymentUrl ? (
|
|
<>
|
|
<h2>Deployment-specific cookies</h2>
|
|
<p>
|
|
This deployment may add additional cookies on top of the
|
|
framework's. See the full deployment policy at:
|
|
</p>
|
|
<p>
|
|
<a href={deploymentUrl} target="_blank" rel="noopener noreferrer">
|
|
{deploymentUrl}
|
|
</a>
|
|
</p>
|
|
</>
|
|
) : null}
|
|
|
|
<p className="policy-footnote">
|
|
See also the <Link to="/privacy">privacy policy</Link>.
|
|
</p>
|
|
</article>
|
|
</div>
|
|
)
|
|
}
|