diff options
Diffstat (limited to 'web/src')
| -rw-r--r-- | web/src/components/Quotes.jsx | 86 | ||||
| -rw-r--r-- | web/src/layouts/Layout.astro | 22 | ||||
| -rw-r--r-- | web/src/pages/index.astro | 29 | ||||
| -rw-r--r-- | web/src/styles/Quote.css | 33 |
4 files changed, 170 insertions, 0 deletions
diff --git a/web/src/components/Quotes.jsx b/web/src/components/Quotes.jsx new file mode 100644 index 0000000..1d563e7 --- /dev/null +++ b/web/src/components/Quotes.jsx @@ -0,0 +1,86 @@ +import { useState, useEffect } from 'react'; +import '../styles/Quote.css' + +export function PendingQuotes() { + const [quotes, setQuotes] = useState([]); + + const fetchQuotes = async () => { + try { + const response = await fetch('http://localhost:3000/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('http://localhost:3000/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('http://localhost:3000/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> + </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 new file mode 100644 index 0000000..e455c61 --- /dev/null +++ b/web/src/layouts/Layout.astro @@ -0,0 +1,22 @@ +<!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>Astro Basics</title> + </head> + <body> + <slot /> + </body> +</html> + +<style> + html, + body { + margin: 0; + width: 100%; + height: 100%; + } +</style> diff --git a/web/src/pages/index.astro b/web/src/pages/index.astro new file mode 100644 index 0000000..b5c607d --- /dev/null +++ b/web/src/pages/index.astro @@ -0,0 +1,29 @@ +--- +import Layout from '../layouts/Layout.astro'; +import { PendingQuotes } from '../components/Quotes'; + +const version = await fetch('http://localhost:3000/api/version').then(res => res.json()); +--- + +<Layout> + <div class="container"> + <h1>AleeBot {version}</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> diff --git a/web/src/styles/Quote.css b/web/src/styles/Quote.css new file mode 100644 index 0000000..8adfb29 --- /dev/null +++ b/web/src/styles/Quote.css @@ -0,0 +1,33 @@ +.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; +} |
