mhsf-dev/src/components/feat/AchievementList.tsx

95 lines
2.8 KiB
TypeScript
Raw Normal View History

2024-09-08 22:34:51 -05:00
import { getAchievements } from "@/lib/api";
import type { Achievement } from "@/lib/types/achievement";
import { useEffectOnce } from "@/lib/useEffectOnce";
import { useState } from "react";
import { Card, CardContent } from "../ui/card";
import { Skeleton } from "../ui/skeleton";
import A from "../misc/Link";
import { formalNames } from "@/config/achievements";
2024-09-08 22:34:51 -05:00
export default function AchievementList({ server }: { server: string }) {
const [achievements, setAchievements] = useState<
Array<WithInterval<Achievement>>
>([]);
const [loading, setLoading] = useState(true);
useEffectOnce(() => {
setAchievements(() => []);
getAchievements(server).then((v) => {
for (const a of v)
a.achievements.forEach((item, interval) =>
setAchievements((prev) => [...prev, { interval, ...item }])
);
setLoading(false);
});
});
if (loading)
return (
<div>
<Skeleton className="w-full h-[112px] my-4" />
<Skeleton className="w-full h-[112px] my-4" />
<Skeleton className="w-full h-[112px] my-4" />
</div>
);
return (
<div>
<span>
Achievements are earned automatically when the server is online. See{" "}
2024-09-10 17:45:03 -05:00
<A alt="Achievement collection">Docs:Advanced/Achievements</A>
2024-09-08 22:34:51 -05:00
</span>
{achievements
.filter(
(value, index) => listify(achievements).indexOf(value.type) === index
)
.map((a) => {
const Icon = formalNames[a.type].icon;
return (
<div key={`${a.date}--${a.interval}`}>
<Card className="my-4">
<CardContent className="pt-4">
<span
className="flex items-center"
style={{ color: formalNames[a.type].color }}
>
<Icon size={16} className="mr-2" />
<span
dangerouslySetInnerHTML={{
__html: formalNames[a.type].title,
}}
/>
</span>
<p>{formalNames[a.type].description}</p>
<span className="text-sm text-muted-foreground">
Achieved on {new Date(a.date).getMonth()}/
{new Date(a.date).getDate()}/
{new Date(a.date).getFullYear()}{" "}
<span className="text-muted-foreground/70">
{new Date(a.date).toLocaleTimeString()}
</span>
</span>
</CardContent>
</Card>
</div>
);
})}
</div>
);
}
2024-09-08 22:34:51 -05:00
type WithInterval<K> = K & {
interval: number;
};
const listify = (list: WithInterval<Achievement>[]) => {
const newL: Array<string> = [];
list.forEach((c) => newL.push(c.type));
return newL;
};