mirror of
				https://github.com/valentineus/popov.link.git
				synced 2025-11-03 22:39:44 +03:00 
			
		
		
		
	@@ -51,4 +51,4 @@ Comments on the site are powered by [giscus.app](https://giscus.app) and stored
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## License
 | 
					## License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This project is licensed under the [MIT License](LICENSE.txt).
 | 
					This project is licensed under the [MIT License](LICENSE.txt).
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,10 +15,4 @@ export default defineConfig({
 | 
				
			|||||||
			theme: "vitesse-dark",
 | 
								theme: "vitesse-dark",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	redirects: {
 | 
					 | 
				
			||||||
		"/blog": {
 | 
					 | 
				
			||||||
			destination: "/",
 | 
					 | 
				
			||||||
			status: 301,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								src/components/Header.astro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/components/Header.astro
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					<style lang="scss">
 | 
				
			||||||
 | 
						@import "../scss/_variables.scss";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						header {
 | 
				
			||||||
 | 
							padding-bottom: 1rem;
 | 
				
			||||||
 | 
							text-align: right;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						a {
 | 
				
			||||||
 | 
							text-decoration: none;
 | 
				
			||||||
 | 
							margin-right: 1.5rem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							&:last-child {
 | 
				
			||||||
 | 
								margin-right: 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<header>
 | 
				
			||||||
 | 
						<a href="/">Home</a>
 | 
				
			||||||
 | 
						<a href="/blog/">Blog</a>
 | 
				
			||||||
 | 
					</header>
 | 
				
			||||||
@@ -1,35 +0,0 @@
 | 
				
			|||||||
---
 | 
					 | 
				
			||||||
type Props = {
 | 
					 | 
				
			||||||
	readonly nextUrl?: string;
 | 
					 | 
				
			||||||
	readonly prevUrl?: string;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const { nextUrl, prevUrl } = Astro.props;
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss">
 | 
					 | 
				
			||||||
	div {
 | 
					 | 
				
			||||||
		text-align: center;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	span {
 | 
					 | 
				
			||||||
		margin: 0 2em;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<div>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		prevUrl && (
 | 
					 | 
				
			||||||
			<span>
 | 
					 | 
				
			||||||
				<a href={prevUrl}>< Prev</a>
 | 
					 | 
				
			||||||
			</span>
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		nextUrl && (
 | 
					 | 
				
			||||||
			<span>
 | 
					 | 
				
			||||||
				<a href={nextUrl}>Next ></a>
 | 
					 | 
				
			||||||
			</span>
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
							
								
								
									
										32
									
								
								src/components/PostElement.astro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/components/PostElement.astro
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					import { type CollectionEntry } from "astro:content";
 | 
				
			||||||
 | 
					import dayjs from "dayjs";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Props = {
 | 
				
			||||||
 | 
						readonly post: CollectionEntry<"blog">;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const { post } = Astro.props;
 | 
				
			||||||
 | 
					const { remarkPluginFrontmatter } = await post.render();
 | 
				
			||||||
 | 
					const formattedDate = dayjs(post.data.pubDate.toString()).format("MMMM DD, YYYY");
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss">
 | 
				
			||||||
 | 
						@import "../scss/_variables.scss";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						small {
 | 
				
			||||||
 | 
							font-size: $fontSizeBase * 0.75;
 | 
				
			||||||
 | 
							opacity: 0.5;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<li>
 | 
				
			||||||
 | 
						<a href={`/blog/${post.slug}`}>{post.data.title}</a>
 | 
				
			||||||
 | 
						<div>
 | 
				
			||||||
 | 
							<small>
 | 
				
			||||||
 | 
								<time datetime={post.data.pubDate.toISOString()}>{formattedDate}</time>
 | 
				
			||||||
 | 
								<span>•</span>
 | 
				
			||||||
 | 
								<span>{remarkPluginFrontmatter.minutesRead}</span>
 | 
				
			||||||
 | 
							</small>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
					</li>
 | 
				
			||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
---
 | 
					---
 | 
				
			||||||
import Analytics from "../components/Analytics.astro";
 | 
					import Analytics from "../components/Analytics.astro";
 | 
				
			||||||
import Head from "../components/Head.astro";
 | 
					import Head from "../components/Head.astro";
 | 
				
			||||||
 | 
					import Header from "../components/Header.astro";
 | 
				
			||||||
import "../scss/global.scss";
 | 
					import "../scss/global.scss";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props = {
 | 
					type Props = {
 | 
				
			||||||
@@ -19,6 +20,10 @@ const { description, title } = Astro.props;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	<body>
 | 
						<body>
 | 
				
			||||||
		<main>
 | 
							<main>
 | 
				
			||||||
 | 
								<section>
 | 
				
			||||||
 | 
									<Header />
 | 
				
			||||||
 | 
								</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<slot />
 | 
								<slot />
 | 
				
			||||||
		</main>
 | 
							</main>
 | 
				
			||||||
		<Analytics title={title ?? import.meta.env.DEFAULT_TITLE} />
 | 
							<Analytics title={title ?? import.meta.env.DEFAULT_TITLE} />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,33 +0,0 @@
 | 
				
			|||||||
---
 | 
					 | 
				
			||||||
import type { GetStaticPaths, InferGetStaticPropsType } from "astro";
 | 
					 | 
				
			||||||
import { getCollection } from "astro:content";
 | 
					 | 
				
			||||||
import Layout from "../layouts/BaseLayout.astro";
 | 
					 | 
				
			||||||
import Pagination from "../components/Pagination.astro";
 | 
					 | 
				
			||||||
import PostSummary from "../components/PostSummary.astro";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const getStaticPaths = (async ({ paginate }) => {
 | 
					 | 
				
			||||||
	const posts = await getCollection("blog", ({ data }) => {
 | 
					 | 
				
			||||||
		return data.draft !== true;
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	posts.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return paginate(posts, {
 | 
					 | 
				
			||||||
		pageSize: 10,
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}) satisfies GetStaticPaths;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const { page } = Astro.props;
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<Layout>
 | 
					 | 
				
			||||||
	<section style={{ "margin-top": "3rem" }}>
 | 
					 | 
				
			||||||
		{page.data.map((post) => <PostSummary post={post} />)}
 | 
					 | 
				
			||||||
	</section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	<section>
 | 
					 | 
				
			||||||
		<Pagination nextUrl={page.url.next} prevUrl={page.url.prev} />
 | 
					 | 
				
			||||||
	</section>
 | 
					 | 
				
			||||||
</Layout>
 | 
					 | 
				
			||||||
@@ -32,11 +32,13 @@ const formattedDate = dayjs(post.data.pubDate.toString()).format("MMMM DD, YYYY"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<Layout description={post.data.description} title={post.data.title}>
 | 
					<Layout description={post.data.description} title={post.data.title}>
 | 
				
			||||||
	<article>
 | 
						<article>
 | 
				
			||||||
 | 
							<section>
 | 
				
			||||||
 | 
								<h1>{post.data.title}</h1>
 | 
				
			||||||
 | 
							</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<section>
 | 
							<section>
 | 
				
			||||||
			<p>
 | 
								<p>
 | 
				
			||||||
				<small>
 | 
									<small>
 | 
				
			||||||
					<a href="/">< Home</a>
 | 
					 | 
				
			||||||
					<span> • </span>
 | 
					 | 
				
			||||||
					Posted
 | 
										Posted
 | 
				
			||||||
					<time datetime={post.data.pubDate.toISOString()}>{formattedDate}</time>
 | 
										<time datetime={post.data.pubDate.toISOString()}>{formattedDate}</time>
 | 
				
			||||||
					by {post.data.author}
 | 
										by {post.data.author}
 | 
				
			||||||
@@ -46,10 +48,6 @@ const formattedDate = dayjs(post.data.pubDate.toString()).format("MMMM DD, YYYY"
 | 
				
			|||||||
			</p>
 | 
								</p>
 | 
				
			||||||
		</section>
 | 
							</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<section>
 | 
					 | 
				
			||||||
			<h1>{post.data.title}</h1>
 | 
					 | 
				
			||||||
		</section>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		<section>
 | 
							<section>
 | 
				
			||||||
			<Content />
 | 
								<Content />
 | 
				
			||||||
		</section>
 | 
							</section>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								src/pages/blog/index.astro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/pages/blog/index.astro
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					import { getCollection } from "astro:content";
 | 
				
			||||||
 | 
					import Layout from "../../layouts/BaseLayout.astro";
 | 
				
			||||||
 | 
					import PostElement from "../../components/PostElement.astro";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const posts = await getCollection("blog", ({ data }) => {
 | 
				
			||||||
 | 
						return data.draft !== true;
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					posts.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime());
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<Layout>
 | 
				
			||||||
 | 
						<section style={{ "margin-top": "3rem" }}>
 | 
				
			||||||
 | 
							<ul>
 | 
				
			||||||
 | 
								{posts.map((post) => <PostElement post={post} />)}
 | 
				
			||||||
 | 
							</ul>
 | 
				
			||||||
 | 
						</section>
 | 
				
			||||||
 | 
					</Layout>
 | 
				
			||||||
							
								
								
									
										17
									
								
								src/pages/index.astro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/pages/index.astro
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					import { getCollection } from "astro:content";
 | 
				
			||||||
 | 
					import Layout from "../layouts/BaseLayout.astro";
 | 
				
			||||||
 | 
					import PostSummary from "../components/PostSummary.astro";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const posts = await getCollection("blog", ({ data }) => {
 | 
				
			||||||
 | 
						return data.draft !== true;
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					posts.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime());
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<Layout>
 | 
				
			||||||
 | 
						<section style={{ "margin-top": "3rem" }}>
 | 
				
			||||||
 | 
							{posts.map((post) => <PostSummary post={post} />)}
 | 
				
			||||||
 | 
						</section>
 | 
				
			||||||
 | 
					</Layout>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user