tangled
alpha
login
or
join now
safwanyp.com
/
website
0
fork
atom
Code for my personal website
0
fork
atom
overview
issues
pulls
pipelines
feat: create pages for projects
Safwan Parker
2 years ago
a3d4939e
656d2fb3
+100
2 changed files
expand all
collapse all
unified
split
src
pages
projects
[...slug].astro
index.astro
+68
src/pages/projects/[...slug].astro
···
1
1
+
---
2
2
+
import { type CollectionEntry, getCollection } from 'astro:content';
3
3
+
import Layout from '@/layouts/Layout.astro';
4
4
+
import Container from '@/components/Container.astro';
5
5
+
import DateComponent from '@/components/Date.astro';
6
6
+
import { readingTime } from '@/utils';
7
7
+
import Back from '@/components/Back.astro';
8
8
+
import Link from '@/components/Link.astro';
9
9
+
10
10
+
export async function getStaticPaths() {
11
11
+
const projects = (await getCollection('projects'))
12
12
+
.filter((post) => !post.data.draft)
13
13
+
.sort(
14
14
+
(a, b) =>
15
15
+
new Date(b.data.date).valueOf() - new Date(a.data.date).valueOf()
16
16
+
);
17
17
+
return projects.map((project) => ({
18
18
+
params: { slug: project.slug },
19
19
+
props: project
20
20
+
}));
21
21
+
}
22
22
+
type Props = CollectionEntry<'projects'>;
23
23
+
24
24
+
const project = Astro.props;
25
25
+
const { Content } = await project.render();
26
26
+
---
27
27
+
28
28
+
<Layout title={project.data.title} description={project.data.description}>
29
29
+
<Container>
30
30
+
<div class='animate'>
31
31
+
<Back href='/projects'> Back to projects </Back>
32
32
+
</div>
33
33
+
<div class='space-y-1 my-10'>
34
34
+
<div class='animate flex items-center gap-1.5'>
35
35
+
<div class='font-base text-sm'>
36
36
+
<DateComponent date={new Date(project.data.date)} />
37
37
+
</div>
38
38
+
•
39
39
+
<div class='font-base text-sm'>
40
40
+
{readingTime(project.body)}
41
41
+
</div>
42
42
+
</div>
43
43
+
<div class='animate text-2xl font-semibold text-black dark:text-white'>
44
44
+
{project.data.title}
45
45
+
</div>
46
46
+
{
47
47
+
(project.data.demoURL || project.data.repoURL) && (
48
48
+
<nav class='animate flex gap-1'>
49
49
+
{project.data.demoURL && (
50
50
+
<Link href={project.data.demoURL} external>
51
51
+
demo
52
52
+
</Link>
53
53
+
)}
54
54
+
{project.data.demoURL && project.data.repoURL && <span>/</span>}
55
55
+
{project.data.repoURL && (
56
56
+
<Link href={project.data.repoURL} external>
57
57
+
repo
58
58
+
</Link>
59
59
+
)}
60
60
+
</nav>
61
61
+
)
62
62
+
}
63
63
+
</div>
64
64
+
<article class='animate'>
65
65
+
<Content />
66
66
+
</article>
67
67
+
</Container>
68
68
+
</Layout>
+32
src/pages/projects/index.astro
···
1
1
+
---
2
2
+
import { getCollection } from 'astro:content';
3
3
+
import Layout from '@/layouts/Layout.astro';
4
4
+
import Container from '@/components/Container.astro';
5
5
+
import NavCard from '@/components/NavCard.astro';
6
6
+
import { PROJECTS } from '@/config';
7
7
+
8
8
+
const projects = (await getCollection('projects'))
9
9
+
.filter((project) => !project.data.draft)
10
10
+
.sort(
11
11
+
(a, b) => new Date(b.data.date).valueOf() - new Date(a.data.date).valueOf()
12
12
+
);
13
13
+
---
14
14
+
15
15
+
<Layout title={PROJECTS.TITLE} description={PROJECTS.DESCRIPTION}>
16
16
+
<Container>
17
17
+
<div class='space-y-10'>
18
18
+
<div class='animate font-semibold text-black dark:text-white'>
19
19
+
Projects
20
20
+
</div>
21
21
+
<ul class='animate flex flex-col gap-4'>
22
22
+
{
23
23
+
projects.map((project) => (
24
24
+
<li>
25
25
+
<NavCard entry={project} />
26
26
+
</li>
27
27
+
))
28
28
+
}
29
29
+
</ul>
30
30
+
</div>
31
31
+
</Container>
32
32
+
</Layout>