import { Globe, HardDrives, LinkSimple, Warning, } from "@phosphor-icons/react/dist/ssr"; import { ControlPlaneConfigurationError, ControlPlaneRequestError, getControlPlaneConfig, issueMountProfile, listExports, type MountProfile, type StorageExport, } from "@/lib/control-plane"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Badge } from "@/components/ui/badge"; import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Separator } from "@/components/ui/separator"; import { cn } from "@/lib/utils"; import { CopyField } from "./copy-field"; export const dynamic = "force-dynamic"; interface PageProps { searchParams: Promise<{ exportId?: string | string[] }>; } export default async function Home({ searchParams }: PageProps) { const resolvedSearchParams = await searchParams; const selectedExportId = readSearchParam(resolvedSearchParams.exportId); const controlPlaneConfig = await getControlPlaneConfig(); let exports: StorageExport[] = []; let mountProfile: MountProfile | null = null; let feedback: string | null = null; try { exports = await listExports(); if (selectedExportId !== null) { if (exports.some((e) => e.id === selectedExportId)) { mountProfile = await issueMountProfile(selectedExportId); } else { feedback = `Export "${selectedExportId}" was not found.`; } } } catch (error) { if ( error instanceof ControlPlaneConfigurationError || error instanceof ControlPlaneRequestError ) { feedback = error.message; } else { throw error; } } const selectedExport = selectedExportId === null ? null : (exports.find((e) => e.id === selectedExportId) ?? null); return (

betterNAS

Control Plane

{controlPlaneConfig.baseUrl ?? "Not configured"} {controlPlaneConfig.clientToken !== null ? "Bearer auth" : "No token"} {exports.length === 1 ? "1 export" : `${exports.length} exports`}
{feedback !== null && ( Configuration error {feedback} )}
Exports Storage exports registered with this control plane. {exports.length === 1 ? "1 export" : `${exports.length} exports`} {exports.length === 0 ? (

No exports registered yet. Start the node agent and connect it to this control plane.

) : ( )}
{selectedExport !== null ? `Mount ${selectedExport.label}` : "Mount instructions"} {selectedExport !== null ? "Issued WebDAV credentials for Finder." : "Select an export to issue mount credentials."} {mountProfile === null ? (

Pick an export to issue WebDAV credentials for Finder.

) : (
Issued profile {mountProfile.readonly ? "Read-only" : "Read-write"}
Mode
{mountProfile.credential.mode}
Expires
{mountProfile.credential.expiresAt}

Finder steps

    {[ "Open Finder and choose Go, then Connect to Server.", `Paste the mount URL into the server address field.`, "Enter the issued username and password when prompted.", "Save to Keychain only if the credential expiry suits your workflow.", ].map((step, index) => (
  1. {index + 1} {step}
  2. ))}
)}
); } function readSearchParam(value: string | string[] | undefined): string | null { if (typeof value === "string" && value.trim() !== "") { return value.trim(); } if (Array.isArray(value)) { const first = value.find((v) => v.trim() !== ""); return first?.trim() ?? null; } return null; }