diff --git a/README.md b/README.md index 607ee31..96adb11 100644 --- a/README.md +++ b/README.md @@ -39,4 +39,6 @@ Check out our [Next.js deployment documentation](https://nextjs.org/docs/deploym ```sql CREATE TABLE aliases (id INTEGER PRIMARY KEY AUTOINCREMENT, address TEXT NOT NULL, alias TEXT NOT NULL, pending INTEGER DEFAULT 0, temporary INTEGER DEFAULT 0); CREATE TABLE temp_alias_requests (key TEXT PRIMARY KEY, address TEXT NOT NULL, alias TEXT NOT NULL, expires INTEGER NOT NULL); + +CREATE TABLE api_keys (id INTEGER PRIMARY KEY AUTOINCREMENT, address TEXT NOT NULL, token TEXT NOT NULL); ``` diff --git a/src/app/admin/aliases/page.tsx b/src/app/(dashboard)/admin/aliases/page.tsx similarity index 100% rename from src/app/admin/aliases/page.tsx rename to src/app/(dashboard)/admin/aliases/page.tsx diff --git a/src/app/admin/audit/page.tsx b/src/app/(dashboard)/admin/audit/page.tsx similarity index 100% rename from src/app/admin/audit/page.tsx rename to src/app/(dashboard)/admin/audit/page.tsx diff --git a/src/app/admin/users/page.tsx b/src/app/(dashboard)/admin/users/page.tsx similarity index 100% rename from src/app/admin/users/page.tsx rename to src/app/(dashboard)/admin/users/page.tsx diff --git a/src/app/(dashboard)/api-keys/page.tsx b/src/app/(dashboard)/api-keys/page.tsx new file mode 100644 index 0000000..2fafa82 --- /dev/null +++ b/src/app/(dashboard)/api-keys/page.tsx @@ -0,0 +1,19 @@ +import { Button, Flex, Heading, Text } from "@radix-ui/themes"; +import { ExternalLinkIcon } from "lucide-react"; +import Link from "next/link"; + +export default function ApiKeys() { + return ( + <> + + + API keys + Generate long lasting API keys that can be used to perform certain actions programatically. + + + + + + + ); +} \ No newline at end of file diff --git a/src/app/favicon.ico b/src/app/(dashboard)/favicon.ico similarity index 100% rename from src/app/favicon.ico rename to src/app/(dashboard)/favicon.ico diff --git a/src/app/globals.css b/src/app/(dashboard)/globals.css similarity index 100% rename from src/app/globals.css rename to src/app/(dashboard)/globals.css diff --git a/src/app/layout.tsx b/src/app/(dashboard)/layout.tsx similarity index 100% rename from src/app/layout.tsx rename to src/app/(dashboard)/layout.tsx diff --git a/src/app/page.tsx b/src/app/(dashboard)/page.tsx similarity index 100% rename from src/app/page.tsx rename to src/app/(dashboard)/page.tsx diff --git a/src/app/self-service/page.tsx b/src/app/(dashboard)/self-service/page.tsx similarity index 100% rename from src/app/self-service/page.tsx rename to src/app/(dashboard)/self-service/page.tsx diff --git a/src/app/(swagger)/api-doc/page.tsx b/src/app/(swagger)/api-doc/page.tsx new file mode 100644 index 0000000..0259c5f --- /dev/null +++ b/src/app/(swagger)/api-doc/page.tsx @@ -0,0 +1,11 @@ +import { getApiDocs } from '@/lib/swagger'; +import ReactSwagger from './swagger'; + +export default async function IndexPage() { + const spec = await getApiDocs(); + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/app/(swagger)/api-doc/swagger.tsx b/src/app/(swagger)/api-doc/swagger.tsx new file mode 100644 index 0000000..35c8675 --- /dev/null +++ b/src/app/(swagger)/api-doc/swagger.tsx @@ -0,0 +1,14 @@ +'use client'; + +import SwaggerUI from 'swagger-ui-react'; +import 'swagger-ui-react/swagger-ui.css'; + +type Props = { + spec: Record, +}; + +function ReactSwagger({ spec }: Props) { + return ; +} + +export default ReactSwagger; diff --git a/src/app/(swagger)/layout.tsx b/src/app/(swagger)/layout.tsx new file mode 100644 index 0000000..0e06e54 --- /dev/null +++ b/src/app/(swagger)/layout.tsx @@ -0,0 +1,13 @@ +export default async function RootLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( + + + {children} + + + ); +} diff --git a/src/app/api/test/route.ts b/src/app/api/test/route.ts new file mode 100644 index 0000000..475f931 --- /dev/null +++ b/src/app/api/test/route.ts @@ -0,0 +1,15 @@ +/** + * @swagger + * /api/test: + * get: + * description: Returns the hello world + * responses: + * 200: + * description: Hello World! + */ +export async function GET(_request: Request) { + // Do whatever you want + return new Response('Hello World!', { + status: 200, + }); +} \ No newline at end of file diff --git a/src/lib/components/ui/NavigationPanel.tsx b/src/lib/components/ui/NavigationPanel.tsx index ef61263..f0ac510 100644 --- a/src/lib/components/ui/NavigationPanel.tsx +++ b/src/lib/components/ui/NavigationPanel.tsx @@ -2,7 +2,7 @@ import { isAdmin } from "@/lib/util"; import { Avatar, Button, Card, Flex, IconButton, Popover, ScrollArea, Text, Tooltip } from "@radix-ui/themes"; -import { BookUserIcon, HomeIcon, ScrollTextIcon, Users2Icon } from "lucide-react"; +import { BookUserIcon, HomeIcon, KeyRoundIcon, ScrollTextIcon, Users2Icon } from "lucide-react"; import { signOut, useSession } from "next-auth/react"; import Link from "next/link"; import dayjs from "dayjs"; @@ -67,6 +67,14 @@ export default function NavigationPanel({ mobileUi }: { mobileUi?: boolean }) { + + + + + + + + {isAdmin(session.data) && ( <> diff --git a/src/lib/swagger.ts b/src/lib/swagger.ts new file mode 100644 index 0000000..5c94c37 --- /dev/null +++ b/src/lib/swagger.ts @@ -0,0 +1,25 @@ +import { createSwaggerSpec } from 'next-swagger-doc'; + +export const getApiDocs = async () => { + const spec = createSwaggerSpec({ + apiFolder: 'src/app/api', // define api folder under app folder + definition: { + openapi: '3.0.0', + info: { + title: 'Maddy Panel API', + version: '1.0', + }, + components: { + securitySchemes: { + BearerAuth: { + type: 'http', + scheme: 'bearer', + bearerFormat: 'JWT', + }, + }, + }, + security: [], + }, + }); + return spec; +}; \ No newline at end of file