diff --git a/src/server.rs b/src/server.rs index 738a90b..c80af62 100644 --- a/src/server.rs +++ b/src/server.rs @@ -95,7 +95,14 @@ async fn health() -> &'static str { } async fn config_endpoint(State(state): State) -> Json { - Json(serde_json::json!({ "public_url": state.config.public_url })) + Json(serde_json::json!({ + "public_url": state.config.public_url, + "version": env!("CARGO_PKG_VERSION"), + "database_backend": format!("{:?}", state.config.database_backend).to_lowercase(), + "jetstream_url": state.config.jetstream_url, + "relay_url": state.config.relay_url, + "plc_url": state.config.plc_url, + })) } async fn client_metadata(State(state): State) -> Json { diff --git a/web/src/app/dashboard/about/page.tsx b/web/src/app/dashboard/about/page.tsx new file mode 100644 index 0000000..daa4728 --- /dev/null +++ b/web/src/app/dashboard/about/page.tsx @@ -0,0 +1,83 @@ +"use client" + +import { useEffect, useState } from "react" + +import { SiteHeader } from "@/components/site-header" +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card" + +interface ConfigInfo { + version: string + public_url: string + database_backend: string + jetstream_url: string + relay_url: string + plc_url: string +} + +export default function AboutPage() { + const [config, setConfig] = useState(null) + const [error, setError] = useState(null) + + useEffect(() => { + fetch("/config", { credentials: "same-origin" }) + .then((r) => { + if (!r.ok) throw new Error("Failed to load config") + return r.json() + }) + .then(setConfig) + .catch((e) => setError(e.message)) + }, []) + + const rows: { label: string; value: string | undefined }[] = config + ? [ + { label: "Version", value: config.version }, + { label: "Public URL", value: config.public_url }, + { label: "Database", value: config.database_backend }, + { label: "Jetstream", value: config.jetstream_url }, + { label: "Relay", value: config.relay_url }, + { label: "PLC Directory", value: config.plc_url }, + ] + : [] + + return ( + <> + +
+ {error &&

{error}

} + + + + HappyView + + ATProto AppView instance information + + + + {config ? ( +
+ {rows.map((row) => ( +
+
+ {row.label} +
+
{row.value ?? "—"}
+
+ ))} +
+ ) : ( + !error && ( +

Loading...

+ ) + )} +
+
+
+ + ) +} diff --git a/web/src/components/app-sidebar.tsx b/web/src/components/app-sidebar.tsx index d11f096..230ed23 100644 --- a/web/src/components/app-sidebar.tsx +++ b/web/src/components/app-sidebar.tsx @@ -17,6 +17,7 @@ import { IconLink, IconPuzzle, IconLockAccess, + IconInfoCircle, } from "@tabler/icons-react" import Image from "next/image" import Link from "next/link" @@ -159,6 +160,14 @@ export function AppSidebar({ + + + + + About + + +