/ src / pages / projects / [project].astro
[project].astro
  1  ---
  2  import "../../styles/article.css";
  3  
  4  import type { CollectionEntry } from "astro:content";
  5  import { getCollection, render } from "astro:content";
  6  import type { GetStaticPaths } from "astro";
  7  import Card from "../../components/Card.astro";
  8  import Icon from "../../components/Icon.astro";
  9  import ImageGlow from "../../components/ImageGlow.astro";
 10  import Layout from "../../layouts/Layout.astro";
 11  
 12  interface Props {
 13  	project: CollectionEntry<"projects">;
 14  }
 15  
 16  const { project } = Astro.props;
 17  
 18  export const getStaticPaths = (async () => {
 19  	const projects = await getCollection("projects");
 20  
 21  	return projects.map((project) => ({
 22  		params: { project: project.id },
 23  		props: { project },
 24  	}));
 25  }) satisfies GetStaticPaths;
 26  
 27  const { Content } = await render(project);
 28  ---
 29  
 30  <Layout
 31  	title={project.data.title}
 32  	description={project.data.description}
 33  	image={project.data.image}
 34  	article={{
 35  		createdAt: project.data.date,
 36  	}}
 37  >
 38  	<div class="left" slot="left">
 39  		<Card class="toc-card">
 40  			<h2 class="no-mt">Info</h2>
 41  			<ul class="overview-list">
 42  				{
 43  					project.data.info.map((info) => {
 44  						const Tag = info.link ? "a" : "div";
 45  						return (
 46  							<li>
 47  								<Tag href={info.link} class="project-info-item">
 48  									<Icon
 49  										type={info.icon.type}
 50  										name={info.icon.name as any}
 51  										width={24}
 52  										height={24}
 53  										class="glow-icon"
 54  									/>
 55  									<span>{info.text}</span>
 56  								</Tag>
 57  							</li>
 58  						);
 59  					})
 60  				}
 61  			</ul>
 62  		</Card>
 63  	</div>
 64  	<article slot="right" data-pagefind-body>
 65  		<Card>
 66  			<div class="article-header" id="_top" data-pagefind-ignore>
 67  				{
 68  					project.data.image && (
 69  						<ImageGlow
 70  							quality={100}
 71  							class="article-image"
 72  							src={project.data.image}
 73  							alt={project.data.title}
 74  						/>
 75  					)
 76  				}
 77  				<div class="header">
 78  					<div>
 79  						<h1 class="no-mt article-h1">{project.data.title}</h1>
 80  					</div>
 81  					<div class="article-info">
 82  						<span>{project.data.date.toLocaleDateString()}</span>
 83  					</div>
 84  				</div>
 85  			</div>
 86  			<Content />
 87  			<hr class="end-of-article" />
 88  			<a href="/projects" class="block-link" data-pagefind-ignore
 89  				>← Back to projects</a
 90  			>
 91  		</Card>
 92  	</article>
 93  </Layout>
 94  <style>
 95  	.project-info-item {
 96  		display: flex;
 97  		align-items: center;
 98  		gap: 1rem;
 99  	}
100  </style>