Skip to content

Commit 104c3f4

Browse files
feat: Enhance About Me page and implement Open to Work feature
- Updated About Me page with new milestones and technical badges. - Introduced Milestone component for better organization of career achievements. - Enhanced visual elements and layout for improved user experience. - Added Open to Work component with admin PIN functionality for visibility control. - Created utility functions for managing Open to Work state in local storage. - Defined openToWorkPositions data structure for available roles.
1 parent 26a94de commit 104c3f4

File tree

15 files changed

+1033
-529
lines changed

15 files changed

+1033
-529
lines changed

TODO.md

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1-
# TODO: Implement Cool Responsive Card Slider for Research Interests
1+
# TODO: Improve UI of ProjectDetail.tsx with Mandatory Headings
22

3-
- [x] Replace grid layout with horizontal card slider using Framer Motion
4-
- [x] Add state for current slide index and navigation logic
5-
- [x] Implement left/right arrow navigation buttons
6-
- [x] Make slider responsive (1 card mobile, 2 tablet, 3 desktop)
7-
- [x] Add smooth drag/swipe support for touch devices
8-
- [x] Remove "Show More/Less" button and expand/collapse logic
9-
- [x] Adjust card styling and animations for slider layout
10-
- [x] Test slider on different screen sizes and run dev server
11-
- [x] Fix TypeScript errors and complete implementation
3+
## Tasks
4+
- [x] Add Abstract / Executive Summary section using project.description
5+
- [x] Add Introduction section using project.longDescription
6+
- [x] Add Problem Statement section inferred from objectives
7+
- [x] Keep existing Objectives / Aims section
8+
- [x] Add Scope of the Study / Project section using type and technologies
9+
- [x] Add Literature Review section with placeholder
10+
- [x] Add Methodology / System Design section using methods
11+
- [x] Add Implementation / Experimentation section using technologies and methods
12+
- [x] Keep existing Results and Analysis section (Results & Impact)
13+
- [x] Add Discussion section inferred from results
14+
- [x] Add Conclusion section inferred from results
15+
- [x] Add Limitations section using challenges
16+
- [x] Add Future Scope / Recommendations section with placeholder
17+
- [x] Add References / Bibliography section with placeholder
18+
- [x] Ensure all sections use appropriate icons and maintain responsive design
19+
- [x] Test the updated UI for layout and responsiveness
20+
- [x] Verify that all sections display correctly with the mapped data

src/components/Achievement.tsx

Lines changed: 167 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,180 @@
1-
import React from 'react';
2-
import { motion } from 'framer-motion';
3-
import { ExternalLink } from 'lucide-react';
1+
import React, { useState } from 'react';
2+
import { motion, AnimatePresence } from 'framer-motion';
3+
import {
4+
ArrowUpRight,
5+
ChevronDown,
6+
ChevronUp,
7+
LucideIcon,
8+
Activity,
9+
BookOpen,
10+
Badge,
11+
Trophy
12+
} from 'lucide-react';
413

5-
interface AchievementItemProps {
6-
title: string;
7-
verificationLink?: {
8-
url: string;
9-
label: string;
10-
};
14+
interface AchievementLink {
15+
url: string;
16+
label: string;
1117
}
1218

13-
interface AchievementSectionProps {
19+
interface AchievementItem {
20+
description: string;
21+
links: AchievementLink[];
22+
}
23+
24+
interface AchievementCategory {
25+
id: string;
1426
title: string;
15-
items: AchievementItemProps[];
27+
icon: LucideIcon;
28+
category: string;
29+
items: AchievementItem[];
1630
}
1731

18-
interface AchievementsProps {
19-
sections: AchievementSectionProps[];
32+
interface AchievementSectionProps {
33+
categories: AchievementCategory[];
2034
}
2135

22-
const Achievement: React.FC<AchievementsProps> = ({ sections }) => {
36+
// --- Reusable Log Entry Component ---
37+
const LogEntry = ({ item }: { item: AchievementItem }) => (
38+
<div className="group/entry relative pl-10 pb-10 last:pb-0">
39+
{/* Visual Rail Dot */}
40+
<div className="absolute left-0 top-1.5 w-2 h-2 rounded-full bg-slate-200 group-hover/entry:bg-blue-600 group-hover/entry:shadow-[0_0_10px_rgba(37,99,235,0.8)] transition-all duration-300" />
41+
42+
<div className="flex flex-col gap-4">
43+
<p className="text-slate-600 text-base md:text-lg leading-relaxed font-medium">
44+
{item.description}
45+
</p>
46+
47+
<div className="flex flex-wrap gap-3">
48+
{item.links.map((link, i) => (
49+
link.url !== "#" && (
50+
<motion.a
51+
key={i}
52+
whileHover={{ y: -2 }}
53+
whileTap={{ scale: 0.95 }}
54+
href={link.url}
55+
target="_blank"
56+
rel="noopener noreferrer"
57+
className="inline-flex items-center gap-2 px-4 py-2 bg-slate-50 text-blue-600 border border-slate-100 rounded-xl text-xs font-mono font-black uppercase tracking-wider hover:bg-blue-600 hover:text-white transition-all shadow-sm hover:shadow-md"
58+
>
59+
{link.label}
60+
<ArrowUpRight size={14} />
61+
</motion.a>
62+
)
63+
))}
64+
</div>
65+
</div>
66+
</div>
67+
);
68+
69+
// --- Main Achievement Component ---
70+
const Achievement: React.FC<AchievementSectionProps> = ({ categories }) => {
71+
const [expanded, setExpanded] = useState<Record<string, boolean>>({});
72+
73+
const toggle = (id: string) => setExpanded(prev => ({ ...prev, [id]: !prev[id] }));
74+
2375
return (
24-
<div className="space-y-6 max-w-7xl">
25-
{sections.map((section, sectionIndex) => (
26-
<motion.div
27-
key={sectionIndex}
28-
initial={{ opacity: 0, y: 20 }}
29-
animate={{ opacity: 1, y: 0 }}
30-
className="bg-white rounded-lg p-6 shadow-sm"
31-
>
32-
<h3 className="text-lg font-semibold mb-4 text-gray-800">{section.title}</h3>
33-
<ul className="space-y-3">
34-
{section.items.map((item, itemIndex) => (
35-
<li key={itemIndex} className="flex items-start">
36-
<span className="text-blue-500 mr-2 mt-1"></span>
37-
<div>
38-
<p className="text-sm text-gray-700">
39-
{item.title}
40-
{item.verificationLink && (
41-
<a
42-
href={item.verificationLink.url}
43-
target="_blank"
44-
rel="noopener noreferrer"
45-
className="text-blue-500 hover:text-blue-600 ml-2 text-xs inline-flex items-center"
46-
>
47-
{item.verificationLink.label}
48-
<ExternalLink className="w-3 h-3 ml-1" />
49-
</a>
50-
)}
51-
</p>
76+
<section className="w-full pt-32 pb-24 font-sans selection:bg-blue-100">
77+
{/* Section Header */}
78+
<div className="mb-16">
79+
<div className="flex items-center gap-2 mb-4">
80+
<Trophy size={16} className="text-blue-600" />
81+
<span className="text-[10px] font-mono font-black uppercase tracking-[0.3em] text-blue-600">
82+
Achievements & Milestones
83+
</span>
84+
</div>
85+
<h2 className="text-3xl md:text-5xl font-black text-slate-900 tracking-tighter">
86+
Awards & Recognitions
87+
</h2>
88+
<div className="w-16 h-1.5 bg-blue-600 mt-6 rounded-full" />
89+
</div>
90+
91+
{/* --- LEDGER LIST --- */}
92+
<div className="px-6lg:space-y-12">
93+
{categories.map((category) => {
94+
const isExpanded = expanded[category.id] || false;
95+
const shownItems = isExpanded ? category.items : category.items.slice(0, 2);
96+
const needsToggle = category.items.length > 2;
97+
98+
return (
99+
<motion.div
100+
key={category.id}
101+
layout
102+
className="w-full border-t-2 border-slate-100 pt-16 lg:pt-24 group"
103+
>
104+
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-8 items-start">
105+
106+
{/* Meta Column */}
107+
<div className="lg:col-span-2">
108+
<div className="flex items-center gap-4 mb-6">
109+
<motion.div
110+
whileHover={{ scale: 1.05 }}
111+
className="p-3 bg-gradient-to-br from-slate-900 to-slate-800 text-white rounded-2xl shadow-xl hover:shadow-2xl transition-shadow"
112+
>
113+
<category.icon size={24} />
114+
</motion.div>
115+
<span className="text-sm font-mono font-black text-blue-600 uppercase tracking-widest">
116+
Log_{category.id}
117+
</span>
118+
</div>
119+
<span className="inline-block px-3 py-1 bg-blue-50 text-blue-700 text-[10px] font-mono font-bold uppercase tracking-widest rounded-full hover:bg-blue-100 transition-colors">
120+
{category.category}
121+
</span>
52122
</div>
53-
</li>
54-
))}
55-
</ul>
56-
</motion.div>
57-
))}
58-
</div>
123+
124+
{/* Content Column */}
125+
<div className="lg:col-span-10">
126+
<h3 className="text-2xl md:text-3xl font-black text-slate-900 tracking-tighter mb-12 uppercase leading-none hover:text-blue-600 transition-colors">
127+
{category.title}
128+
</h3>
129+
130+
<div className="relative">
131+
{/* Vertical Rail Line */}
132+
<div className="absolute left-[3.5px] top-4 bottom-4 w-px bg-gradient-to-b from-slate-100 to-slate-50" />
133+
134+
<div className="space-y-4">
135+
<AnimatePresence>
136+
{shownItems.map((item, idx) => (
137+
<motion.div
138+
key={idx}
139+
initial={{ opacity: 0, y: 10 }}
140+
animate={{ opacity: 1, y: 0 }}
141+
exit={{ opacity: 0, y: -10 }}
142+
transition={{ delay: idx * 0.1 }}
143+
>
144+
<LogEntry item={item} />
145+
</motion.div>
146+
))}
147+
</AnimatePresence>
148+
</div>
149+
</div>
150+
151+
{needsToggle && (
152+
<motion.button
153+
onClick={() => toggle(category.id)}
154+
whileHover={{ x: 5 }}
155+
whileTap={{ scale: 0.98 }}
156+
className="mt-12 ml-10 flex items-center gap-3 text-slate-900 font-black text-sm uppercase tracking-widest group hover:text-blue-600 transition-colors"
157+
>
158+
{isExpanded ? (
159+
<>
160+
<ChevronUp size={20} className="group-hover:-translate-y-1 transition-transform" />
161+
Collapse Registry
162+
</>
163+
) : (
164+
<>
165+
Expand {category.items.length - 2} More Entries
166+
<ChevronDown size={20} className="group-hover:translate-y-1 transition-transform" />
167+
</>
168+
)}
169+
</motion.button>
170+
)}
171+
</div>
172+
</div>
173+
</motion.div>
174+
);
175+
})}
176+
</div>
177+
</section>
59178
);
60179
};
61180

0 commit comments

Comments
 (0)