Skip to content

Commit 7b29b04

Browse files
Merge branch 'main' into feature/improve-contactpage
2 parents 6de7ab8 + c6706e8 commit 7b29b04

21 files changed

Lines changed: 1733 additions & 425 deletions

File tree

.github/workflows/auto-label-gssoc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ jobs:
2727
labels: |
2828
level:intermediate
2929
quality:clean
30+
type:accessibility
3031
gssoc:approved

backend/server.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,17 @@ const logger = require('./logger');
1414
const app = express();
1515

1616
// CORS configuration
17-
app.use(cors('*'));
17+
const allowedOrigins = ['http://localhost:5173', 'https://github-spy.etlify.app'];
18+
app.use(cors({
19+
origin: function (origin, callback) {
20+
if (!origin || allowedOrigins.indexOf(origin) !== -1) {
21+
callback(null, true);
22+
} else{
23+
callback(new Error('Blocked by CORS policy'));
24+
}
25+
},
26+
credentials: true
27+
}));
1828

1929
// Middleware
2030
app.use(bodyParser.json());
@@ -33,8 +43,10 @@ app.use('/api/auth', authRoutes);
3343
// Connect to MongoDB
3444
mongoose.connect(process.env.MONGO_URI, {}).then(() => {
3545
logger.info('Connected to MongoDB');
36-
app.listen(process.env.PORT, () => {
37-
logger.info(`Server running on port ${process.env.PORT}`);
46+
47+
const PORT = process.env.PORT || 5000;
48+
app.listen(PORT, () => {
49+
logger.info(`Server running on port ${PORT}`);
3850
});
3951
}).catch((err) => {
4052
logger.error('MongoDB connection error', err);

index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
<meta charset="UTF-8" />
55
<link rel="icon" type="image/svg+xml" href="/crl-icon.png" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<link rel="preconnect" href="https://fonts.googleapis.com" />
8+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9+
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet" />
710
<title>Github Tracker</title>
811
</head>
912
<body>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "GitHub Tracker",
2+
"name": "github-tracker",
33
"private": true,
44
"version": "0.0.0",
55
"type": "module",

src/Routes/Router.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Login from "../pages/Login/Login.tsx";
88
import ContributorProfile from "../pages/ContributorProfile/ContributorProfile.tsx";
99
import Home from "../pages/Home/Home.tsx";
1010
import Activity from "../pages/Activity.tsx";
11+
import PrivacyPolicy from "../pages/Privacy/PrivacyPolicy.tsx"; // ✅ Updated import path to match your new folder structure
1112

1213
const Router = () => {
1314
return (
@@ -20,9 +21,10 @@ const Router = () => {
2021
<Route path="/contact" element={<Contact />} />
2122
<Route path="/contributors" element={<Contributors />} />
2223
<Route path="/contributor/:username" element={<ContributorProfile />} />
23-
24-
{/* ✅ new route */}
2524
<Route path="/activity" element={<Activity />} />
25+
26+
{/* Privacy Policy page route */}
27+
<Route path="/privacy" element={<PrivacyPolicy />} />
2628
</Routes>
2729
);
2830
};

src/components/Features.tsx

Lines changed: 141 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,91 @@
11
import { BarChart3, Users, Search, Zap, Shield, Globe } from 'lucide-react';
2+
import type { CSSProperties, ReactNode } from 'react';
3+
4+
type TerminalHeadingProps = {
5+
title: string;
6+
as?: 'h2' | 'h3' | 'h4';
7+
className?: string;
8+
promptClassName?: string;
9+
titleClassName?: string;
10+
animated?: boolean;
11+
};
12+
13+
type TerminalCardProps = {
14+
label: string;
15+
children: ReactNode;
16+
className?: string;
17+
contentClassName?: string;
18+
accent?: 'blue' | 'green';
19+
};
20+
21+
const headingSizes: Record<NonNullable<TerminalHeadingProps['as']>, string> = {
22+
h2: 'text-3xl md:text-4xl',
23+
h3: 'text-xl md:text-2xl',
24+
h4: 'text-lg md:text-xl',
25+
};
26+
27+
const TerminalHeading = ({
28+
title,
29+
as: HeadingTag = 'h2',
30+
className = '',
31+
promptClassName = '',
32+
titleClassName = '',
33+
animated = false,
34+
}: TerminalHeadingProps) => {
35+
const chars = title.length + 2;
36+
37+
return (
38+
<HeadingTag
39+
className={`inline-flex items-center gap-2 text-balance text-[#c9d1d9] ${headingSizes[HeadingTag]} ${className}`}
40+
style={animated ? ({ '--terminal-chars': chars } as CSSProperties) : undefined}
41+
>
42+
<span
43+
className={`font-["VT323"] text-[#58a6ff] ${animated ? 'terminal-typewriter inline-block' : ''} ${promptClassName}`}
44+
>
45+
&gt;
46+
</span>
47+
<span
48+
className={`font-["VT323"] tracking-[0.03em] ${animated ? 'terminal-typewriter inline-block' : ''} ${titleClassName}`}
49+
>
50+
{title}
51+
</span>
52+
</HeadingTag>
53+
);
54+
};
55+
56+
const TerminalCard = ({
57+
label,
58+
children,
59+
className = '',
60+
contentClassName = '',
61+
accent = 'blue',
62+
}: TerminalCardProps) => {
63+
const accentClasses = accent === 'green' ? 'text-[#3fb950] border-[#3fb950]/30' : 'text-[#58a6ff] border-[#58a6ff]/30';
64+
65+
return (
66+
<article
67+
className={`group relative overflow-hidden rounded-2xl border border-[#30363d] bg-[#161b22] shadow-[0_12px_30px_rgba(1,4,9,0.22)] transition-all duration-300 ease-out hover:-translate-y-1 hover:border-[#58a6ff]/40 hover:shadow-[0_18px_38px_rgba(1,4,9,0.35)] ${className}`}
68+
>
69+
<div className="flex items-center justify-between gap-4 border-b border-[#30363d] bg-[#0d1117]/90 px-4 py-3">
70+
<div className="flex items-center gap-1.5" aria-hidden="true">
71+
<span className="h-2.5 w-2.5 rounded-full bg-[#f85149]/80" />
72+
<span className="h-2.5 w-2.5 rounded-full bg-[#d29922]/80" />
73+
<span className="h-2.5 w-2.5 rounded-full bg-[#3fb950]/80" />
74+
</div>
75+
76+
<div className={`flex items-center gap-2 font-["VT323"] text-sm uppercase tracking-[0.22em] ${accentClasses}`}>
77+
<span>{label}</span>
78+
<span className="terminal-card-cursor opacity-0 transition-opacity duration-200 group-hover:opacity-100">_</span>
79+
</div>
80+
</div>
81+
82+
<div className={`relative px-5 py-5 sm:px-6 sm:py-6 ${contentClassName}`}>
83+
<div className="absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white/5 to-transparent" />
84+
{children}
85+
</div>
86+
</article>
87+
);
88+
};
289

390
const Features = () => {
491
const features = [
@@ -59,28 +146,67 @@ const Features = () => {
59146
];
60147

61148
return (
62-
<section id="features" className="px-6 py-6 bg-white dark:bg-gray-900 transition-colors duration-300">
63-
<div className="mx-auto">
64-
<div className="text-center mb-16">
65-
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-4">Powerful Features</h2>
66-
<p className="text-xl text-gray-600 dark:text-gray-300 max-w-2xl mx-auto">
67-
Everything you need to track, analyze, and understand GitHub activity patterns
149+
<section
150+
id="features"
151+
className="relative left-1/2 right-1/2 w-screen -mx-[50vw] overflow-hidden bg-[linear-gradient(to_bottom,#f8fafc_0%,#dbe7f5_20%,#0d1117_100%)] px-6 py-16 text-[#c9d1d9] transition-colors duration-300 sm:py-20"
152+
style={{
153+
boxShadow: '0 -40px 80px rgba(88,166,255,0.08), 0 40px 80px rgba(88,166,255,0.05)',
154+
}}
155+
>
156+
<div className="absolute inset-0 bg-[radial-gradient(circle_at_top,_rgba(88,166,255,0.08),_transparent_32%),radial-gradient(circle_at_bottom_right,_rgba(63,185,80,0.05),_transparent_28%)] pointer-events-none" />
157+
<div className="absolute inset-x-0 top-0 h-28 bg-gradient-to-b from-[#f8fafc]/75 via-[#dbe7f5]/20 to-transparent pointer-events-none" />
158+
<div className="absolute inset-x-0 bottom-0 h-24 bg-gradient-to-t from-[#0d1117] via-[#0d1117]/70 to-transparent pointer-events-none" />
159+
<div className="mx-auto max-w-7xl relative">
160+
<div className="mx-auto mb-10 max-w-3xl text-center sm:mb-12">
161+
<p className="font-['VT323'] text-sm uppercase tracking-[0.32em] text-[#58a6ff] sm:text-base">
162+
&gt; initialize tracking capabilities
163+
</p>
164+
<h2 className="mt-3 text-3xl font-semibold tracking-tight text-black md:text-4xl">
165+
Powerful Features
166+
</h2>
167+
<p className="mx-auto mt-4 max-w-2xl text-sm leading-relaxed text-[#8b949e] sm:text-base">
168+
Everything you need to track, analyze, and understand GitHub activity patterns.
68169
</p>
69170
</div>
70171

71-
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
172+
<div className="grid gap-5 md:grid-cols-2 xl:grid-cols-3">
72173
{features.map((feature, index) => {
73174
const IconComponent = feature.icon;
175+
const promptLabel = `feature-${String(index + 1).padStart(2, '0')}`;
176+
const titleTone = index % 2 === 0 ? 'blue' : 'green';
74177
return (
75-
<div key={index} className={`group h-72 w-full bg-gray-100 dark:bg-gray-800 ${feature.hoverColor} ${feature.borderColor} rounded-2xl shadow-md hover:shadow-2xl hover:shadow-blue-500/20 border dark:border-gray-800 transform hover:-translate-y-3 hover:scale-105 backdrop-blur-sm transition-all duration-300 ease-linear p-6`}>
76-
<div className={`${feature.bgColor} w-12 h-12 rounded-lg flex items-center justify-center mb-6 transition-transform duration-300 group-hover:rotate-6 group-hover:scale-110`}>
77-
<IconComponent className={`h-6 w-6 ${feature.iconColor}`} />
178+
<TerminalCard key={index} label={promptLabel} accent={titleTone} className="h-full">
179+
<div className="flex h-full flex-col gap-4">
180+
<div className="flex items-start gap-4">
181+
<div className="flex h-11 w-11 shrink-0 items-center justify-center rounded-xl border border-[#30363d] bg-[#0d1117] text-[#58a6ff] transition-transform duration-300 group-hover:-translate-y-0.5 group-hover:scale-105">
182+
<IconComponent className="h-5 w-5" />
183+
</div>
184+
<div className="min-w-0 flex-1 space-y-2">
185+
<TerminalHeading
186+
title={feature.title}
187+
as="h3"
188+
className="items-start"
189+
titleClassName="text-[#f0f6fc]"
190+
/>
191+
<div className="flex flex-wrap items-center gap-2 text-[11px] uppercase tracking-[0.24em] text-[#8b949e]">
192+
<span className="rounded-full border border-[#30363d] bg-[#0d1117] px-2.5 py-1 font-['VT323'] text-[#58a6ff]">
193+
cmd
194+
</span>
195+
<span className="font-['VT323']">gh tracker --feature</span>
196+
</div>
197+
</div>
198+
</div>
199+
200+
<p className="text-sm leading-relaxed text-[#8b949e] sm:text-[0.95rem]">
201+
{feature.description}
202+
</p>
203+
204+
<div className="mt-auto flex items-center justify-between border-t border-[#30363d] pt-4 text-xs text-[#8b949e]">
205+
<span className="font-['VT323'] uppercase tracking-[0.2em] text-[#3fb950]">ready</span>
206+
<span className="font-['VT323'] text-[#58a6ff]">{feature.title.toLowerCase().replace(/\s+/g, '-')}</span>
207+
</div>
78208
</div>
79-
<h3 className=" text-2xl font-bold text-gray-900 dark:text-gray-100 group-hover:text-black dark:group-hover:text-white transition-colors duration-300">{feature.title}</h3>
80-
<p className="text-gray-600 dark:text-gray-300 text-base font-semibold leading-relaxed group-hover:text-gray-700 dark:group-hover:text-gray-200 transition-colors duration-300">
81-
{feature.description}
82-
</p>
83-
</div>
209+
</TerminalCard>
84210
);
85211
})}
86212
</div>

src/components/Footer.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
FaArrowRight,
88
FaEnvelope,
99
FaInfoCircle,
10+
FaShieldAlt, // ✅ Added Privacy Icon
1011
} from 'react-icons/fa';
1112

1213
function Footer() {
@@ -80,6 +81,15 @@ function Footer() {
8081
<FaInfoCircle className="h-3.5 w-3.5" />
8182
About
8283
</Link>
84+
85+
{/* ✅ New Privacy Policy link integration */}
86+
<Link
87+
to="/privacy"
88+
className="inline-flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"
89+
>
90+
<FaShieldAlt className="h-3.5 w-3.5" />
91+
Privacy Policy
92+
</Link>
8393
</div>
8494
</div>
8595

@@ -99,6 +109,7 @@ function Footer() {
99109
placeholder="Enter email address"
100110
value={email}
101111
onChange={(e) => setEmail(e.target.value)}
112+
autoComplete="email"
102113
className="
103114
flex-grow text-sm px-4 py-3
104115
bg-zinc-50 dark:bg-zinc-800/40
@@ -181,4 +192,4 @@ function Footer() {
181192
);
182193
}
183194

184-
export default Footer;
195+
export default Footer;

0 commit comments

Comments
 (0)