diff options
Diffstat (limited to 'web')
| -rw-r--r-- | web/.gitignore | 47 | ||||
| -rw-r--r-- | web/.vscode/extensions.json | 4 | ||||
| -rw-r--r-- | web/.vscode/launch.json | 11 | ||||
| -rw-r--r-- | web/Dockerfile | 9 | ||||
| -rw-r--r-- | web/README.md | 36 | ||||
| -rw-r--r-- | web/astro.config.mjs | 21 | ||||
| -rw-r--r-- | web/bun.lockb | bin | 179198 -> 154951 bytes | |||
| -rw-r--r-- | web/eslint.config.mjs | 14 | ||||
| -rw-r--r-- | web/jsconfig.json | 7 | ||||
| -rw-r--r-- | web/next.config.mjs | 4 | ||||
| -rw-r--r-- | web/package.json | 26 | ||||
| -rw-r--r-- | web/postcss.config.mjs | 5 | ||||
| -rw-r--r-- | web/public/favicon.svg | 9 | ||||
| -rw-r--r-- | web/src/app/api/auth/[...nextauth]/route.js | 2 | ||||
| -rw-r--r-- | web/src/app/components/sign-in.jsx | 14 | ||||
| -rw-r--r-- | web/src/app/components/sign-out.jsx | 14 | ||||
| -rw-r--r-- | web/src/app/dashboard/page.js | 16 | ||||
| -rw-r--r-- | web/src/app/favicon.ico | bin | 0 -> 25931 bytes | |||
| -rw-r--r-- | web/src/app/globals.css | 26 | ||||
| -rw-r--r-- | web/src/app/layout.js | 29 | ||||
| -rw-r--r-- | web/src/app/page.js | 15 | ||||
| -rw-r--r-- | web/src/components/Quotes.jsx | 88 | ||||
| -rw-r--r-- | web/src/layouts/Layout.astro | 22 | ||||
| -rw-r--r-- | web/src/lib/auth.js | 6 | ||||
| -rw-r--r-- | web/src/pages/index.astro | 45 | ||||
| -rw-r--r-- | web/src/styles/Quote.css | 33 | ||||
| -rw-r--r-- | web/tsconfig.json | 14 |
27 files changed, 235 insertions, 282 deletions
diff --git a/web/.gitignore b/web/.gitignore index 016b59e..5ef6a52 100644 --- a/web/.gitignore +++ b/web/.gitignore @@ -1,24 +1,41 @@ -# build output -dist/ - -# generated types -.astro/ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies -node_modules/ +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build -# logs +# misc +.DS_Store +*.pem + +# debug npm-debug.log* yarn-debug.log* yarn-error.log* -pnpm-debug.log* +.pnpm-debug.log* -# environment variables -.env -.env.production +# env files (can opt-in for committing if needed) +.env* -# macOS-specific files -.DS_Store +# vercel +.vercel -# jetbrains setting folder -.idea/ +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/web/.vscode/extensions.json b/web/.vscode/extensions.json deleted file mode 100644 index 22a1505..0000000 --- a/web/.vscode/extensions.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "recommendations": ["astro-build.astro-vscode"], - "unwantedRecommendations": [] -} diff --git a/web/.vscode/launch.json b/web/.vscode/launch.json deleted file mode 100644 index d642209..0000000 --- a/web/.vscode/launch.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "command": "./node_modules/.bin/astro dev", - "name": "Development server", - "request": "launch", - "type": "node-terminal" - } - ] -} diff --git a/web/Dockerfile b/web/Dockerfile deleted file mode 100644 index e021df4..0000000 --- a/web/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM oven/bun:latest - -WORKDIR /web - -COPY . . - -RUN bun run build - -ENTRYPOINT ["bun", "run", "/web/dist/server/entry.mjs"] diff --git a/web/README.md b/web/README.md new file mode 100644 index 0000000..66bb426 --- /dev/null +++ b/web/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/web/astro.config.mjs b/web/astro.config.mjs deleted file mode 100644 index d32e23b..0000000 --- a/web/astro.config.mjs +++ /dev/null @@ -1,21 +0,0 @@ -// @ts-check -import { defineConfig, envField } from 'astro/config'; - -import react from '@astrojs/react'; - -import node from '@astrojs/node'; - -// https://astro.build/config -export default defineConfig({ - integrations: [react()], - - adapter: node({ - mode: 'standalone' - }), - - env: { - schema: { - API_URL: envField.string({ context: 'client', access: 'public' }), - } - } -}); diff --git a/web/bun.lockb b/web/bun.lockb Binary files differindex 26b85b4..4a7df2d 100644 --- a/web/bun.lockb +++ b/web/bun.lockb diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs new file mode 100644 index 0000000..348c45a --- /dev/null +++ b/web/eslint.config.mjs @@ -0,0 +1,14 @@ +import { dirname } from "path"; +import { fileURLToPath } from "url"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const compat = new FlatCompat({ + baseDirectory: __dirname, +}); + +const eslintConfig = [...compat.extends("next/core-web-vitals")]; + +export default eslintConfig; diff --git a/web/jsconfig.json b/web/jsconfig.json new file mode 100644 index 0000000..b8d6842 --- /dev/null +++ b/web/jsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/web/next.config.mjs b/web/next.config.mjs new file mode 100644 index 0000000..4678774 --- /dev/null +++ b/web/next.config.mjs @@ -0,0 +1,4 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = {}; + +export default nextConfig; diff --git a/web/package.json b/web/package.json index 2a7be8a..5bac297 100644 --- a/web/package.json +++ b/web/package.json @@ -1,20 +1,24 @@ { "name": "aleebot-web", - "type": "module", - "version": "0.0.1", + "version": "0.1.0", + "private": true, "scripts": { - "dev": "astro dev", - "build": "astro build", - "preview": "astro preview", - "astro": "astro" + "dev": "next dev --turbopack", + "build": "next build", + "start": "next start", + "lint": "next lint" }, "dependencies": { - "@astrojs/node": "^9.0.0", - "@astrojs/react": "^4.1.3", - "@types/react": "^19.0.4", - "@types/react-dom": "^19.0.2", - "astro": "^5.1.5", + "next": "15.2.3", + "next-auth": "^5.0.0-beta.25", "react": "^19.0.0", "react-dom": "^19.0.0" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4", + "tailwindcss": "^4", + "eslint": "^9", + "eslint-config-next": "15.2.3", + "@eslint/eslintrc": "^3" } } diff --git a/web/postcss.config.mjs b/web/postcss.config.mjs new file mode 100644 index 0000000..c7bcb4b --- /dev/null +++ b/web/postcss.config.mjs @@ -0,0 +1,5 @@ +const config = { + plugins: ["@tailwindcss/postcss"], +}; + +export default config; diff --git a/web/public/favicon.svg b/web/public/favicon.svg deleted file mode 100644 index f157bd1..0000000 --- a/web/public/favicon.svg +++ /dev/null @@ -1,9 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128"> - <path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" /> - <style> - path { fill: #000; } - @media (prefers-color-scheme: dark) { - path { fill: #FFF; } - } - </style> -</svg> diff --git a/web/src/app/api/auth/[...nextauth]/route.js b/web/src/app/api/auth/[...nextauth]/route.js new file mode 100644 index 0000000..5951f83 --- /dev/null +++ b/web/src/app/api/auth/[...nextauth]/route.js @@ -0,0 +1,2 @@ +import { handlers } from "@/lib/auth" +export const { GET, POST } = handlers diff --git a/web/src/app/components/sign-in.jsx b/web/src/app/components/sign-in.jsx new file mode 100644 index 0000000..bb891c7 --- /dev/null +++ b/web/src/app/components/sign-in.jsx @@ -0,0 +1,14 @@ +import { signIn } from "@/lib/auth" + +export default function SignIn() { + return ( + <form + action={async () => { + "use server" + await signIn("discord") + }} + > + <button type="submit">Login with Discord</button> + </form> + ) +} diff --git a/web/src/app/components/sign-out.jsx b/web/src/app/components/sign-out.jsx new file mode 100644 index 0000000..69162a4 --- /dev/null +++ b/web/src/app/components/sign-out.jsx @@ -0,0 +1,14 @@ +import { signOut } from "@/lib/auth" + +export default function SignOut() { + return ( + <form + action={async () => { + "use server" + await signOut("discord") + }} + > + <button type="submit">Log out</button> + </form> + ) +} diff --git a/web/src/app/dashboard/page.js b/web/src/app/dashboard/page.js new file mode 100644 index 0000000..065bfb0 --- /dev/null +++ b/web/src/app/dashboard/page.js @@ -0,0 +1,16 @@ +import { redirect } from "next/navigation"; +import { auth } from "@/lib/auth"; +import SignOut from "@/app/components/sign-out"; + +export default async function Home() { + const session = await auth(); + if (!session) redirect("/"); + + return ( + <div> + <h1>Dashboard</h1> + <p>Welcome {session.user?.name}</p> + <SignOut /> + </div> + ) +} diff --git a/web/src/app/favicon.ico b/web/src/app/favicon.ico Binary files differnew file mode 100644 index 0000000..718d6fe --- /dev/null +++ b/web/src/app/favicon.ico diff --git a/web/src/app/globals.css b/web/src/app/globals.css new file mode 100644 index 0000000..a2dc41e --- /dev/null +++ b/web/src/app/globals.css @@ -0,0 +1,26 @@ +@import "tailwindcss"; + +:root { + --background: #ffffff; + --foreground: #171717; +} + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); +} + +@media (prefers-color-scheme: dark) { + :root { + --background: #0a0a0a; + --foreground: #ededed; + } +} + +body { + background: var(--background); + color: var(--foreground); + font-family: Arial, Helvetica, sans-serif; +} diff --git a/web/src/app/layout.js b/web/src/app/layout.js new file mode 100644 index 0000000..bec6c45 --- /dev/null +++ b/web/src/app/layout.js @@ -0,0 +1,29 @@ +import { Geist, Geist_Mono } from "next/font/google"; +import "./globals.css"; + +const geistSans = Geist({ + variable: "--font-geist-sans", + subsets: ["latin"], +}); + +const geistMono = Geist_Mono({ + variable: "--font-geist-mono", + subsets: ["latin"], +}); + +export const metadata = { + title: "AleeBot", + description: "Generated by create next app", +}; + +export default function RootLayout({ children }) { + return ( + <html lang="en"> + <body + className={`${geistSans.variable} ${geistMono.variable} antialiased`} + > + {children} + </body> + </html> + ); +} diff --git a/web/src/app/page.js b/web/src/app/page.js new file mode 100644 index 0000000..1890f99 --- /dev/null +++ b/web/src/app/page.js @@ -0,0 +1,15 @@ +import { redirect } from "next/navigation"; +import SignIn from "@/app/components/sign-in"; +import { auth } from "@/lib/auth"; + +export default async function Home() { + const session = await auth(); + if (session) redirect("/dashboard"); + return ( + <> + <main> + <SignIn /> + </main> + </> + ); +} diff --git a/web/src/components/Quotes.jsx b/web/src/components/Quotes.jsx deleted file mode 100644 index 1eb258a..0000000 --- a/web/src/components/Quotes.jsx +++ /dev/null @@ -1,88 +0,0 @@ -import { useState, useEffect } from 'react'; -import '../styles/Quote.css' -import { API_URL } from "astro:env/client"; - -export function PendingQuotes() { - const [quotes, setQuotes] = useState([]); - - const fetchQuotes = async () => { - try { - const response = await fetch(`${API_URL}/api/pending-quotes`); - const data = await response.json(); - setQuotes(data); - } catch (error) { - console.error('Failed to fetch quotes:', error); - } - }; - - useEffect(() => { - fetchQuotes(); - }, []); - - const approveQuote = async (id) => { - try { - const response = await fetch(`${API_URL}/api/approve-quote`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ id }), - }); - - if (response.ok) { - fetchQuotes(); // Refresh the listing after approving the quote - } else { - console.error('Failed to approve quote'); - } - } catch (error) { - console.error('Error approving quote:', error); - } - }; - - const rejectQuote = async (id) => { - try { - const response = await fetch(`${API_URL}/api/reject-quote`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ id }), - }); - - if (response.ok) { - fetchQuotes(); // Refresh the listing after approving the quote - } else { - console.error('Failed to reject quote'); - } - } catch (error) { - console.error('Error rejecting quote:', error); - } - }; - - return ( - <div> - <h1>Pending Quotes</h1> - {quotes.length > 0 ? ( - <ul className="quoteList"> - {quotes.map((quote) => ( - <li key={quote.id} className="quoteList"> - <div className="quote"> - <div className="author"> - <img src={quote.authorImage} alt="No Profile" width="50" height="50"/> - <h1 className="quoteAuthor">{quote.author}</h1> - </div> - <p className="quoteText">{quote.quote}</p> - <small>- {quote.year}</small> - <small>Submitted by {quote.submitterAuthor} ({quote.submitterID})</small> - </div> - <button onClick={() => approveQuote(quote.id)}>Approve</button> - <button onClick={() => rejectQuote(quote.id)}>Reject</button> - </li> - ))} - </ul> - ) : ( - <p>No pending quotes available.</p> - )} - </div> - ); -} diff --git a/web/src/layouts/Layout.astro b/web/src/layouts/Layout.astro deleted file mode 100644 index 2f6032d..0000000 --- a/web/src/layouts/Layout.astro +++ /dev/null @@ -1,22 +0,0 @@ -<!doctype html> -<html lang="en"> - <head> - <meta charset="UTF-8" /> - <meta name="viewport" content="width=device-width" /> - <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> - <meta name="generator" content={Astro.generator} /> - <title>AleeBot Web Interface</title> - </head> - <body> - <slot /> - </body> -</html> - -<style> - html, - body { - margin: 0; - width: 100%; - height: 100%; - } -</style> diff --git a/web/src/lib/auth.js b/web/src/lib/auth.js new file mode 100644 index 0000000..bc482b1 --- /dev/null +++ b/web/src/lib/auth.js @@ -0,0 +1,6 @@ +import NextAuth from "next-auth" +import Discord from "next-auth/providers/discord" + +export const { handlers, signIn, signOut, auth } = NextAuth({ + providers: [Discord], +}) diff --git a/web/src/pages/index.astro b/web/src/pages/index.astro deleted file mode 100644 index f1dc6e7..0000000 --- a/web/src/pages/index.astro +++ /dev/null @@ -1,45 +0,0 @@ ---- -import Layout from '../layouts/Layout.astro'; -import { PendingQuotes } from '../components/Quotes'; - ---- - -<Layout> - <div class="container"> - <h1 id="version">AleeBot</h1> - <PendingQuotes client:load /> - </div> -</Layout> - -<style> - @import url('https://fonts.googleapis.com/css2?family=Exo+2:ital,wght@0,100..900;1,100..900&display=swap'); - html, - body { - margin: 0; - width: 100%; - height: 100%; - font-family: "Exo 2", sans-serif; - } - - .container { - margin: 2em; - } - -</style> - -<script> - import { API_URL } from "astro:env/client" - document.addEventListener('DOMContentLoaded', async () => { - try { - const version = await fetch(`${API_URL}/api/version`).then((res) => res.json()); - const versionElement = document.getElementById('version'); - if (versionElement) { - versionElement.textContent = `AleeBot ${version}`; - } else { - console.error('Element with ID "version" not found.'); - } - } catch (e) { - console.error('Failed to fetch version:', e); - } - }); -</script> diff --git a/web/src/styles/Quote.css b/web/src/styles/Quote.css deleted file mode 100644 index 8adfb29..0000000 --- a/web/src/styles/Quote.css +++ /dev/null @@ -1,33 +0,0 @@ -.quote { - display: flex; - flex-direction: column; - background: #555555; - color: #FFFFFF; - padding: 1em; -} - -ul.quoteList { - margin: 0; - padding: 0; -} - -li.quoteList { - list-style-type: none; - margin-top: 1em; - margin-bottom: 1em; -} - -.author { - display: flex; - flex-direction: row; -} - -h1.quoteAuthor { - font-size: 1.5em; - padding: 0; - margin: 0 0 0 .5em; -} - -.quoteText { - margin: .5em 0; -} diff --git a/web/tsconfig.json b/web/tsconfig.json deleted file mode 100644 index 69c1600..0000000 --- a/web/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "extends": "astro/tsconfigs/strict", - "include": [ - ".astro/types.d.ts", - "**/*" - ], - "exclude": [ - "dist" - ], - "compilerOptions": { - "jsx": "react-jsx", - "jsxImportSource": "react" - } -}
\ No newline at end of file |
