11import { ImageCarousel } from '@/components/organisms/image-carousel' ;
22import { TechStackDiagram } from '@/components/organisms/tech-stack-diagram' ;
3- import { Badge } from '@/components/ui/badge' ;
43import { Project } from '@/lib/projects' ;
54import { ArrowLeft , Briefcase , ExternalLink , Github } from 'lucide-react' ;
65import Link from 'next/link' ;
@@ -25,13 +24,13 @@ export default async function ProjectDetailsView({
2524 if ( level === 1 ) {
2625 return (
2726 < h2 key = { index } className = "mt-8 text-2xl font-bold first:mt-0" >
28- { text }
27+ { renderInlineFormatting ( text ) }
2928 </ h2 >
3029 ) ;
3130 } else {
3231 return (
3332 < h3 key = { index } className = "mt-6 text-xl font-semibold first:mt-0" >
34- { text }
33+ { renderInlineFormatting ( text ) }
3534 </ h3 >
3635 ) ;
3736 }
@@ -45,7 +44,7 @@ export default async function ProjectDetailsView({
4544 key = { index }
4645 className = "mt-6 text-lg font-bold tracking-wide uppercase first:mt-0"
4746 >
48- { text }
47+ { renderInlineFormatting ( text ) }
4948 </ h3 >
5049 ) ;
5150 }
@@ -56,7 +55,7 @@ export default async function ProjectDetailsView({
5655 return (
5756 < li
5857 key = { index }
59- className = "text-muted- foreground ml-6 text-base leading-relaxed"
58+ className = "text-foreground/85 ml-6 text-base leading-relaxed"
6059 >
6160 { renderInlineFormatting ( text ) }
6261 </ li >
@@ -65,37 +64,57 @@ export default async function ProjectDetailsView({
6564
6665 // Regular paragraph with inline formatting
6766 return (
68- < p
69- key = { index }
70- className = "text-muted-foreground text-base leading-relaxed"
71- >
67+ < p key = { index } className = "text-foreground/85 text-base leading-relaxed" >
7268 { renderInlineFormatting ( paragraph ) }
7369 </ p >
7470 ) ;
7571 }
7672
77- // Helper function to render inline formatting (bold, italic, etc. )
73+ // Helper function to render inline formatting (links and styled text )
7874 function renderInlineFormatting ( text : string ) {
79- // Split by ** for bold text
80- const parts = text . split ( / ( \* \* .* ?\* \* ) / g) ;
75+ // First, split by markdown links [text](url)
76+ const linkPattern = / ( \[ .* ?\] \( .* ?\) ) / g;
77+ const linkParts = text . split ( linkPattern ) ;
78+
79+ return linkParts . map ( ( linkPart , linkIndex ) => {
80+ // Check if this part is a markdown link
81+ const linkMatch = linkPart . match ( / \[ ( .* ?) \] \( ( .* ?) \) / ) ;
8182
82- return parts . map ( ( part , i ) => {
83- // Bold text wrapped in **
84- if ( part . startsWith ( '**' ) && part . endsWith ( '**' ) ) {
85- const content = part . slice ( 2 , - 2 ) ;
83+ if ( linkMatch ) {
84+ const [ , linkText , url ] = linkMatch ;
8685 return (
87- < strong key = { i } className = "text-foreground font-semibold" >
88- { content }
89- </ strong >
86+ < Link
87+ key = { linkIndex }
88+ href = { url }
89+ target = "_blank"
90+ rel = "noopener noreferrer"
91+ className = "text-primary font-medium hover:underline"
92+ >
93+ { linkText }
94+ </ Link >
9095 ) ;
9196 }
9297
93- // Check for HTML strong tags
94- if ( part . includes ( '<strong>' ) || part . includes ( '<em>' ) ) {
95- return < span key = { i } dangerouslySetInnerHTML = { { __html : part } } /> ;
96- }
97-
98- return part ;
98+ // Process remaining text for styled text {text|className}
99+ const stylePattern = / ( \{ .* ?\| .* ?\} ) / g;
100+ const styleParts = linkPart . split ( stylePattern ) ;
101+
102+ return styleParts . map ( ( stylePart , styleIndex ) => {
103+ // Check if this part is styled text
104+ const styleMatch = stylePart . match ( / \{ ( .* ?) \| ( .* ?) \} / ) ;
105+
106+ if ( styleMatch ) {
107+ const [ , styledText , className ] = styleMatch ;
108+ return (
109+ < span key = { `${ linkIndex } -${ styleIndex } ` } className = { className } >
110+ { styledText }
111+ </ span >
112+ ) ;
113+ }
114+
115+ // Return plain text
116+ return stylePart ;
117+ } ) ;
99118 } ) ;
100119 }
101120
@@ -108,7 +127,7 @@ export default async function ProjectDetailsView({
108127 className = "text-muted-foreground hover:text-primary inline-flex items-center gap-2 transition-colors"
109128 >
110129 < ArrowLeft size = { 20 } />
111- < span > Back to Projects</ span >
130+ < span > { ' Back to Projects' } </ span >
112131 </ Link >
113132 < h1 className = "text-4xl font-bold sm:text-5xl md:text-6xl" >
114133 { project . title }
@@ -134,61 +153,71 @@ export default async function ProjectDetailsView({
134153 { /* Project Details */ }
135154 < div className = "animate-fade-in-delay-2 space-y-8" >
136155 { /* Category Badges and Links */ }
137- < div className = "flex flex-wrap items-center gap-3" >
138- { project . domains . map ( ( domain ) => (
156+ { project . githubUrl && project . liveUrl && (
157+ < div className = "flex flex-wrap items-center gap-3" >
158+ { /* {project.domains.map((domain) => (
139159 <Badge key={domain} variant="secondary" className="text-sm">
140160 {domain}
141161 </Badge>
162+ ))} */ }
163+ { project . githubUrl && (
164+ < a
165+ href = { project . githubUrl }
166+ target = "_blank"
167+ rel = "noopener noreferrer"
168+ className = "text-muted-foreground hover:text-primary p-2 transition-colors"
169+ aria-label = "View on GitHub"
170+ >
171+ < Github size = { 20 } />
172+ </ a >
173+ ) }
174+ { project . liveUrl && (
175+ < a
176+ href = { project . liveUrl }
177+ target = "_blank"
178+ rel = "noopener noreferrer"
179+ className = "text-muted-foreground hover:text-primary p-2 transition-colors"
180+ aria-label = "View live site"
181+ >
182+ < ExternalLink size = { 20 } />
183+ </ a >
184+ ) }
185+ </ div >
186+ ) }
187+
188+ { /* Achievements */ }
189+ < div className = "space-y-4" >
190+ { project . achievements . map ( ( paragraph , index ) => (
191+ < p key = { index } className = "text-base leading-relaxed" >
192+ { renderInlineFormatting ( paragraph ) }
193+ </ p >
142194 ) ) }
143- { project . githubUrl && (
144- < a
145- href = { project . githubUrl }
146- target = "_blank"
147- rel = "noopener noreferrer"
148- className = "text-muted-foreground hover:text-primary p-2 transition-colors"
149- aria-label = "View on GitHub"
150- >
151- < Github size = { 20 } />
152- </ a >
153- ) }
154- { project . liveUrl && (
155- < a
156- href = { project . liveUrl }
157- target = "_blank"
158- rel = "noopener noreferrer"
159- className = "text-muted-foreground hover:text-primary p-2 transition-colors"
160- aria-label = "View live site"
161- >
162- < ExternalLink size = { 20 } />
163- </ a >
164- ) }
165195 </ div >
166196
167197 { /* Full Description */ }
168198 < div className = "space-y-4" >
199+ < h2 className = "mt-8 text-2xl font-bold first:mt-0" >
200+ { 'What is this project about?' }
201+ </ h2 >
169202 { project . fullDescription . map ( ( paragraph , index ) =>
170203 renderFormattedParagraph ( paragraph , index )
171204 ) }
172205 </ div >
173206
207+ { /* Lessons Learned */ }
208+ < div className = "space-y-4" >
209+ { project . lessons . map ( ( paragraph , index ) =>
210+ renderFormattedParagraph ( paragraph , index )
211+ ) }
212+ </ div >
213+
174214 { /* Tech Stack */ }
175215 < div className = "space-y-1" >
176216 < h2 className = "flex items-center gap-2 text-xl font-bold" >
177217 < span > 🛠️</ span >
178218 < span > Tech Stack</ span >
179219 </ h2 >
180220 < TechStackDiagram technologies = { project . technologies } />
181- { /* Old Tech Stack Implementation - Commented Out */ }
182- { /* <div className="flex flex-wrap gap-3">
183- {project.technologies.map((tech) => (
184- <div
185- key={tech}
186- className="bg-card border-border hover:border-primary flex items-center gap-2 rounded-lg border px-4 py-2 transition-colors"
187- >
188- <span className="text-sm font-medium">{tech}</span>
189- </div>
190- ))}
191- </div> */ }
192221 </ div >
193222 </ div >
194223 </ div >
0 commit comments