diff --git a/logo.png b/logo.png index 91d1022c..81fc669e 100644 Binary files a/logo.png and b/logo.png differ diff --git a/public/DevPath-logo.png b/public/DevPath-logo.png index 91d1022c..81fc669e 100644 Binary files a/public/DevPath-logo.png and b/public/DevPath-logo.png differ diff --git a/public/devpath3d.glb b/public/devpath3d.glb new file mode 100644 index 00000000..6b7a76d3 --- /dev/null +++ b/public/devpath3d.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2586f177663c43efaa5f1ed83580b44486f8478e2b4567843bdfc4dfac5d8d9c +size 1370396 diff --git a/public/images/apple-touch-icon.png b/public/images/apple-touch-icon.png index 3d3f1cc0..81fc669e 100644 Binary files a/public/images/apple-touch-icon.png and b/public/images/apple-touch-icon.png differ diff --git a/public/images/favicon-16x16.png b/public/images/favicon-16x16.png index 030a1355..81fc669e 100644 Binary files a/public/images/favicon-16x16.png and b/public/images/favicon-16x16.png differ diff --git a/public/images/favicon-32x32.png b/public/images/favicon-32x32.png index a6d720e6..81fc669e 100644 Binary files a/public/images/favicon-32x32.png and b/public/images/favicon-32x32.png differ diff --git a/public/images/favicon.ico b/public/images/favicon.ico index 0a6b2813..81fc669e 100644 Binary files a/public/images/favicon.ico and b/public/images/favicon.ico differ diff --git a/public/logo-circle.png b/public/logo-circle.png index 91d1022c..81fc669e 100644 Binary files a/public/logo-circle.png and b/public/logo-circle.png differ diff --git a/public/logo.png b/public/logo.png index 91d1022c..81fc669e 100644 Binary files a/public/logo.png and b/public/logo.png differ diff --git a/src/assets/logo.png b/src/assets/logo.png index 91d1022c..81fc669e 100644 Binary files a/src/assets/logo.png and b/src/assets/logo.png differ diff --git a/src/components/profile/Profile.module.css b/src/components/profile/Profile.module.css index dcda1415..fe2896b2 100644 --- a/src/components/profile/Profile.module.css +++ b/src/components/profile/Profile.module.css @@ -1,186 +1,280 @@ -.profile { - padding: 120px 24px; - background: var(--bg-primary); - min-height: 100vh; -} - -.container { - max-width: 1000px; - margin: 0 auto; -} - -.header { - position: relative; - margin-bottom: 80px; -} - -.cover { - height: 200px; - background: linear-gradient(135deg, #3b82f6, #8b5cf6); - border-radius: 24px; - position: relative; - overflow: hidden; -} - -.cover::after { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.1'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); -} - -.userInfo { - position: absolute; - bottom: -60px; - left: 40px; - display: flex; - align-items: flex-end; - gap: 24px; -} - -.avatar { - width: 120px; - height: 120px; - border-radius: 50%; - border: 4px solid var(--bg-primary); - background: #1a1f35; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-size: 48px; - font-weight: 700; -} - -.details { - margin-bottom: 12px; -} - -.name { - font-size: 32px; - font-weight: 700; - color: var(--text-primary); - margin-bottom: 4px; -} - -.bio { - color: var(--text-secondary); - font-size: 16px; -} - -.statsGrid { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 24px; - margin-bottom: 40px; -} - -.statCard { - background: var(--bg-secondary); - border: 1px solid var(--glass-border); - border-radius: 16px; - padding: 24px; - display: flex; - flex-direction: column; - align-items: center; - text-align: center; -} - -.statValue { - font-size: 32px; - font-weight: 700; - color: var(--text-primary); - margin-bottom: 8px; -} - -.statLabel { - color: var(--text-secondary); - font-size: 14px; - display: flex; - align-items: center; - gap: 6px; -} - -.tabs { - display: flex; - gap: 32px; - border-bottom: 1px solid var(--glass-border); - margin-bottom: 40px; -} - -.tab { - padding: 16px 0; - color: var(--text-secondary); - font-weight: 600; - cursor: pointer; - position: relative; - transition: color 0.2s ease; -} - -.tab:hover { - color: var(--text-primary); -} - -.activeTab { - color: var(--text-primary); -} - -.activeTab::after { - content: ''; - position: absolute; - bottom: -1px; - left: 0; - right: 0; - height: 2px; - background: var(--accent-primary); -} - -.sectionTitle { - font-size: 24px; - font-weight: 700; - margin-bottom: 24px; - color: var(--text-primary); -} - -.activityGraph { - background: var(--bg-secondary); - border-radius: 16px; - padding: 24px; - border: 1px solid var(--glass-border); - height: 200px; - display: flex; - align-items: center; - justify-content: center; - color: var(--text-secondary); -} - -@media (max-width: 768px) { - .statsGrid { - grid-template-columns: repeat(2, 1fr); - } - - .userInfo { - flex-direction: column; - align-items: center; - bottom: -100px; - left: 50%; - transform: translateX(-50%); - text-align: center; - } - - .header { - margin-bottom: 120px; - } - - .tabs { - overflow-x: auto; - padding-bottom: 4px; - } - - .tab { - white-space: nowrap; - } -} \ No newline at end of file +.profile { + padding: 120px 24px; + background: var(--bg-primary); + min-height: 100vh; +} + +.container { + max-width: 1000px; + margin: 0 auto; +} + +.header { + position: relative; + margin-bottom: 80px; +} + +.cover { + height: 200px; + background: linear-gradient(135deg, #3b82f6, #8b5cf6); + border-radius: 24px; + position: relative; + overflow: hidden; +} + +.cover::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.1'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); +} + +.userInfo { + position: absolute; + bottom: -60px; + left: 40px; + display: flex; + align-items: flex-end; + gap: 24px; +} + +.avatar { + width: 120px; + height: 120px; + border-radius: 50%; + border: 4px solid var(--bg-primary); + background: #1a1f35; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 48px; + font-weight: 700; +} + +.details { + margin-bottom: 12px; +} + +.name { + font-size: 32px; + font-weight: 700; + color: var(--text-primary); + margin-bottom: 4px; +} + +.bio { + color: var(--text-secondary); + font-size: 16px; +} + +.statsGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 24px; + margin-bottom: 40px; +} + +.statCard { + background: var(--bg-secondary); + border: 1px solid var(--glass-border); + border-radius: 16px; + padding: 24px; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + +.statValue { + font-size: 32px; + font-weight: 700; + color: var(--text-primary); + margin-bottom: 8px; +} + +.statLabel { + color: var(--text-secondary); + font-size: 14px; + display: flex; + align-items: center; + gap: 6px; +} + +.tabs { + display: flex; + gap: 32px; + border-bottom: 1px solid var(--glass-border); + margin-bottom: 40px; +} + +.tab { + padding: 16px 0; + color: var(--text-secondary); + font-weight: 600; + cursor: pointer; + position: relative; + transition: color 0.2s ease; +} + +.tab:hover { + color: var(--text-primary); +} + +.activeTab { + color: var(--text-primary); +} + +.activeTab::after { + content: ''; + position: absolute; + bottom: -1px; + left: 0; + right: 0; + height: 2px; + background: var(--accent-primary); +} + +.sectionTitle { + font-size: 24px; + font-weight: 700; + margin-bottom: 24px; + color: var(--text-primary); +} + +.activityGraph { + background: var(--bg-secondary); + border-radius: 16px; + padding: 24px; + border: 1px solid var(--glass-border); + height: 200px; + display: flex; + align-items: center; + justify-content: center; + color: var(--text-secondary); +} + +@media (max-width: 768px) { + .statsGrid { + grid-template-columns: repeat(2, 1fr); + } + + .userInfo { + flex-direction: column; + align-items: center; + bottom: -100px; + left: 50%; + transform: translateX(-50%); + text-align: center; + } + + .header { + margin-bottom: 120px; + } + + .tabs { + overflow-x: auto; + padding-bottom: 4px; + } + + .tab { + white-space: nowrap; + } +} + +/* --- Premium Circular Progress Ring Styles --- */ +.ringWrapper { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 12px; + padding: 12px; + background: rgba(255, 255, 255, 0.02); + border: 1px solid rgba(255, 255, 255, 0.05); + border-radius: 20px; + backdrop-filter: blur(10px); + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +.ringWrapper:hover { + background: rgba(255, 255, 255, 0.04); + border-color: rgba(0, 191, 191, 0.2); + transform: translateY(-2px); + box-shadow: 0 10px 30px -10px rgba(0, 191, 191, 0.15); +} + +.progressContainer { + position: relative; + width: 140px; + height: 140px; + display: flex; + align-items: center; + justify-content: center; +} + +.svgRing { + transform: rotate(-90deg); + transform-origin: 50% 50%; +} + +.circleBg { + fill: none; + stroke: rgba(255, 255, 255, 0.04); + stroke-width: 8; +} + +.circleProgress { + fill: none; + stroke-width: 8; + stroke-linecap: round; + transition: stroke-dashoffset 1.5s cubic-bezier(0.4, 0, 0.2, 1); + filter: drop-shadow(0 0 6px rgba(0, 191, 191, 0.4)); +} + +.ringWrapper:hover .circleProgress { + filter: drop-shadow(0 0 10px rgba(0, 191, 191, 0.6)) drop-shadow(0 0 20px rgba(139, 92, 246, 0.3)); +} + +.centerText { + position: absolute; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + width: 100%; + height: 100%; +} + +.percentText { + font-size: 26px; + font-weight: 800; + color: #ffffff; + font-family: var(--font-space), monospace; + background: linear-gradient(135deg, #00bfbf 30%, #8b5cf6 90%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + display: flex; + align-items: center; + justify-content: center; +} + +.lvlText { + font-size: 10px; + font-weight: 700; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.05em; + margin-top: 1px; +} + +.xpDetails { + font-size: 12px; + font-weight: 500; + color: var(--text-secondary); + font-family: var(--font-space), monospace; +} \ No newline at end of file diff --git a/src/components/profile/UserProfile.tsx b/src/components/profile/UserProfile.tsx index 41a22e6f..9a6845dd 100644 --- a/src/components/profile/UserProfile.tsx +++ b/src/components/profile/UserProfile.tsx @@ -32,6 +32,19 @@ export default function UserProfile() { }, [user, router]); const [isEditingPhoto, setIsEditingPhoto] = useState(false); + const [mountedProgress, setMountedProgress] = useState(0); + + const levelInfo = calculateLevel(user?.points || 0); + const targetProgress = levelInfo.progress; + + useEffect(() => { + if (user) { + const timer = setTimeout(() => { + setMountedProgress(targetProgress); + }, 100); + return () => clearTimeout(timer); + } + }, [user, targetProgress]); const [newPhotoURL, setNewPhotoURL] = useState(''); const [isSaving, setIsSaving] = useState(false); const [showPrivacyModal, setShowPrivacyModal] = useState(false); @@ -384,31 +397,105 @@ export default function UserProfile() { {/* Hero / Intro */}
-
+
-

Hi 👋, I'm {user.name}

- - {/* Level & Points Display */} -
- {calculateLevel(user.points || 0).currentLevel.name === 'Sanrakshak' ? ( - - - Sanrakshak - - ) : ( - - {calculateLevel(user.points || 0).currentLevel.name} - - )} - - {user.points || 0} Dev Points - -
+ +
+ {/* Left Content Column */} +
+

Hi 👋, I'm {user.name}

+ + {/* Level & Points Display */} +
+ {calculateLevel(user.points || 0).currentLevel.name === 'Sanrakshak' ? ( + + + Sanrakshak + + ) : ( + + {calculateLevel(user.points || 0).currentLevel.name} + + )} + + {user.points || 0} Dev Points + +
+ +

+ {user.bio || "Passionate developer building amazing things. Welcome to my profile!"} +

+
-

- {user.bio || "Passionate developer building amazing things. Welcome to my profile!"} -

+ {/* Right Progress Ring Column */} +
+
+
+ {/* Glowing SVG Filter and Gradient */} + + + + + + + + + {/* Background Track Circle */} + + + {/* Active Animated Progress Circle */} + + + + {/* Content inside the Ring */} +
+ {calculateLevel(user.points || 0).currentLevel.name === 'Sanrakshak' ? ( +
+ + MAX +
+ ) : ( + <> + + {Math.round(calculateLevel(user.points || 0).progress)}% + + + Progress + + + )} +
+
+ + {/* Sub-label under the Ring */} +
+

+ {calculateLevel(user.points || 0).currentLevel.name === 'Sanrakshak' ? 'Sanrakshak Rank' : `Level Progress`} +

+

+ {calculateLevel(user.points || 0).currentLevel.name === 'Sanrakshak' + ? `${(user.points || 0).toLocaleString()} XP` + : `${(user.points || 0).toLocaleString()} / ${(calculateLevel(user.points || 0).nextLevelPoints).toLocaleString()} XP` + } +

+
+
+
+
{/* Login Heatmap */} diff --git a/src/components/resources/QuizComponent.tsx b/src/components/resources/QuizComponent.tsx index 87c91ff6..8fef9fe5 100644 --- a/src/components/resources/QuizComponent.tsx +++ b/src/components/resources/QuizComponent.tsx @@ -40,9 +40,9 @@ export default function QuizComponent() { setShowResult(true); if (updatedScore === questions.length) { - addXp(350); + addXp(350, "Perfect Quiz Score"); } else if (updatedScore >= Math.ceil(questions.length * 0.7)) { - addXp(200); + addXp(200, "Quiz Completed"); } } };