-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathscript.js
More file actions
321 lines (295 loc) · 13.8 KB
/
script.js
File metadata and controls
321 lines (295 loc) · 13.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
// Dynamic year in footer
try {
const yearElement = document.getElementById('current-year');
if (yearElement) {
yearElement.textContent = new Date().getFullYear();
}
} catch (error) {
console.error('Error updating year:', error);
}
// Skills stagger entrance animation
try {
const skillsGrid = document.querySelector('.skillsGrid');
if (skillsGrid) {
const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (reducedMotion) {
// Show all immediately for reduced-motion users
skillsGrid.querySelectorAll('.skill-item').forEach(item => {
item.classList.add('skill-visible');
});
} else if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.querySelectorAll('.skill-item').forEach((item, i) => {
setTimeout(() => item.classList.add('skill-visible'), i * 55);
});
observer.unobserve(entry.target);
}
});
}, { threshold: 0.12 });
observer.observe(skillsGrid);
} else {
// Fallback for browsers without IntersectionObserver
skillsGrid.querySelectorAll('.skill-item').forEach(item => {
item.classList.add('skill-visible');
});
}
}
} catch (error) {
console.error('Error setting up skills animation:', error);
}
const copyEmail = () => {
navigator.clipboard.writeText("uzairmanandev@gmail.com");
alert("Email copied to clipboard.");
};
// Smooth scroll implementation with error handling
document.addEventListener('DOMContentLoaded', function() {
try {
// Get all links that have hash (#) in them
const links = document.querySelectorAll('a[href^="#"]');
links.forEach(link => {
link.addEventListener('click', function(e) {
try {
const targetId = this.getAttribute('href');
// Skip if it's just "#"
if (targetId === '#') return;
e.preventDefault();
const targetElement = document.querySelector(targetId);
if (targetElement) {
targetElement.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
} catch (error) {
console.error('Error during smooth scroll:', error);
}
});
});
} catch (error) {
console.error('Error setting up smooth scroll:', error);
}
});
// Project data for modal
const projectData = {
coinquest: {
title: "CoinQuest",
year: "2026",
url: "https://coinquest-codiest.vercel.app/",
techStack: ["React", "Node.js", "Express.js", "MongoDB", "Stripe API", "JWT Authentication"],
description: "CoinQuest is an educational platform designed to teach children financial literacy through engaging interactive lessons, games, and a comprehensive rewards system. Parents can sign up their children for structured learning paths that make understanding money management fun and accessible.",
features: [
"Integrated Stripe payment gateway for secure subscription management",
"Interactive learning modules delivered via video tutorials and carousel-based lessons",
"Built-in educational games to reinforce financial concepts",
"Comprehensive admin dashboard for managing learning modules and creating new lessons",
"Gamification system with XP points and in-app currency (coins) to motivate learning",
"Achievement system to track student progress and milestones",
"User feedback forms for continuous improvement",
"Parent and child account management with progress tracking",
"Responsive design optimized for tablets and computers used by children"
]
},
corlee: {
title: "Corlee & Co",
year: "2024",
url: "https://corleeandco.com",
techStack: ["React", "Node.js", "Express.js", "MongoDB", "JWT Authentication", "REST API"],
description: "Corlee is a comprehensive B2B e-commerce platform designed specifically for a wholesale fabric business. This full-stack application connects fabric suppliers with businesses worldwide, providing a seamless browsing and ordering experience for wholesale buyers.",
features: [
"Dynamic product catalog with advanced filtering and search capabilities",
"Secure user authentication system with JWT tokens and session management",
"Role-based access control for customers and administrators",
"Shopping cart functionality with real-time inventory tracking",
"Responsive design optimized for desktop and mobile devices",
"Admin dashboard for product management and order tracking",
"RESTful API architecture ensuring scalability and maintainability",
"MongoDB database with optimized queries for fast data retrieval"
]
},
trendsjoy: {
title: "TrendsJoy",
year: "2025",
url: "https://trendsjoy.vercel.app/",
techStack: ["React", "Node.js", "Express.js", "MongoDB", "AI/ML APIs", "i18next"],
description: "TrendsJoy is a dynamic trend discovery platform where users can submit, explore, and engage with current trends across various categories. Featuring a sophisticated feed algorithm and AI-powered assistance, it creates a personalized experience for trend enthusiasts worldwide. Note: The AI assistant is currently inactive as the client has abandoned the project and the API key has expired.",
features: [
"Custom feed algorithm that ranks posts based on upload time and user engagement metrics",
"User authentication system with account creation and profile management",
"Full social interaction features: like, dislike, and comment on posts",
"Post creation and submission system for users to share their trend discoveries",
"Built-in AI assistant for trend insights (currently inactive due to expired API key)",
"Save posts functionality for bookmarking favorite trends",
"Real-time language toggle supporting multiple languages across the entire platform",
"Dynamic content feeds with personalized recommendations",
"Responsive design for seamless mobile and desktop experiences",
"Internationalization (i18n) implementation for global accessibility"
]
},
webhoster: {
title: "WebHoster",
year: "2026",
url: "https://webhoster-codiest.vercel.app/",
techStack: ["React", "Node.js", "Express.js", "MongoDB", "Lighthouse API", "Nodemailer"],
description: "WebHoster is a comprehensive website performance analysis platform that helps businesses and developers understand their website's health. Users simply enter their website URL and email to receive detailed performance metrics and actionable insights delivered directly to their inbox.",
features: [
"Automated website performance analysis using Google Lighthouse API",
"Comprehensive metrics tracking: LCP, FCP, CLS, TTI, and Speed Index",
"SEO analysis with actionable recommendations for search optimization",
"Accessibility audit ensuring WCAG compliance standards",
"Best practices evaluation for modern web development standards",
"Beautiful, intuitive UI for visualizing performance metrics",
"Automated email reporting with detailed PDF reports via Nodemailer",
"Historical performance tracking for monitoring improvements over time",
"Mobile and desktop performance analysis",
"Real-time processing with progress indicators"
]
},
thoughtsarea: {
title: "Thoughts Area",
year: "2025",
url: "https://thoughts-area.vercel.app",
techStack: ["React", "Node.js", "Express.js", "MongoDB", "OAuth 2.0", "JWT", "Passport.js"],
description: "Thoughts Area is a feature-rich social media platform inspired by Reddit's community-driven approach. This personal project demonstrates advanced full-stack development skills, implementing complex social features including user interactions, content management, and multiple authentication strategies.",
features: [
"Reddit-inspired post and comment system with nested threading",
"Upvote/downvote mechanism with real-time score updates",
"User profiles with customizable information and activity tracking",
"Follower/following system for building user connections",
"OAuth 2.0 integration supporting multiple providers (Google, Facebook, GitHub)",
"Content feed with algorithmic sorting based on popularity and recency",
"Rich text editor for creating formatted posts",
"Search functionality across posts, comments, and users",
"Notification system for interactions and follower updates",
"Responsive design with smooth animations and transitions"
]
},
yona: {
title: "YONA",
year: "2024",
url: "https://yona-pi.vercel.app/",
figmaUrl: "https://www.figma.com/design/r4yPVFCoja4cLdL3DvtTC0/Luxury-Website---UI-UX?node-id=0-1&p=f&t=q31pS9MCXD7CNOO9-0",
techStack: ["React", "Next.js", "Tailwind CSS", "Framer Motion", "TypeScript"],
description: "YONA is an elegant, luxury website created for a premium Iraqi brand. This project showcases pixel-perfect implementation from Figma designs, emphasizing sophistication, clean aesthetics, and premium user experience. The focus was on achieving design excellence and creating a stunning visual presence that reflects the brand's luxury positioning.",
features: [
"Pixel-perfect implementation matching the original Figma design specifications",
"Elegant and premium UI/UX with sophisticated typography and spacing",
"Smooth, subtle animations using Framer Motion for enhanced user experience",
"Fully responsive design maintaining elegance across all device sizes",
"Optimized performance with Next.js for fast page loads",
"Clean, minimalist aesthetic that emphasizes luxury and sophistication",
"Attention to detail in every element, from spacing to color transitions",
"Custom components built with Tailwind CSS for maintainability",
"SEO-optimized structure for better search engine visibility",
"Cross-browser compatibility ensuring consistent experience"
]
}
};
// Modal functionality with error handling
try {
const modal = document.getElementById('projectModal');
if (!modal) {
throw new Error('Modal element not found');
}
const modalOverlay = modal.querySelector('.modal-overlay');
const modalClose = modal.querySelector('.modal-close');
const modalTitle = modal.querySelector('.modal-title');
const modalTechStack = modal.querySelector('.modal-tech-stack');
const modalDescription = modal.querySelector('.modal-description');
const modalFeatures = modal.querySelector('.modal-features');
const modalVisitBtn = modal.querySelector('.modal-visit-btn');
const modalFigmaBtn = modal.querySelector('.modal-figma-btn');
// Open modal with loading state
function openModal(projectKey) {
try {
const project = projectData[projectKey];
if (!project) {
console.error(`Project data not found for key: ${projectKey}`);
return;
}
// Show loading state
modal.classList.add('active');
modalTitle.textContent = 'Loading...';
modalTechStack.innerHTML = '';
modalDescription.textContent = '';
modalFeatures.innerHTML = '';
// Simulate loading delay for smooth transition
setTimeout(() => {
// Populate modal content
modalTitle.textContent = `${project.title} (${project.year})`;
// Tech stack
modalTechStack.innerHTML = project.techStack
.map(tech => `<span>${tech}</span>`)
.join('');
// Description
modalDescription.textContent = project.description;
// Features
modalFeatures.innerHTML = `
<h3>Key Features & Technologies</h3>
<ul>
${project.features.map(feature => `<li>${feature}</li>`).join('')}
</ul>
`;
// Visit button
modalVisitBtn.href = project.url;
modalVisitBtn.target = '_blank';
// Figma button (show only if project has figmaUrl)
if (project.figmaUrl) {
modalFigmaBtn.href = project.figmaUrl;
modalFigmaBtn.target = '_blank';
modalFigmaBtn.style.display = 'inline-block';
} else {
modalFigmaBtn.style.display = 'none';
}
}, 100);
document.body.style.overflow = 'hidden';
} catch (error) {
console.error('Error opening modal:', error);
modalTitle.textContent = 'Error loading project';
modalDescription.textContent = 'Sorry, there was an error loading this project.';
}
}
// Close modal
function closeModal() {
try {
modal.classList.remove('active');
document.body.style.overflow = 'auto';
} catch (error) {
console.error('Error closing modal:', error);
}
}
// Event listeners for project cards
document.querySelectorAll('.projectinfo').forEach(card => {
card.addEventListener('click', function() {
try {
const projectKey = this.getAttribute('data-project');
if (projectKey) {
openModal(projectKey);
}
} catch (error) {
console.error('Error handling project card click:', error);
}
});
});
// Close modal on overlay click
if (modalOverlay) {
modalOverlay.addEventListener('click', closeModal);
}
// Close modal on close button click
if (modalClose) {
modalClose.addEventListener('click', closeModal);
}
// Close modal on ESC key
document.addEventListener('keydown', function(e) {
try {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
} catch (error) {
console.error('Error handling ESC key:', error);
}
});
} catch (error) {
console.error('Error initializing modal functionality:', error);
}