mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-19 19:36:38 +00:00
✨ blueprint details page
This commit is contained in:
66
src/app/[orgId]/settings/blueprints/[blueprintId]/page.tsx
Normal file
66
src/app/[orgId]/settings/blueprints/[blueprintId]/page.tsx
Normal 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} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -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}`);
|
||||
|
||||
@@ -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 (
|
||||
|
||||
17
src/app/[orgId]/settings/not-found.tsx
Normal file
17
src/app/[orgId]/settings/not-found.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user