import type { Metadata } from "next" import { getTranslations, getMessages, setRequestLocale } from "next-intl/server" import { Link } from "@/i18n/navigation" import Image from "next/image" import { ExternalLink, Database, Server, HardDrive, MonitorIcon } from "lucide-react" import { DocHeader } from "@/components/ui/doc-header" import { Callout } from "@/components/ui/callout" export async function generateMetadata({ params, }: { params: Promise<{ locale: string }> }): Promise { const { locale } = await params const t = await getTranslations({ locale, namespace: "docs.createVm.systemNas.systemNasOthers.meta" }) return { title: t("title"), description: t("description"), openGraph: { title: t("ogTitle"), description: t("ogDescription"), type: "article", url: "https://macrimi.github.io/ProxMenux/docs/create-vm/system-nas/system-nas-others", images: [ { url: "/vm/system-nas-menu.png", width: 1200, height: 630, alt: t("ogImageAlt"), }, ], }, } } type DefaultRow = { param: string; valueRich: string } type AdvancedRow = { param: string; optionsRich: string } type RelatedItem = { href: string; label: string; tail: string } type SystemEntry = { id: string title: string icon: string officialName: string officialUrl: string description: string specs: string[] shellImg?: string webImg?: string shellAlt?: string webAlt?: string } const ICONS: Record> = { Database, Server, HardDrive, MonitorIcon, } export default async function OtherNASSystemsPage({ params, }: { params: Promise<{ locale: string }> }) { const { locale } = await params setRequestLocale(locale) const t = await getTranslations({ locale, namespace: "docs.createVm.systemNas.systemNasOthers" }) const messages = (await getMessages({ locale })) as unknown as { docs: { createVm: { systemNas: { systemNasOthers: { config: { defaultRowsRich: DefaultRow[]; advancedRowsRich: AdvancedRow[] } storagePlan: { virtualItemsRich: string[]; importItemsRich: string[]; pciItemsRich: string[] } endToEnd: { itemsRich: string[] } systems: Record related: { itemsRich: RelatedItem[] } } } } } } const o = messages.docs.createVm.systemNas.systemNasOthers const defaultRows = o.config.defaultRowsRich const advancedRows = o.config.advancedRowsRich const virtualItems = o.storagePlan.virtualItemsRich const importItems = o.storagePlan.importItemsRich const pciItems = o.storagePlan.pciItemsRich const endToEndItems = o.endToEnd.itemsRich const systemOrder = ["truenasScale", "truenasCore", "openmediavault", "xigmanas", "rockstor", "zimaos"] const relatedItems = o.related.itemsRich const code = (chunks: React.ReactNode) => {chunks} const strong = (chunks: React.ReactNode) => {chunks} const em = (chunks: React.ReactNode) => {chunks} const note = (chunks: React.ReactNode) => {chunks} const gpuLink = (chunks: React.ReactNode) => ( {chunks} ) return (
{t.rich("intro.bodyRich", { code })}

{t("config.heading")}

{t("config.intro")}

{t("config.defaultHeading")}

{defaultRows.map((row, idx) => ( ))}
{t("config.headerParam")} {t("config.headerValue")}
{row.param} {t.rich(`config.defaultRowsRich.${idx}.valueRich`, { code, note })}

{t("config.advancedHeading")}

{t("config.advancedIntro")}

{advancedRows.map((row, idx) => ( ))}
{t("config.headerParam")} {t("config.headerOptions")}
{row.param} {t.rich(`config.advancedRowsRich.${idx}.optionsRich`, { code })}
{t("config.zfsCalloutBody")}

{t("storagePlan.heading")}

{t("storagePlan.intro")}

{t("storagePlan.virtualHeading")}

    {virtualItems.map((_, idx) => (
  • {t.rich(`storagePlan.virtualItemsRich.${idx}`, { code })}
  • ))}

{t("storagePlan.importHeading")}

    {importItems.map((_, idx) => (
  • {t.rich(`storagePlan.importItemsRich.${idx}`, { code })}
  • ))}

{t("storagePlan.pciHeading")}

    {pciItems.map((_, idx) => (
  • {t.rich(`storagePlan.pciItemsRich.${idx}`, { code, em })}
  • ))}
{t.rich("storagePlan.resetCalloutBodyRich", { strong })}

{t("gpu.heading")}

{t.rich("gpu.bodyRich", { link: gpuLink })}

{t("autoFeatures.heading")}

{t("autoFeatures.efiTitle")}

{t("autoFeatures.efiBody")}

{t("autoFeatures.isoTitle")}

{t.rich("autoFeatures.isoBodyRich", { code })}

{t("autoFeatures.guestTitle")}

{t("autoFeatures.guestBody")}

{t("endToEnd.heading")}

    {endToEndItems.map((_, idx) => (
  1. {t.rich(`endToEnd.itemsRich.${idx}`, { code })}
  2. ))}

{t("perSystem.heading")}

{systemOrder.map((key) => { const sys = o.systems[key] const Icon = ICONS[sys.icon] ?? Database return ( } officialName={sys.officialName} officialUrl={sys.officialUrl} description={sys.description} specs={sys.specs} shellImg={sys.shellImg} webImg={sys.webImg} shellAlt={sys.shellAlt} webAlt={sys.webAlt} shellLabel={t("perSystem.shellLabel")} webLabel={t("perSystem.webLabel")} /> ) })}

{t("related.heading")}

    {relatedItems.map((item) => (
  • {item.label} {item.tail}
  • ))}
) } interface NASSectionProps { id: string title: string icon: React.ReactNode officialName: string officialUrl: string description: string specs: string[] shellImg?: string webImg?: string shellAlt?: string webAlt?: string shellLabel: string webLabel: string } function NASSection({ id, title, icon, officialName, officialUrl, description, specs, shellImg, webImg, shellAlt, webAlt, shellLabel, webLabel, }: NASSectionProps) { return (

{icon} {title} {officialName}

{description}

    {specs.map((s, i) => (
  • {s}
  • ))}
{(shellImg || webImg) && (
{shellImg && (

{shellLabel}

{shellAlt
)} {webImg && (

{webLabel}

{webAlt
)}
)}
) }