diff options
Diffstat (limited to 'web/src')
| -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 |
13 files changed, 122 insertions, 188 deletions
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; -} |
