69 lines
3.4 KiB
Plaintext
69 lines
3.4 KiB
Plaintext
---
|
|
import { Image } from "astro:assets";
|
|
import { Icon } from "astro-icon/components";
|
|
import "dayjs/locale/es";
|
|
import "dayjs/locale/fr";
|
|
import "dayjs/locale/he";
|
|
import "dayjs/locale/uk";
|
|
import "dayjs/locale/pt";
|
|
import "dayjs/locale/ru";
|
|
import "dayjs/locale/rw";
|
|
import dayjs from "dayjs";
|
|
import utc from "dayjs/plugin/utc";
|
|
|
|
const locale = Astro.currentLocale || "es";
|
|
const regionNames = new Intl.DisplayNames([locale], { type: "region" });
|
|
|
|
import { createTranslator, getLocalizedRoute } from "@/i18n";
|
|
const tl = createTranslator(locale);
|
|
dayjs.extend(utc);
|
|
dayjs.locale(locale);
|
|
|
|
const { data, content, routeKey = "news" } = Astro.props;
|
|
const nicedate = dayjs.utc(data.data.date).format("D MMMM YYYY");
|
|
const countryName = data?.data?.country ? regionNames.of(data.data.country) : "";
|
|
|
|
const location = [data.data.city, data.data.state, countryName].filter(Boolean).join(", ");
|
|
|
|
const newsUrl = `/${locale}/${getLocalizedRoute(routeKey, locale)}/${data.id}`;
|
|
|
|
const rawContent = data.data?.body || "";
|
|
const plainText = rawContent.replace(/^#.*$/gm, "").replace(/^###.*$/gm, "").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*]+)\*/g, "$1").replace(/_([^_]+)_/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^>.*$/gm, "").replace(/`[^`]+`/g, "").replace(/^[-*]\s+/gm, "").trim();
|
|
const words = plainText.split(/\s+/).filter((w) => w.length > 0).slice(0, 40);
|
|
const excerpt = words.join(" ") + (words.length === 40 ? "..." : "");
|
|
---
|
|
|
|
<a href={newsUrl} class="block group">
|
|
<article class="flex flex-col md:flex-row gap-6 md:gap-8 p-4 md:p-6 border-b border-tertiary/20 hover:bg-tertiary/5 transition-colors">
|
|
<div class="md:w-1/3 flex-shrink-0 overflow-hidden justify-center items-center flex">
|
|
<Image src={data.data.thumbnail_square || data.data.thumbnail?.url} alt={data.data.title} width={480} class="w-full h-auto object-contain transform group-hover:scale-105 transition-transform duration-300" />
|
|
</div>
|
|
|
|
<div class="md:w-2/3 flex flex-col">
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<span class="font-normal font-primary text-sm text-tertiary/70">{nicedate}</span>
|
|
{location && <><span class="text-tertiary/40">|</span><span class="font-normal font-primary text-sm text-tertiary/70">{location}</span></>}
|
|
</div>
|
|
|
|
<h3 class="text-xl md:text-2xl font-bold font-secondary text-tertiary group-hover:text-tertiary/80 transition-colors mb-2">{data.data.title}</h3>
|
|
|
|
<p class="font-primary text-base text-tertiary/80 mb-4 line-clamp-3">{excerpt}</p>
|
|
|
|
{data.data.tags && data.data.tags.length > 0 && (
|
|
<div class="flex flex-nowrap md:flex-wrap gap-2 overflow-x-auto md:overflow-visible pb-2 md:pb-0 mb-4">
|
|
{data.data.tags.map((tag: string) => (
|
|
<span class="badge rounded-none bg-[#EBE6D2] border-none text-[#003421] whitespace-nowrap">{Tag}</span>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
<div class="mt-auto">
|
|
<span class="inline-flex items-center gap-1 text-sm font-primary text-tertiary font-semibold group-hover:underline">
|
|
{tl(routeKey + ".seemore")}
|
|
<Icon name="ph:arrow-right" class="transform group-hover:translate-x-1 transition-transform" />
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
</a>
|