This commit is contained in:
Michel Roegl-Brunner 2025-03-18 16:02:29 +01:00
parent 9e7f276d95
commit 5ba9c81efc
3 changed files with 99 additions and 86 deletions

View File

@ -57,6 +57,7 @@ function ScriptItem({
const os = defaultInstallMethod?.resources?.os || "Proxmox Node";
const version = defaultInstallMethod?.resources?.version || "";
const [linksVisible, setLinksVisible] = useState<boolean>(false);
return (
<div className="mr-7 mt-0 flex w-full min-w-fit">
@ -82,7 +83,7 @@ function ScriptItem({
unoptimized
/>
<div className="ml-4 flex flex-col justify-between">
<div className="flex h-full w-full flex-col justify-between">
<div className="flex h-full w-full flex-col mb-4">
<div>
<h1 className="text-lg font-semibold">
{item.name} {getDisplayValueFromType(item.type)}
@ -126,10 +127,20 @@ function ScriptItem({
<div className="flex flex-col items-end gap-4 ml-auto">
<DefaultSettings item={item} />
<InterFaces item={item} />
<Buttons item={item} />
<div>
<>
<button
onClick={() => setLinksVisible(!linksVisible)}
className="flex items-right justify-right gap-1 mb-2 rounded-md border border-accent bg-accent/20 px-2 py-1 text-l hover:bg-accent w-30"
>
Show Links {linksVisible ? '▲' : '▼'}
</button>
{linksVisible && <Buttons item={item} />}
</>
</div>
</div>
</div>
<Separator className="mt-4" />
<div>
<div className="mt-4">
<Description item={item} />

View File

@ -5,77 +5,78 @@ import { BookOpenText, Code, Globe, RefreshCcw } from "lucide-react";
import Link from "next/link";
const generateInstallSourceUrl = (slug: string) => {
const baseUrl = `https://raw.githubusercontent.com/community-scripts/${basePath}/main`;
return `${baseUrl}/install/${slug}-install.sh`;
const baseUrl = `https://raw.githubusercontent.com/community-scripts/${basePath}/main`;
return `${baseUrl}/install/${slug}-install.sh`;
};
const generateSourceUrl = (slug: string, type: string) => {
const baseUrl = `https://raw.githubusercontent.com/community-scripts/${basePath}/main`;
return type === "vm" ? `${baseUrl}/vm/${slug}.sh` : `${baseUrl}/misc/${slug}.sh`;
return `${baseUrl}/misc/${slug}.sh`;
const baseUrl = `https://raw.githubusercontent.com/community-scripts/${basePath}/main`;
return type === "vm" ? `${baseUrl}/vm/${slug}.sh` : `${baseUrl}/misc/${slug}.sh`;
return `${baseUrl}/misc/${slug}.sh`;
};
const generateUpdateUrl = (slug: string) => {
const baseUrl = `https://raw.githubusercontent.com/community-scripts/${basePath}/main`;
return `${baseUrl}/ct/${slug}.sh`;
const baseUrl = `https://raw.githubusercontent.com/community-scripts/${basePath}/main`;
return `${baseUrl}/ct/${slug}.sh`;
};
interface ButtonLinkProps {
href: string;
icon: React.ReactNode;
text: string;
href: string;
icon: React.ReactNode;
text: string;
}
const ButtonLink = ({ href, icon, text }: ButtonLinkProps) => (
<Button variant="secondary" asChild>
<Link target="_blank" href={href}>
<span className="flex items-center gap-2">
{icon}
{text}
</span>
</Link>
</Button>
<Button variant="secondary" asChild>
<Link target="_blank" href={href}>
<span className="flex items-center gap-2">
{icon}
{text}
</span>
</Link>
</Button>
);
export default function Buttons({ item }: { item: Script }) {
const isCtOrDefault = ["ct"].includes(item.type);
const installSourceUrl = isCtOrDefault ? generateInstallSourceUrl(item.slug) : null;
const updateSourceUrl = isCtOrDefault ? generateUpdateUrl(item.slug) : null;
const sourceUrl = !isCtOrDefault ? generateSourceUrl(item.slug, item.type) : null;
const isCtOrDefault = ["ct"].includes(item.type);
const installSourceUrl = isCtOrDefault ? generateInstallSourceUrl(item.slug) : null;
const updateSourceUrl = isCtOrDefault ? generateUpdateUrl(item.slug) : null;
const sourceUrl = !isCtOrDefault ? generateSourceUrl(item.slug, item.type) : null;
const buttons = [
item.website && {
href: item.website,
icon: <Globe className="h-4 w-4" />,
text: "Website",
},
item.documentation && {
href: item.documentation,
icon: <BookOpenText className="h-4 w-4" />,
text: "Documentation",
},
installSourceUrl && {
href: installSourceUrl,
icon: <Code className="h-4 w-4" />,
text: "Install-Source",
},
updateSourceUrl && {
href: updateSourceUrl,
icon: <RefreshCcw className="h-4 w-4" />,
text: "Update-Source",
},
sourceUrl && {
href: sourceUrl,
icon: <Code className="h-4 w-4" />,
text: "Source Code",
},
].filter(Boolean) as ButtonLinkProps[];
const buttons = [
item.website && {
href: item.website,
icon: <Globe className="h-4 w-4" />,
text: "Website",
},
item.documentation && {
href: item.documentation,
icon: <BookOpenText className="h-4 w-4" />,
text: "Documentation",
},
installSourceUrl && {
href: installSourceUrl,
icon: <Code className="h-4 w-4" />,
text: "Install-Source",
},
updateSourceUrl && {
href: updateSourceUrl,
icon: <RefreshCcw className="h-4 w-4" />,
text: "Update-Source",
},
sourceUrl && {
href: sourceUrl,
icon: <Code className="h-4 w-4" />,
text: "Source Code",
},
].filter(Boolean) as ButtonLinkProps[];
return (
<div className="flex flex-wrap justify-end gap-2">
{buttons.map((props, index) => (
<ButtonLink key={index} {...props} />
))}
</div>
);
return (
<div className="flex flex-wrap justify-end gap-2">
{buttons.map((props, index) => (
<ButtonLink key={index} {...props} />
))}
</div>
);
}

View File

@ -5,37 +5,38 @@ import { cn } from "@/lib/utils";
import { ClipboardIcon } from "lucide-react";
const CopyButton = ({
label,
value,
label,
value,
}: {
label: string;
value: string | number;
label: string;
value: string | number;
}) => (
<span
className={cn(
buttonVariants({ size: "sm", variant: "secondary" }),
"flex items-center gap-2",
)}
>
{value}
<ClipboardIcon
onClick={() => handleCopy(label, String(value))}
className="size-4 cursor-pointer"
/>
</span>
<span
className={cn(
buttonVariants({ size: "sm", variant: "secondary" }),
"flex items-center gap-2",
)}
>
{value}
<ClipboardIcon
onClick={() => handleCopy(label, String(value))}
className="size-4 cursor-pointer"
/>
</span>
);
export default function InterFaces({ item }: { item: Script }) {
return (
<div className="flex flex-col gap-2">
{item.interface_port !== null ? (
<div className="flex items-center justify-end">
<h2 className="mr-2 text-end text-lg font-semibold">
{"Default Interface:"}
</h2>{" "}
<CopyButton label="default interface" value={item.interface_port} />
return (
<div className="flex flex-col gap-2">
{item.interface_port !== null ? (
<div className="flex items-center justify-end">
<h2 className="mr-2 text-end text-l font-semibold">
{"Default Interface:"}
</h2>{" "}
<CopyButton label="default interface" value={item.interface_port} />
</div>
) : null}
</div>
) : null}
</div>
);
);
}