- localization-svc: defaultLocale ru, resolveLocale only by geo - web-svc: DEFAULT_LOCALE ru, layout lang=ru, embeddedTranslations fallback ru - countryToLocale: default ru when no country or unknown country Co-authored-by: Cursor <cursoragent@cursor.com>
72 lines
2.8 KiB
TypeScript
72 lines
2.8 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
|
|
interface Article {
|
|
title: string;
|
|
content: string;
|
|
url: string;
|
|
thumbnail: string;
|
|
}
|
|
|
|
const NewsArticleWidget = () => {
|
|
const [article, setArticle] = useState<Article | null>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState(false);
|
|
|
|
useEffect(() => {
|
|
fetch('/api/v1/discover?mode=preview')
|
|
.then((res) => res.json())
|
|
.then((data) => {
|
|
const articles = (data.blogs || []).filter((a: Article) => a.thumbnail);
|
|
setArticle(articles[Math.floor(Math.random() * articles.length)]);
|
|
setLoading(false);
|
|
})
|
|
.catch(() => {
|
|
setError(true);
|
|
setLoading(false);
|
|
});
|
|
}, []);
|
|
|
|
return (
|
|
<div className="bg-light-secondary dark:bg-dark-secondary rounded-2xl border border-light-200 dark:border-dark-200 shadow-sm shadow-light-200/10 dark:shadow-black/25 flex flex-row items-stretch w-full h-20 min-h-[80px] max-h-[80px] p-0 overflow-hidden">
|
|
{loading ? (
|
|
<div className="animate-pulse flex flex-row items-stretch w-full h-full">
|
|
<div className="w-20 min-w-20 max-w-20 h-full bg-light-200 dark:bg-dark-200" />
|
|
<div className="flex flex-col justify-center flex-1 px-2.5 py-1.5 gap-1">
|
|
<div className="h-3 w-full max-w-[80%] rounded bg-light-200 dark:bg-dark-200" />
|
|
<div className="h-3 w-16 rounded bg-light-200 dark:bg-dark-200" />
|
|
</div>
|
|
</div>
|
|
) : error ? (
|
|
<div className="w-full text-xs text-red-400">Could not load news.</div>
|
|
) : article ? (
|
|
<a
|
|
href={`/?q=${encodeURIComponent(`Summary: ${article.url}`)}&title=${encodeURIComponent(article.title)}`}
|
|
className="flex flex-row items-stretch w-full h-full relative overflow-hidden group"
|
|
>
|
|
<div className="relative w-20 min-w-20 max-w-20 h-full overflow-hidden">
|
|
<img
|
|
className="object-cover w-full h-full bg-light-200 dark:bg-dark-200 group-hover:scale-110 transition-transform duration-300"
|
|
src={
|
|
new URL(article.thumbnail).origin +
|
|
new URL(article.thumbnail).pathname +
|
|
`?id=${new URL(article.thumbnail).searchParams.get('id')}`
|
|
}
|
|
alt={article.title}
|
|
/>
|
|
</div>
|
|
<div className="flex flex-col justify-center flex-1 px-2.5 py-1.5 min-w-0">
|
|
<div className="font-semibold text-[11px] text-black dark:text-white leading-tight line-clamp-2 mb-0.5">
|
|
{article.title}
|
|
</div>
|
|
<p className="text-black/60 dark:text-white/60 text-[9px] leading-relaxed line-clamp-2">
|
|
{article.content}
|
|
</p>
|
|
</div>
|
|
</a>
|
|
) : null}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default NewsArticleWidget;
|