1- ```vue
21<script setup lang="ts">
3- import { ref , computed , watch , nextTick } from " vue" ;
2+ import { ref , watch , nextTick } from " vue" ;
43import data from " ~/assets/data.json" ;
54
6-
7- // Components
85import Header from " ~/components/Header.vue" ;
96import ProfileCard from " ~/components/ProfileCard.vue" ;
107import SkillsCard from " ~/components/SkillsCard.vue" ;
8+ import StatsGrid from " ~/components/StatsGrid.vue" ;
119import ProjectList from " ~/components/ProjectList.vue" ;
1210import ExperienceList from " ~/components/ExperienceList.vue" ;
1311import MobileNav from " ~/components/MobileNav.vue" ;
@@ -62,17 +60,15 @@ watch(activeTab, async () => {
6260
6361 <!-- Mobile View -->
6462 <div class =" lg:hidden flex-1 min-h-0 flex flex-col" >
65- <Transition name =" fade" mode =" out-in" >
66- <div ref =" scrollContainer" class =" flex-1 overflow-y-auto scrollbar-hide" >
67- <!-- Header -->
68- <div
69- class =" sticky top-0 z-10 border-b border-slate-200 dark:border-slate-800 bg-white/95 dark:bg-black/95 backdrop-blur-xl px-4 py-2 flex items-center justify-between" >
70- <Logo class =" h-6 w-auto text-slate-900 dark:text-white" />
71- <ThemeToggle />
72- </div >
63+ <div ref =" scrollContainer" class =" flex-1 overflow-y-auto scrollbar-hide" >
64+ <div
65+ class =" sticky top-0 z-10 border-b border-slate-200 dark:border-slate-800 bg-white/95 dark:bg-black/95 backdrop-blur-xl px-4 py-2 flex items-center justify-between" >
66+ <Logo class =" h-6 w-auto text-slate-900 dark:text-white" />
67+ <ThemeToggle />
68+ </div >
7369
74- < div v-if = " activeTab === 'profile' " class = " h-full flex flex-col " >
75- <!-- Content -- >
70+ < Transition name = " fade " mode = " out-in " >
71+ < div v-if = " activeTab === 'profile' " key = " profile " class = " h-full flex flex-col " >
7672 <div class =" p-4 space-y-3 pb-32" >
7773 <ProfileCard :profile =" profile" />
7874
@@ -81,64 +77,38 @@ watch(activeTab, async () => {
8177 style =" animation-delay : 300ms " >
8278 <div class =" flex items-center gap-2 mb-4" >
8379 <Icon name =" lucide:link" class =" w-4 h-4 text-emerald-500 dark:text-emerald-400" />
84- <h2 class =" font-bold font-mono text-sm text-slate-900 dark:text-white" >
85- Connect
86- </h2 >
80+ <h2 class =" font-bold font-mono text-sm text-slate-900 dark:text-white" >Connect</h2 >
8781 </div >
8882 <SocialLinks :links =" social_links" mode =" grid" />
8983 </div >
9084
91- <div class =" grid grid-cols-3 gap-3 animate-slide-up" style =" animation-delay : 400ms " >
92- <div
93- class =" border border-slate-200 dark:border-slate-800 rounded-xl p-4 bg-slate-50 dark:bg-slate-900/50 backdrop-blur-sm text-center flex flex-col items-center justify-center gap-1 group hover:border-emerald-500/30 dark:hover:border-emerald-400/30 transition-colors" >
94- <Icon name =" lucide:code-2" class =" w-4 h-4 text-emerald-500 dark:text-emerald-400 mb-1" />
95- <div class =" text-xl font-bold text-slate-900 dark:text-white" >
96- {{ projects.length }}
97- </div >
98- <div class =" text-[10px] font-mono text-slate-500 uppercase tracking-wide" >Projects</div >
99- </div >
100- <div
101- class =" border border-slate-200 dark:border-slate-800 rounded-xl p-4 bg-slate-50 dark:bg-slate-900/50 backdrop-blur-sm text-center flex flex-col items-center justify-center gap-1 group hover:border-emerald-500/30 dark:hover:border-emerald-400/30 transition-colors" >
102- <Icon name =" lucide:terminal" class =" w-4 h-4 text-emerald-500 dark:text-emerald-400 mb-1" />
103- <div class =" text-xl font-bold text-slate-900 dark:text-white" >
104- {{ skills.length }}
105- </div >
106- <div class =" text-[10px] font-mono text-slate-500 uppercase tracking-wide" >Skills</div >
107- </div >
108- <div
109- class =" border border-slate-200 dark:border-slate-800 rounded-xl p-4 bg-slate-50 dark:bg-slate-900/50 backdrop-blur-sm text-center flex flex-col items-center justify-center gap-1 group hover:border-emerald-500/30 dark:hover:border-emerald-400/30 transition-colors" >
110- <Icon name =" lucide:briefcase" class =" w-4 h-4 text-emerald-500 dark:text-emerald-400 mb-1" />
111- <div class =" text-xl font-bold text-slate-900 dark:text-white" >
112- {{ experience.length }}
113- </div >
114- <div class =" text-[10px] font-mono text-slate-500 uppercase tracking-wide" >Roles</div >
115- </div >
116- </div >
85+ <StatsGrid
86+ :project-count =" projects.length"
87+ :skill-count =" skills.length"
88+ :role-count =" experience.length"
89+ />
11790 </div >
11891 </div >
11992
120- <div v-else-if =" activeTab === 'projects'" >
121- <!-- Content -->
93+ <div v-else-if =" activeTab === 'projects'" key =" projects" >
12294 <div class =" py-4 min-h-0 pb-32" >
12395 <ProjectList :projects =" projects" />
12496 </div >
12597 </div >
12698
127- <div v-else-if =" activeTab === 'skills'" >
128- <!-- Content -->
99+ <div v-else-if =" activeTab === 'skills'" key =" skills" >
129100 <div class =" py-4 min-h-0 pb-32" >
130101 <SkillsCard :skills =" skills" />
131102 </div >
132103 </div >
133104
134- <div v-else-if =" activeTab === 'experience'" >
135- <!-- Content -->
105+ <div v-else-if =" activeTab === 'experience'" key =" experience" >
136106 <div class =" py-4 min-h-0 pb-32" >
137107 <ExperienceList :experience =" experience" />
138108 </div >
139109 </div >
140- </div >
141- </Transition >
110+ </Transition >
111+ </div >
142112 </div >
143113
144114 <!-- Mobile Navigation -->
0 commit comments