Skip to content

Commit

Permalink
Use static assets instead of fetching from github (community-scripts#156
Browse files Browse the repository at this point in the history
)
  • Loading branch information
havardthom authored Nov 9, 2024
1 parent 2af11d1 commit d199762
Show file tree
Hide file tree
Showing 18 changed files with 135 additions and 106 deletions.
1 change: 1 addition & 0 deletions frontend/public/json
53 changes: 32 additions & 21 deletions frontend/src/app/api/categories/route.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import { basePath } from "@/config/siteConfig";
import { Category, Script } from "@/lib/types";
import { Metadata, Script } from "@/lib/types";
import { promises as fs } from "fs";
import { NextResponse } from "next/server";
import path from "path";

export const dynamic = "force-static";

const fetchCategories = async (): Promise<Category[]> => {
const response = await fetch(
`https://raw.githubusercontent.com/community-scripts/${basePath}/refs/heads/main/json/metadata.json`,
);
const data = await response.json();
return data.categories;
const jsonDir = "public/json";
const metadataFileName = "metadata.json";
const encoding = "utf-8";

const getMetadata = async () => {
const filePath = path.resolve(jsonDir, metadataFileName);
const fileContent = await fs.readFile(filePath, encoding);
const metadata: Metadata = JSON.parse(fileContent);
return metadata;
};

const fetchScripts = async (): Promise<Script[]> => {
const response = await fetch(
`https://api.github.com/repos/community-scripts/${basePath}/contents/json`,
);
const files: { download_url: string }[] = await response.json();
const getScripts = async () => {
const filePaths = (await fs.readdir(jsonDir))
.filter((fileName) => fileName !== metadataFileName)
.map((fileName) => path.resolve(jsonDir, fileName));

const scripts = await Promise.all(
files.map(async (file) : Promise<Script> => {
const response = await fetch(file.download_url);
const script = await response.json();
filePaths.map(async (filePath) => {
const fileContent = await fs.readFile(filePath, encoding);
const script: Script = JSON.parse(fileContent);
return script;
}),
);
Expand All @@ -29,11 +33,18 @@ const fetchScripts = async (): Promise<Script[]> => {

export async function GET() {
try {
const categories = await fetchCategories();
const scripts = await fetchScripts();
for (const category of categories) {
category.scripts = scripts.filter((script) => script.categories.includes(category.id));
}
const metadata = await getMetadata();
const scripts = await getScripts();

const categories = metadata.categories
.map((category) => {
category.scripts = scripts.filter((script) =>
script.categories.includes(category.id),
);
return category;
})
.sort((a, b) => a.sort_order - b.sort_order);

return NextResponse.json(categories);
} catch (error) {
console.error(error as Error);
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import Footer from "@/components/Footer";
import Navbar from "@/components/Navbar";
import { ThemeProvider } from "@/components/theme-provider";
import { Toaster } from "@/components/ui/sonner";
import { analytics, basePath } from "@/config/siteConfig";
import "@/styles/globals.css";
import { Inter } from "next/font/google";
import React from "react";
import { NuqsAdapter } from "nuqs/adapters/next/app";
import { analytics, basePath } from "@/config/siteConfig";
import React from "react";

const inter = Inter({ subsets: ["latin"] });

Expand Down Expand Up @@ -65,7 +65,6 @@ export default function RootLayout({
data-website-id={analytics.token}
></script>
<link rel="manifest" href="manifest.webmanifest" />
<link rel="preconnect" href={process.env.NEXT_PUBLIC_POCKETBASE_URL} />
<link rel="preconnect" href="https://api.github.com" />
</head>
<body className={inter.className}>
Expand Down
15 changes: 11 additions & 4 deletions frontend/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
"use client";
import AnimatedGradientText from "@/components/ui/animated-gradient-text";
import Particles from "@/components/ui/particles";
import { Button } from "@/components/ui/button";
import { CardFooter } from "@/components/ui/card";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import Particles from "@/components/ui/particles";
import { Separator } from "@/components/ui/separator";
import { basePath } from "@/config/siteConfig";
import { cn } from "@/lib/utils";
import { ArrowRightIcon, ExternalLink } from "lucide-react";
import { useTheme } from "next-themes";
import Link from "next/link";
import { useEffect, useState } from "react";
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { CardFooter } from "@/components/ui/card";
import { FaGithub } from "react-icons/fa";
import { basePath } from "@/config/siteConfig";

function CustomArrowRightIcon() {
return <ArrowRightIcon className="h-4 w-4" width={1} />;
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/app/scripts/_components/ScriptItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ function ScriptItem({
<div className="ml-4 flex flex-col justify-between">
<div className="flex h-full w-full flex-col justify-between">
<div>
<h1 className="text-lg font-semibold">{item.name} {getDisplayValueFromType(item.type)}</h1>
<h1 className="text-lg font-semibold">
{item.name} {getDisplayValueFromType(item.type)}
</h1>
<p className="w-full text-sm text-muted-foreground">
Date added: {extractDate(item.date_created)}
</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import handleCopy from "@/components/handleCopy";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import handleCopy from "@/components/handleCopy";
import { Script } from "@/lib/types";

export default function DefaultPassword({ item }: { item: Script }) {
const hasDefaultLogin = item.default_credentials.username && item.default_credentials.password;
const hasDefaultLogin =
item.default_credentials.username && item.default_credentials.password;

return (
<div>
Expand All @@ -25,7 +26,10 @@ export default function DefaultPassword({ item }: { item: Script }) {
variant={"secondary"}
size={"null"}
onClick={() =>
handleCopy("username", item.default_credentials.username ?? "")
handleCopy(
"username",
item.default_credentials.username ?? "",
)
}
>
{item.default_credentials.username}
Expand All @@ -37,7 +41,10 @@ export default function DefaultPassword({ item }: { item: Script }) {
variant={"secondary"}
size={"null"}
onClick={() =>
handleCopy("password", item.default_credentials.password ?? "")
handleCopy(
"password",
item.default_credentials.password ?? "",
)
}
>
{item.default_credentials.password}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ export default function DefaultSettings({ item }: { item: Script }) {
CPU: {defaultAlpineSettings?.resources.cpu}vCPU
</p>
<p className="text-sm text-muted-foreground">
RAM: {getDisplayValueFromRAM(defaultAlpineSettings?.resources.ram ?? 0)}
RAM:{" "}
{getDisplayValueFromRAM(defaultAlpineSettings?.resources.ram ?? 0)}
</p>
<p className="text-sm text-muted-foreground">
HDD: {defaultAlpineSettings?.resources.hdd}GB
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import { getDisplayValueFromType } from "../ScriptInfoBlocks";

const getInstallCommand = (scriptPath?: string) => {
return `bash -c "$(wget -qLO - https://github.com/community-scripts/${basePath}/raw/main/${scriptPath})"`;
}
};

export default function InstallCommand({ item }: { item: Script }) {
const alpineScript = item.install_methods.find(
(method) => method.type === "alpine",
);

const defaultScript = item.install_methods.find(
(method) => method.type === "default"
(method) => method.type === "default",
);

const renderInstructions = (isAlpine = false) => (
Expand Down Expand Up @@ -60,7 +60,9 @@ export default function InstallCommand({ item }: { item: Script }) {
</TabsList>
<TabsContent value="default">
{renderInstructions()}
<CodeCopyButton>{getInstallCommand(defaultScript?.script)}</CodeCopyButton>
<CodeCopyButton>
{getInstallCommand(defaultScript?.script)}
</CodeCopyButton>
</TabsContent>
<TabsContent value="alpine">
{renderInstructions(true)}
Expand Down
19 changes: 10 additions & 9 deletions frontend/src/app/scripts/_components/ScriptItems/InterFaces.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Button, buttonVariants } from "@/components/ui/button";
import handleCopy from "@/components/handleCopy";
import { buttonVariants } from "@/components/ui/button";
import { Script } from "@/lib/types";
import { cn } from "@/lib/utils";
import { ClipboardIcon } from "lucide-react";
import { Script } from "@/lib/types";

const CopyButton = ({
label,
Expand All @@ -11,7 +11,12 @@ const CopyButton = ({
label: string;
value: string | number;
}) => (
<span className={cn(buttonVariants({size: "sm", variant: "secondary"}), "flex items-center gap-2")}>
<span
className={cn(
buttonVariants({ size: "sm", variant: "secondary" }),
"flex items-center gap-2",
)}
>
{value}
<ClipboardIcon
onClick={() => handleCopy(label, String(value))}
Expand All @@ -20,19 +25,15 @@ const CopyButton = ({
</span>
);

export default function InterFaces({item} : {item : Script}) {

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}
/>
<CopyButton label="default interface" value={item.interface_port} />
</div>
) : null}
</div>
Expand Down
11 changes: 6 additions & 5 deletions frontend/src/app/scripts/_components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ const Sidebar = ({
<div className="flex items-end justify-between pb-4">
<h1 className="text-xl font-bold">Categories</h1>
<p className="text-xs italic text-muted-foreground">
{items.reduce(
(acc, category) => acc + category.scripts.length,
0,
)}{" "}
{items.reduce((acc, category) => acc + category.scripts.length, 0)}{" "}
Total scripts
</p>
</div>
<div className="rounded-lg">
<ScriptAccordion items={items} selectedScript={selectedScript} setSelectedScript={setSelectedScript} />
<ScriptAccordion
items={items}
selectedScript={selectedScript}
setSelectedScript={setSelectedScript}
/>
</div>
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/ui/codeblock.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import { basePath } from "@/config/siteConfig";
import { cn } from "@/lib/utils";
import { cva, type VariantProps } from "class-variance-authority";
import { Clipboard, Copy } from "lucide-react";
Expand All @@ -8,7 +9,6 @@ import * as React from "react";
import { toast } from "sonner";
import { Button } from "./button";
import { Separator } from "./separator";
import { basePath } from "@/config/siteConfig";

const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
Expand Down Expand Up @@ -135,4 +135,4 @@ const CodeBlock = React.forwardRef<HTMLDivElement, CodeBlockProps>(
);
CodeBlock.displayName = "CodeBlock";

export { CodeBlock, buttonVariants };
export { buttonVariants, CodeBlock };
2 changes: 1 addition & 1 deletion frontend/src/components/ui/navigation-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,6 @@ export {
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
NavigationMenuViewport,
navigationMenuTriggerStyle,
NavigationMenuViewport,
};
13 changes: 8 additions & 5 deletions frontend/src/components/ui/star-on-github-button.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { basePath } from "@/config/siteConfig";
import { cn } from "@/lib/utils";
import Link from "next/link";
import { useEffect, useState } from "react";
import { FaGithub, FaStar } from "react-icons/fa";
import NumberTicker from "./number-ticker";
import { buttonVariants } from "./button";
import { basePath } from "@/config/siteConfig";
import NumberTicker from "./number-ticker";

export default function StarOnGithubButton() {
const [stars, setStars] = useState(0);

useEffect(() => {
const fetchStars = async () => {
try {
const res = await fetch(`https://api.github.com/repos/community-scripts/${basePath}`, {
next: { revalidate: 60 * 60 * 24 },
});
const res = await fetch(
`https://api.github.com/repos/community-scripts/${basePath}`,
{
next: { revalidate: 60 * 60 * 24 },
},
);

if (res.ok) {
const data = await res.json();
Expand Down
9 changes: 7 additions & 2 deletions frontend/src/components/ui/theme-toggle.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
"use client";

import { MoonIcon, SunIcon } from "@radix-ui/react-icons";
import { useTheme } from "next-themes";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./tooltip";
import { Button } from "./button";
import { MoonIcon, SunIcon } from "@radix-ui/react-icons";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "./tooltip";

export function ThemeToggle() {
const { setTheme, theme: currentTheme } = useTheme();
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/config/siteConfig.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MessagesSquare, Scroll } from "lucide-react";
import { FaGithub } from "react-icons/fa";

export const basePath = process.env.BASE_PATH;
export const basePath = process.env.BASE_PATH;

export const navbarLinks = [
{
Expand All @@ -17,7 +17,7 @@ export const navbarLinks = [
text: "Change Log",
},
{
href: `https://github.com/community-scripts/${basePath}/discussions`,
href: `https://github.com/community-scripts/${basePath}/discussions`,
event: "Discussions",
icon: <MessagesSquare className="h-4 w-4" />,
text: "Discussions",
Expand Down
Loading

0 comments on commit d199762

Please sign in to comment.