v1 review pass: fixed some minor bugs
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Link, useLocation, useParams } from "react-router";
|
||||
import { Link, useLocation, useNavigate, useParams } from "react-router";
|
||||
|
||||
import { API_URL } from "../config/api.ts";
|
||||
|
||||
import type { Dump, PublicUser } from "../model.ts";
|
||||
import { deserializeDump, deserializePublicUser } from "../model.ts";
|
||||
|
||||
import { useAuth } from "../hooks/useAuth.ts";
|
||||
import { relativeTime } from "../utils/relativeTime.ts";
|
||||
@@ -13,6 +14,7 @@ import RichContentCard from "../components/RichContentCard.tsx";
|
||||
import FilePreview from "../components/FilePreview.tsx";
|
||||
import { VoteButton } from "../components/VoteButton.tsx";
|
||||
import { PageShell } from "../components/PageShell.tsx";
|
||||
import { PageError } from "../components/PageError.tsx";
|
||||
|
||||
type DumpState =
|
||||
| { status: "loading" }
|
||||
@@ -22,6 +24,7 @@ type DumpState =
|
||||
export function Dump() {
|
||||
const { selectedDump } = useParams();
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const preloaded = (location.state as { dump?: Dump } | null)?.dump ?? null;
|
||||
|
||||
const [dumpState, setDumpState] = useState<DumpState>(
|
||||
@@ -38,7 +41,7 @@ export function Dump() {
|
||||
if (preloaded) {
|
||||
fetch(`${API_URL}/api/users/by-id/${preloaded.userId}`)
|
||||
.then((r) => r.json())
|
||||
.then((r) => r.success && setOp(r.data))
|
||||
.then((r) => r.success && setOp(deserializePublicUser(r.data)))
|
||||
.catch(() => {});
|
||||
return;
|
||||
}
|
||||
@@ -48,16 +51,18 @@ export function Dump() {
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const res = await fetch(`${API_URL}/api/dumps/${selectedDump}`, { cache: "no-store" });
|
||||
const res = await fetch(`${API_URL}/api/dumps/${selectedDump}`, {
|
||||
cache: "no-store",
|
||||
});
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||
|
||||
const apiResponse = await res.json();
|
||||
const dump: Dump = apiResponse.data;
|
||||
const dump: Dump = deserializeDump(apiResponse.data);
|
||||
setDumpState({ status: "loaded", dump });
|
||||
|
||||
fetch(`${API_URL}/api/users/by-id/${dump.userId}`)
|
||||
.then((r) => r.json())
|
||||
.then((r) => r.success && setOp(r.data))
|
||||
.then((r) => r.success && setOp(deserializePublicUser(r.data)))
|
||||
.catch(() => {});
|
||||
} catch (err) {
|
||||
setDumpState({
|
||||
@@ -66,22 +71,39 @@ export function Dump() {
|
||||
});
|
||||
}
|
||||
})();
|
||||
}, [selectedDump]);
|
||||
}, [selectedDump, preloaded]);
|
||||
|
||||
if (dumpState.status === "loading") {
|
||||
return <PageShell><p className="page-loading">Loading dump…</p></PageShell>;
|
||||
return (
|
||||
<PageShell>
|
||||
<p className="page-loading">Loading dump…</p>
|
||||
</PageShell>
|
||||
);
|
||||
}
|
||||
|
||||
if (dumpState.status === "error") {
|
||||
return (
|
||||
<PageShell>
|
||||
<div className="page-error">
|
||||
<h2>Error</h2>
|
||||
<p>{dumpState.error}</p>
|
||||
<button type="button" onClick={() => globalThis.location.reload()}>Retry</button>
|
||||
<Link to="/">← Back to all dumps</Link>
|
||||
</div>
|
||||
</PageShell>
|
||||
<PageError
|
||||
message={dumpState.error}
|
||||
actions={
|
||||
<>
|
||||
<button
|
||||
className="logout-btn"
|
||||
type="button"
|
||||
onClick={() => globalThis.location.reload()}
|
||||
>
|
||||
Retry
|
||||
</button>
|
||||
<button
|
||||
className="logout-btn"
|
||||
type="button"
|
||||
onClick={() => navigate("/")}
|
||||
>
|
||||
← Back to all dumps
|
||||
</button>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -112,9 +134,17 @@ export function Dump() {
|
||||
size={22}
|
||||
/>
|
||||
{op
|
||||
? <Link to={`/users/${op.username}`} className="dump-op-link">{op.username}</Link>
|
||||
? (
|
||||
<Link to={`/users/${op.username}`} className="dump-op-link">
|
||||
{op.username}
|
||||
</Link>
|
||||
)
|
||||
: <span className="dump-op-link">…</span>}
|
||||
<time className="dump-card-date" dateTime={dump.createdAt} title={new Date(dump.createdAt).toLocaleString()}>
|
||||
<time
|
||||
className="dump-card-date"
|
||||
dateTime={dump.createdAt.toISOString()}
|
||||
title={dump.createdAt.toLocaleString()}
|
||||
>
|
||||
{relativeTime(dump.createdAt)}
|
||||
</time>
|
||||
</div>
|
||||
@@ -133,7 +163,12 @@ export function Dump() {
|
||||
: dump.richContent
|
||||
? <RichContentCard richContent={dump.richContent} />
|
||||
: (
|
||||
<a href={dump.url} target="_blank" rel="noopener noreferrer" className="dump-url-link">
|
||||
<a
|
||||
href={dump.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="dump-url-link"
|
||||
>
|
||||
{dump.url}
|
||||
</a>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user