Skip to content

Commit fbcb1c7

Browse files
committed
Refactor App component to utilize structured CV data and enhance section rendering
1 parent ca34c55 commit fbcb1c7

2 files changed

Lines changed: 458 additions & 58 deletions

File tree

src/App.tsx

Lines changed: 166 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,166 @@
11
import React, { useState } from 'react';
2-
import { Github, Linkedin, Mail, Code2, Terminal, Database, Globe, ExternalLink } from 'lucide-react';
2+
import { Github, Linkedin, Mail, ExternalLink } from 'lucide-react';
3+
34
import { BlogSection } from './components/BlogSection';
4-
import { useIntersectionObserver } from './hooks/useIntersectionObserver';
5+
56
import { WebGLBackground } from './components/WebGLBackground';
7+
import cvData from './data/cv';
8+
69

7-
function SkillCard({ icon, title, items }: { icon: React.ReactNode; title: string; items: string[] }) {
8-
const cardRef = useIntersectionObserver({ threshold: 0.2 });
10+
// Utility components for rendering sections
11+
function SectionTitle({ children }: { children: React.ReactNode }) {
12+
return <h2 className="text-3xl md:text-4xl font-bold text-center mb-12">{children}</h2>;
13+
}
914

15+
function EducationSection() {
1016
return (
11-
<div ref={cardRef} className="hidden-element p-6 rounded-xl bg-white/5 backdrop-blur-sm hover:bg-white/10 transition-all duration-300 hover:scale-105 transform">
12-
<div className="flex items-center gap-4 mb-4">
13-
{icon}
14-
<h3 className="text-xl font-semibold">{title}</h3>
17+
<section className="min-h-screen py-20 snap-start">
18+
<div className="container mx-auto px-4">
19+
<SectionTitle>Education</SectionTitle>
20+
<div className="space-y-8 max-w-3xl mx-auto">
21+
{cvData.education.map((edu, i) => (
22+
<div key={i} className="bg-white/5 rounded-xl p-6">
23+
<div className="flex flex-col md:flex-row md:justify-between md:items-center mb-2">
24+
<div>
25+
<h3 className="text-xl font-semibold">{edu.degree}</h3>
26+
<p className="text-gray-300">{edu.institution}</p>
27+
</div>
28+
<span className="text-gray-400 text-sm mt-2 md:mt-0">{edu.date}</span>
29+
</div>
30+
{edu.honors && edu.honors.length > 0 && (
31+
<ul className="text-gray-400 text-sm mb-2 list-disc ml-5">
32+
{edu.honors.map((h, j) => <li key={j}>{h}</li>)}
33+
</ul>
34+
)}
35+
{edu.relevantCourses && edu.relevantCourses.length > 0 && (
36+
<div className="text-gray-300 text-sm">
37+
<span className="font-semibold">Relevant Courses:</span> {edu.relevantCourses.join(', ')}
38+
</div>
39+
)}
40+
</div>
41+
))}
42+
</div>
1543
</div>
16-
<ul className="space-y-2">
17-
{items.map((item) => (
18-
<li key={item} className="text-gray-300">{item}</li>
19-
))}
20-
</ul>
21-
</div>
44+
</section>
45+
);
46+
}
47+
48+
function SkillsSection() {
49+
return (
50+
<section className="min-h-screen py-20 snap-start">
51+
<div className="container mx-auto px-4">
52+
<SectionTitle>Core Skills</SectionTitle>
53+
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 max-w-4xl mx-auto">
54+
<div className="bg-white/5 rounded-xl p-6">
55+
<h3 className="text-xl font-semibold mb-2">Hard Skills</h3>
56+
<ul className="flex flex-wrap gap-2">
57+
{cvData.skills.hard.map((skill, i) => (
58+
<li key={i} className="px-3 py-1 rounded-full bg-blue-500/20 text-blue-300 text-sm">{skill}</li>
59+
))}
60+
</ul>
61+
</div>
62+
<div className="bg-white/5 rounded-xl p-6">
63+
<h3 className="text-xl font-semibold mb-2">Soft Skills</h3>
64+
<ul className="flex flex-wrap gap-2">
65+
{cvData.skills.soft.map((skill, i) => (
66+
<li key={i} className="px-3 py-1 rounded-full bg-teal-500/20 text-teal-300 text-sm">{skill}</li>
67+
))}
68+
</ul>
69+
</div>
70+
</div>
71+
</div>
72+
</section>
2273
);
2374
}
2475

25-
function ProjectCard({ title, description, tech, link }: { title: string; description: string; tech: string[]; link: string }) {
26-
const cardRef = useIntersectionObserver({ threshold: 0.2 });
76+
function ExperienceSection() {
77+
return (
78+
<section className="min-h-screen py-20 snap-start">
79+
<div className="container mx-auto px-4">
80+
<SectionTitle>Experience</SectionTitle>
81+
<div className="space-y-8 max-w-3xl mx-auto">
82+
{cvData.experience.map((exp, i) => (
83+
<div key={i} className="bg-white/5 rounded-xl p-6">
84+
<div className="flex flex-col md:flex-row md:justify-between md:items-center mb-2">
85+
<div>
86+
<h3 className="text-lg font-semibold">{exp.title}</h3>
87+
<p className="text-gray-300">{exp.organization}</p>
88+
</div>
89+
<span className="text-gray-400 text-sm mt-2 md:mt-0">{exp.date}</span>
90+
</div>
91+
{exp.description.length > 0 && (
92+
<ul className="text-gray-400 text-sm list-disc ml-5">
93+
{exp.description.map((d, j) => <li key={j}>{d}</li>)}
94+
</ul>
95+
)}
96+
</div>
97+
))}
98+
</div>
99+
</div>
100+
</section>
101+
);
102+
}
27103

104+
function ProjectsSection() {
28105
return (
29-
<div ref={cardRef} className="hidden-element p-6 rounded-xl bg-white/5 backdrop-blur-sm hover:bg-white/10 transition-all duration-300 hover:scale-105 transform h-full">
30-
<h3 className="text-xl font-semibold mb-3">{title}</h3>
31-
<p className="text-gray-300 mb-4">{description}</p>
32-
<div className="flex flex-wrap gap-2 mb-4">
33-
{tech.map((item) => (
34-
<span key={item} className="px-3 py-1 rounded-full bg-blue-500/20 text-blue-300 text-sm">
35-
{item}
36-
</span>
37-
))}
106+
<section className="min-h-screen py-20 snap-start">
107+
<div className="container mx-auto px-4">
108+
<SectionTitle>Projects</SectionTitle>
109+
<div className="space-y-8 max-w-3xl mx-auto">
110+
{cvData.projects.map((proj, i) => (
111+
<div key={i} className="bg-white/5 rounded-xl p-6">
112+
<h3 className="text-lg font-semibold mb-2">{proj.title}</h3>
113+
<ul className="text-gray-300 text-sm mb-2 list-disc ml-5">
114+
{proj.description.map((desc, j) => <li key={j}>{desc}</li>)}
115+
</ul>
116+
{proj.links && proj.links.length > 0 && (
117+
<div className="flex flex-wrap gap-3 mt-2">
118+
{proj.links.map((l, k) => (
119+
<a key={k} href={l.url} target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-1 text-blue-400 hover:text-blue-300 transition-colors underline">
120+
{l.label} <ExternalLink size={14} />
121+
</a>
122+
))}
123+
</div>
124+
)}
125+
</div>
126+
))}
127+
</div>
38128
</div>
39-
<a
40-
href={link}
41-
className="inline-flex items-center gap-2 text-blue-400 hover:text-blue-300 transition-colors"
42-
>
43-
View Project <ExternalLink size={16} />
44-
</a>
45-
</div>
129+
</section>
130+
);
131+
}
132+
133+
function CertificationsSection() {
134+
return (
135+
<section className="py-20 snap-start">
136+
<div className="container mx-auto px-4">
137+
<SectionTitle>Certifications, Courses & Workshops</SectionTitle>
138+
<ul className="flex flex-wrap gap-2 max-w-4xl mx-auto justify-center">
139+
{cvData.certifications.map((cert, i) => (
140+
<li key={i} className="px-3 py-1 rounded-full bg-purple-500/20 text-purple-300 text-sm mb-2">{cert.name}</li>
141+
))}
142+
</ul>
143+
</div>
144+
</section>
145+
);
146+
}
147+
148+
function ClubsSection() {
149+
return (
150+
<section className="py-20 snap-start">
151+
<div className="container mx-auto px-4">
152+
<SectionTitle>Clubs & Leadership</SectionTitle>
153+
<div className="flex flex-wrap gap-4 justify-center">
154+
{cvData.clubs.map((club, i) => (
155+
<div key={i} className="bg-white/5 rounded-xl p-4 min-w-[220px]">
156+
<h4 className="font-semibold text-lg mb-1">{club.name}</h4>
157+
<div className="text-gray-300 text-sm mb-1">{club.role}</div>
158+
<div className="text-gray-400 text-xs">{club.date}</div>
159+
</div>
160+
))}
161+
</div>
162+
</div>
163+
</section>
46164
);
47165
}
48166

@@ -76,33 +194,23 @@ function App() {
76194
</div>
77195
</header>
78196

79-
{/* Skills Section */}
80-
<section className="min-h-screen py-20 snap-start">
81-
<div className="container mx-auto px-4">
82-
<h2 className="text-3xl md:text-4xl font-bold text-center mb-16">Technical Skills</h2>
83-
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
84-
<SkillCard icon={<Code2 size={32} />} title="Languages" items={["Python", "C++", "R", "Matlab"]} />
85-
<SkillCard icon={<Terminal size={32} />} title="Tools" items={["Git", "Docker", "Linux", "VS Code"]} />
86-
<SkillCard icon={<Database size={32} />} title="Databases" items={["MySQL", "MongoDB"]} />
87-
<SkillCard icon={<Globe size={32} />} title="Web" items={["Flask", "Django", "React", "HTML/CSS"]} />
88-
</div>
89-
</div>
90-
</section>
197+
{/* Education Section */}
198+
<EducationSection />
91199

92-
{/* Projects Section */}
93-
<section className="min-h-screen py-20 snap-start">
94-
<div className="container mx-auto px-4">
95-
<h2 className="text-3xl md:text-4xl font-bold text-center mb-16">Featured Projects</h2>
96-
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
97-
<ProjectCard
98-
title="TBD"
99-
description="TBD"
100-
tech={["TBD"]}
101-
link="https://github.com"
102-
/>
103-
</div>
104-
</div>
105-
</section>
200+
{/* Skills Section */}
201+
<SkillsSection />
202+
203+
{/* Experience Section */}
204+
<ExperienceSection />
205+
206+
{/* Projects Section */}
207+
<ProjectsSection />
208+
209+
{/* Certifications Section */}
210+
<CertificationsSection />
211+
212+
{/* Clubs Section */}
213+
<ClubsSection />
106214

107215
{/* Blog Section */}
108216
<div className="snap-start">

0 commit comments

Comments
 (0)