blueprint details page

This commit is contained in:
Fred KISSIE
2025-10-28 00:14:27 +01:00
parent a05ee2483b
commit 7ce6fadb3d
19 changed files with 482 additions and 66 deletions

View File

@@ -0,0 +1,66 @@
import BlueprintDetailsForm from "@app/components/BlueprintDetailsForm";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import { Button } from "@app/components/ui/button";
import { internal } from "@app/lib/api";
import { authCookieHeader } from "@app/lib/api/cookies";
import { getCachedOrg } from "@app/lib/api/getCachedOrg";
import { GetBlueprintResponse } from "@server/routers/blueprints";
import { AxiosResponse } from "axios";
import { ArrowLeft } from "lucide-react";
import { Metadata } from "next";
import { getTranslations } from "next-intl/server";
import Link from "next/link";
import { notFound, redirect } from "next/navigation";
type BluePrintsPageProps = {
params: Promise<{ orgId: string; blueprintId: string }>;
};
export const metadata: Metadata = {
title: "Blueprint Detail"
};
export default async function BluePrintDetailPage(props: BluePrintsPageProps) {
const params = await props.params;
let org = null;
try {
const res = await getCachedOrg(params.orgId);
org = res.data.data;
} catch {
redirect(`/${params.orgId}`);
}
let blueprint = null;
try {
const res = await internal.get<AxiosResponse<GetBlueprintResponse>>(
`/org/${params.orgId}/blueprint/${params.blueprintId}`,
await authCookieHeader()
);
blueprint = res.data.data;
} catch (e) {
console.error(e);
notFound();
}
const t = await getTranslations();
return (
<>
<div className="flex flex-col gap-2 items-start">
<Button variant="link" asChild className="gap-1 px-0">
<Link href={`/${params.orgId}/settings/blueprints`}>
<ArrowLeft className="size-4 flex-none" />
{t("blueprintGoBack")}
</Link>
</Button>
<SettingsSectionTitle
title={t("blueprintDetails")}
description={t("blueprintDetailsDescription")}
/>
</div>
<BlueprintDetailsForm blueprint={blueprint} />
</>
);
}

View File

@@ -4,18 +4,16 @@ import BlueprintsTable, {
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import { internal } from "@app/lib/api";
import { authCookieHeader } from "@app/lib/api/cookies";
import { getCachedOrg } from "@app/lib/api/getCachedOrg";
import OrgProvider from "@app/providers/OrgProvider";
import { ListBlueprintsResponse } from "@server/routers/blueprints";
import { GetOrgResponse } from "@server/routers/org";
import { AxiosResponse } from "axios";
import { Metadata } from "next";
import { getTranslations } from "next-intl/server";
import { redirect } from "next/navigation";
import { cache } from "react";
type BluePrintsPageProps = {
params: Promise<{ orgId: string }>;
searchParams: Promise<{ view?: string }>;
};
export const metadata: Metadata = {
@@ -39,13 +37,7 @@ export default async function BluePrintsPage(props: BluePrintsPageProps) {
let org = null;
try {
const getOrg = cache(async () =>
internal.get<AxiosResponse<GetOrgResponse>>(
`/org/${params.orgId}`,
await authCookieHeader()
)
);
const res = await getOrg();
const res = await getCachedOrg(params.orgId);
org = res.data.data;
} catch {
redirect(`/${params.orgId}`);

View File

@@ -9,7 +9,8 @@ import { GetOrgResponse } from "@server/routers/org";
import { redirect } from "next/navigation";
import OrgProvider from "@app/providers/OrgProvider";
import { ListDomainsResponse } from "@server/routers/domain";
import { toUnicode } from 'punycode';
import { toUnicode } from "punycode";
import { getCachedOrg } from "@app/lib/api/getCachedOrg";
type Props = {
params: Promise<{ orgId: string }>;
@@ -20,15 +21,16 @@ export default async function DomainsPage(props: Props) {
let domains: DomainRow[] = [];
try {
const res = await internal.get<
AxiosResponse<ListDomainsResponse>
>(`/org/${params.orgId}/domains`, await authCookieHeader());
const res = await internal.get<AxiosResponse<ListDomainsResponse>>(
`/org/${params.orgId}/domains`,
await authCookieHeader()
);
const rawDomains = res.data.data.domains as DomainRow[];
domains = rawDomains.map((domain) => ({
...domain,
baseDomain: toUnicode(domain.baseDomain),
baseDomain: toUnicode(domain.baseDomain)
}));
} catch (e) {
console.error(e);
@@ -36,21 +38,12 @@ export default async function DomainsPage(props: Props) {
let org = null;
try {
const getOrg = cache(async () =>
internal.get<AxiosResponse<GetOrgResponse>>(
`/org/${params.orgId}`,
await authCookieHeader()
)
);
const res = await getOrg();
const res = await getCachedOrg(params.orgId);
org = res.data.data;
} catch {
redirect(`/${params.orgId}`);
}
if (!org) {
}
const t = await getTranslations();
return (

View File

@@ -0,0 +1,17 @@
import { getTranslations } from "next-intl/server";
export default async function NotFound() {
const t = await getTranslations();
return (
<div className="w-full max-w-md mx-auto p-3 md:mt-32 text-center">
<h1 className="text-6xl font-bold mb-4">404</h1>
<h2 className="text-2xl font-semibold text-neutral-500 mb-4">
{t("pageNotFound")}
</h2>
<p className="text-neutral-500 dark:text-neutral-700 mb-8">
{t("pageNotFoundDescription")}
</p>
</div>
);
}