feat: add category and recommendations pages
This commit is contained in:
61
src/pages/OfficialRecommendations/index.tsx
Normal file
61
src/pages/OfficialRecommendations/index.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { getJSON, itemsOrEmpty, type Category } from "../../api";
|
||||
import { RecommendedCard } from "../../components/RecommendedCard";
|
||||
import { SectionHeader } from "../../components/SectionHeader";
|
||||
import { langQuery, useI18n } from "../../i18n";
|
||||
import { sourceLanguageQuery } from "../../i18nLanguages";
|
||||
import type { Post } from "../../types/post";
|
||||
import {
|
||||
postToResource,
|
||||
type PostBackedResource,
|
||||
} from "../../utils/postResourceAdapter";
|
||||
|
||||
export function OfficialRecommendationsPage() {
|
||||
const { t, lang } = useI18n();
|
||||
const [items, setItems] = useState<PostBackedResource[]>([]);
|
||||
const [err, setErr] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const langParam = encodeURIComponent(langQuery(lang));
|
||||
const languageParam = encodeURIComponent(sourceLanguageQuery(lang));
|
||||
Promise.all([
|
||||
getJSON<Category[]>(`/api/categories?lang=${langParam}`),
|
||||
getJSON<{ items: Post[] }>(
|
||||
`/api/posts/recommended?lang=${langParam}&language=${languageParam}&limit=100`,
|
||||
),
|
||||
])
|
||||
.then(([categories, recommended]) => {
|
||||
const cats = itemsOrEmpty(categories);
|
||||
setItems(
|
||||
itemsOrEmpty(recommended.items).map((post) =>
|
||||
postToResource(post, lang, cats),
|
||||
),
|
||||
);
|
||||
})
|
||||
.catch((e) => setErr(String(e)));
|
||||
}, [lang]);
|
||||
|
||||
if (err) {
|
||||
return (
|
||||
<div className="rounded-xl border border-red-900 bg-red-950/40 p-4 text-red-200">
|
||||
{err}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<section>
|
||||
<SectionHeader title={t("officialSection")} />
|
||||
<div className="mt-7 grid grid-cols-[repeat(auto-fill,208px)] justify-center gap-3 md:grid-cols-[repeat(auto-fill,240px)] md:justify-start md:gap-4 lg:grid-cols-[repeat(auto-fill,246.4px)]">
|
||||
{items.map((item, index) => (
|
||||
<RecommendedCard
|
||||
key={item.id}
|
||||
r={item}
|
||||
visualIndex={index}
|
||||
useFigmaDesign
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user