diff --git a/src/components/Article.astro b/src/components/Article.astro new file mode 100644 index 0000000..5e4c354 --- /dev/null +++ b/src/components/Article.astro @@ -0,0 +1,44 @@ +--- +import { AstroComponentFactory } from 'astro/dist/runtime/server'; + +export interface Props { + PostContent: AstroComponentFactory; + title: string; + description: string; + readingTime: number; + date: Date; + image: string; + preview?: boolean; +} + +const { + PostContent, title, description, + readingTime, date, image, + preview = false, +} = Astro.props; + +const locale = 'ru'; +--- + +
+

{title}

+
+ on + + by + + // + + {readingTime.toFixed(1)} min read + +
+
+{ + !preview ? +
+ +
: +
+ {description} +
+} diff --git a/src/components/ArticleCard.astro b/src/components/ArticleCard.astro new file mode 100644 index 0000000..60a9926 --- /dev/null +++ b/src/components/ArticleCard.astro @@ -0,0 +1,113 @@ +--- +import Article from './Article.astro'; +import MenuItem from './MenuItem.astro'; + +import postRenderer from '../post-renderer.mjs'; +import { postType } from '../post-renderer.mjs'; + +export interface Props { + post: postType; +} + +const { post } = Astro.props; +const { + PostContent, title, description, + readingTime, date, image, +} = await postRenderer(post); +const link = `/blog/${post.slug}`; +--- + +
+
+ +
+ + + + diff --git a/src/components/MenuItem.astro b/src/components/MenuItem.astro index b71007f..a1e9f26 100644 --- a/src/components/MenuItem.astro +++ b/src/components/MenuItem.astro @@ -5,35 +5,42 @@ export interface Props { name: string; link: string; icon: string; + atLeft?: boolean; } -const { name, link, icon } = Astro.props; +const { name, link, icon, atLeft = true } = Astro.props; ---
  • + - + {!atLeft ? name : ""} + - {name} + {atLeft ? name : ""}
  • + diff --git a/src/pages/blog/[slug].astro b/src/pages/blog/[slug].astro index 42dd40c..81e6766 100644 --- a/src/pages/blog/[slug].astro +++ b/src/pages/blog/[slug].astro @@ -1,24 +1,9 @@ --- import BlogLayout from "../../layouts/BlogLayout.astro"; +import Article from "../../components/Article.astro"; import { getCollection } from "astro:content"; - -import { AstroComponentFactory } from "astro/dist/runtime/server"; -import { MarkdownHeading } from "astro"; - -type postType = { - id: string; - slug: string; - body: string; - collection: "blog"; - data: any; -} & { - render(): Promise<{ - Content: AstroComponentFactory; - headings: MarkdownHeading[]; - remarkPluginFrontmatter: Record; - }>; -}; +import postRenderer from "../../post-renderer.mjs"; export async function getStaticPaths() { const posts = await getCollection("blog"); @@ -31,29 +16,14 @@ export async function getStaticPaths() { } const { slug } = Astro.params; -const post: postType = Astro.props.post; +const { post } = Astro.props; -const postObj = await post.render(); -const fm = postObj.remarkPluginFrontmatter; +const { + PostContent, title, description, + readingTime, date, image, +} = await postRenderer(post); -const title = postObj.headings[0]?.text || ''; -const description = fm.description; -const readingTime = fm.readingTime; - -let dateStr = slug.split("-", 1)[0]; -let date: Date | undefined; -if (isNaN(Number(dateStr))) { - dateStr = undefined; -} -else { - date = new Date( - `${dateStr.slice(0,4)}-` + - `${dateStr.slice(4,6)}-` + - `${dateStr.slice(6,8)}` - ) -} - -const image = (post.body.match(/(?:\s|^)!\[.*\]\((.*?)\)/) || [])[1]; +const locale = 'ru-RU'; --- @@ -69,28 +39,18 @@ const image = (post.body.match(/(?:\s|^)!\[.*\]\((.*?)\)/) || [])[1]; -
    -

    {title}

    -
    - on - - by - - // - - {readingTime} - -
    -
    -
    - -
    +
    diff --git a/src/post-renderer.mts b/src/post-renderer.mts new file mode 100644 index 0000000..5e8517c --- /dev/null +++ b/src/post-renderer.mts @@ -0,0 +1,46 @@ +import { AstroComponentFactory } from "astro/dist/runtime/server" +import { MarkdownHeading } from "astro" + +export type postType = { + id: string + slug: string + body: string + collection: "blog" + data: any +} & { + render(): Promise<{ + Content: AstroComponentFactory + headings: MarkdownHeading[] + remarkPluginFrontmatter: Record + }> +} + +export default async function postRenderer(post: postType) { + const postObj = await post.render() + const fm = postObj.remarkPluginFrontmatter + + const title = postObj.headings[0]?.text || '' + const description: string = fm.description + const readingTime: number = fm.readingTime + + const dateStr = post.slug.split("-", 1)[0] + let date: Date | undefined + if (!isNaN(Number(dateStr))) { + date = new Date( + `${dateStr.slice(0,4)}-` + + `${dateStr.slice(4,6)}-` + + `${dateStr.slice(6,8)}` + ) + } + + const image = (post.body.match(/(?:\s|^)!\[.*\]\((.*?)\)/) || [])[1] + + return { + PostContent: postObj.Content, + title: title, + description: description, + readingTime: readingTime, + date: date, + image: image, + } +}