diff options
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/404.astro | 23 | ||||
| -rw-r--r-- | src/pages/[...page].astro | 33 | ||||
| -rw-r--r-- | src/pages/blog/[...slug].astro | 45 | ||||
| -rw-r--r-- | src/pages/blog/index.astro | 61 | ||||
| -rw-r--r-- | src/pages/feed.xml.js | 9 | ||||
| -rw-r--r-- | src/pages/index.astro | 27 |
6 files changed, 144 insertions, 54 deletions
diff --git a/src/pages/404.astro b/src/pages/404.astro index e140464..3ec9feb 100644 --- a/src/pages/404.astro +++ b/src/pages/404.astro @@ -1,17 +1,30 @@ --- +import { config } from "../config"; import Layout from "../layouts/BaseLayout.astro"; +import pageSchema from "../utils/schemas/pageSchema"; + +const title = "404 — Page Not Found | Valentin Popov"; +const description = "The page you're looking for doesn't exist!"; +const preview = config.og.defaultPreview; +const lang = "en"; + +const schema = pageSchema({ + siteUrl: new URL("/", Astro.site).toString(), + page: "/404", + title, + description, + lang, +}); --- -<Layout> - <div style="text-align:center;"> +<Layout title={title} description={description} preview={preview} lang={lang} schema={schema}> + <div style={{ "text-align": "center" }}> <h1>404</h1> <p><strong>Page not found</strong></p> <p> <small> If you see this message, please - <a href=`mailto:valentin@popov.link?subject=${encodeURIComponent('I found a broken page')}`> - let me know - </a> + <a href=`mailto:valentin@popov.link?subject=${encodeURIComponent('I found a broken page')}`>let me know</a> </small> </p> </div> diff --git a/src/pages/[...page].astro b/src/pages/[...page].astro deleted file mode 100644 index 6d513b2..0000000 --- a/src/pages/[...page].astro +++ /dev/null @@ -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> diff --git a/src/pages/blog/[...slug].astro b/src/pages/blog/[...slug].astro index 41b0f5c..d12ff05 100644 --- a/src/pages/blog/[...slug].astro +++ b/src/pages/blog/[...slug].astro @@ -2,6 +2,7 @@ import { type CollectionEntry, getCollection } from "astro:content"; import Comments from "../../components/Comments.astro"; import Layout from "../../layouts/BaseLayout.astro"; +import blogPostSchema from "../../utils/schemas/blogPostSchema"; import dayjs from "dayjs"; type Props = CollectionEntry<"blog">; @@ -18,37 +19,55 @@ export async function getStaticPaths() { } const post = Astro.props; + const { Content, remarkPluginFrontmatter } = await post.render(); -const formattedDate = dayjs(post.data.pubDate.toString()).format("MMMM DD, YYYY"); + +const description = post.data.description; +const isBasedOn = post.data.basedOn; +const lang = post.data.lang; +const preview = `/images/preview/${post.slug}.png`; +const slug = post.slug; +const title = post.data.title; + +const dateModified = post.data.dateModified?.toISOString(); +const datePublished = post.data.datePublished.toISOString(); +const formattedDate = dayjs(post.data.datePublished.toString()).format("MMMM DD, YYYY"); + +const schema = blogPostSchema({ + siteUrl: new URL("/", Astro.site).toString(), + dateModified, + datePublished, + description, + isBasedOn, + lang, + preview, + slug, + title, +}); --- <style lang="scss"> - @import "../../scss/_variables.scss"; + @use "../../scss/variables" as *; p { opacity: 0.5; } </style> -<Layout description={post.data.description} title={post.data.title}> +<Layout title={title} description={description} preview={preview} lang={lang} schema={schema}> <article> - <section> + <header> + <h1>{title}</h1> + <p> <small> - <a href="/">< Home</a> - <span> • </span> Posted - <time datetime={post.data.pubDate.toISOString()}>{formattedDate}</time> - by {post.data.author} + <time datetime={datePublished} lang="en">{formattedDate}</time> <span> • </span> <span>{remarkPluginFrontmatter.minutesRead}</span> </small> </p> - </section> - - <section> - <h1>{post.data.title}</h1> - </section> + </header> <section> <Content /> diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro new file mode 100644 index 0000000..3a27111 --- /dev/null +++ b/src/pages/blog/index.astro @@ -0,0 +1,61 @@ +--- +import type { CollectionEntry } from "astro:content"; +import { config } from "../../config"; +import { getCollection } from "astro:content"; +import blogSchema from "../../utils/schemas/blogSchema"; +import Layout from "../../layouts/BaseLayout.astro"; +import PostElement from "../../components/PostElement.astro"; +import RSSIcon from "../../components/Icons/RSS.astro"; + +const posts = await getCollection("blog", ({ data }) => { + return data.draft !== true; +}); + +posts.sort((a, b) => b.data.datePublished.getTime() - a.data.datePublished.getTime()); + +const postsByYear = posts.reduce<Record<string, CollectionEntry<"blog">[]>>((acc, post) => { + const year = post.data.datePublished.getFullYear().toString(); + if (!acc[year]) { + acc[year] = []; + } + acc[year].push(post); + return acc; +}, {}); + +const years = Object.keys(postsByYear).sort((a, b) => Number(b) - Number(a)); + +const title = "Valentin Popov's Blog | Software Development, Leadership & Open-Source"; +const description = "Explore Valentin Popov's blog on software development, tech leadership, and open-source experiments. Stay updated with in-depth tutorials and expert insights."; +const preview = config.og.defaultPreview; +const lang = "en"; + +const schema = blogSchema({ + siteUrl: new URL("/", Astro.site).toString(), + title, + posts, +}); +--- + +<Layout title={title} description={description} preview={preview} lang={lang} schema={schema}> + <section> + <h1> + Blog posts + <RSSIcon /> + </h1> + </section> + + <section> + { + years.map((year) => ( + <div> + <h2>{year}</h2> + <ul> + {postsByYear[year].map((post) => ( + <PostElement post={post} /> + ))} + </ul> + </div> + )) + } + </section> +</Layout> diff --git a/src/pages/feed.xml.js b/src/pages/feed.xml.js index d71a020..7c41b4f 100644 --- a/src/pages/feed.xml.js +++ b/src/pages/feed.xml.js @@ -2,13 +2,16 @@ import { getCollection } from "astro:content"; import rss from "@astrojs/rss"; export async function GET(context) { + const title = "RSS Feed | Valentin Popov Blog"; + const description = "Follow the latest posts from Valentin Popov via RSS."; + const posts = await getCollection("blog", ({ data }) => { return data.draft !== true; }); return rss({ - customData: `<language>ru-ru</language>`, - description: import.meta.env.DEFAULT_DESCRIPTION, + customData: `<language>en</language>`, + description: description, items: posts.map((post) => ({ customData: post.data.customData, description: post.data.description, @@ -17,6 +20,6 @@ export async function GET(context) { title: post.data.title, })), site: context.site, - title: import.meta.env.DEFAULT_TITLE, + title: title, }); } diff --git a/src/pages/index.astro b/src/pages/index.astro new file mode 100644 index 0000000..b235b9b --- /dev/null +++ b/src/pages/index.astro @@ -0,0 +1,27 @@ +--- +import { config } from "../config"; +import LatestPostsSection from "../components/Sections/LatestPosts.astro"; +import Layout from "../layouts/BaseLayout.astro"; +import pageSchema from "../utils/schemas/pageSchema"; +import SocialLinksSection from "../components/Sections/SocialLinks.astro"; +import WelcomeSection from "../components/Sections/Welcome.astro"; + +const title = "Valentin Popov – Software Developer & Team Lead | Tech Insights"; +const description = "Blog by Valentin Popov — software developer and team lead writing about code, side projects, digital tools, and fun experiments."; +const preview = config.og.defaultPreview; +const lang = "en"; + +const schema = pageSchema({ + siteUrl: new URL("/", Astro.site).toString(), + page: "/", + title, + description, + lang, +}); +--- + +<Layout title={title} description={description} preview={preview} lang={lang} schema={schema}> + <WelcomeSection /> + <SocialLinksSection /> + <LatestPostsSection /> +</Layout> |
