"use client"; import { useEffect, useMemo, useRef, useState } from "react"; import dynamic from "next/dynamic"; import { useRouter, useSearchParams } from "next/navigation"; import { cn } from "@/lib/utils"; type Item = { key: string; // used in ?t= label: string; note?: string; icon?: string; // optional icon (public/images/utils/) href?: string; // optional absolute URL (used if no component) component?: React.ComponentType<{ embedded?: boolean }>; }; // Lazy-load heavy utilities const BackgroundRemoverPanel = dynamic( () => import("@/components/utilities/BackgroundRemoverPanel"), { ssr: false } ); const SVGNestPanel = dynamic(() => import("@/components/utilities/SVGNestPanel"), { ssr: false, }); const LaserToolkitSwitcher = dynamic( () => import("@/components/portal/LaserToolkitSwitcher"), { ssr: false } ); // Inline File Server const FileBrowserPanel = dynamic( () => import("@/components/utilities/files/FileBrowserPanel"), { ssr: false } ); const ITEMS: Item[] = [ { key: "laser-toolkit", label: "Laser Toolkit", note: "convert laser settings, interval and more", icon: "toolkit.png", component: LaserToolkitSwitcher, href: "/laser-toolkit", }, { key: "files", label: "File Server", note: "download from our file explorer", icon: "fs.png", component: FileBrowserPanel, href: "/files", }, { key: "svgnest", label: "SVGnest", note: "automatically nests parts and exports svg", icon: "nest.png", component: SVGNestPanel, href: "/svgnest", }, { key: "background-remover", label: "BG Remover", note: "open source background remover", icon: "bgrm.png", component: BackgroundRemoverPanel, href: "/background-remover", }, // These stay on makearmy (external services) { key: "picsur", label: "Picsur", note: "Simple Image Host", icon: "picsur.png", href: "https://images.makearmy.io", }, { key: "privatebin", label: "PrivateBin", note: "Encrypted internet clipboard", icon: "privatebin.png", href: "https://paste.makearmy.io/", }, { key: "forgejo", label: "Forgejo", note: "git for our community members", icon: "forge.png", href: "https://forge.makearmy.io", }, ]; function isAbsoluteUrl(href: string) { return /^https?:\/\//i.test(href); } /** * External if it's an absolute URL and NOT same-origin as the current site. * Relative paths are always internal. */ function isExternalHref(href?: string) { if (!href) return false; if (!isAbsoluteUrl(href)) return false; try { const u = new URL(href); if (typeof window === "undefined") return true; return u.origin !== window.location.origin; } catch { return true; } } /** * If href is absolute AND same-origin, convert it to a site-relative path. * Otherwise return as-is. */ function toSameOriginPath(href: string) { if (!isAbsoluteUrl(href)) return href; try { const u = new URL(href); if (typeof window === "undefined") return href; if (u.origin === window.location.origin) { return `${u.pathname}${u.search}${u.hash}`; } } catch {} return href; } function Panel({ item }: { item: Item }) { if (item.component) { const Cmp = item.component; return (
{/* Removed notes/headers to keep UI clean */}
); } const href = item.href || "/"; const external = isExternalHref(href); if (external) { return (
Open {item.label}
); } const src = toSameOriginPath(href); return (