Initial frontend import
This commit is contained in:
46
src/pages/FavoritesPage.tsx
Normal file
46
src/pages/FavoritesPage.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { getJSON, type Resource } from "../api";
|
||||
import { ResourceCard } from "../components/ResourceCard";
|
||||
import { readFavorites } from "../favorites";
|
||||
import { useI18n } from "../i18n";
|
||||
|
||||
export function FavoritesPage() {
|
||||
const { t, lang } = useI18n();
|
||||
const [items, setItems] = useState<Resource[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
const ids = readFavorites();
|
||||
const out: Resource[] = [];
|
||||
for (const id of ids) {
|
||||
try {
|
||||
const r = await getJSON<Resource>(
|
||||
`/api/resources/${id}?lang=${encodeURIComponent(lang)}`,
|
||||
);
|
||||
out.push(r);
|
||||
} catch {
|
||||
// ignore missing
|
||||
}
|
||||
}
|
||||
if (!cancelled) setItems(out);
|
||||
})();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [lang]);
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<h1 className="text-2xl font-bold">{t("favorites")}</h1>
|
||||
{items.length === 0 ? (
|
||||
<p className="text-neutral-400">{t("favoritesEmpty")}</p>
|
||||
) : null}
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{items.map((r) => (
|
||||
<ResourceCard key={r.id} r={r} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user