import type { Metadata } from "next" import { getTranslations, getMessages, setRequestLocale } from "next-intl/server" import { Link } from "@/i18n/navigation" import Image from "next/image" import { ArrowRight, HardDrive, Server, Network, FolderOpen, Database, Share2, Download, Upload, Link2, } 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.storageShare.meta" }) return { title: t("title"), description: t("description"), keywords: [ "proxmox nfs", "proxmox samba", "proxmox cifs", "proxmox iscsi", "proxmox lxc mount points", "proxmox bind mount", "proxmox shared storage", "proxmox storage share", "proxmox nfs server lxc", "proxmox samba server lxc", ], alternates: { canonical: "https://proxmenux.com/docs/storage-share" }, openGraph: { title: t("ogTitle"), description: t("ogDescription"), type: "article", url: "https://proxmenux.com/docs/storage-share", }, twitter: { card: "summary", title: t("twitterTitle"), description: t("twitterDescription"), }, } } type OptionData = { href: string; icon: string; title: string; description: string } type StringItem = string const ICONS: Record> = { Network, Share2, Database, HardDrive, FolderOpen, Download, Upload, Link2, } function OptionCard({ option }: { option: OptionData }) { const Icon = ICONS[option.icon] || Network return (
{option.title}
{option.description}
) } export default async function StorageShareOverviewPage({ params, }: { params: Promise<{ locale: string }> }) { const { locale } = await params setRequestLocale(locale) const t = await getTranslations({ locale, namespace: "docs.storageShare" }) const messages = (await getMessages({ locale })) as unknown as { docs: { storageShare: { groups: { hostItems: StringItem[]; lxcMountItems: StringItem[]; lxcNetItems: StringItem[] } host: { options: OptionData[] } lxcNet: { options: OptionData[] } } } } const hostItems = messages.docs.storageShare.groups.hostItems const lxcMountItems = messages.docs.storageShare.groups.lxcMountItems const lxcNetItems = messages.docs.storageShare.groups.lxcNetItems const hostOptions = messages.docs.storageShare.host.options const lxcNetOptions = messages.docs.storageShare.lxcNet.options const code = (chunks: React.ReactNode) => {chunks} const strong = (chunks: React.ReactNode) => {chunks} const em = (chunks: React.ReactNode) => {chunks} const mountLink = (chunks: React.ReactNode) => ( {chunks} ) return (
{t.rich("intro.body", { em, strong })}

{t("opening.heading")}

{t.rich("opening.body", { strong })}

{t("opening.imageAlt")}

{t("groups.heading")}

{t.rich("groups.intro", { strong, em })}

{t("groups.hostTitle")}

{t.rich("groups.hostBody", { code })}

    {hostItems.map((_, idx) => (
  • {t(`groups.hostItems.${idx}`)}
  • ))}

{t("groups.lxcMountTitle")}

{t.rich("groups.lxcMountBody", { code })}

    {lxcMountItems.map((_, idx) => (
  • {t.rich(`groups.lxcMountItems.${idx}`, { code })}
  • ))}

{t("groups.lxcNetTitle")}

{t.rich("groups.lxcNetBody", { strong })}

    {lxcNetItems.map((_, idx) => (
  • {t.rich(`groups.lxcNetItems.${idx}`, { strong })}
  • ))}

{t("host.heading")}

{t.rich("host.intro", { code, strong })}

{hostOptions.map((o) => ( ))}

{t("lxcMount.heading")}

{t.rich("lxcMount.intro", { code })}

{t("lxcNet.heading")}

{t.rich("lxcNet.intro", { em, mountLink })}

{lxcNetOptions.map((o) => ( ))}
{t.rich("privReq.body", { strong, code, mountLink })} {t.rich("unprivExplain.body", { strong, em, code })}

{t("scripts.heading")}

{t("scripts.intro")}

) }