Skip to content

Commit edf8663

Browse files
committed
feat: add privacy policy page and footer link
1 parent 6169d2b commit edf8663

12 files changed

Lines changed: 297 additions & 9 deletions

File tree

app/components/Footer.error-resilience.test.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ vi.mock('lucide-react', () => ({
4848
BookOpen: () => null,
4949
GitBranch: () => null,
5050
HelpCircle: () => null,
51+
Shield: () => <div>Shield</div>,
52+
FileText: () => <div>FileText</div>,
5153
}));
5254

5355
vi.mock('react-icons/fa', () => ({

app/components/Footer.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
BookOpen,
1313
GitBranch,
1414
HelpCircle,
15+
Shield,
16+
FileText,
1517
} from 'lucide-react';
1618
import { FaGithub, FaDiscord, FaLinkedin } from 'react-icons/fa';
1719
import { FaXTwitter } from 'react-icons/fa6';
@@ -92,6 +94,8 @@ const RESOURCE_ICON_MAP: Record<string, React.ReactNode> = {
9294
github_repo: <GitBranch size={15} className="shrink-0" />,
9395
guidelines: <BookOpen size={15} className="shrink-0" />,
9496
faq: <HelpCircle size={15} className="shrink-0" />,
97+
privacy: <Shield size={15} className="shrink-0" />,
98+
terms: <FileText size={15} className="shrink-0" />,
9599
};
96100

97101
export function Footer() {
@@ -128,6 +132,16 @@ export function Footer() {
128132
href: '/support',
129133
isExternal: false,
130134
},
135+
{
136+
label: t('footer.privacy'),
137+
href: '/privacy',
138+
isExternal: false,
139+
},
140+
{
141+
label: t('footer.terms'),
142+
href: '/terms',
143+
isExternal: false,
144+
},
131145
];
132146

133147
const socialLinks: SocialLink[] = [
@@ -207,6 +221,8 @@ export function Footer() {
207221
if (link.href.includes('README')) iconKey = 'documentation';
208222
else if (link.href.includes('CODE_OF_CONDUCT') || link.href.includes('guidelines'))
209223
iconKey = 'guidelines';
224+
else if (link.href === '/privacy') iconKey = 'privacy';
225+
else if (link.href === '/terms') iconKey = 'terms';
210226
else if (link.href.includes('support') || link.href.includes('faq'))
211227
iconKey = 'faq';
212228

app/privacy/page.tsx

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
import type { Metadata } from 'next';
2+
import Link from 'next/link';
3+
4+
export const metadata: Metadata = {
5+
title: 'Privacy Policy | CommitPulse',
6+
description:
7+
'Learn how CommitPulse collects, uses, and protects your data when you use our GitHub analytics platform.',
8+
};
9+
10+
export default function PrivacyPage() {
11+
return (
12+
<main className="min-h-screen bg-white dark:bg-gray-950 text-gray-900 dark:text-gray-100 px-4 py-16">
13+
<div className="max-w-4xl mx-auto">
14+
{/* Header */}
15+
<div className="mb-12">
16+
<Link
17+
href="/"
18+
className="inline-flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 transition-colors mb-8"
19+
>
20+
<svg
21+
className="w-4 h-4"
22+
fill="none"
23+
viewBox="0 0 24 24"
24+
stroke="currentColor"
25+
strokeWidth={2}
26+
>
27+
<path strokeLinecap="round" strokeLinejoin="round" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
28+
</svg>
29+
Back to Home
30+
</Link>
31+
32+
<div className="inline-flex items-center gap-2 bg-blue-500/10 dark:bg-blue-400/10 text-blue-600 dark:text-blue-400 text-xs font-semibold px-3 py-1 rounded-full mb-4">
33+
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
34+
<path
35+
fillRule="evenodd"
36+
d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z"
37+
clipRule="evenodd"
38+
/>
39+
</svg>
40+
Privacy Policy
41+
</div>
42+
43+
<h1 className="text-4xl md:text-5xl font-bold tracking-tight mb-4">
44+
Your Privacy Matters
45+
</h1>
46+
<p className="text-lg text-gray-500 dark:text-gray-400 max-w-2xl">
47+
CommitPulse is built for developers, by developers. Here&apos;s exactly what data we
48+
collect, why we collect it, and how we protect it.
49+
</p>
50+
<p className="text-sm text-gray-400 dark:text-gray-500 mt-3">Last updated: July 2026</p>
51+
</div>
52+
53+
{/* Sections */}
54+
<div className="space-y-8">
55+
<section
56+
className="bg-gray-50 dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl p-8
57+
transition-all duration-300 hover:-translate-y-1 hover:shadow-lg hover:shadow-gray-200/50 dark:hover:shadow-black/30
58+
hover:border-gray-300 dark:hover:border-gray-700"
59+
>
60+
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
61+
<span className="w-7 h-7 bg-blue-500/10 dark:bg-blue-400/10 text-blue-600 dark:text-blue-400 rounded-lg flex items-center justify-center text-sm font-bold">
62+
1
63+
</span>
64+
Information We Collect
65+
</h2>
66+
<p className="text-gray-600 dark:text-gray-400 leading-relaxed mb-4">
67+
When you sign in with GitHub, we access the following information via GitHub OAuth:
68+
</p>
69+
<ul className="space-y-2 text-gray-600 dark:text-gray-400">
70+
<li className="flex items-start gap-2">
71+
<span className="text-blue-500 mt-1"></span>
72+
<span>Your public GitHub profile (username, avatar, bio)</span>
73+
</li>
74+
<li className="flex items-start gap-2">
75+
<span className="text-blue-500 mt-1"></span>
76+
<span>Your public repositories and commit history</span>
77+
</li>
78+
<li className="flex items-start gap-2">
79+
<span className="text-blue-500 mt-1"></span>
80+
<span>Your email address (if public on GitHub)</span>
81+
</li>
82+
<li className="flex items-start gap-2">
83+
<span className="text-blue-500 mt-1"></span>
84+
<span>Basic usage data such as pages visited and features used</span>
85+
</li>
86+
</ul>
87+
</section>
88+
89+
<section
90+
className="bg-gray-50 dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl p-8
91+
transition-all duration-300 hover:-translate-y-1 hover:shadow-lg hover:shadow-gray-200/50 dark:hover:shadow-black/30
92+
hover:border-gray-300 dark:hover:border-gray-700"
93+
>
94+
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
95+
<span className="w-7 h-7 bg-blue-500/10 dark:bg-blue-400/10 text-blue-600 dark:text-blue-400 rounded-lg flex items-center justify-center text-sm font-bold">
96+
2
97+
</span>
98+
How We Use Your Data
99+
</h2>
100+
<ul className="space-y-2 text-gray-600 dark:text-gray-400">
101+
<li className="flex items-start gap-2">
102+
<span className="text-blue-500 mt-1"></span>
103+
<span>To generate your commit analytics, streaks, and insights</span>
104+
</li>
105+
<li className="flex items-start gap-2">
106+
<span className="text-blue-500 mt-1"></span>
107+
<span>To power features like burnout analysis and README generation</span>
108+
</li>
109+
<li className="flex items-start gap-2">
110+
<span className="text-blue-500 mt-1"></span>
111+
<span>To improve platform performance and fix bugs</span>
112+
</li>
113+
<li className="flex items-start gap-2">
114+
<span className="text-blue-500 mt-1"></span>
115+
<span>We never sell your data to third parties</span>
116+
</li>
117+
</ul>
118+
</section>
119+
120+
<section
121+
className="bg-gray-50 dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl p-8
122+
transition-all duration-300 hover:-translate-y-1 hover:shadow-lg hover:shadow-gray-200/50 dark:hover:shadow-black/30
123+
hover:border-gray-300 dark:hover:border-gray-700"
124+
>
125+
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
126+
<span className="w-7 h-7 bg-blue-500/10 dark:bg-blue-400/10 text-blue-600 dark:text-blue-400 rounded-lg flex items-center justify-center text-sm font-bold">
127+
3
128+
</span>
129+
Data Storage & Security
130+
</h2>
131+
<p className="text-gray-600 dark:text-gray-400 leading-relaxed">
132+
Your data is stored securely using industry-standard encryption. GitHub OAuth tokens
133+
are stored only for the duration of your session and are never logged or shared. We
134+
use secure HTTPS connections for all data transmission.
135+
</p>
136+
</section>
137+
138+
<section
139+
className="bg-gray-50 dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl p-8
140+
transition-all duration-300 hover:-translate-y-1 hover:shadow-lg hover:shadow-gray-200/50 dark:hover:shadow-black/30
141+
hover:border-gray-300 dark:hover:border-gray-700"
142+
>
143+
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
144+
<span className="w-7 h-7 bg-blue-500/10 dark:bg-blue-400/10 text-blue-600 dark:text-blue-400 rounded-lg flex items-center justify-center text-sm font-bold">
145+
4
146+
</span>
147+
Third Party Services
148+
</h2>
149+
<p className="text-gray-600 dark:text-gray-400 leading-relaxed">
150+
CommitPulse uses GitHub OAuth for authentication. By signing in, you also agree to{' '}
151+
<a
152+
href="https://docs.github.com/en/site-policy/privacy-policies/github-privacy-statement"
153+
target="_blank"
154+
rel="noopener noreferrer"
155+
className="text-blue-500 dark:text-blue-400 hover:underline"
156+
>
157+
GitHub&apos;s Privacy Policy
158+
</a>
159+
. We do not use any advertising or tracking third-party services.
160+
</p>
161+
</section>
162+
163+
<section
164+
className="bg-gray-50 dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl p-8
165+
transition-all duration-300 hover:-translate-y-1 hover:shadow-lg hover:shadow-gray-200/50 dark:hover:shadow-black/30
166+
hover:border-gray-300 dark:hover:border-gray-700"
167+
>
168+
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
169+
<span className="w-7 h-7 bg-blue-500/10 dark:bg-blue-400/10 text-blue-600 dark:text-blue-400 rounded-lg flex items-center justify-center text-sm font-bold">
170+
5
171+
</span>
172+
Your Rights
173+
</h2>
174+
<ul className="space-y-2 text-gray-600 dark:text-gray-400">
175+
<li className="flex items-start gap-2">
176+
<span className="text-blue-500 mt-1"></span>
177+
<span>You may request access to your personal data at any time</span>
178+
</li>
179+
<li className="flex items-start gap-2">
180+
<span className="text-blue-500 mt-1"></span>
181+
<span>You may request deletion of your account and associated data</span>
182+
</li>
183+
<li className="flex items-start gap-2">
184+
<span className="text-blue-500 mt-1"></span>
185+
<span>
186+
You can revoke GitHub OAuth access at any time from your GitHub settings
187+
</span>
188+
</li>
189+
</ul>
190+
</section>
191+
192+
<section
193+
className="bg-gray-50 dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl p-8
194+
transition-all duration-300 hover:-translate-y-1 hover:shadow-lg hover:shadow-gray-200/50 dark:hover:shadow-black/30
195+
hover:border-gray-300 dark:hover:border-gray-700"
196+
>
197+
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
198+
<span className="w-7 h-7 bg-blue-500/10 dark:bg-blue-400/10 text-blue-600 dark:text-blue-400 rounded-lg flex items-center justify-center text-sm font-bold">
199+
6
200+
</span>
201+
Changes to This Policy
202+
</h2>
203+
<p className="text-gray-600 dark:text-gray-400 leading-relaxed">
204+
We may update this Privacy Policy from time to time. Continued use of CommitPulse
205+
after changes implies acceptance of the updated policy. Please review this page
206+
periodically.
207+
</p>
208+
</section>
209+
210+
<section
211+
className="bg-gray-50 dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl p-8
212+
transition-all duration-300 hover:-translate-y-1 hover:shadow-lg hover:shadow-gray-200/50 dark:hover:shadow-black/30
213+
hover:border-gray-300 dark:hover:border-gray-700"
214+
>
215+
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
216+
<span className="w-7 h-7 bg-blue-500/10 dark:bg-blue-400/10 text-blue-600 dark:text-blue-400 rounded-lg flex items-center justify-center text-sm font-bold">
217+
7
218+
</span>
219+
Contact
220+
</h2>
221+
<p className="text-gray-600 dark:text-gray-400 leading-relaxed">
222+
If you have any questions about this Privacy Policy, please reach out via{' '}
223+
<Link href="/support" className="text-blue-500 dark:text-blue-400 hover:underline">
224+
our support page
225+
</Link>{' '}
226+
or open an issue on{' '}
227+
<a
228+
href="https://github.com/JhaSourav07/commitpulse/issues"
229+
target="_blank"
230+
rel="noopener noreferrer"
231+
className="text-blue-500 dark:text-blue-400 hover:underline"
232+
>
233+
GitHub
234+
</a>
235+
.
236+
</p>
237+
</section>
238+
</div>
239+
240+
{/* Footer note */}
241+
<div className="mt-12 pt-8 border-t border-gray-200 dark:border-gray-800 flex flex-col sm:flex-row items-center justify-between gap-4">
242+
<p className="text-sm text-gray-400 dark:text-gray-500">
243+
© 2026 CommitPulse. All rights reserved.
244+
</p>
245+
<Link href="/terms" className="text-sm text-blue-500 dark:text-blue-400 hover:underline">
246+
Terms of Use →
247+
</Link>
248+
</div>
249+
</div>
250+
</main>
251+
);
252+
}

locales/de.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
"generator": "Generator",
3434
"guidelines": "Richtlinien",
3535
"faq": "FAQ",
36-
"support": "Support"
36+
"support": "Support",
37+
"privacy": "Datenschutzerklärung",
38+
"terms": "Nutzungsbedingungen"
3739
},
3840
"landing": {
3941
"empty_username_warning": "Bitte gib einen GitHub-Benutzernamen ein, um deinen Badge-Link zu kopieren.",

locales/en.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
"generator": "Generator",
3434
"guidelines": "Guidelines",
3535
"faq": "FAQ",
36-
"support": "Support"
36+
"support": "Support",
37+
"privacy": "Privacy Policy",
38+
"terms": "Terms of Use"
3739
},
3840
"landing": {
3941
"empty_username_warning": "Please enter a GitHub username to copy your badge link.",

locales/es.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
"generator": "Generador",
3434
"guidelines": "Directrices",
3535
"faq": "Preguntas Frecuentes",
36-
"support": "Soporte"
36+
"support": "Soporte",
37+
"privacy": "Política de Privacidad",
38+
"terms": "Términos de Uso"
3739
},
3840
"landing": {
3941
"empty_username_warning": "Ingresa un usuario de GitHub para copiar el enlace de tu insignia.",

locales/fr.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
"generator": "Générateur",
3434
"guidelines": "Directives",
3535
"faq": "FAQ",
36-
"support": "Support"
36+
"support": "Support",
37+
"privacy": "Politique de Confidentialité",
38+
"terms": "Conditions d'Utilisation"
3739
},
3840
"landing": {
3941
"empty_username_warning": "Please enter a GitHub username to copy your badge link.",

locales/hi.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
"generator": "जनरेटर",
3434
"guidelines": "दिशानिर्देश",
3535
"faq": "सामान्य प्रश्न",
36-
"support": "सहायता"
36+
"support": "सहायता",
37+
"privacy": "गोपनीयता नीति",
38+
"terms": "उपयोग की शर्तें"
3739
},
3840
"landing": {
3941
"empty_username_warning": "बैज लिंक कॉपी करने के लिए कृपया गिटहब यूजरनेम दर्ज करें।",

locales/ja.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
"generator": "ジェネレーター",
3434
"guidelines": "ガイドライン",
3535
"faq": "よくある質問",
36-
"support": "サポート"
36+
"support": "サポート",
37+
"privacy": "プライバシーポリシー",
38+
"terms": "利用規約"
3739
},
3840
"landing": {
3941
"empty_username_warning": "Please enter a GitHub username to copy your badge link.",

locales/ko.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
"generator": "제너레이터",
3434
"guidelines": "가이드라인",
3535
"faq": "자주 묻는 질문",
36-
"support": "지원"
36+
"support": "지원",
37+
"privacy": "개인정보처리방침",
38+
"terms": "이용약관"
3739
},
3840
"landing": {
3941
"empty_username_warning": "Please enter a GitHub username to copy your badge link.",

0 commit comments

Comments
 (0)