Skip to content

Commit 8359535

Browse files
committed
fixing project
1 parent fb9d3e4 commit 8359535

40 files changed

Lines changed: 4680 additions & 5713 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ dist-ssr
2222
*.njsproj
2323
*.sln
2424
*.sw?
25+
.env

App.tsx

Lines changed: 7 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,7 @@
1-
import React, { useEffect } from 'react';
2-
import Page from './app/page';
3-
import AdminPage from './app/admin';
4-
import LoginPage from './app/login';
5-
import ProjectsPage from './app/projects';
6-
import ProjectDetailPage from './app/project-detail';
7-
import BlogPage from './app/blog';
8-
import BlogDetailPage from './app/blog-detail';
9-
import AboutPage from './app/about';
10-
import PrivacyPage from './app/privacy';
11-
import TermsPage from './app/terms';
1+
import React from 'react';
2+
import { Outlet } from 'react-router-dom';
123
import { Toaster } from 'sonner';
13-
import { RouterProvider, useRouter } from './lib/router';
14-
import { StoreProvider, useStore } from './lib/store';
4+
import { ThemeProvider } from './lib/ThemeContext';
155
import { ScrollToTop } from './components/ScrollToTop';
166

177
// Global Background Animation
@@ -25,73 +15,14 @@ function BackgroundBeams() {
2515
);
2616
}
2717

28-
// Navigation Manager Component
29-
function AppContent() {
30-
const { path } = useRouter();
31-
const { isAuthenticated, theme } = useStore();
32-
33-
// Initialize theme on mount to ensure class is present
34-
useEffect(() => {
35-
if (theme === 'dark') {
36-
document.documentElement.classList.add('dark');
37-
} else {
38-
document.documentElement.classList.remove('dark');
39-
}
40-
}, [theme]);
41-
42-
// Scroll to contact section if path is /contact
43-
useEffect(() => {
44-
if (path === '/contact') {
45-
setTimeout(() => {
46-
const contactSection = document.getElementById('contact');
47-
if (contactSection) {
48-
contactSection.scrollIntoView({ behavior: 'smooth' });
49-
}
50-
}, 100);
51-
}
52-
}, [path]);
53-
54-
if (path.startsWith('/admin')) {
55-
if (!isAuthenticated) return <LoginPage />;
56-
return <AdminPage />;
57-
}
58-
59-
if (path === '/login') {
60-
if (isAuthenticated) return <AdminPage />;
61-
return <LoginPage />;
62-
}
63-
64-
// Routes
65-
if (path === '/projects') return <ProjectsPage />;
66-
if (path === '/blog') return <BlogPage />;
67-
if (path === '/about') return <AboutPage />;
68-
if (path === '/privacy') return <PrivacyPage />;
69-
if (path === '/terms') return <TermsPage />;
70-
71-
// Dynamic Routes
72-
if (path.startsWith('/projects/')) {
73-
const id = path.split('/projects/')[1];
74-
return <ProjectDetailPage id={id} />;
75-
}
76-
77-
if (path.startsWith('/blog/')) {
78-
const id = path.split('/blog/')[1];
79-
return <BlogDetailPage id={id} />;
80-
}
81-
82-
return <Page />;
83-
}
84-
8518
export default function App() {
8619
return (
8720
<div className="min-h-screen text-slate-900 dark:text-slate-50 antialiased selection:bg-indigo-500/30">
88-
<StoreProvider>
89-
<BackgroundBeams />
90-
<RouterProvider>
91-
<AppContent />
21+
<ThemeProvider>
22+
<BackgroundBeams />
23+
<Outlet />
9224
<ScrollToTop />
93-
</RouterProvider>
94-
</StoreProvider>
25+
</ThemeProvider>
9526
<Toaster position="bottom-right" theme="system" />
9627
</div>
9728
);

app/about.tsx

Lines changed: 41 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import React from 'react';
2-
import { useStore } from '../lib/store';
2+
import { useTheme } from '../lib/ThemeContext';
3+
import { useQuery } from '@tanstack/react-query';
4+
import * as api from '../lib/api';
35
import { Navbar } from '../components/Navbar';
46
import { Download, MapPin, Briefcase, GraduationCap, Mail, Github, Linkedin, Twitter, Instagram, Youtube, Code, Smartphone, Cloud, Terminal, Layout, Database, Zap } from 'lucide-react';
57
import { motion } from 'framer-motion';
68

7-
const IconMap = {
9+
const IconMap: { [key: string]: React.ElementType } = {
810
code: Code,
911
smartphone: Smartphone,
1012
cloud: Cloud,
@@ -14,17 +16,31 @@ const IconMap = {
1416
};
1517

1618
export default function AboutPage() {
17-
const { profile, experience, education, services, theme } = useStore();
19+
const { theme } = useTheme();
1820

19-
const getGithubUsername = (url: string) => {
20-
if (!url) return '';
21-
const cleanUrl = url.replace(/\/$/, ''); // Remove trailing slash
22-
return cleanUrl.split('/').pop();
23-
};
21+
const { data: profile, isLoading: isLoadingProfile } = useQuery({ queryKey: ['profile'], queryFn: api.getProfile });
22+
const { data: experience, isLoading: isLoadingExp } = useQuery({ queryKey: ['resume', 'experience'], queryFn: () => api.getResume('experience') });
23+
const { data: education, isLoading: isLoadingEdu } = useQuery({ queryKey: ['resume', 'education'], queryFn: () => api.getResume('education') });
24+
const { data: services, isLoading: isLoadingServices } = useQuery({ queryKey: ['services'], queryFn: api.getServices });
2425

25-
const username = getGithubUsername(profile.socials.github);
26+
const isLoading = isLoadingProfile || isLoadingExp || isLoadingEdu || isLoadingServices;
2627
const statsTheme = theme === 'dark' ? 'dark' : 'default';
2728

29+
// const getGithubUsername = (url: string | undefined) => {
30+
// if (!url) return '';
31+
// const cleanUrl = url.replace(/\/$/, ''); // Remove trailing slash
32+
// return cleanUrl.split('/').pop();
33+
// };
34+
// const username = getGithubUsername(profile?.socials.github);
35+
36+
if (isLoading) {
37+
return (
38+
<div className="min-h-screen bg-slate-50 dark:bg-slate-950 flex items-center justify-center">
39+
<p>Loading...</p>
40+
</div>
41+
)
42+
}
43+
2844
return (
2945
<div className="min-h-screen bg-slate-50 dark:bg-slate-950 text-slate-900 dark:text-white transition-colors duration-300">
3046
<Navbar />
@@ -35,43 +51,15 @@ export default function AboutPage() {
3551
<div className="w-full md:w-1/3 shrink-0">
3652
<div className="aspect-square rounded-2xl overflow-hidden border-4 border-white dark:border-slate-800 shadow-xl relative mb-6">
3753
<div className="absolute inset-0 bg-indigo-500/10 mix-blend-overlay" />
38-
<img src={profile.avatar_url} alt={profile.name} className="w-full h-full object-cover bg-white dark:bg-slate-900" />
54+
<img src={profile?.avatar_url || ''} alt={profile?.full_name || 'User'} className="w-full h-full object-cover bg-white dark:bg-slate-900" />
3955
</div>
4056

4157
<div className="flex flex-col gap-4">
42-
<div className="flex items-center gap-3 text-slate-600 dark:text-slate-400">
43-
<MapPin className="h-5 w-5 text-indigo-500" />
44-
<span>{profile.address}</span>
45-
</div>
46-
{profile.socials.mail && (
47-
<div className="flex items-center gap-3 text-slate-600 dark:text-slate-400">
48-
<Mail className="h-5 w-5 text-indigo-500" />
49-
<a href={`mailto:${profile.socials.mail}`} className="hover:text-indigo-500">{profile.socials.mail}</a>
50-
</div>
51-
)}
52-
53-
{/* Social Icons */}
54-
<div className="flex flex-wrap gap-4 mt-2">
55-
{profile.socials.github && (
56-
<a href={profile.socials.github} target="_blank" rel="noreferrer" className="p-2 bg-slate-200 dark:bg-slate-900 rounded-lg hover:bg-indigo-100 dark:hover:bg-indigo-900/50 text-slate-600 dark:text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"><Github className="h-5 w-5" /></a>
57-
)}
58-
{profile.socials.linkedin && (
59-
<a href={profile.socials.linkedin} target="_blank" rel="noreferrer" className="p-2 bg-slate-200 dark:bg-slate-900 rounded-lg hover:bg-indigo-100 dark:hover:bg-indigo-900/50 text-slate-600 dark:text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"><Linkedin className="h-5 w-5" /></a>
60-
)}
61-
{profile.socials.twitter && (
62-
<a href={profile.socials.twitter} target="_blank" rel="noreferrer" className="p-2 bg-slate-200 dark:bg-slate-900 rounded-lg hover:bg-indigo-100 dark:hover:bg-indigo-900/50 text-slate-600 dark:text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"><Twitter className="h-5 w-5" /></a>
63-
)}
64-
{profile.socials.instagram && (
65-
<a href={profile.socials.instagram} target="_blank" rel="noreferrer" className="p-2 bg-slate-200 dark:bg-slate-900 rounded-lg hover:bg-indigo-100 dark:hover:bg-indigo-900/50 text-slate-600 dark:text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"><Instagram className="h-5 w-5" /></a>
66-
)}
67-
{profile.socials.youtube && (
68-
<a href={profile.socials.youtube} target="_blank" rel="noreferrer" className="p-2 bg-slate-200 dark:bg-slate-900 rounded-lg hover:bg-indigo-100 dark:hover:bg-indigo-900/50 text-slate-600 dark:text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"><Youtube className="h-5 w-5" /></a>
69-
)}
70-
</div>
58+
{/* Placeholder for Address & Socials */}
7159
</div>
7260

7361
<a
74-
href={profile.resume_url}
62+
href="#" // Placeholder for resume_url
7563
target="_blank"
7664
className="mt-8 w-full flex items-center justify-center gap-2 bg-indigo-600 hover:bg-indigo-700 text-white py-3 rounded-lg font-medium transition-all shadow-lg shadow-indigo-500/20"
7765
>
@@ -83,7 +71,7 @@ export default function AboutPage() {
8371
<h1 className="text-4xl font-bold mb-6">About Me</h1>
8472
<div className="prose prose-lg prose-slate dark:prose-invert">
8573
<p className="whitespace-pre-wrap leading-relaxed text-slate-600 dark:text-slate-300">
86-
{profile.detailed_bio}
74+
{/* Placeholder for detailed_bio */}
8775
</p>
8876
</div>
8977
</div>
@@ -100,7 +88,7 @@ export default function AboutPage() {
10088
</h2>
10189
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
10290
{services.map((service, idx) => {
103-
const Icon = IconMap[service.icon] || Code;
91+
const Icon = service.icon_name ? IconMap[service.icon_name] || Code : Code;
10492
return (
10593
<motion.div
10694
key={service.id}
@@ -131,7 +119,7 @@ export default function AboutPage() {
131119
Experience
132120
</h2>
133121
<div className="space-y-8 border-l-2 border-slate-200 dark:border-slate-800 ml-3 pl-8 relative">
134-
{experience.map((exp, idx) => (
122+
{experience?.map((exp, idx) => (
135123
<motion.div
136124
key={exp.id}
137125
initial={{ opacity: 0, x: -20 }}
@@ -140,21 +128,12 @@ export default function AboutPage() {
140128
className="relative"
141129
>
142130
<span className="absolute -left-[41px] top-1 w-5 h-5 rounded-full border-4 border-white dark:border-slate-950 bg-indigo-500" />
143-
<h3 className="text-xl font-bold text-slate-900 dark:text-white">{exp.role}</h3>
144-
<div className="text-indigo-600 dark:text-indigo-400 font-medium mb-2">{exp.company}</div>
145-
<div className="text-sm text-slate-500 mb-3">{exp.period}</div>
131+
<h3 className="text-xl font-bold text-slate-900 dark:text-white">{exp.title}</h3>
132+
<div className="text-indigo-600 dark:text-indigo-400 font-medium mb-2">{exp.institution}</div>
133+
<div className="text-sm text-slate-500 mb-3">{exp.start_date} - {exp.end_date || 'Present'}</div>
146134
<p className="text-slate-600 dark:text-slate-400 text-sm leading-relaxed mb-3">
147135
{exp.description}
148136
</p>
149-
{exp.tags && exp.tags.length > 0 && (
150-
<div className="flex flex-wrap gap-2">
151-
{exp.tags.map(tag => (
152-
<span key={tag} className="px-2 py-1 bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 text-xs rounded-md border border-slate-200 dark:border-slate-700">
153-
{tag}
154-
</span>
155-
))}
156-
</div>
157-
)}
158137
</motion.div>
159138
))}
160139
</div>
@@ -169,7 +148,7 @@ export default function AboutPage() {
169148
Education
170149
</h2>
171150
<div className="space-y-8 border-l-2 border-slate-200 dark:border-slate-800 ml-3 pl-8 relative">
172-
{education.map((edu, idx) => (
151+
{education?.map((edu, idx) => (
173152
<motion.div
174153
key={edu.id}
175154
initial={{ opacity: 0, x: -20 }}
@@ -178,53 +157,17 @@ export default function AboutPage() {
178157
className="relative"
179158
>
180159
<span className="absolute -left-[41px] top-1 w-5 h-5 rounded-full border-4 border-white dark:border-slate-950 bg-purple-500" />
181-
<h3 className="text-xl font-bold text-slate-900 dark:text-white">{edu.degree}</h3>
182-
<div className="text-purple-600 dark:text-purple-400 font-medium mb-1">{edu.school}</div>
183-
<div className="text-sm text-slate-500 mb-2">{edu.period}</div>
184-
{edu.gpa && (
185-
<div className="text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
186-
GPA: {edu.gpa}
187-
</div>
188-
)}
189-
{edu.description && (
190-
<p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
191-
{edu.description}
192-
</p>
193-
)}
194-
{edu.tags && edu.tags.length > 0 && (
195-
<div className="flex flex-wrap gap-2">
196-
{edu.tags.map(tag => (
197-
<span key={tag} className="px-2 py-1 bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 text-xs rounded-md border border-slate-200 dark:border-slate-700">
198-
{tag}
199-
</span>
200-
))}
201-
</div>
202-
)}
160+
<h3 className="text-xl font-bold text-slate-900 dark:text-white">{edu.title}</h3>
161+
<div className="text-purple-600 dark:text-purple-400 font-medium mb-1">{edu.institution}</div>
162+
<div className="text-sm text-slate-500 mb-2">{edu.start_date} - {edu.end_date || 'Present'}</div>
163+
<p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
164+
{edu.description}
165+
</p>
203166
</motion.div>
204167
))}
205168
</div>
206169
</div>
207170
</div>
208-
209-
{/* GitHub Stats Section */}
210-
{username && (
211-
<div className="border-t border-slate-200 dark:border-white/10 pt-16">
212-
<h2 className="text-2xl font-bold mb-8 text-center text-slate-900 dark:text-white">Coding Activity</h2>
213-
<div className="flex flex-col md:flex-row gap-6 justify-center items-center">
214-
<img
215-
src={`https://github-readme-stats.vercel.app/api?username=${username}&show_icons=true&theme=${statsTheme}&bg_color=${statsTheme === 'dark' ? '0f172a' : 'ffffff'}&title_color=${statsTheme === 'dark' ? 'ffffff' : '0f172a'}&text_color=${statsTheme === 'dark' ? '94a3b8' : '475569'}&icon_color=6366f1&border_color=${statsTheme === 'dark' ? '1e293b' : 'e2e8f0'}`}
216-
alt="GitHub Stats"
217-
className="rounded-xl border border-slate-200 dark:border-white/10 shadow-lg max-w-full"
218-
/>
219-
<img
220-
src={`https://github-readme-stats.vercel.app/api/top-langs/?username=${username}&layout=compact&theme=${statsTheme}&bg_color=${statsTheme === 'dark' ? '0f172a' : 'ffffff'}&title_color=${statsTheme === 'dark' ? 'ffffff' : '0f172a'}&text_color=${statsTheme === 'dark' ? '94a3b8' : '475569'}&border_color=${statsTheme === 'dark' ? '1e293b' : 'e2e8f0'}`}
221-
alt="Top Languages"
222-
className="rounded-xl border border-slate-200 dark:border-white/10 shadow-lg max-w-full"
223-
/>
224-
</div>
225-
</div>
226-
)}
227-
228171
</div>
229172
</div>
230173
);

0 commit comments

Comments
 (0)