Next and previous buttons for posts and projects

Sort connections by date published
Move some styling to SCSS files
This commit is contained in:
Michał 2024-05-24 14:35:56 +01:00
parent c843050c8f
commit e9d1191ec1
11 changed files with 134 additions and 96 deletions

View file

@ -3,7 +3,7 @@ interface Props {
post: any,
}
const { post } = Astro.props;
const { post, prev, next, base } = Astro.props;
const { Content } = await post.render();
---
@ -12,7 +12,7 @@ const { Content } = await post.render();
<h1>{post.data.title}</h1>
<p>{post.data.description}</p>
<ul id="tags">
<ul id="tags" class="pill-list">
{post.data.tags.map((item: string) => ( <li class="pill">#{item}</li> ))}
</ul>
@ -25,29 +25,16 @@ const { Content } = await post.render();
<hr>
<ul id="controls">
<li><a class="button" href="/">Prev</a></li>
<li><a class="button" href="/">Next</a></li>
<li>{prev && <a class="button" href=`${base}/${prev.slug}` id="prev">{prev.data.title}</a>}</li>
<li>{next && <a class="button" href=`${base}/${next.slug}` id="next">{next?.data.title}</a>}</li>
</ul>
<style is:global lang="scss">
@import "../styles/vars";
#home {
margin-bottom: 32px;
}
#tags {
padding-top: 16px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 8px;
}
#markdown {
flex-grow: 1;
}
#home { margin-bottom: 32px; }
#tags { padding-top: 16px; }
#markdown { flex-grow: 1; }
#controls {
display: flex;

View file

@ -1,6 +1,5 @@
---
import { getCollection } from 'astro:content';
import { getPosts} from "../utils";
import Layout from "../layouts/Layout.astro";
import Card from "../components/Card.astro";
import Music from "../components/Music.astro";
@ -8,8 +7,8 @@ import Music from "../components/Music.astro";
const tools = ["Proxmox", "JetBrain IDEs", "Docker", "Linux", "SQLite", "Postgres", "MySQL"];
const languages = ["Go", "Python", "HTML", "CSS", "Sass", "TypeScript", "JavaScript", "Scratch", "PHP", "SQL", "Bash"];
const frameworks = ["Gin", "Echo", "Flask", "Svelte", "Astro", "raylib"];
const projects = await getCollection('projects');
const posts = await getCollection('posts');
const projects = await getPosts("projects");
const posts = await getPosts("posts");
---
<Layout title="Leggy Land" src="/banner-alt.webp" alt="Temporary Banner">
@ -67,7 +66,7 @@ const posts = await getCollection('posts');
<section>
<h2>Projects</h2>
<ul class="project-list">
{projects.map(project => (
{projects.slice(0, 2).map(project => (
<Card
href=`/projects/${project.slug}`
title={project.data.title}
@ -75,13 +74,13 @@ const posts = await getCollection('posts');
/>
))}
</ul>
<a class="button" id="see-all-projects" href="/projects">See Projects</a>
<a class="button" id="see-all-projects" href="/projects">All Projects</a>
</section>
<section>
<h2>Recent Posts</h2>
<ul class="project-list">
{posts.map(project => (
{posts.slice(0, 2).map(project => (
<Card
href=`/posts/${project.slug}`
title={project.data.title}
@ -89,31 +88,13 @@ const posts = await getCollection('posts');
/>
))}
</ul>
<a class="button" id="see-all-posts" href="/posts">See Posts</a>
<a class="button" id="see-all-posts" href="/posts">All Posts</a>
</section>
</Layout>
<style lang="scss">
@import "../styles/vars.scss";
.pill-list {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 8px;
> li {
list-style: none;
}
}
.project-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(30ch, 1fr));
gap: 16px;
padding: 0;
}
#see-all-projects,
#see-all-posts {
margin-top: 16px;

View file

@ -14,7 +14,5 @@ import Layout from "../layouts/Layout.astro";
</Layout>
<style lang="scss">
#home {
margin-bottom: 32px;
}
#home { margin-bottom: 32px; }
</style>

View file

@ -1,22 +1,24 @@
---
import { getCollection } from "astro:content";
import { getPosts } from "../../utils";
import Layout from "../../layouts/Layout.astro";
import Markdown from "../../layouts/Markdown.astro";
export async function getStaticPaths() {
const collection = await getCollection('posts')
return collection.map(post => {
return {
params: { slug: post.slug },
props: { post: post },
};
});
const collection = await getPosts("posts");
return collection.map((post, i) => ({
params: { slug: post.slug },
props: {
post: post,
prev: i > 0 ? collection[i - 1] : undefined,
next: i < collection.length - 1 ? collection[i + 1] : undefined
}
}));
}
const { post } = Astro.props;
const { post, prev, next } = Astro.props;
---
<Layout title="Leggy Land" src={post.data.image.url} alt={post.data.image.alt}>
<Markdown post={post} />
<Markdown {post} {prev} {next} base="/posts" />
</Layout>

View file

@ -11,10 +11,15 @@ const posts = await getCollection('posts');
<a class="button" id="home" href="/">Home</a>
<h1>All Posts</h1>
<p>Some regrettable, some not so bad...</p>
<p>Egg Book</p>
<hr>
<!--<div class="search-box">-->
<!-- <label for="search">Search</label>-->
<!-- <input type="text" id="search" name="search" />-->
<!--</div>-->
<ul role="list" class="project-list">
{posts.map(project => (
<Card
@ -29,14 +34,57 @@ const posts = await getCollection('posts');
<style lang="scss">
@import "../../styles/vars.scss";
.project-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(30ch, 1fr));
gap: 16px;
padding: 0;
.search-box {
padding: 8px 0 32px;
width: 100%;
position: relative;
> label {
padding: 0 8px;
position: absolute;
top: -4px;
left: 20px;
background: $dark;
pointer-events: none;
z-index: +1;
}
> input {
padding: 0 16px;
width: 100%;
height: 35px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 8px;
text-decoration: none;
border-radius: 9999px;
border: 2px solid $gray;
background-color: $dark;
color: $light;
overflow: hidden;
&:hover {
border: 2px solid lighten($gray, 1%);
}
&:focus-visible {
outline: 0 solid transparent;
border: 2px solid $light;
}
}
}
#home {
margin-bottom: 32px;
}
#home { margin-bottom: 32px; }
</style>

View file

@ -1,23 +1,24 @@
---
import { getCollection } from 'astro:content';
import { getPosts } from "../../utils";
import Layout from "../../layouts/Layout.astro";
import Markdown from "../../layouts/Markdown.astro";
export async function getStaticPaths() {
const collection = await getCollection('projects')
return collection.map(project => {
return {
params: { slug: project.slug },
props: { project: project },
};
});
const collection = await getPosts("projects");
return collection.map((post, i) => ({
params: { slug: post.slug },
props: {
post: post,
prev: i > 0 ? collection[i - 1] : undefined,
next: i < collection.length - 1 ? collection[i + 1] : undefined
}
}));
}
const { project } = Astro.props;
const { post, prev, next } = Astro.props;
---
<Layout title="Leggy Land" src={project.data.image.url} alt={project.data.image.alt}>
<Markdown post={project} />
<Layout title="Leggy Land" src={post.data.image.url} alt={post.data.image.alt}>
<Markdown {post} {prev} {next} base="/projects" />
</Layout>

View file

@ -10,7 +10,7 @@ const projects = await getCollection('projects');
<Layout title="Leggy Land" src="/banner-alt.webp" alt="Temporary Banner">
<a class="button" id="home" href="/">Home</a>
<h1>All Projects</h1>
<p>Too many, so many</p>
<p>Come back next week for 4 new projects!</p>
<hr>
@ -26,16 +26,5 @@ const projects = await getCollection('projects');
</Layout>
<style lang="scss">
@import "../../styles/vars.scss";
.project-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(30ch, 1fr));
gap: 16px;
padding: 0;
}
#home {
margin-bottom: 32px;
}
#home { margin-bottom: 32px; }
</style>

View file

@ -0,0 +1,11 @@
.pill-list {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 8px;
// if the anchor tag has the pill class
> li {
list-style: none;
}
}

View file

@ -0,0 +1,8 @@
.project-list {
padding: 0;
display: flex;
flex-direction: column;
gap: 16px;
}

View file

@ -3,4 +3,6 @@
@import "button";
@import "pill";
@import "pill_list";
@import "project_list";
@import "main";

11
src/utils.ts Normal file
View file

@ -0,0 +1,11 @@
import { type ContentEntryMap, getCollection } from "astro:content";
// https://github.com/hellotham/hello-astro/blob/e05706cf488bcec6e4c5494a622eedfc4e47d763/src/config.ts#L55C1-L62C2
export async function getPosts(collection: keyof ContentEntryMap) {
const posts = await getCollection(collection, ({ data }) => {
return data.draft !== true
})
return posts.sort((a, b) =>
a.data.pubDate && b.data.pubDate ? +b.data.pubDate - +a.data.pubDate : 0
)
}