Skip to content

Commit e327717

Browse files
Sai Sridhar Tarraclaude
authored andcommitted
Add footer pages and fix footer links
- Add 8 new public pages: changelog, docs, support, status, integrations, terms, cookies, gdpr - Update footer links in index.tsx to point to real routes instead of href="#" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent e4d78a8 commit e327717

9 files changed

Lines changed: 1030 additions & 13 deletions

File tree

frontend/pages/changelog.tsx

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import Head from 'next/head';
2+
import Link from 'next/link';
3+
4+
const releases = [
5+
{
6+
version: 'v1.4.0',
7+
date: 'March 22, 2026',
8+
tag: 'Latest',
9+
tagColor: '#dcfce7',
10+
tagText: '#16a34a',
11+
changes: [
12+
{ type: 'New', text: 'Platform admin dashboard at /admin — view MRR, users, usage, and webhook logs' },
13+
{ type: 'New', text: 'Manual AI processing per email — click "Process with AI" to control your usage' },
14+
{ type: 'New', text: 'Email body renders as HTML inside a sandboxed iframe (like Gmail)' },
15+
{ type: 'New', text: 'Cancel subscription button — cancels at end of billing period via Razorpay API' },
16+
{ type: 'Improved', text: 'Plan limit banner in inbox when free users reach 5/5 AI-processed emails' },
17+
{ type: 'Fixed', text: 'Auth form now correctly renders in light mode (white background)' },
18+
{ type: 'Fixed', text: 'All website pricing updated to INR: Pro ₹199/mo, Agency ₹1,499/mo' },
19+
],
20+
},
21+
{
22+
version: 'v1.3.0',
23+
date: 'March 15, 2026',
24+
tag: 'Billing',
25+
tagColor: '#ede9fe',
26+
tagText: '#7c3aed',
27+
changes: [
28+
{ type: 'New', text: 'Razorpay integration — accept payments from India with subscription billing' },
29+
{ type: 'New', text: 'Billing page shows exact error messages when payment setup is misconfigured' },
30+
{ type: 'New', text: 'Webhook handlers for subscription.activated, subscription.charged, subscription.halted, invoice.paid, invoice.expired' },
31+
{ type: 'Improved', text: 'Email usage count now only counts AI-processed emails (not all emails)' },
32+
{ type: 'Fixed', text: 'CORS errors blocking API calls from mailair.company' },
33+
],
34+
},
35+
{
36+
version: 'v1.2.0',
37+
date: 'March 5, 2026',
38+
tag: 'Security',
39+
tagColor: '#fef3c7',
40+
tagText: '#d97706',
41+
changes: [
42+
{ type: 'New', text: 'HMAC-SHA256 signed OAuth state parameter for CSRF protection on Gmail flow' },
43+
{ type: 'New', text: 'Fernet encryption for stored CRM credentials (HubSpot, Salesforce)' },
44+
{ type: 'Improved', text: 'Team features: org membership verified before accessing internal notes' },
45+
{ type: 'Improved', text: 'Auto-assign rules now verify assigned user is org member' },
46+
{ type: 'Fixed', text: 'Webhook URL validated as proper HTTP/HTTPS URL via Pydantic HttpUrl' },
47+
],
48+
},
49+
{
50+
version: 'v1.1.0',
51+
date: 'February 20, 2026',
52+
tag: 'Auth',
53+
tagColor: '#dbeafe',
54+
tagText: '#1d4ed8',
55+
changes: [
56+
{ type: 'New', text: 'Supabase implicit OAuth flow with localStorage session storage' },
57+
{ type: 'New', text: 'Session-gated SWR hooks — no unauthenticated API fetches' },
58+
{ type: 'Fixed', text: 'Removed auto sign-out on 401 — prevented infinite redirect loop on load' },
59+
{ type: 'Fixed', text: 'Auth callback now uses useRef to prevent double navigation' },
60+
{ type: 'Fixed', text: 'Middleware stripped of auth logic — incompatible with localStorage sessions' },
61+
],
62+
},
63+
{
64+
version: 'v1.0.0',
65+
date: 'February 1, 2026',
66+
tag: 'Launch',
67+
tagColor: '#fce7f3',
68+
tagText: '#be185d',
69+
changes: [
70+
{ type: 'New', text: 'AI email categorization (Urgent, Needs Response, Follow Up, FYI, Newsletter, Spam)' },
71+
{ type: 'New', text: 'Priority inbox with AI-scored priority levels' },
72+
{ type: 'New', text: 'Action item extraction from email content' },
73+
{ type: 'New', text: 'Smart reply drafts using Claude AI' },
74+
{ type: 'New', text: 'Gmail OAuth integration with multi-account support' },
75+
{ type: 'New', text: 'Slack notifications for urgent emails' },
76+
{ type: 'New', text: 'Team collaboration: internal notes, email assignment, org management' },
77+
{ type: 'New', text: 'CRM integrations: HubSpot and Salesforce' },
78+
{ type: 'New', text: 'Google Calendar integration for meeting detection' },
79+
],
80+
},
81+
];
82+
83+
const typeColors: Record<string, { bg: string; text: string }> = {
84+
New: { bg: '#dcfce7', text: '#15803d' },
85+
Improved: { bg: '#dbeafe', text: '#1d4ed8' },
86+
Fixed: { bg: '#fef9c3', text: '#a16207' },
87+
};
88+
89+
export default function ChangelogPage() {
90+
return (
91+
<>
92+
<Head>
93+
<title>Changelog — Mailair</title>
94+
<meta name="description" content="See what's new in Mailair — new features, improvements, and bug fixes." />
95+
</Head>
96+
97+
<nav style={{ borderBottom: '1px solid #e5e7eb', padding: '0 24px', height: 64, display: 'flex', alignItems: 'center', justifyContent: 'space-between', background: '#fff' }}>
98+
<Link href="/"><img src="/logo.svg" alt="Mailair" style={{ height: 36 }} /></Link>
99+
<div style={{ display: 'flex', gap: 24, alignItems: 'center' }}>
100+
<Link href="/docs" style={{ color: '#6b7280', fontSize: 14, textDecoration: 'none' }}>Docs</Link>
101+
<Link href="/auth/signin" style={{ color: '#6b7280', fontSize: 14, textDecoration: 'none' }}>Sign In</Link>
102+
<Link href="/auth/signup" style={{ background: '#2563eb', color: '#fff', padding: '8px 18px', borderRadius: 8, fontSize: 14, fontWeight: 600, textDecoration: 'none' }}>Start Free</Link>
103+
</div>
104+
</nav>
105+
106+
<div style={{ maxWidth: 720, margin: '0 auto', padding: '60px 24px' }}>
107+
<h1 style={{ fontSize: 40, fontWeight: 800, color: '#111827', margin: '0 0 8px' }}>Changelog</h1>
108+
<p style={{ color: '#6b7280', fontSize: 16, marginBottom: 56 }}>Every update to Mailair, documented.</p>
109+
110+
<div style={{ position: 'relative' }}>
111+
{releases.map((release, idx) => (
112+
<div key={release.version} style={{ display: 'flex', gap: 32, marginBottom: 56 }}>
113+
{/* Timeline */}
114+
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', flexShrink: 0 }}>
115+
<div style={{ width: 12, height: 12, borderRadius: '50%', background: idx === 0 ? '#2563eb' : '#d1d5db', border: '2px solid', borderColor: idx === 0 ? '#2563eb' : '#d1d5db', marginTop: 6 }} />
116+
{idx < releases.length - 1 && <div style={{ width: 2, flexGrow: 1, background: '#e5e7eb', marginTop: 8 }} />}
117+
</div>
118+
119+
{/* Content */}
120+
<div style={{ flex: 1, paddingBottom: 16 }}>
121+
<div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 4, flexWrap: 'wrap' }}>
122+
<span style={{ fontSize: 20, fontWeight: 800, color: '#111827' }}>{release.version}</span>
123+
<span style={{ fontSize: 11, fontWeight: 700, padding: '2px 10px', borderRadius: 99, background: release.tagColor, color: release.tagText, textTransform: 'uppercase', letterSpacing: '0.05em' }}>
124+
{release.tag}
125+
</span>
126+
<span style={{ fontSize: 13, color: '#9ca3af' }}>{release.date}</span>
127+
</div>
128+
129+
<ul style={{ listStyle: 'none', padding: 0, margin: '16px 0 0' }}>
130+
{release.changes.map((change, i) => {
131+
const tc = typeColors[change.type] ?? typeColors.New;
132+
return (
133+
<li key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 10, marginBottom: 10 }}>
134+
<span style={{ fontSize: 11, fontWeight: 700, padding: '2px 8px', borderRadius: 6, background: tc.bg, color: tc.text, flexShrink: 0, marginTop: 2 }}>
135+
{change.type}
136+
</span>
137+
<span style={{ fontSize: 14, color: '#374151', lineHeight: 1.6 }}>{change.text}</span>
138+
</li>
139+
);
140+
})}
141+
</ul>
142+
</div>
143+
</div>
144+
))}
145+
</div>
146+
</div>
147+
</>
148+
);
149+
}

frontend/pages/cookies.tsx

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import Head from 'next/head';
2+
import Link from 'next/link';
3+
4+
const s = {
5+
wrap: { maxWidth: 760, margin: '60px auto', padding: '0 24px', fontFamily: 'ui-sans-serif, system-ui, sans-serif', lineHeight: 1.8, color: '#1a1a1a' } as React.CSSProperties,
6+
back: { color: '#2563eb', textDecoration: 'none', fontSize: 14 } as React.CSSProperties,
7+
h1: { marginTop: 32, fontSize: 32, fontWeight: 700 } as React.CSSProperties,
8+
h2: { marginTop: 32, fontSize: 20, fontWeight: 700, borderBottom: '1px solid #e5e7eb', paddingBottom: 8 } as React.CSSProperties,
9+
meta: { color: '#6b7280', fontSize: 14 } as React.CSSProperties,
10+
p: { color: '#374151', marginTop: 12 } as React.CSSProperties,
11+
li: { color: '#374151', marginBottom: 6 } as React.CSSProperties,
12+
table: { width: '100%', borderCollapse: 'collapse' as const, marginTop: 16, fontSize: 14 },
13+
th: { textAlign: 'left' as const, padding: '10px 12px', background: '#f9fafb', border: '1px solid #e5e7eb', fontWeight: 600, color: '#374151' },
14+
td: { padding: '10px 12px', border: '1px solid #e5e7eb', color: '#374151' },
15+
};
16+
17+
export default function CookiePolicy() {
18+
return (
19+
<>
20+
<Head><title>Cookie Policy — Mailair</title></Head>
21+
<div style={s.wrap}>
22+
<Link href="/" style={s.back}>← Back to Mailair</Link>
23+
<h1 style={s.h1}>Cookie Policy</h1>
24+
<p style={s.meta}>Last updated: March 22, 2026</p>
25+
26+
<h2 style={s.h2}>1. What Are Cookies?</h2>
27+
<p style={s.p}>Cookies are small text files stored on your device when you visit a website. They help websites remember your preferences and improve your experience. Mailair uses a minimal set of cookies strictly necessary to operate the service.</p>
28+
29+
<h2 style={s.h2}>2. Cookies We Use</h2>
30+
<table style={s.table}>
31+
<thead>
32+
<tr>
33+
<th style={s.th}>Cookie</th>
34+
<th style={s.th}>Purpose</th>
35+
<th style={s.th}>Duration</th>
36+
<th style={s.th}>Type</th>
37+
</tr>
38+
</thead>
39+
<tbody>
40+
{[
41+
['mailair-auth', 'Stores your authentication session so you stay signed in', 'Session / 7 days', 'Essential'],
42+
['sb-*', 'Supabase authentication tokens for secure API access', 'Session', 'Essential'],
43+
['__vercel_*', 'Vercel deployment and routing (Next.js hosting)', 'Session', 'Technical'],
44+
['theme', 'Remembers your dark/light mode preference', '1 year', 'Preference'],
45+
].map(([name, purpose, duration, type]) => (
46+
<tr key={name}>
47+
<td style={{ ...s.td, fontFamily: 'monospace', fontSize: 13 }}>{name}</td>
48+
<td style={s.td}>{purpose}</td>
49+
<td style={s.td}>{duration}</td>
50+
<td style={s.td}>{type}</td>
51+
</tr>
52+
))}
53+
</tbody>
54+
</table>
55+
56+
<h2 style={s.h2}>3. What We Do NOT Use</h2>
57+
<ul>
58+
<li style={s.li}>We do <strong>not</strong> use advertising or tracking cookies.</li>
59+
<li style={s.li}>We do <strong>not</strong> use third-party analytics cookies (e.g. Google Analytics).</li>
60+
<li style={s.li}>We do <strong>not</strong> sell or share cookie data with third parties.</li>
61+
</ul>
62+
63+
<h2 style={s.h2}>4. Managing Cookies</h2>
64+
<p style={s.p}>Since all cookies used by Mailair are essential for the service to function, disabling them may prevent you from signing in or using core features.</p>
65+
<p style={s.p}>You can manage or delete cookies through your browser settings:</p>
66+
<ul>
67+
<li style={s.li}><strong>Chrome:</strong> Settings → Privacy and Security → Cookies</li>
68+
<li style={s.li}><strong>Firefox:</strong> Settings → Privacy & Security Cookies and Site Data</li>
69+
<li style={s.li}><strong>Safari:</strong> Preferences → Privacy → Manage Website Data</li>
70+
</ul>
71+
72+
<h2 style={s.h2}>5. Contact</h2>
73+
<p style={s.p}>Questions about our cookie use? Email us at <a href="mailto:saisridhart@gmail.com" style={{ color: '#2563eb' }}>saisridhart@gmail.com</a></p>
74+
75+
<p style={{ ...s.meta, marginTop: 48, borderTop: '1px solid #e5e7eb', paddingTop: 24 }}>© 2025 Mailair. All rights reserved.</p>
76+
</div>
77+
</>
78+
);
79+
}

0 commit comments

Comments
 (0)