11import { Link , Outlet , useLocation } from "react-router-dom" ;
22import {
3+ BookOpen ,
4+ ExternalLink ,
5+ FileCode2 ,
36 Github ,
47 Menu ,
8+ User ,
59 X ,
610 Youtube ,
7- ExternalLink ,
811} from "lucide-react" ;
912import { useState } from "react" ;
1013import ScrollRestoration from "@/components/ScrollRestoration" ;
@@ -14,9 +17,14 @@ import type { SiteData } from "@/types";
1417const data = siteData as SiteData ;
1518
1619const NAV = [
17- { to : "/" , label : "Sessions" } ,
18- { to : "/youtube" , label : "YouTube" } ,
19- ] ;
20+ { to : "/" , label : "Sessions" , icon : BookOpen } ,
21+ { to : "/youtube" , label : "YouTube" , icon : Youtube } ,
22+ ] as const ;
23+
24+ const EXTERNAL_LINKS = [
25+ { href : data . config . links . portfolio , label : "About Me" , icon : User } ,
26+ { href : data . config . links . templates , label : "Templates" , icon : FileCode2 } ,
27+ ] as const ;
2028
2129export default function Layout ( ) {
2230 const [ mobileOpen , setMobileOpen ] = useState ( false ) ;
@@ -47,28 +55,33 @@ export default function Layout() {
4755 </ Link >
4856
4957 < nav className = "hidden items-center gap-1 md:flex" >
50- { NAV . map ( ( { to, label } ) => (
58+ { NAV . map ( ( { to, label, icon : Icon } ) => (
5159 < Link
5260 key = { to }
5361 to = { to }
54- className = { `rounded-lg px-4 py-2 text-sm font-medium transition-colors ${
62+ className = { `inline-flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors ${
5563 pathname === to
5664 ? "bg-accent/20 text-accent-light"
5765 : "text-slate-300 hover:bg-white/5 hover:text-white"
5866 } `}
5967 >
68+ < Icon className = "h-4 w-4" />
6069 { label }
6170 </ Link >
6271 ) ) }
63- < a
64- href = { data . config . links . templates }
65- target = "_blank"
66- rel = "noopener noreferrer"
67- className = "ml-2 btn-ghost !py-2 !text-xs"
68- >
69- Templates
70- < ExternalLink className = "h-3.5 w-3.5" />
71- </ a >
72+ { EXTERNAL_LINKS . map ( ( { href, label, icon : Icon } ) => (
73+ < a
74+ key = { href }
75+ href = { href }
76+ target = "_blank"
77+ rel = "noopener noreferrer"
78+ className = "ml-1 inline-flex items-center gap-2 btn-ghost !py-2 !text-xs"
79+ >
80+ < Icon className = "h-3.5 w-3.5" />
81+ { label }
82+ < ExternalLink className = "h-3 w-3 opacity-60" />
83+ </ a >
84+ ) ) }
7285 </ nav >
7386
7487 < button
@@ -83,16 +96,30 @@ export default function Layout() {
8396
8497 { mobileOpen && (
8598 < nav className = "border-t border-white/5 px-4 py-4 md:hidden" >
86- { NAV . map ( ( { to, label } ) => (
99+ { NAV . map ( ( { to, label, icon : Icon } ) => (
87100 < Link
88101 key = { to }
89102 to = { to }
90103 onClick = { ( ) => setMobileOpen ( false ) }
91- className = "block rounded-lg px-4 py-3 text-sm font-medium text-slate-200 hover:bg-white/5"
104+ className = "flex items-center gap-3 rounded-lg px-4 py-3 text-sm font-medium text-slate-200 hover:bg-white/5"
92105 >
106+ < Icon className = "h-4 w-4 text-slate-400" />
93107 { label }
94108 </ Link >
95109 ) ) }
110+ { EXTERNAL_LINKS . map ( ( { href, label, icon : Icon } ) => (
111+ < a
112+ key = { href }
113+ href = { href }
114+ target = "_blank"
115+ rel = "noopener noreferrer"
116+ onClick = { ( ) => setMobileOpen ( false ) }
117+ className = "flex items-center gap-3 rounded-lg px-4 py-3 text-sm font-medium text-slate-200 hover:bg-white/5"
118+ >
119+ < Icon className = "h-4 w-4 text-slate-400" />
120+ { label }
121+ </ a >
122+ ) ) }
96123 </ nav >
97124 ) }
98125 </ header >
@@ -111,40 +138,64 @@ export default function Layout() {
111138 < p className = "mt-2 text-sm text-slate-400" >
112139 { data . config . description }
113140 </ p >
141+ < a
142+ href = { data . config . links . portfolio }
143+ target = "_blank"
144+ rel = "noopener noreferrer"
145+ className = "mt-4 inline-flex items-center gap-2 text-sm font-medium text-accent-light transition-colors hover:text-white"
146+ >
147+ < User className = "h-4 w-4" />
148+ View my portfolio
149+ < ExternalLink className = "h-3.5 w-3.5 opacity-70" />
150+ </ a >
114151 </ div >
115152 < div >
116153 < h4 className = "text-sm font-semibold uppercase tracking-wider text-slate-500" >
117154 Resources
118155 </ h4 >
119156 < ul className = "mt-3 space-y-2 text-sm" >
120- < FooterLink href = { data . config . links . juniorSheet } label = "Junior Sheet" />
121- < FooterLink href = { data . config . links . assiutSheet } label = "Assiut Materials" />
122- < FooterLink href = { data . config . links . arabicCpChannel } label = "Arabic CP Channel" />
157+ < FooterLink
158+ href = { data . config . links . templates }
159+ label = "CP Templates"
160+ icon = { FileCode2 }
161+ />
162+ < FooterLink
163+ href = { data . config . links . juniorSheet }
164+ label = "Junior Sheet"
165+ />
166+ < FooterLink
167+ href = { data . config . links . assiutSheet }
168+ label = "Assiut Materials"
169+ />
170+ < FooterLink
171+ href = { data . config . links . arabicCpChannel }
172+ label = "Arabic CP Channel"
173+ />
123174 </ ul >
124175 </ div >
125176 < div >
126177 < h4 className = "text-sm font-semibold uppercase tracking-wider text-slate-500" >
127178 Connect
128179 </ h4 >
129- < div className = "mt-3 flex gap-3" >
130- < a
180+ < div className = "mt-3 flex flex-wrap gap-3" >
181+ < SocialLink
182+ href = { data . config . links . portfolio }
183+ label = "Portfolio"
184+ icon = { User }
185+ className = "text-accent-light"
186+ />
187+ < SocialLink
131188 href = { data . config . youtubeChannel }
132- target = "_blank"
133- rel = "noopener noreferrer"
134- className = "glass-hover rounded-xl p-3 text-red-400"
135- aria-label = "YouTube"
136- >
137- < Youtube className = "h-5 w-5" />
138- </ a >
139- < a
189+ label = "YouTube"
190+ icon = { Youtube }
191+ className = "text-red-400"
192+ />
193+ < SocialLink
140194 href = { data . config . links . github }
141- target = "_blank"
142- rel = "noopener noreferrer"
143- className = "glass-hover rounded-xl p-3 text-slate-300"
144- aria-label = "GitHub"
145- >
146- < Github className = "h-5 w-5" />
147- </ a >
195+ label = "GitHub"
196+ icon = { Github }
197+ className = "text-slate-300"
198+ />
148199 </ div >
149200 </ div >
150201 </ div >
@@ -163,17 +214,51 @@ export default function Layout() {
163214 ) ;
164215}
165216
166- function FooterLink ( { href, label } : { href : string ; label : string } ) {
217+ function FooterLink ( {
218+ href,
219+ label,
220+ icon : Icon ,
221+ } : {
222+ href : string ;
223+ label : string ;
224+ icon ?: typeof User ;
225+ } ) {
167226 return (
168227 < li >
169228 < a
170229 href = { href }
171230 target = "_blank"
172231 rel = "noopener noreferrer"
173- className = "text-slate-400 transition-colors hover:text-accent-light"
232+ className = "inline-flex items-center gap-2 text-slate-400 transition-colors hover:text-accent-light"
174233 >
234+ { Icon && < Icon className = "h-3.5 w-3.5 shrink-0" /> }
175235 { label }
176236 </ a >
177237 </ li >
178238 ) ;
179239}
240+
241+ function SocialLink ( {
242+ href,
243+ label,
244+ icon : Icon ,
245+ className,
246+ } : {
247+ href : string ;
248+ label : string ;
249+ icon : typeof User ;
250+ className ?: string ;
251+ } ) {
252+ return (
253+ < a
254+ href = { href }
255+ target = "_blank"
256+ rel = "noopener noreferrer"
257+ className = { `glass-hover rounded-xl p-3 ${ className ?? "text-slate-300" } ` }
258+ aria-label = { label }
259+ title = { label }
260+ >
261+ < Icon className = "h-5 w-5" />
262+ </ a >
263+ ) ;
264+ }
0 commit comments