mirror of
https://github.com/trafficlunar/tomodachi-share.git
synced 2026-05-13 13:17:45 +00:00
76 lines
2.4 KiB
TypeScript
76 lines
2.4 KiB
TypeScript
import { Suspense, useEffect, useState } from "react";
|
|
import FilterMenu from "../mii/list/filter-menu";
|
|
import SortSelect from "../mii/list/sort-select";
|
|
import MiiGrid from "../mii/list/mii-grid";
|
|
import Pagination from "../pagination";
|
|
import { type Mii } from "@tomodachi-share/backend";
|
|
import Skeleton from "../mii/list/skeleton";
|
|
|
|
interface ApiResponse {
|
|
totalCount: number;
|
|
filteredCount: number;
|
|
miis: Mii[];
|
|
lastPage: number;
|
|
}
|
|
|
|
export default function IndexPage() {
|
|
const searchParams = new URLSearchParams(window.location.search);
|
|
const [data, setData] = useState<ApiResponse>();
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
fetch(`${import.meta.env.PUBLIC_API_URL}/api/mii/list?${searchParams.toString()}`)
|
|
.then((res) => {
|
|
if (!res.ok) throw new Error("Failed to fetch Miis");
|
|
return res.json();
|
|
})
|
|
.then((data) => {
|
|
setData(data);
|
|
setLoading(false);
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
setLoading(false);
|
|
});
|
|
}, []);
|
|
|
|
return (
|
|
<>
|
|
<h1 className="sr-only">
|
|
{searchParams.get("tags") ? `Miis tagged with '${searchParams.get("tags")}' - TomodachiShare` : "TomodachiShare - index mii list"}
|
|
</h1>
|
|
|
|
<Suspense fallback={<Skeleton />}>
|
|
{!loading && (
|
|
<div className="w-full">
|
|
<div className="bg-amber-50 border-2 border-amber-500 rounded-2xl shadow-lg p-4 flex justify-between items-center gap-2 mb-2 max-md:flex-col">
|
|
<div className="flex items-center gap-2">
|
|
{data.totalCount == data.filteredCount ? (
|
|
<>
|
|
<span className="text-2xl font-bold text-amber-900">{data.totalCount}</span>
|
|
<span className="text-lg text-amber-700">{data.totalCount === 1 ? "Mii" : "Miis"}</span>
|
|
</>
|
|
) : (
|
|
<>
|
|
<span className="text-2xl font-bold text-amber-900">{data.filteredCount}</span>
|
|
<span className="text-sm text-amber-700">of</span>
|
|
<span className="text-lg font-semibold text-amber-800">{data.totalCount}</span>
|
|
<span className="text-lg text-amber-700">Miis</span>
|
|
</>
|
|
)}
|
|
</div>
|
|
|
|
<div className="relative flex items-center justify-end gap-2 w-full md:max-w-2/3 max-md:justify-center">
|
|
<FilterMenu />
|
|
<SortSelect />
|
|
</div>
|
|
</div>
|
|
|
|
<MiiGrid miis={data.miis} />
|
|
<Pagination lastPage={data.lastPage} />
|
|
</div>
|
|
)}
|
|
</Suspense>
|
|
</>
|
|
);
|
|
}
|