From 7385705c8de0b7e8a901bb5cda0b60a4ff9310eb Mon Sep 17 00:00:00 2001 From: dvelo <52332868+DeveloLongScript@users.noreply.github.com> Date: Fri, 21 Mar 2025 08:36:05 -0500 Subject: [PATCH] feat: custom filters --- apps/www/next.config.mjs | 3 + apps/www/package.json | 1 + .../server/{ => v2/minehut}/[server]/page.tsx | 0 .../app/(sl-modification-frame)/layout.tsx | 95 ++ .../[category]/modification/[mod]/page.tsx | 79 + .../category/[category]/page.tsx | 91 ++ .../file/[filename]/page.tsx | 150 ++ .../sl-modification-frame/files/page.tsx | 54 + .../embedded/sl-modification-frame/page.tsx | 101 ++ .../modification/modification-action.tsx | 26 + .../modification/modification-button.tsx | 47 + .../modification-file-creation-dialog.tsx | 126 ++ .../modification/modification-frame.tsx | 47 + .../feat/server-list/server-card.tsx | 4 +- .../feat/server-list/server-list.tsx | 6 +- .../reporting/reporting-dialog.tsx | 52 +- .../feat/server-page/server-page-buttons.tsx | 4 + apps/www/src/components/ui/text-area.tsx | 3 +- .../www/src/components/util/font-boundary.tsx | 4 +- .../util/iframe-protector.tsx} | 59 +- apps/www/src/config/sl-mod-db.ts | 76 + apps/www/src/lib/discord.ts | 98 ++ .../lib/hooks/use-iframe-communication.tsx | 64 + apps/www/src/lib/hooks/use-mhsf-server.tsx | 1 + apps/www/src/lib/types/filter.ts | 37 + apps/www/src/lib/types/mh-server.d.ts | 27 + apps/www/src/lib/types/mh-server.ts | 30 + apps/www/src/lib/types/mhsf.d.ts | 29 + apps/www/src/lib/types/sort.ts | 37 + apps/www/src/middleware.ts | 47 +- apps/www/src/pages/api/inngest.ts | 15 - .../v1/server/get/[server]/report-server.ts | 16 +- apps/www/src/poimandres-monaco.json | 1406 +++++++++++++++++ apps/www/src/theme.json | 1393 ++++++++++++++++ yarn.lock | 5 + 35 files changed, 4161 insertions(+), 72 deletions(-) rename apps/www/src/app/(main)/server/{ => v2/minehut}/[server]/page.tsx (100%) create mode 100644 apps/www/src/app/(sl-modification-frame)/layout.tsx create mode 100644 apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/category/[category]/modification/[mod]/page.tsx create mode 100644 apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/category/[category]/page.tsx create mode 100644 apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/file/[filename]/page.tsx create mode 100644 apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/files/page.tsx create mode 100644 apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/page.tsx create mode 100644 apps/www/src/components/feat/server-list/modification/modification-action.tsx create mode 100644 apps/www/src/components/feat/server-list/modification/modification-button.tsx create mode 100644 apps/www/src/components/feat/server-list/modification/modification-file-creation-dialog.tsx create mode 100644 apps/www/src/components/feat/server-list/modification/modification-frame.tsx rename apps/www/src/{lib/linear.ts => components/util/iframe-protector.tsx} (53%) create mode 100644 apps/www/src/config/sl-mod-db.ts create mode 100644 apps/www/src/lib/discord.ts create mode 100644 apps/www/src/lib/hooks/use-iframe-communication.tsx create mode 100644 apps/www/src/lib/types/filter.ts create mode 100644 apps/www/src/lib/types/mh-server.d.ts create mode 100644 apps/www/src/lib/types/mhsf.d.ts create mode 100644 apps/www/src/lib/types/sort.ts create mode 100644 apps/www/src/poimandres-monaco.json create mode 100644 apps/www/src/theme.json diff --git a/apps/www/next.config.mjs b/apps/www/next.config.mjs index a93010b..467a269 100644 --- a/apps/www/next.config.mjs +++ b/apps/www/next.config.mjs @@ -49,6 +49,9 @@ const nextConfig = { }, ] }, + webpack: (config) => { + return config; + }, }; export default withContentlayer(nextConfig); diff --git a/apps/www/package.json b/apps/www/package.json index e8026bb..abe33f2 100644 --- a/apps/www/package.json +++ b/apps/www/package.json @@ -55,6 +55,7 @@ "mini-svg-data-uri": "^1.4.4", "minimessage-2-html": "1.6.0", "minimessage-js": "^1.1.3", + "monaco-editor": "^0.52.2", "mongodb": "^6.8.0", "next": "15.2.0", "next-contentlayer": "^0.3.4", diff --git a/apps/www/src/app/(main)/server/[server]/page.tsx b/apps/www/src/app/(main)/server/v2/minehut/[server]/page.tsx similarity index 100% rename from apps/www/src/app/(main)/server/[server]/page.tsx rename to apps/www/src/app/(main)/server/v2/minehut/[server]/page.tsx diff --git a/apps/www/src/app/(sl-modification-frame)/layout.tsx b/apps/www/src/app/(sl-modification-frame)/layout.tsx new file mode 100644 index 0000000..7fb0827 --- /dev/null +++ b/apps/www/src/app/(sl-modification-frame)/layout.tsx @@ -0,0 +1,95 @@ +/* + * MHSF, Minehut Server List + * All external content is rather licensed under the ECA Agreement + * located here: https://mhsf.app/docs/legal/external-content-agreement + * + * All code under MHSF is licensed under the MIT License + * by open source contributors + * + * Copyright (c) 2025 dvelo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +"use client"; +import "../globals.css"; +import { useSearchParams } from "next/navigation"; +import { Placeholder } from "@/components/ui/placeholder"; +import { X } from "lucide-react"; +import { IsScript } from "@/components/util/is-script"; +import { Button } from "@/components/ui/button"; +import Link from "next/link"; +import { NavBar } from "@/components/feat/navbar/navbar"; +import { TooltipProvider } from "@/components/ui/tooltip"; +import { ThemeProvider } from "@/components/util/theme-provider"; +import { FontBoundary } from "@/components/util/font-boundary"; +import { ClerkProvider } from "@/components/util/clerk-provider"; +import { Toaster } from "sonner"; +import { Footer } from "@/components/feat/footer/footer"; +import { NuqsAdapter } from "nuqs/adapters/next/app"; +import { IframeProtector } from "@/components/util/iframe-protector"; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + const searchParams = useSearchParams(); + const search = searchParams?.get("theme") || "light"; + + return ( + + + + + + + + + + +
{children}
+
+
+
+
+
+
+
+ + ); +} diff --git a/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/category/[category]/modification/[mod]/page.tsx b/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/category/[category]/modification/[mod]/page.tsx new file mode 100644 index 0000000..22a09c7 --- /dev/null +++ b/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/category/[category]/modification/[mod]/page.tsx @@ -0,0 +1,79 @@ +/* + * MHSF, Minehut Server List + * All external content is rather licensed under the ECA Agreement + * located here: https://mhsf.app/docs/legal/external-content-agreement + * + * All code under MHSF is licensed under the MIT License + * by open source contributors + * + * Copyright (c) 2025 dvelo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +"use client"; + +import { ModificationAction } from "@/components/feat/server-list/modification/modification-action"; +import { Button } from "@/components/ui/button"; +import { Link } from "@/components/util/link"; +import { serverModDB } from "@/config/sl-mod-db"; +import { ArrowLeft } from "lucide-react"; +import { useQueryState } from "nuqs"; +import { use } from "react"; +import Markdown from "react-markdown"; + +export default function ModificationPage({ + params, +}: { + params: Promise<{ category: string; mod: string }>; +}) { + const { category, mod } = use(params); + const [backRoute] = useQueryState("b", { + defaultValue: "/servers/embedded/sl-modification-frame", + }); + console.log(mod); + const categoryObj = serverModDB.find( + (c) => c.displayTitle === atob(decodeURIComponent(category)) + ); + let modObj = null; + if (categoryObj !== undefined) + modObj = categoryObj?.entries.find( + (c) => c.name === atob(decodeURIComponent(mod)) + ); + + return ( +
+
+ + + +
+ + +

{modObj?.name}

+ {modObj?.description} + +
+
+ ); +} diff --git a/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/category/[category]/page.tsx b/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/category/[category]/page.tsx new file mode 100644 index 0000000..c288e5e --- /dev/null +++ b/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/category/[category]/page.tsx @@ -0,0 +1,91 @@ +/* + * MHSF, Minehut Server List + * All external content is rather licensed under the ECA Agreement + * located here: https://mhsf.app/docs/legal/external-content-agreement + * + * All code under MHSF is licensed under the MIT License + * by open source contributors + * + * Copyright (c) 2025 dvelo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +"use client"; + +import { ModificationAction } from "@/components/feat/server-list/modification/modification-action"; +import { Material } from "@/components/ui/material"; +import { Link } from "@/components/util/link"; +import { serverModDB } from "@/config/sl-mod-db"; +import { useRouter } from "@/lib/useRouter"; +import { cn } from "@/lib/utils"; +import { ArrowLeft } from "lucide-react"; +import { use } from "react"; +import Markdown from "react-markdown"; + +export default function ServerListCategoryFrame({ + params, +}: { + params: Promise<{ category: string }>; +}) { + const { category } = use(params); + const categoryObj = serverModDB.find( + (c) => c.displayTitle === atob(category) + ); + const router = useRouter(); + + return ( +
+

+ + + + {categoryObj?.displayTitle} +

+ {categoryObj?.description} + +
+ {categoryObj?.entries.map((m) => ( + + router.push( + `/servers/embedded/sl-modification-frame/category/${category}/modification/${btoa(m.name)}?b=${encodeURIComponent(`/servers/embedded/sl-modification-frame/category/${category}`)}` + ) + } + key={m.name} + > +
+ +
+ + {m.name} + +
+ ))} +
+
+ ); +} diff --git a/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/file/[filename]/page.tsx b/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/file/[filename]/page.tsx new file mode 100644 index 0000000..dd571fc --- /dev/null +++ b/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/file/[filename]/page.tsx @@ -0,0 +1,150 @@ +"use client"; + +import { use } from "react"; +import { useUser } from "@clerk/nextjs"; +import type { ClerkCustomModification } from "@/components/feat/server-list/modification/modification-file-creation-dialog"; +import { Link } from "@/components/util/link"; +import { ArrowLeft } from "lucide-react"; +import Editor from "@monaco-editor/react"; +import poimandres from "@/theme.json"; + +const typeDefs = ` +export interface Server { + staticInfo: { + _id: string; + serverPlan: string; + serviceStartDate: number; + platform: string; + planMaxPlayers: number; + planRam: number; + alwaysOnline: boolean; + rawPlan: string; + connectedServers: any[]; + }; + maxPlayers: number; + name: string; + motd: string; + icon: string; + playerData: { + playerCount: number; + timeNoPlayers: number; + }; + connectable: boolean; + visibility: boolean; + allCategories: string[]; + usingCosmetics: boolean; + author?: string; + authorRank: string; +} +`; + +export default function CustomFilePage({ + params, +}: { + params: Promise<{ filename: string }>; +}) { + const { filename } = use(params); + const { user } = useUser(); + const file = ( + (user?.unsafeMetadata.customFiles as Array) ?? [] + ).find((c) => c.name === filename); + + if (!file) { + return <>Bruh.; + } + + const fileContents = file.contents; + + return ( +
+ + + + + {filename}.ts + +
+ { + // Ensure TypeScript is properly configured + monaco.languages.typescript.typescriptDefaults.setCompilerOptions({ + target: monaco.languages.typescript.ScriptTarget.Latest, + allowNonTsExtensions: true, // This is important! + moduleResolution: + monaco.languages.typescript.ModuleResolutionKind.NodeJs, + module: monaco.languages.typescript.ModuleKind.CommonJS, + noEmit: true, + esModuleInterop: true, + jsx: monaco.languages.typescript.JsxEmit.React, + reactNamespace: "React", + allowJs: true, + typeRoots: ["node_modules/@types"], + }); + + // Create a virtual TS file for the types + const libUri = "file:///node_modules/@types/mhsf/index.d.ts"; + + // Add typedefs as a library + monaco.languages.typescript.typescriptDefaults.addExtraLib( + typeDefs, + libUri, + ); + + // Create a model for the libUri file + if (!monaco.editor.getModel(monaco.Uri.parse(libUri))) { + monaco.editor.createModel( + typeDefs, + "typescript", + monaco.Uri.parse(libUri), + ); + } + + // Make sure the current file is using the correct language + const currentModel = editor.getModel(); + if (currentModel) { + monaco.editor.setModelLanguage(currentModel, "typescript"); + } + + const currentUri = monaco.Uri.parse(`file:///${filename}.ts`); + if (!monaco.editor.getModel(currentUri)) { + monaco.editor.createModel( + fileContents, + "typescript", + currentUri, + ); + editor.setModel(monaco.editor.getModel(currentUri)); + } + }} + options={{ + minimap: { enabled: false }, + scrollBeyondLastLine: false, + fontSize: 14, + lineNumbers: "on", + roundedSelection: false, + scrollbar: { + vertical: "visible", + horizontal: "visible", + }, + quickSuggestions: true, + suggestOnTriggerCharacters: true, + acceptSuggestionOnEnter: "on", + tabCompletion: "on", + wordBasedSuggestions: "currentDocument", + parameterHints: { + enabled: true, + }, + hover: { + enabled: true, + delay: 300, + sticky: true, + }, + }} + /> +
+
+ ); +} diff --git a/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/files/page.tsx b/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/files/page.tsx new file mode 100644 index 0000000..241e5db --- /dev/null +++ b/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/files/page.tsx @@ -0,0 +1,54 @@ +/* + * MHSF, Minehut Server List + * All external content is rather licensed under the ECA Agreement + * located here: https://mhsf.app/docs/legal/external-content-agreement + * + * All code under MHSF is licensed under the MIT License + * by open source contributors + * + * Copyright (c) 2025 dvelo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +"use client"; + +import { ClerkCustomModification } from "@/components/feat/server-list/modification/modification-file-creation-dialog"; +import { Link } from "@/components/util/link"; +import { useUser } from "@clerk/nextjs"; +import { File, FileCode } from "lucide-react"; + +export default function ServerListModificationFrame() { + const { user } = useUser(); + const files = + (user?.unsafeMetadata.customFiles as Array) ?? []; + return ( +
+

Files

+
+ {files.map((c) => ( + + {c.name}.ts + + ))} +
+
+ ); +} diff --git a/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/page.tsx b/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/page.tsx new file mode 100644 index 0000000..614949c --- /dev/null +++ b/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/page.tsx @@ -0,0 +1,101 @@ +/* + * MHSF, Minehut Server List + * All external content is rather licensed under the ECA Agreement + * located here: https://mhsf.app/docs/legal/external-content-agreement + * + * All code under MHSF is licensed under the MIT License + * by open source contributors + * + * Copyright (c) 2025 dvelo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +"use client"; + +import { Material } from "@/components/ui/material"; +import { Separator } from "@/components/ui/separator"; +import { Link } from "@/components/util/link"; +import { serverModDB } from "@/config/sl-mod-db"; +import { ArrowRight } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { useRouter } from "@/lib/useRouter"; + +export default function ServerListModificationFrame() { + const router = useRouter(); + + return ( +
+

Filters & Sorting

+
+ + + + + +
+ + Pick out different filters & sorting systems to customize your server + viewing experience. We frequently add new filters in accordance to new + features, as well. + + +
+ {serverModDB.map((c) => ( + +

+ {c.displayTitle} + + + View more + +

+
+ {c.entries.map((m) => ( + + router.push( + `/servers/embedded/sl-modification-frame/category/${btoa(c.displayTitle)}/modification/${btoa(m.name)}` + ) + } + > +
+ +
+ + {m.name} + +
+ ))} +
+
+ ))} +
+
+ ); +} diff --git a/apps/www/src/components/feat/server-list/modification/modification-action.tsx b/apps/www/src/components/feat/server-list/modification/modification-action.tsx new file mode 100644 index 0000000..674d852 --- /dev/null +++ b/apps/www/src/components/feat/server-list/modification/modification-action.tsx @@ -0,0 +1,26 @@ +import { Button } from "@/components/ui/button"; +import type { Filter } from "@/lib/types/filter"; +import type { Sort } from "@/lib/types/sort"; +import { ModificationFileCreationDialog } from "./modification-file-creation-dialog"; + +type Action = Filter | Sort | { customAction: string }; + +export function ModificationAction({ value }: { value?: Action }) { + return ( + <> + {value !== undefined && "customAction" in value ? ( + + + + ) : ( + + )} + + ); +} diff --git a/apps/www/src/components/feat/server-list/modification/modification-button.tsx b/apps/www/src/components/feat/server-list/modification/modification-button.tsx new file mode 100644 index 0000000..5a1cd21 --- /dev/null +++ b/apps/www/src/components/feat/server-list/modification/modification-button.tsx @@ -0,0 +1,47 @@ +/* + * MHSF, Minehut Server List + * All external content is rather licensed under the ECA Agreement + * located here: https://mhsf.app/docs/legal/external-content-agreement + * + * All code under MHSF is licensed under the MIT License + * by open source contributors + * + * Copyright (c) 2025 dvelo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +import { Button } from "@/components/ui/button"; +import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"; +import { ModificationFrame } from "./modification-frame"; + +export function ModificationButton() { + return ( + + + + + + + + + + ); +} diff --git a/apps/www/src/components/feat/server-list/modification/modification-file-creation-dialog.tsx b/apps/www/src/components/feat/server-list/modification/modification-file-creation-dialog.tsx new file mode 100644 index 0000000..37838cb --- /dev/null +++ b/apps/www/src/components/feat/server-list/modification/modification-file-creation-dialog.tsx @@ -0,0 +1,126 @@ +/* + * MHSF, Minehut Server List + * All external content is rather licensed under the ECA Agreement + * located here: https://mhsf.app/docs/legal/external-content-agreement + * + * All code under MHSF is licensed under the MIT License + * by open source contributors + * + * Copyright (c) 2025 dvelo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { useRouter } from "@/lib/useRouter"; +import { useUser } from "@clerk/nextjs"; +import { useState, type ReactNode } from "react"; +import { toast } from "sonner"; + +const sortTemplate = `import type { Server } from "mhsf"; + +export function sort(serverA: Server, serverB: Server): number { + // Your code here + // Use logic like \`Array.sort\` or (a: V, b: V) => number +}`; + +const filterTemplate = `import type { Server } from "mhsf"; + +export function filter(server: Server): boolean { + // Your code here + // Returning true indicates the server will stay, while returning false will remove the server from the queue. +}`; + +export type ClerkCustomModification = { + name: string; // Add .ts to the end + active: boolean; + contents: string; +}; + +export function ModificationFileCreationDialog({ + children, + type, +}: { + children?: ReactNode; + type: "filter" | "sort"; +}) { + const { user, isSignedIn } = useUser(); + const router = useRouter(); + const [fileName, setFileName] = useState(""); + + return ( + + {children} + + Create new file + + Files can be a new filter or sort, made w/ TypeScript. + +
+ setFileName(e.target.value)} + value={fileName} + /> + + .ts + +
+ +
+ + + +
+
+ ); +} diff --git a/apps/www/src/components/feat/server-list/modification/modification-frame.tsx b/apps/www/src/components/feat/server-list/modification/modification-frame.tsx new file mode 100644 index 0000000..7b11fd7 --- /dev/null +++ b/apps/www/src/components/feat/server-list/modification/modification-frame.tsx @@ -0,0 +1,47 @@ +/* + * MHSF, Minehut Server List + * All external content is rather licensed under the ECA Agreement + * located here: https://mhsf.app/docs/legal/external-content-agreement + * + * All code under MHSF is licensed under the MIT License + * by open source contributors + * + * Copyright (c) 2025 dvelo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +import { useIframeCommunication } from "@/lib/hooks/use-iframe-communication" +import { useEffectOnce } from "@/lib/useEffectOnce" +import { useEffect, useRef } from "react" + +export function ModificationFrame() { + const ref = useRef(null) + const communication = useIframeCommunication(ref); + + useEffect(() => { + communication.toIframe.handle("ping", (c) => { + if (c.from === "iframe") + communication.toIframe.send("ping", {from: "top-layer"}) + }) + }, [ref]) + + return