diff --git a/Frontend/bun.lockb b/Frontend/bun.lockb
index a4ee358..0bfd867 100644
Binary files a/Frontend/bun.lockb and b/Frontend/bun.lockb differ
diff --git a/Frontend/next.config.mjs b/Frontend/next.config.mjs
index 9835422..073c832 100644
--- a/Frontend/next.config.mjs
+++ b/Frontend/next.config.mjs
@@ -1,5 +1,8 @@
+import createMDX from '@next/mdx'
+
/** @type {import('next').NextConfig} */
const nextConfig = {
+ pageExtensions: ["ts", "tsx", "js", "jsx", "md", "mdx"],
images: {
remotePatterns: [
{
@@ -8,6 +11,12 @@ const nextConfig = {
},
],
},
+ experimental: {
+ mdxRs: true,
+ },
};
-export default nextConfig;
+const withMDX = createMDX({})
+
+// Merge MDX config with Next.js config
+export default withMDX(nextConfig)
\ No newline at end of file
diff --git a/Frontend/package.json b/Frontend/package.json
index 27b8c76..b8dde81 100644
--- a/Frontend/package.json
+++ b/Frontend/package.json
@@ -14,6 +14,9 @@
"dependencies": {
"@heroicons/react": "^2.1.3",
"@hookform/resolvers": "^3.3.4",
+ "@mdx-js/loader": "^3.0.1",
+ "@mdx-js/react": "^3.0.1",
+ "@next/mdx": "^14.2.2",
"@radix-ui/react-context-menu": "^2.1.5",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-navigation-menu": "^1.1.4",
@@ -22,6 +25,7 @@
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-toast": "^1.1.5",
"@radix-ui/react-tooltip": "^1.0.7",
+ "@types/mdx": "^2.0.13",
"class-variance-authority": "^0.7.0",
"clipboard-copy": "^4.0.1",
"clsx": "^2.1.0",
@@ -33,6 +37,7 @@
"react-countup": "^6.5.3",
"react-dom": "^18",
"react-hook-form": "^7.51.3",
+ "remark-gfm": "^4.0.0",
"restfulmc-lib": "^1.1.3",
"sonner": "^1.4.41",
"tailwind-merge": "^2.2.2",
diff --git a/Frontend/src/app/(pages)/docs/[[...slug]]/page.tsx b/Frontend/src/app/(pages)/docs/[[...slug]]/page.tsx
new file mode 100644
index 0000000..f10e2fa
--- /dev/null
+++ b/Frontend/src/app/(pages)/docs/[[...slug]]/page.tsx
@@ -0,0 +1,26 @@
+import { ReactElement } from "react";
+import { getDocsContent } from "@/lib/mdxUtils";
+import { PageProps } from "@/types/page";
+import { notFound } from "next/navigation";
+
+/**
+ * The page to display content
+ * from an MDX file on the docs.
+ *
+ * @param slug the slug of the mdx file
+ * @return the page jsx
+ */
+const ContentPage = ({ params: { slug } }: PageProps): ReactElement => {
+ const content: DocsContentMetadata | undefined = getDocsContent().find(
+ (metadata: DocsContentMetadata): boolean =>
+ metadata.slug === (slug ? slug[0] : "home")
+ ); // Get the content to display based on the provided slug
+
+ // Return a 404 if the content is not found
+ if (!content) {
+ notFound();
+ }
+
+ return {content.title};
+};
+export default ContentPage;
diff --git a/Frontend/src/app/(pages)/docs/layout.tsx b/Frontend/src/app/(pages)/docs/layout.tsx
new file mode 100644
index 0000000..fb1fb01
--- /dev/null
+++ b/Frontend/src/app/(pages)/docs/layout.tsx
@@ -0,0 +1,20 @@
+import { ReactElement, ReactNode } from "react";
+import Sidebar from "@/components/docs/sidebar";
+
+/**
+ * The layout for the docs page.
+ *
+ * @param children the children of this layout
+ * @returns the layout jsx
+ */
+const DocumentationLayout = ({
+ children,
+}: Readonly<{
+ children: ReactNode;
+}>): ReactElement => (
+
+);
+export default DocumentationLayout;
diff --git a/Frontend/src/app/(pages)/docs/page.tsx b/Frontend/src/app/(pages)/docs/page.tsx
deleted file mode 100644
index 681ed1b..0000000
--- a/Frontend/src/app/(pages)/docs/page.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import Creeper from "@/components/creeper";
-import { minecrafter } from "@/font/fonts";
-import { cn } from "@/lib/utils";
-import { Metadata } from "next";
-import Link from "next/link";
-import { ReactElement } from "react";
-
-/**
- * Page metadata.
- */
-export const metadata: Metadata = {
- title: "Docs",
-};
-
-/**
- * The documentation page.
- *
- * @returns the page jsx
- */
-const DocsPage = (): ReactElement => (
-
- {/* Creeper */}
-
-
- {/* Header */}
-
- Documentation
-
-
- {/* Error */}
-
- This page is still under construction, however we do have a{" "}
-
- Wiki
-
- !
-
-
-);
-export default DocsPage;
diff --git a/Frontend/src/app/(pages)/mojang/page.tsx b/Frontend/src/app/(pages)/mojang/page.tsx
index 917f6e9..dca65c2 100644
--- a/Frontend/src/app/(pages)/mojang/page.tsx
+++ b/Frontend/src/app/(pages)/mojang/page.tsx
@@ -1,5 +1,5 @@
import { minecrafter } from "@/font/fonts";
-import { cn } from "@/lib/utils";
+import { cn } from "@/app/common/utils";
import { Metadata } from "next";
import Link from "next/link";
import { ReactElement } from "react";
diff --git a/Frontend/src/app/(pages)/player/[[...slug]]/page.tsx b/Frontend/src/app/(pages)/player/[[...slug]]/page.tsx
index c39fa6f..88c185d 100644
--- a/Frontend/src/app/(pages)/player/[[...slug]]/page.tsx
+++ b/Frontend/src/app/(pages)/player/[[...slug]]/page.tsx
@@ -3,7 +3,7 @@ import PlayerResult from "@/components/player/player-result";
import PlayerSearch from "@/components/player/player-search";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { minecrafter } from "@/font/fonts";
-import { cn } from "@/lib/utils";
+import { cn } from "@/app/common/utils";
import { PageProps } from "@/types/page";
import { ExclamationCircleIcon } from "@heroicons/react/24/outline";
import { Metadata, Viewport } from "next";
@@ -70,7 +70,7 @@ const PlayerPage = async ({ params }: PageProps): Promise => {
export const generateMetadata = async ({
params,
}: PageProps): Promise => {
- const embed: Metadata | undefined = await getPageEmbed(
+ const embed: Metadata | undefined = await getPlayerEmbed(
trimQuery(params.slug?.[0])
); // Get the page embed
@@ -92,10 +92,10 @@ export const generateMetadata = async ({
export const generateViewport = async ({
params,
}: PageProps): Promise => {
- const embed: Metadata | undefined = await getPageEmbed(
+ const embed: Metadata | undefined = await getPlayerEmbed(
trimQuery(params.slug?.[0])
); // Get the page embed
- return embed ? {} : { themeColor: "#FF5555" };
+ return embed ? {} : { themeColor: "#AA0000" };
};
/**
@@ -118,7 +118,7 @@ const trimQuery = (query: string | undefined): string | undefined => {
* @param query the query to embed, if any
* @returns the page embed
*/
-const getPageEmbed = async (
+const getPlayerEmbed = async (
query: string | undefined
): Promise => {
if (!query) {
diff --git a/Frontend/src/app/(pages)/server/[[...slug]]/page.tsx b/Frontend/src/app/(pages)/server/[[...slug]]/page.tsx
index ee77fdb..392ea38 100644
--- a/Frontend/src/app/(pages)/server/[[...slug]]/page.tsx
+++ b/Frontend/src/app/(pages)/server/[[...slug]]/page.tsx
@@ -3,8 +3,8 @@ import ServerResult from "@/components/server/server-result";
import ServerSearch from "@/components/server/server-search";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { minecrafter } from "@/font/fonts";
-import { capitalize } from "@/lib/stringUtils";
-import { cn } from "@/lib/utils";
+import { capitalize } from "@/app/common/stringUtils";
+import { cn } from "@/app/common/utils";
import { PageProps } from "@/types/page";
import { ExclamationCircleIcon } from "@heroicons/react/24/outline";
import { Metadata } from "next";
diff --git a/Frontend/src/app/common/mdxUtils.ts b/Frontend/src/app/common/mdxUtils.ts
new file mode 100644
index 0000000..865fc85
--- /dev/null
+++ b/Frontend/src/app/common/mdxUtils.ts
@@ -0,0 +1,66 @@
+import * as fs from "node:fs";
+import path from "node:path";
+
+/**
+ * The regex to match for metadata.
+ */
+const METADATA_REGEX: RegExp = /---\s*([\s\S]*?)\s*---/;
+
+/**
+ * Get the content to
+ * display in the docs.
+ */
+export const getDocsContent = (): DocsContentMetadata[] =>
+ getMetadata(
+ path.join(process.cwd(), "src", "markdown", "docs")
+ );
+
+/**
+ * Get the metadata of mdx
+ * files in the given directory.
+ *
+ * @param directory the directory to search
+ */
+export const getMetadata = (directory: string): T[] => {
+ const files: string[] = fs
+ .readdirSync(directory)
+ .filter((file: string): boolean => path.extname(file) === ".mdx"); // Read the MDX files
+ return files.map((file: string): T => {
+ const filePath: string = path.join(directory, file); // The path of the file
+ return {
+ ...parseMetadata(fs.readFileSync(filePath, "utf-8")),
+ slug: path.basename(file, path.extname(file)),
+ }; // Map each file to its metadata
+ });
+};
+
+/**
+ * Parse the metadata from
+ * the given content.
+ *
+ * @param content the content to parse
+ * @returns the metadata and content
+ * @template T the type of metadata
+ */
+const parseMetadata = (content: string): T => {
+ const metadataBlock: string = METADATA_REGEX.exec(content)![1]; // Get the block of metadata
+ content = content.replace(METADATA_REGEX, "").trim(); // Remove the metadata block from the content
+ let metadata: Partial<{
+ [key: string]: string;
+ }> = {}; // The metadata to return
+
+ // Parse the metadata block as a key-value pair
+ metadataBlock
+ .trim() // Trim any leading or trailing whitespace
+ .split("\n") // Get each line
+ .forEach((line: string): void => {
+ const split: string[] = line.split(": "); // Split the metadata by the colon
+ let value: string = split[1].trim(); // The value of the metadata
+ value = value.replace(/^['"](.*)['"]$/, "$1"); // Remove quotes
+ metadata[split[0].trim()] = value; // Add the metadata to the object
+ });
+
+ // Return the metadata and content. The initial
+ // slug is empty, and is defined later on.
+ return { ...metadata, content } as T;
+};
diff --git a/Frontend/src/app/lib/stringUtils.ts b/Frontend/src/app/common/stringUtils.ts
similarity index 100%
rename from Frontend/src/app/lib/stringUtils.ts
rename to Frontend/src/app/common/stringUtils.ts
diff --git a/Frontend/src/app/lib/utils.ts b/Frontend/src/app/common/utils.ts
similarity index 100%
rename from Frontend/src/app/lib/utils.ts
rename to Frontend/src/app/common/utils.ts
diff --git a/Frontend/src/app/components/counter.tsx b/Frontend/src/app/components/counter.tsx
index 774dea3..8914f49 100644
--- a/Frontend/src/app/components/counter.tsx
+++ b/Frontend/src/app/components/counter.tsx
@@ -1,7 +1,7 @@
"use client";
import { minecrafter } from "@/font/fonts";
-import { cn } from "@/lib/utils";
+import { cn } from "@/app/common/utils";
import CountUp from "react-countup";
import { ReactElement } from "react";
diff --git a/Frontend/src/app/components/docs/sidebar.tsx b/Frontend/src/app/components/docs/sidebar.tsx
new file mode 100644
index 0000000..c8ab3af
--- /dev/null
+++ b/Frontend/src/app/components/docs/sidebar.tsx
@@ -0,0 +1,13 @@
+import { ReactElement } from "react";
+
+/**
+ * The sidebar for the docs page.
+ *
+ * @returns the sidebar jsx
+ */
+const Sidebar = (): ReactElement => (
+
+
SIDEBAR
+
+);
+export default Sidebar;
diff --git a/Frontend/src/app/components/footer.tsx b/Frontend/src/app/components/footer.tsx
index 01671e9..c8d00bf 100644
--- a/Frontend/src/app/components/footer.tsx
+++ b/Frontend/src/app/components/footer.tsx
@@ -3,7 +3,7 @@ import Link from "next/link";
import { ReactElement } from "react";
import config from "@/config";
import { minecrafter } from "@/font/fonts";
-import { cn } from "@/lib/utils";
+import { cn } from "@/app/common/utils";
import { FooterLinks } from "@/types/config";
/**
diff --git a/Frontend/src/app/components/github-star-button.tsx b/Frontend/src/app/components/github-star-button.tsx
index 312a432..75e607e 100644
--- a/Frontend/src/app/components/github-star-button.tsx
+++ b/Frontend/src/app/components/github-star-button.tsx
@@ -4,14 +4,7 @@ import MinecraftButton from "@/components/minecraft-button";
import { Skeleton } from "@/components/ui/skeleton";
import { StarIcon } from "@heroicons/react/24/outline";
import Link from "next/link";
-import {
- Dispatch,
- ReactElement,
- SetStateAction,
- Suspense,
- useEffect,
- useState,
-} from "react";
+import { Dispatch, ReactElement, SetStateAction, Suspense, useEffect, useState } from "react";
/**
* The button to display the amount
diff --git a/Frontend/src/app/components/landing/background.tsx b/Frontend/src/app/components/landing/background.tsx
index dbafa9d..84f7fce 100644
--- a/Frontend/src/app/components/landing/background.tsx
+++ b/Frontend/src/app/components/landing/background.tsx
@@ -1,5 +1,5 @@
import { ReactElement } from "react";
-import { cn } from "../../lib/utils";
+import { cn } from "@/app/common/utils";
/**
* The background hero component.
diff --git a/Frontend/src/app/components/landing/featured-content.tsx b/Frontend/src/app/components/landing/featured-content.tsx
index 89c9a69..e84b0ee 100644
--- a/Frontend/src/app/components/landing/featured-content.tsx
+++ b/Frontend/src/app/components/landing/featured-content.tsx
@@ -1,6 +1,6 @@
import config from "@/config";
import { minecrafter } from "@/font/fonts";
-import { cn } from "@/lib/utils";
+import { cn } from "@/app/common/utils";
import { FeaturedItemProps } from "@/types/config";
import Link from "next/link";
import { ReactElement } from "react";
diff --git a/Frontend/src/app/components/landing/hero.tsx b/Frontend/src/app/components/landing/hero.tsx
index 860a3e2..e9def42 100644
--- a/Frontend/src/app/components/landing/hero.tsx
+++ b/Frontend/src/app/components/landing/hero.tsx
@@ -2,7 +2,7 @@ import GitHubStarButton from "@/components/github-star-button";
import MinecraftButton from "@/components/minecraft-button";
import config from "@/config";
import { minecrafter } from "@/font/fonts";
-import { cn } from "@/lib/utils";
+import { cn } from "@/app/common/utils";
import Link from "next/link";
import { ReactElement } from "react";
diff --git a/Frontend/src/app/components/minecraft-button.tsx b/Frontend/src/app/components/minecraft-button.tsx
index fc00ecc..a0841db 100644
--- a/Frontend/src/app/components/minecraft-button.tsx
+++ b/Frontend/src/app/components/minecraft-button.tsx
@@ -1,5 +1,5 @@
import { Button } from "@/components/ui/button";
-import { cn } from "@/lib/utils";
+import { cn } from "@/app/common/utils";
import { ButtonHTMLAttributes, ReactElement, ReactNode } from "react";
/**
diff --git a/Frontend/src/app/components/navbar.tsx b/Frontend/src/app/components/navbar.tsx
index e4830bd..089d9d4 100644
--- a/Frontend/src/app/components/navbar.tsx
+++ b/Frontend/src/app/components/navbar.tsx
@@ -3,7 +3,7 @@
import GitHubStarButton from "@/components/github-star-button";
import config from "@/config";
import { minecrafter } from "@/font/fonts";
-import { cn } from "@/lib/utils";
+import { cn } from "@/app/common/utils";
import Image from "next/image";
import Link from "next/link";
import { usePathname } from "next/navigation";
diff --git a/Frontend/src/app/components/player/player-result.tsx b/Frontend/src/app/components/player/player-result.tsx
index 7dabdbd..b332f97 100644
--- a/Frontend/src/app/components/player/player-result.tsx
+++ b/Frontend/src/app/components/player/player-result.tsx
@@ -1,11 +1,6 @@
import CopyButton from "@/components/copy-button";
import { Badge } from "@/components/ui/badge";
-import {
- ContextMenu,
- ContextMenuContent,
- ContextMenuItem,
- ContextMenuTrigger,
-} from "@/components/ui/context-menu";
+import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from "@/components/ui/context-menu";
import config from "@/config";
import Image from "next/image";
import Link from "next/link";
diff --git a/Frontend/src/app/components/server/server-result.tsx b/Frontend/src/app/components/server/server-result.tsx
index 9a6341a..f8e70f1 100644
--- a/Frontend/src/app/components/server/server-result.tsx
+++ b/Frontend/src/app/components/server/server-result.tsx
@@ -1,4 +1,4 @@
-import { cn } from "@/lib/utils";
+import { cn } from "@/app/common/utils";
import Image from "next/image";
import { ReactElement } from "react";
import {
diff --git a/Frontend/src/app/components/server/server-search.tsx b/Frontend/src/app/components/server/server-search.tsx
index 850fd76..4a2a0d3 100644
--- a/Frontend/src/app/components/server/server-search.tsx
+++ b/Frontend/src/app/components/server/server-search.tsx
@@ -9,7 +9,7 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
-import { capitalize } from "@/lib/stringUtils";
+import { capitalize } from "@/app/common/stringUtils";
import { redirect } from "next/navigation";
import { ReactElement } from "react";
import { ServerPlatform } from "restfulmc-lib";
diff --git a/Frontend/src/app/components/ui/alert.tsx b/Frontend/src/app/components/ui/alert.tsx
index b4eeba6..e101ac8 100644
--- a/Frontend/src/app/components/ui/alert.tsx
+++ b/Frontend/src/app/components/ui/alert.tsx
@@ -1,7 +1,7 @@
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
-import { cn } from "@/app/lib/utils";
+import { cn } from "@/app/common/utils";
const alertVariants = cva(
"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
diff --git a/Frontend/src/app/components/ui/badge.tsx b/Frontend/src/app/components/ui/badge.tsx
index 5990b73..a358d76 100644
--- a/Frontend/src/app/components/ui/badge.tsx
+++ b/Frontend/src/app/components/ui/badge.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";
-import { cn } from "@/app/lib/utils";
+import { cn } from "@/app/common/utils";
const badgeVariants = cva(
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
diff --git a/Frontend/src/app/components/ui/button.tsx b/Frontend/src/app/components/ui/button.tsx
index dc76d90..f222dc1 100644
--- a/Frontend/src/app/components/ui/button.tsx
+++ b/Frontend/src/app/components/ui/button.tsx
@@ -2,7 +2,7 @@ import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
-import { cn } from "@/app/lib/utils";
+import { cn } from "@/app/common/utils";
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",
diff --git a/Frontend/src/app/components/ui/context-menu.tsx b/Frontend/src/app/components/ui/context-menu.tsx
index a7812cc..0d89fb2 100644
--- a/Frontend/src/app/components/ui/context-menu.tsx
+++ b/Frontend/src/app/components/ui/context-menu.tsx
@@ -4,7 +4,7 @@ import * as React from "react";
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
import { Check, ChevronRight, Circle } from "lucide-react";
-import { cn } from "@/app/lib/utils";
+import { cn } from "@/app/common/utils";
const ContextMenu = ContextMenuPrimitive.Root;
diff --git a/Frontend/src/app/components/ui/input.tsx b/Frontend/src/app/components/ui/input.tsx
index bc0e2df..8a07036 100644
--- a/Frontend/src/app/components/ui/input.tsx
+++ b/Frontend/src/app/components/ui/input.tsx
@@ -1,6 +1,6 @@
import * as React from "react";
-import { cn } from "@/app/lib/utils";
+import { cn } from "@/app/common/utils";
export interface InputProps
extends React.InputHTMLAttributes {}
diff --git a/Frontend/src/app/components/ui/label.tsx b/Frontend/src/app/components/ui/label.tsx
index dbb2d78..c1259fa 100644
--- a/Frontend/src/app/components/ui/label.tsx
+++ b/Frontend/src/app/components/ui/label.tsx
@@ -4,7 +4,7 @@ import * as LabelPrimitive from "@radix-ui/react-label";
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
-import { cn } from "@/app/lib/utils";
+import { cn } from "@/app/common/utils";
const labelVariants = cva(
"text-sm font-medium text-zinc-300 leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
diff --git a/Frontend/src/app/components/ui/select.tsx b/Frontend/src/app/components/ui/select.tsx
index 5329a24..bb86cb8 100644
--- a/Frontend/src/app/components/ui/select.tsx
+++ b/Frontend/src/app/components/ui/select.tsx
@@ -4,7 +4,7 @@ import * as React from "react";
import * as SelectPrimitive from "@radix-ui/react-select";
import { Check, ChevronDown, ChevronUp } from "lucide-react";
-import { cn } from "@/app/lib/utils";
+import { cn } from "@/app/common/utils";
const Select = SelectPrimitive.Root;
diff --git a/Frontend/src/app/components/ui/skeleton.tsx b/Frontend/src/app/components/ui/skeleton.tsx
index e8cde28..0020342 100644
--- a/Frontend/src/app/components/ui/skeleton.tsx
+++ b/Frontend/src/app/components/ui/skeleton.tsx
@@ -1,4 +1,4 @@
-import { cn } from "@/app/lib/utils";
+import { cn } from "@/app/common/utils";
function Skeleton({
className,
diff --git a/Frontend/src/app/components/ui/toast.tsx b/Frontend/src/app/components/ui/toast.tsx
index a32532a..cd8ad97 100644
--- a/Frontend/src/app/components/ui/toast.tsx
+++ b/Frontend/src/app/components/ui/toast.tsx
@@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority";
import { X } from "lucide-react";
import * as React from "react";
-import { cn } from "@/app/lib/utils";
+import { cn } from "@/app/common/utils";
const ToastProvider = ToastPrimitives.Provider;
diff --git a/Frontend/src/app/components/ui/tooltip.tsx b/Frontend/src/app/components/ui/tooltip.tsx
index 7853f95..3c5f228 100644
--- a/Frontend/src/app/components/ui/tooltip.tsx
+++ b/Frontend/src/app/components/ui/tooltip.tsx
@@ -3,7 +3,7 @@
import * as React from "react";
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
-import { cn } from "@/app/lib/utils";
+import { cn } from "@/app/common/utils";
const TooltipProvider = TooltipPrimitive.Provider;
diff --git a/Frontend/src/app/layout.tsx b/Frontend/src/app/layout.tsx
index c258a06..58affc6 100644
--- a/Frontend/src/app/layout.tsx
+++ b/Frontend/src/app/layout.tsx
@@ -4,7 +4,7 @@ import { Toaster } from "@/components/ui/sonner";
import { TooltipProvider } from "@/components/ui/tooltip";
import config from "@/config";
import { notoSans } from "@/font/fonts";
-import { cn } from "@/lib/utils";
+import { cn } from "@/app/common/utils";
import type { Metadata, Viewport } from "next";
import PlausibleProvider from "next-plausible";
import { ReactElement, ReactNode } from "react";
diff --git a/Frontend/src/app/not-found.tsx b/Frontend/src/app/not-found.tsx
index 7d077bc..e5b3efc 100644
--- a/Frontend/src/app/not-found.tsx
+++ b/Frontend/src/app/not-found.tsx
@@ -1,6 +1,6 @@
import Creeper from "@/components/creeper";
import { minecrafter } from "@/font/fonts";
-import { cn } from "@/lib/utils";
+import { cn } from "@/app/common/utils";
import { ReactElement } from "react";
/**
diff --git a/Frontend/src/app/types/mdx.d.ts b/Frontend/src/app/types/mdx.d.ts
new file mode 100644
index 0000000..d813282
--- /dev/null
+++ b/Frontend/src/app/types/mdx.d.ts
@@ -0,0 +1,41 @@
+/**
+ * Metadata for documentation content.
+ */
+type DocsContentMetadata = MDXMetadata & {
+ /**
+ * The title of this content.
+ */
+ title: string;
+
+ /**
+ * The date this content was published.
+ */
+ published: string;
+
+ /**
+ * The summary of this content.
+ */
+ summary: string;
+};
+
+/**
+ * Metadata for an MDX file.
+ */
+type MDXMetadata = {
+ /**
+ * The slug of the file, defined once read.
+ */
+ slug: string;
+
+ /**
+ * The metadata of the file.
+ */
+ metadata: {
+ [key: string]: string;
+ };
+
+ /**
+ * The content of the file.
+ */
+ content: string;
+};
diff --git a/Frontend/src/markdown/docs/bob.mdx b/Frontend/src/markdown/docs/bob.mdx
new file mode 100644
index 0000000..8c48765
--- /dev/null
+++ b/Frontend/src/markdown/docs/bob.mdx
@@ -0,0 +1,8 @@
+---
+title: 'option utinam malorum tempor sapien.'
+published: '04-19-2024'
+summary: 'utinam delicata nominavi ornare eirmod pharetra decore interesset necessitatibus.'
+---
+
+# bob
+HELLO JOHN
\ No newline at end of file
diff --git a/Frontend/src/markdown/docs/home.mdx b/Frontend/src/markdown/docs/home.mdx
new file mode 100644
index 0000000..0b0f139
--- /dev/null
+++ b/Frontend/src/markdown/docs/home.mdx
@@ -0,0 +1,8 @@
+---
+title: 'HOME YES.'
+published: '04-19-2024'
+summary: 'utinam delicata nominavi ornare eirmod pharetra decore interesset necessitatibus.'
+---
+
+# bob
+HELLO JOHN
\ No newline at end of file
diff --git a/Frontend/src/mdx-components.tsx b/Frontend/src/mdx-components.tsx
new file mode 100644
index 0000000..107f5c3
--- /dev/null
+++ b/Frontend/src/mdx-components.tsx
@@ -0,0 +1,10 @@
+import type { MDXComponents } from "mdx/types";
+
+export const useMDXComponents = (components: MDXComponents): MDXComponents => {
+ return {
+ h1: ({ children }) => (
+ {children}
+ ),
+ ...components,
+ };
+};
diff --git a/Frontend/tailwind.config.ts b/Frontend/tailwind.config.ts
index a894293..b6750b8 100644
--- a/Frontend/tailwind.config.ts
+++ b/Frontend/tailwind.config.ts
@@ -4,7 +4,7 @@ const { screens } = require("tailwindcss/defaultTheme");
const config = {
darkMode: ["class"],
- content: ["./src/app/**/*.{ts,tsx}"],
+ content: ["./src/app/**/*.{ts,tsx,mdx}"],
theme: {
container: {
center: true,
diff --git a/Frontend/tsconfig.json b/Frontend/tsconfig.json
index bce7d9a..9dc3f85 100644
--- a/Frontend/tsconfig.json
+++ b/Frontend/tsconfig.json
@@ -24,7 +24,8 @@
"@/provider/*": ["./src/app/provider/*"],
"@/font/*": ["./src/app/font/*"],
"@/types/*": ["./src/app/types/*"],
- "@/lib/*": ["./src/app/lib/*"],
+ "@/lib/*": ["./src/app/common/*"],
+ "@/markdown/*": ["./src/markdown/*"],
"@/configJson": ["./config.json"]
}
},