mirror of
https://github.com/sergeyyarkov/yarkov.tech.git
synced 2026-10-11 10:29:21 +03:00
91 lines
2.2 KiB
Plaintext
91 lines
2.2 KiB
Plaintext
---
|
|
import { Picture } from "@astrojs/image/components";
|
|
import { Icon } from "astro-icon";
|
|
import { createDateFormatter } from "@root/utils";
|
|
import { isURL } from "@utils/string";
|
|
import ArticleComments from "@components/ArticleComments";
|
|
import TranslatedLink from "../TranslatedLink";
|
|
import "./ArticlePost.scss";
|
|
import { useTranslation } from "@root/i18n/utils";
|
|
|
|
export type Props = {
|
|
data: ArticleType;
|
|
lang: string;
|
|
};
|
|
|
|
const { data, lang } = Astro.props as Props;
|
|
const { slug, title, description, coverImage, tags, author, published_at } = data;
|
|
const t = useTranslation(Astro);
|
|
---
|
|
|
|
<article itemscope itemtype="http://schema.org/BlogPosting" class="article">
|
|
<header>
|
|
<div>
|
|
<div class="tags">
|
|
<ul itemprop="keywords">
|
|
{
|
|
tags.map((tag) => (
|
|
<li>
|
|
<TranslatedLink rel="tag" to={`/articles/?tags=${tag.toLocaleLowerCase()}`}>{`${tag}${
|
|
tags.at(-1) === tag ? "" : ","
|
|
}`}</TranslatedLink>
|
|
</li>
|
|
))
|
|
}
|
|
</ul>
|
|
</div>
|
|
<div class="views">
|
|
<Icon name="eye" width="21" height="21" />
|
|
<span><span id="views">---</span> {t("article.views")}</span>
|
|
</div>
|
|
</div>
|
|
<div class="heading">
|
|
<h1 itemprop="headline">{title}</h1>
|
|
</div>
|
|
<div class="published">
|
|
<time itemprop="datePublished" datetime={published_at}
|
|
>{createDateFormatter(lang).format(new Date(published_at))}
|
|
</time>
|
|
<span itemprop="author">{author}</span>
|
|
</div>
|
|
{
|
|
coverImage && (
|
|
<div class="cover">
|
|
<figure>
|
|
<Picture
|
|
itemprop="image"
|
|
src={isURL(coverImage) ? coverImage : `../../../content/assets/images/${coverImage}`}
|
|
sizes="(max-width: 450px) 450px, 700px"
|
|
widths={[450, 700]}
|
|
formats={["webp"]}
|
|
aspectRatio={"16:9"}
|
|
alt={title}
|
|
/>
|
|
</figure>
|
|
</div>
|
|
)
|
|
}
|
|
<div class="description">
|
|
<p>
|
|
{description}
|
|
</p>
|
|
</div>
|
|
</header>
|
|
<slot />
|
|
<ArticleComments />
|
|
</article>
|
|
|
|
<script define:vars={{ slug }}>
|
|
(async () => {
|
|
const response = await fetch(`/api/views?slug=${slug}`, { method: "POST" });
|
|
|
|
if (!response.ok) return;
|
|
|
|
const views = await response.text();
|
|
const $views = document.getElementById("views");
|
|
|
|
if (isNaN(parseInt(views, 10))) return;
|
|
if ($views) $views.textContent = views;
|
|
})();
|
|
</script>
|