diff --git a/src/components/AssetCard.astro b/src/components/AssetCard.astro new file mode 100644 index 0000000..865b0b2 --- /dev/null +++ b/src/components/AssetCard.astro @@ -0,0 +1,24 @@ +--- +interface Props { + asset: Asset; +} +import { Image } from "astro:assets"; +import { ASSET_URL, type Asset } from "@/lib/asset"; +import { Ban, CircleAlert, UserRoundPlus } from "lucide-astro"; + +const { asset } = Astro.props; +--- + + diff --git a/src/lib/asset-script.ts b/src/lib/asset-script.ts index f6ba009..632b6c9 100644 --- a/src/lib/asset-script.ts +++ b/src/lib/asset-script.ts @@ -1,3 +1,4 @@ +import { navigate } from "astro:transitions/client"; import type { Asset } from "@/lib/asset"; document.addEventListener("astro:page-load", () => { const buttons = document.querySelectorAll( @@ -23,4 +24,22 @@ document.addEventListener("astro:page-load", () => { } }); } + const assetAdd = document.getElementById("add-asset") as HTMLButtonElement | null; + if (assetAdd) { + assetAdd.addEventListener("click", async () => { + const type = assetAdd.dataset.type; + const name = prompt(`Enter the name of the ${type}`); + if (!name) return alert("Invalid name"); + const link = prompt(`Enter the link of the ${type}`); + if (!link) return alert("Invalid link"); + const response = await fetch("/api/add-asset", { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ type, name, link }), + }); + const json = await response.json(); + if (json.error) return alert(json.error); + if (json.success) return navigate(location.pathname); + }); + } }); diff --git a/src/lib/asset.ts b/src/lib/asset.ts index 938cc6e..16bb943 100644 --- a/src/lib/asset.ts +++ b/src/lib/asset.ts @@ -7,6 +7,7 @@ export type Asset = { link?: string; links?: { name: string; url: string }[]; say?: string; + custom?: boolean; partial?: boolean | string; error?: boolean | string; blank?: boolean | string; diff --git a/src/pages/ap.astro b/src/pages/ap.astro index 411ed42..e9bfef0 100644 --- a/src/pages/ap.astro +++ b/src/pages/ap.astro @@ -1,33 +1,24 @@ --- -import { Image } from "astro:assets"; -import Obfuscated from "@/components/Obfuscated.astro"; +import AssetCard from "@/components/AssetCard.astro"; import Layout from "@/layouts/Main.astro"; import { ASSET_URL, type Asset } from "@/lib/asset"; -import { LayoutGrid } from "lucide-astro"; +import { LayoutGrid, PlusCircle } from "lucide-astro"; const apps: Asset[] = await (await fetch(`${ASSET_URL}/json/apps.json`)).json(); +const customApps = (Astro.cookies.get("asset.app")?.json() as Asset[]) ?? []; --- -
-
+
+
Apps
+
- { - apps.map((app) => ( - - )) - } + {[...customApps, ...apps].map((app) => )}
diff --git a/src/pages/api/add-asset.ts b/src/pages/api/add-asset.ts new file mode 100644 index 0000000..56c617f --- /dev/null +++ b/src/pages/api/add-asset.ts @@ -0,0 +1,28 @@ +import type { Asset } from "@/lib/asset"; +import type { APIRoute } from "astro"; + +export const PUT: APIRoute = async ({ cookies, request }) => { + const body = (await request.json()) as { + type: string; + name: string; + link: string; + }; + if (!body.type || !body.name || !body.link) { + return Response.json({ error: "Missing required fields" }, { status: 400 }); + } + if (!["app", "game"].includes(body.type)) { + return Response.json({ error: "Invalid asset type" }, { status: 400 }); + } + const currentAssets: Asset[] = cookies.get(`asset.${body.type}`)?.json() || []; + currentAssets.push({ + name: body.name, + link: body.link, + image: "/media/icons/custom.webp", + custom: true, + }); + cookies.set(`asset.${body.type}`, JSON.stringify(currentAssets), { + path: "/", + expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365), + }); + return Response.json({ success: true }); +}; diff --git a/src/pages/ga.astro b/src/pages/ga.astro index 051b1c8..dbf565e 100644 --- a/src/pages/ga.astro +++ b/src/pages/ga.astro @@ -1,33 +1,24 @@ --- -import { Image } from "astro:assets"; -import Obfuscated from "@/components/Obfuscated.astro"; +import AssetCard from "@/components/AssetCard.astro"; import Layout from "@/layouts/Main.astro"; import { ASSET_URL, type Asset } from "@/lib/asset"; -import { Gamepad2 } from "lucide-astro"; +import { Gamepad2, PlusCircle } from "lucide-astro"; const games: Asset[] = await (await fetch(`${ASSET_URL}/json/games.json`)).json(); +const customGames = (Astro.cookies.get("asset.game")?.json() as Asset[]) ?? []; --- -
-
+
+
Games
+
- { - games.map((game) => ( - - )) - } + {[...customGames, ...games].map((game) => )}
diff --git a/src/pages/to.astro b/src/pages/to.astro index 39646e5..54d58eb 100644 --- a/src/pages/to.astro +++ b/src/pages/to.astro @@ -1,6 +1,5 @@ --- -import { Image } from "astro:assets"; -import Obfuscated from "@/components/Obfuscated.astro"; +import AssetCard from "@/components/AssetCard.astro"; import Layout from "@/layouts/Main.astro"; import { ASSET_URL, type Asset } from "@/lib/asset"; import { Wrench } from "lucide-astro"; @@ -14,16 +13,7 @@ const tools: Asset[] = await (await fetch(`${ASSET_URL}/json/tools.json`)).json( Tools
- { - tools.map((tool) => ( - - )) - } + {tools.map((tool) => )}