mirror of
https://github.com/wgh136/nysoure.git
synced 2025-12-16 07:51:14 +00:00
Update home page
This commit is contained in:
@@ -205,3 +205,9 @@ export interface Collection {
|
||||
images: Image[];
|
||||
isPublic: boolean;
|
||||
}
|
||||
|
||||
export interface Statistics {
|
||||
total_resources: number;
|
||||
total_files: number;
|
||||
start_time: number;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
Activity,
|
||||
CommentWithRef,
|
||||
Collection,
|
||||
Statistics,
|
||||
} from "./models.ts";
|
||||
|
||||
class Network {
|
||||
@@ -795,6 +796,12 @@ class Network {
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
async getStatistic(): Promise<Response<Statistics>> {
|
||||
return this._callApi(() =>
|
||||
axios.get(`${this.apiBaseUrl}/config/statistics`),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const network = new Network();
|
||||
|
||||
@@ -2,12 +2,17 @@ import { useEffect, useState } from "react";
|
||||
import ResourcesView from "../components/resources_view.tsx";
|
||||
import { network } from "../network/network.ts";
|
||||
import { app } from "../app.ts";
|
||||
import { Resource, RSort } from "../network/models.ts";
|
||||
import { Resource, RSort, Statistics } from "../network/models.ts";
|
||||
import { useTranslation } from "../utils/i18n";
|
||||
import { useAppContext } from "../components/AppContext.tsx";
|
||||
import Select from "../components/select.tsx";
|
||||
import { useNavigate } from "react-router";
|
||||
import { useNavigator } from "../components/navigator.tsx";
|
||||
import {
|
||||
MdOutlineAccessTime,
|
||||
MdOutlineArchive,
|
||||
MdOutlineClass,
|
||||
} from "react-icons/md";
|
||||
|
||||
export default function HomePage() {
|
||||
useEffect(() => {
|
||||
@@ -33,7 +38,7 @@ export default function HomePage() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PinnedResources />
|
||||
<HomeHeader />
|
||||
<div className={"flex pt-4 px-4 items-center"}>
|
||||
<Select
|
||||
values={[
|
||||
@@ -64,8 +69,9 @@ export default function HomePage() {
|
||||
|
||||
let cachedPinnedResources: Resource[] | null = null;
|
||||
|
||||
function PinnedResources() {
|
||||
function HomeHeader() {
|
||||
const [pinnedResources, setPinnedResources] = useState<Resource[]>([]);
|
||||
const [statistic, setStatistic] = useState<Statistics | null>(null);
|
||||
const navigator = useNavigator();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -79,9 +85,18 @@ function PinnedResources() {
|
||||
network.getResampledImageUrl(prefetchData.background),
|
||||
);
|
||||
}
|
||||
let ok1 = false;
|
||||
let ok2 = false;
|
||||
if (prefetchData && prefetchData.statistics) {
|
||||
setStatistic(prefetchData.statistics);
|
||||
ok1 = true;
|
||||
}
|
||||
if (prefetchData && prefetchData.pinned) {
|
||||
cachedPinnedResources = prefetchData.pinned;
|
||||
setPinnedResources(cachedPinnedResources!);
|
||||
ok2 = true;
|
||||
}
|
||||
if (ok1 && ok2) {
|
||||
return;
|
||||
}
|
||||
const fetchPinnedResources = async () => {
|
||||
@@ -91,18 +106,30 @@ function PinnedResources() {
|
||||
setPinnedResources(res.data ?? []);
|
||||
}
|
||||
};
|
||||
const fetchStatistics = async () => {
|
||||
const res = await network.getStatistic();
|
||||
if (res.success) {
|
||||
setStatistic(res.data!);
|
||||
}
|
||||
};
|
||||
fetchPinnedResources();
|
||||
}, []);
|
||||
fetchStatistics();
|
||||
}, [navigator]);
|
||||
|
||||
if (pinnedResources.length == 0) {
|
||||
if (pinnedResources.length == 0 || statistic == null) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 p-4">
|
||||
{pinnedResources.map((resource) => (
|
||||
<PinnedResourceItem key={resource.id} resource={resource} />
|
||||
))}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 p-4 gap-4">
|
||||
<PinnedResourceItem resource={pinnedResources[0]} />
|
||||
<div className={"hidden md:block"}>
|
||||
<div className={"card w-full shadow p-4 mb-4 bg-base-100-tr82 h-28"}>
|
||||
<h2 className={"text-lg font-bold pb-2"}>{app.appName}</h2>
|
||||
<p className={"text-xs"}>{app.siteInfo}</p>
|
||||
</div>
|
||||
<StatisticCard statistic={statistic} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -129,7 +156,7 @@ function PinnedResourceItem({ resource }: { resource: Resource }) {
|
||||
<img
|
||||
src={network.getResampledImageUrl(resource.image.id)}
|
||||
alt="cover"
|
||||
className="w-full aspect-[7/3] object-cover"
|
||||
className="w-full h-52 lg:h-60 object-cover"
|
||||
/>
|
||||
</figure>
|
||||
)}
|
||||
@@ -140,3 +167,40 @@ function PinnedResourceItem({ resource }: { resource: Resource }) {
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
function StatisticCard({ statistic }: { statistic: Statistics }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const now = new Date();
|
||||
const createdAt = new Date(statistic.start_time * 1000);
|
||||
const diffTime = Math.abs(now.getTime() - createdAt.getTime());
|
||||
const survivalTime = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
||||
|
||||
return (
|
||||
<div className="stats shadow w-full bg-base-100-tr82">
|
||||
<div className="stat">
|
||||
<div className="stat-figure text-secondary pt-2">
|
||||
<MdOutlineClass size={28} />
|
||||
</div>
|
||||
<div className="stat-title">{t("Resources")}</div>
|
||||
<div className="stat-value">{statistic.total_resources}</div>
|
||||
</div>
|
||||
|
||||
<div className="stat">
|
||||
<div className="stat-figure text-secondary pt-2">
|
||||
<MdOutlineArchive size={28} />
|
||||
</div>
|
||||
<div className="stat-title">{t("Files")}</div>
|
||||
<div className="stat-value">{statistic.total_files}</div>
|
||||
</div>
|
||||
|
||||
<div className="stat">
|
||||
<div className="stat-figure text-accent pt-2">
|
||||
<MdOutlineAccessTime size={28} />
|
||||
</div>
|
||||
<div className="stat-title">{t("Survival time")}</div>
|
||||
<div className="stat-value">{survivalTime}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -158,10 +158,12 @@ func serveIndexHtml(c fiber.Ctx) error {
|
||||
} else if path == "/" || path == "" {
|
||||
pinned, err := service.GetPinnedResources()
|
||||
random, err1 := service.RandomCover()
|
||||
if err == nil && err1 == nil {
|
||||
statistic, err2 := service.GetStatistic()
|
||||
if err == nil && err1 == nil && err2 == nil {
|
||||
preFetchDataJson, _ := json.Marshal(map[string]interface{}{
|
||||
"pinned": pinned,
|
||||
"background": random,
|
||||
"statistic": statistic,
|
||||
})
|
||||
preFetchData = url.PathEscape(string(preFetchDataJson))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user