feat: add daily product intelligence and versioned site assets (#64)
Adds privacy-safe aggregate product intelligence, reviewed/versioned website assets, and a dispatch-only rollout until the dedicated Sentry token is verified. Independent review blockers were fixed in 8bc47e4; app checks, website production build, Android CI, and iOS CI are green. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
61
website/app/privacy/page.tsx
Normal file
61
website/app/privacy/page.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { readFileSync } from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Privacy Policy',
|
||||
description:
|
||||
'OpenCode Mobile privacy policy. We do not collect your code, prompts, or AI responses. Crash diagnostics via Sentry are opt-in only.',
|
||||
alternates: { canonical: 'https://opencode.agentlabs.cc/privacy' },
|
||||
openGraph: {
|
||||
title: 'Privacy Policy | OpenCode Mobile',
|
||||
description: 'OpenCode Mobile privacy policy — minimal data collection, opt-in crash reporting.',
|
||||
url: 'https://opencode.agentlabs.cc/privacy',
|
||||
},
|
||||
}
|
||||
|
||||
export default function PrivacyPage() {
|
||||
// Read the canonical privacy policy HTML generated by the Android distribution workflow.
|
||||
// This ensures the policy shown on the site is always in sync with app store submissions.
|
||||
const policyPath = path.join(
|
||||
process.cwd(),
|
||||
'../../../opencode-mobile/distribution/privacy-policy.html',
|
||||
)
|
||||
|
||||
let policyHtml = ''
|
||||
try {
|
||||
const raw = readFileSync(policyPath, 'utf8')
|
||||
// Extract just the <body> content so we can render it inside our layout
|
||||
const bodyMatch = raw.match(/<body[^>]*>([\s\S]*?)<\/body>/i)
|
||||
policyHtml = bodyMatch ? bodyMatch[1] : raw
|
||||
} catch {
|
||||
policyHtml = `<p style="color:#94A3B8">Privacy policy document not found. Please contact
|
||||
<a href="mailto:support@vibebrowser.app" style="color:#3B82F6">support@vibebrowser.app</a>.</p>`
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="max-w-3xl mx-auto px-4 sm:px-6 py-16">
|
||||
{/* Override the inline HTML colors from the standalone file with dark theme */}
|
||||
<style>{`
|
||||
.privacy-content body { color: inherit; background: transparent; }
|
||||
.privacy-content header { border-bottom-color: #3B82F6; }
|
||||
.privacy-content header h1 { color: #F1F5F9; }
|
||||
.privacy-content .meta { color: #94A3B8; }
|
||||
.privacy-content h2 { color: #F1F5F9; border-left-color: #3B82F6; }
|
||||
.privacy-content p, .privacy-content li { color: #CBD5E1; }
|
||||
.privacy-content a { color: #3B82F6; }
|
||||
.privacy-content .highlight-box { background: rgba(59,130,246,0.1); border-color: rgba(59,130,246,0.4); }
|
||||
.privacy-content .highlight-box strong { color: #93C5FD; }
|
||||
.privacy-content th { background: #1E293B; border-color: #334155; color: #F1F5F9; }
|
||||
.privacy-content td { border-color: #334155; color: #CBD5E1; }
|
||||
.privacy-content tr:nth-child(even) td { background: rgba(30,41,59,0.5); }
|
||||
.privacy-content footer { border-top-color: #334155; color: #64748B; }
|
||||
.privacy-content code { color: #94A3B8; font-size: 0.85em; }
|
||||
`}</style>
|
||||
<div
|
||||
className="privacy-content"
|
||||
dangerouslySetInnerHTML={{ __html: policyHtml }}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user