From 3ba43bc8b863e2cc8e94acfbfa992c06888d9b48 Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Sat, 9 Apr 2022 23:19:47 -0700 Subject: [PATCH] Plumbing events Signed-off-by: James Ketrenos --- client/src/App.js | 2 +- client/src/Dashboard.js | 8 +-- client/src/Event.css | 4 ++ client/src/Event.js | 109 +++++++++++++++++++++++++++++++++++++ client/src/Group.js | 19 ++++--- client/src/Location.js | 6 +- server/event-data.js | 8 +-- server/group-data.js | 12 ++-- server/routes/events.js | 46 +++++++++++----- server/routes/locations.js | 2 - 10 files changed, 177 insertions(+), 39 deletions(-) create mode 100644 client/src/Event.css create mode 100644 client/src/Event.js diff --git a/client/src/App.js b/client/src/App.js index 24583d8..30daaa3 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -117,7 +117,7 @@ const App = () => { Not implemented... yet. }/> - }/> + }/> { user && user.mailVerified && }/> } diff --git a/client/src/Dashboard.js b/client/src/Dashboard.js index 57a3608..93f4a44 100644 --- a/client/src/Dashboard.js +++ b/client/src/Dashboard.js @@ -48,7 +48,7 @@ function Dashboard() { }, [user, setGroups, csrfToken ]); const upcomingEvents = groups - .filter(group => group.nextEvent > Date.now()); + .filter(group => group.nextEvent.date > Date.now()); return (
{ return ; }) diff --git a/client/src/Event.css b/client/src/Event.css new file mode 100644 index 0000000..ef38beb --- /dev/null +++ b/client/src/Event.css @@ -0,0 +1,4 @@ +.Event { + text-align: left; +} + diff --git a/client/src/Event.js b/client/src/Event.js new file mode 100644 index 0000000..c326177 --- /dev/null +++ b/client/src/Event.js @@ -0,0 +1,109 @@ +import React, { useState, useEffect, useContext } from "react"; +import Paper from '@mui/material/Paper'; +import { + useParams, + useNavigate +} from "react-router-dom"; + +import './Event.css'; +import { GlobalContext } from "./GlobalContext.js"; +import { base } from "./Common.js"; + +function Event({ groupId }) { + const eventId = useParams().event; + const { csrfToken, setError } = useContext(GlobalContext); + const [ event, setEvent ] = useState(undefined); + + useEffect(() => { + if (!csrfToken || event || !eventId || !groupId) { + return; + } + + const effect = async () => { + const res = await window.fetch( + `${base}/api/v1/events/${eventId}?groupId=${groupId}`, { + method: 'GET', + cache: 'no-cache', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json', + 'CSRF-Token': csrfToken + } + }); + const data = await res.json(); + if (res.status >= 400) { + setError(data.message ? data.message : res.statusText); + return; + } + if (!data) { + return; + } + setEvent(data[0]); + } + effect(); + }, [eventId, csrfToken, event, setError]); + + const showEvent = (event) => { + const fields = Object.getOwnPropertyNames(event) + .filter(field => event[field]) + .map(field => { + return
+
{field}
+
+ { typeof event[field] === 'string' + && event[field].match(/^http.*/) + && {field.toUpperCase()} } + { typeof event[field] === 'string' + && !event[field].match(/^http.*/) + && event[field] } + { typeof event[field] === 'number' && event[field]} +
+
+ } ); + return
+
{fields}
+
; + }; + + if (!event) { + return <>No event; + } + + return ( + + { showEvent(event) } + + ); +} + +export { Event }; diff --git a/client/src/Group.js b/client/src/Group.js index 5a9e97e..0364918 100644 --- a/client/src/Group.js +++ b/client/src/Group.js @@ -2,13 +2,15 @@ import React, { useState, useEffect, useContext } from "react"; import Paper from '@mui/material/Paper'; import { useParams, - useNavigate + Routes, + Route } from "react-router-dom"; import './Group.css'; import { GlobalContext } from "./GlobalContext.js"; import { base } from "./Common.js"; import { Location } from "./Location.js"; +import { Event } from "./Event.js"; function Group() { const { csrfToken, user, setError } = useContext(GlobalContext); @@ -110,12 +112,15 @@ function Group() { flexDirection: 'column', textAlign: 'left', }}> - { group && <> -
{group.name}
-
Locations
- { locations.map(location => - ) } - } + + } /> + +
{group.name}
+
Locations
+ { locations.map(location => + ) } + }/> +
); } diff --git a/client/src/Location.js b/client/src/Location.js index e62b630..9a6e2e7 100644 --- a/client/src/Location.js +++ b/client/src/Location.js @@ -44,9 +44,9 @@ function Location(props) { setLocation(data); } effect(); - }, [locationId, csrfToken, location]); + }, [locationId, csrfToken, location, setError]); - const createLocation = (location) => { + const showLocation = (location) => { const fields = Object.getOwnPropertyNames(location) .filter(field => location[field]) .map(field => { @@ -109,7 +109,7 @@ function Location(props) { marginTop: '0.25rem', marginBottom: '0.25rem' }}> - { createLocation(location) } + { showLocation(location) } ); } diff --git a/server/event-data.js b/server/event-data.js index 7cb547f..09f85a2 100644 --- a/server/event-data.js +++ b/server/event-data.js @@ -1,8 +1,8 @@ const originalEvents = [ { - id: 1, - name: 'Tuesday', - event: 'tuesday', - date: Date.now() + 86400 * 14 * 1000 /* 2 weeks from now */ + groupId: 1, + name: 'Tuesday', + event: 'tuesday', + date: Date.now() + 86400 * 14 * 1000 /* 2 weeks from now */ } ]; originalEvents.forEach((item, index) => item.id = index + 1); module.exports = originalEvents; \ No newline at end of file diff --git a/server/group-data.js b/server/group-data.js index c8f6ba7..6ef0e57 100644 --- a/server/group-data.js +++ b/server/group-data.js @@ -1,10 +1,12 @@ +const originalEvents = require('./event-data.js'); const originalGroups = [ { - ownerId: 1, - name: 'Beer Tuesday', - group: 'beer-tuesday', - nextEvent: Date.now() + 86400 * 14 * 1000, /* 2 weeks from now */ - nextEventId: 1 + ownerId: 1, + name: 'Beer Tuesday', + group: 'beer-tuesday', } ]; + +originalGroups[0].nextEvent = originalEvents[0]; +originalEvents.forEach(item => item.groupId = 1); originalGroups.forEach((item, index) => item.id = index + 1); module.exports = originalGroups; \ No newline at end of file diff --git a/server/routes/events.js b/server/routes/events.js index 6248e37..4405717 100644 --- a/server/routes/events.js +++ b/server/routes/events.js @@ -1,10 +1,9 @@ -'use strict'; - const config = require('config'); const express = require('express'); const router = express.Router(); const originalEvents = require('../event-data.js'); +const originalGroups = require('../group-data.js'); router.put('/', (req, res) => { const event = req.body; @@ -17,19 +16,40 @@ router.get('/google-api-key', (req, res) => { return res.status(200).send({ key: config.get('googleApi') }); }); -router.get('/:eventId?', (req, res) => { - const { eventId } = req.params; - if (eventId) { - const event = originalEvents.find( - item => item.id === eventId - ); - if (!event) { - return res.status(404).send({ message: `Event ${eventId} not found.` }); - } - return res.status(200).send([event]); +router.get('/:event?', (req, res) => { + const { event } = req.params; + const { groupId } = req.query; + + if (!event) { + return res.status(200).send(originalEvents); } - return res.status(200).send(originalEvents); + const group = originalGroups.find(item => { + return (item.groupId === groupId || item.group === groupId); + }); + + if (!group) { + return res.status(500).send({ message: `Invalid group-event link.` }); + } + + const found = originalEvents.find((item) => { + if (item.groupId !== group.id) { + return false; + } + if (typeof event === 'number') { + return item.id === event; + } + if (typeof event === 'string') { + return item.event === event; + } + return false; + }); + if (!found) { + return res.status(404).send({ + message: `Unable to find ${groupId}:${event}.` + }); + } + return res.status(200).send([found]); }); router.post('/:eventId', (req, res) => { diff --git a/server/routes/locations.js b/server/routes/locations.js index f2c438b..6545cc0 100644 --- a/server/routes/locations.js +++ b/server/routes/locations.js @@ -1,5 +1,3 @@ -'use strict'; - const config = require('config'); const express = require('express'); const router = express.Router();