@@ -10,7 +10,7 @@ import { Badge } from '@components/ui/badge';
1010import { Button } from '@components/ui/button' ;
1111import "../../../styles/code-block-node.css"
1212import { Avatar , AvatarFallback , AvatarImage } from '@components/ui/avatar' ;
13- import { ArrowLeftIcon , Calendar , Clock , ExternalLink , Globe , User } from 'lucide-react' ;
13+ import { ArrowLeftIcon , ArrowRightIcon , Calendar , Clock , ExternalLink , Globe , User } from 'lucide-react' ;
1414import BreadcrumbStructuredData from '@components/breadcrumb-structured-data' ;
1515import SoftwareApplicationStructuredData from '@components/data-structured/software-application' ;
1616import { MarkdownRenderer } from '@components/ui/markdown-renderer' ;
@@ -73,6 +73,7 @@ export async function generateStaticParams() {
7373export default async function ProjectDetail ( props : Params ) {
7474 const params = await props . params ;
7575 const project = getProjectBySlug ( params . slug ) ;
76+ const projects = getPublishedProjects ( ) ;
7677
7778 if ( ! project ) {
7879 return (
@@ -82,7 +83,7 @@ export default async function ProjectDetail(props: Params) {
8283 height = { 30 }
8384 x = { - 1 }
8485 y = { - 1 }
85- className = { '[ mask-image: linear-gradient(to_bottom_right,white,transparent,transparent)] ' }
86+ className = { 'mask-[ linear-gradient(to_bottom_right,white,transparent,transparent)] ' }
8687 />
8788
8889 < NavigationBar className = 'sticky' />
@@ -106,6 +107,9 @@ export default async function ProjectDetail(props: Params) {
106107 const createdAtValid = isValidDateValue ( project . createdAt ) ;
107108 const createdDate = createdAtValid ? new Date ( project . createdAt ) : null ;
108109 const screenshot = project . image ? [ project . image ] : [ ] ;
110+ const currentIndex = projects . findIndex ( ( item ) => item . slug === project . slug ) ;
111+ const previousProject = currentIndex > 0 ? projects [ currentIndex - 1 ] : null ;
112+ const nextProject = currentIndex >= 0 && currentIndex < projects . length - 1 ? projects [ currentIndex + 1 ] : null ;
109113
110114 return (
111115 < >
@@ -135,13 +139,13 @@ export default async function ProjectDetail(props: Params) {
135139 height = { 30 }
136140 x = { - 1 }
137141 y = { - 1 }
138- className = { '[ mask-image: linear-gradient(to_bottom_right,white,transparent,transparent)] ' }
142+ className = { 'mask-[ linear-gradient(to_bottom_right,white,transparent,transparent)] ' }
139143 />
140144 </ div >
141145
142146 < article className = 'max-w-5xl sm:px-4 relative mx-auto max-xs:pt-0 sm:mt-16 py-8' >
143147 { project . image && (
144- < div className = 'relative w-full sm:p-2 ring-1 rounded-3xl ring-foreground/10 h-full max-xs:max-h-96 md:h-[29rem] max-xs:rounded-none max-xs:rounded-b-4xl overflow-hidden' >
148+ < div className = 'relative w-full sm:p-2 ring-1 rounded-3xl ring-foreground/10 h-full max-xs:max-h-96 md:h-116 max-xs:rounded-none max-xs:rounded-b-4xl overflow-hidden' >
145149 < PostCoverImage src = { project . image } alt = { project . title } />
146150 </ div >
147151 ) }
@@ -153,7 +157,7 @@ export default async function ProjectDetail(props: Params) {
153157 </ Link >
154158 </ Button >
155159
156- < div className = 'flex justify-end max-sm:pr-3 items-center py-4 gap-2 flex-wrap' >
160+ < div className = 'flex justify-end items-center py-4 gap-2 flex-wrap' >
157161 { ( project . source ?? [ ] ) . map ( ( source ) => (
158162 < Button asChild key = { `${ source . type } -${ source . url } ` } className = 'mt-0 border' >
159163 < Link href = { source . url } target = '_blank' rel = 'noopener noreferrer' >
@@ -169,7 +173,7 @@ export default async function ProjectDetail(props: Params) {
169173 </ div >
170174 </ div >
171175
172- < div className = 'flex flex-wrap items-center mb-4 justify-between' >
176+ < div className = 'flex px-3 xs:px-0 gap-2 flex-wrap items-center mb-4 justify-between' >
173177 { ( project . languages ?. length || 0 ) > 0 && (
174178 < div className = 'flex w-fit justify-center rounded-full p-0.5 sm:p-1 ring-1 ring-foreground/10 gap-1 bg-background' >
175179 { ( project . languages ?? [ ] ) . map ( ( language ) => (
@@ -216,7 +220,7 @@ export default async function ProjectDetail(props: Params) {
216220
217221 < div className = 'max-sm:px-3 flex flex-col relative order-1 mb-4' >
218222 < h1 className = 'text-4xl md:text-5xl font-bold leading-tight' >
219- < span className = "text-left bg-background bg-clip-text bg-no-repeat text-transparent bg-gradient -to-r from-sky-500 via-teal-500 to-green-500 [text-shadow:0_0_rgba(0,0,0,0.1)]" > { project . title } </ span >
223+ < span className = "text-left bg-background bg-clip-text bg-no-repeat text-transparent bg-linear -to-r from-sky-500 via-teal-500 to-green-500 [text-shadow:0_0_rgba(0,0,0,0.1)]" > { project . title } </ span >
220224 </ h1 >
221225 < p className = 'text-base text-foreground/80 mt-3 leading-relaxed font-sans' > { project . description } </ p >
222226 </ div >
@@ -253,20 +257,28 @@ export default async function ProjectDetail(props: Params) {
253257 < MarkdownRenderer content = { project . content } />
254258 </ div >
255259
256- < div className = 'flex items-center mx-auto justify-between max-xs:px-3 mt-8' >
257- < div className = 'flex flex-wrap gap-2' >
258- { project . tags ?. map ( ( tag ) => (
259- < Badge key = { `${ project . slug } -${ tag } ` } variant = 'outline' >
260- #{ tag }
261- </ Badge >
262- ) ) }
260+ < div className = 'flex flex-col gap-3 max-xs:px-3 mt-10' >
261+ < div className = 'flex items-center mx-auto justify-between w-full gap-3' >
262+ { previousProject ? (
263+ < Button asChild >
264+ < Link href = { `/projects/${ previousProject . slug } ` } >
265+ < ArrowLeftIcon className = 'w-4 h-4 mr-2 shrink-0' />
266+ < span className = 'line-clamp-1 max-xs:hidden' > { previousProject . title } </ span >
267+ < span className = 'sm:hidden' > Prev</ span >
268+ </ Link >
269+ </ Button >
270+ ) : ( < div /> ) }
271+
272+ { nextProject ? (
273+ < Button asChild >
274+ < Link href = { `/projects/${ nextProject . slug } ` } >
275+ < span className = 'line-clamp-1 max-xs:hidden' > { nextProject . title } </ span >
276+ < span className = 'sm:hidden' > Next</ span >
277+ < ArrowRightIcon className = 'w-4 h-4 ml-2 shrink-0' />
278+ </ Link >
279+ </ Button >
280+ ) : ( < div /> ) }
263281 </ div >
264-
265- < Button asChild >
266- < Link href = '/projects' >
267- < ArrowLeftIcon className = 'w-4 h-4 mr-2' /> All Projects
268- </ Link >
269- </ Button >
270282 </ div >
271283 </ div >
272284
0 commit comments