diff --git a/client/src/App.js b/client/src/App.js
index 21858f8..30359ee 100644
--- a/client/src/App.js
+++ b/client/src/App.js
@@ -1,4 +1,4 @@
-import { useState } from "react";
+import { useEffect, useState } from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import { Home } from "./pages/Home";
import { About } from "./pages/About";
@@ -8,57 +8,96 @@ import { NotFound } from "./pages/NotFound";
import { Navbar } from "./components/Navbar";
import { CreateEvent } from "./pages/CreateEvent";
import { Event } from "./pages/Event";
-import { EVENT_CONTEXT } from "./constants";
+import { API_CLIENT } from "./constants";
import { LoginPage } from "./pages/Login";
-export const App = (props) => {
- const [context, setContext] = useState({
- events: props.events,
- updateEvents: function (events = []) {
- if (!Array.isArray(events)) throw new TypeError("Events must come in array");
- setContext({
- events: events,
- updateEvents: this.updateEvents,
- });
- },
- });
+export const App = () => {
+ const [routes, setRoutes] = useState(
+ API_CLIENT.events.map((e) => {
+ return (
+
+
+
+ );
+ })
+ );
+
+ useEffect(() => {
+ API_CLIENT.on("EVENT_RELOAD", (list) => {
+ setRoutes(
+ list.map((e) => {
+ return (
+
+
+
+ );
+ })
+ );
+ });
+ API_CLIENT.on("EVENT_CREATE", (list) => {
+ setRoutes(
+ list.map((e) => {
+ return (
+
+
+
+ );
+ })
+ );
+ });
+ }, []);
return (
-
-
-
-
-
-
-
-
-
-
-
-
- {Array.isArray(props.events) &&
- props.events.map((e) => {
- return (
-
-
-
- );
- })}
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ {routes}
+
+
+
);
};
diff --git a/client/src/constants.js b/client/src/constants.js
index b0097b8..f241070 100644
--- a/client/src/constants.js
+++ b/client/src/constants.js
@@ -1,10 +1,8 @@
-import { createContext } from "react";
import { APIClient } from "./utils/APIClient";
require("dotenv").config();
export const APP_NAME = "eco-meet";
export const BACKEND_URL = "http://localhost:5000";
-export const EVENT_CONTEXT = createContext();
export const API_CLIENT = new APIClient(process.env.DEPLOY ? "" : BACKEND_URL);
export const EVENT_TYPES = {
colors: {
diff --git a/client/src/index.js b/client/src/index.js
index 74823c3..118170c 100644
--- a/client/src/index.js
+++ b/client/src/index.js
@@ -6,11 +6,11 @@ import "bootstrap/dist/css/bootstrap.min.css";
import { API_CLIENT } from "./constants";
(async () => {
- const dbEvents = await API_CLIENT.getEvents();
+ await API_CLIENT.fetchEvents();
ReactDOM.render(
-
+
,
document.getElementById("root")
);
diff --git a/client/src/pages/CreateEvent/index.js b/client/src/pages/CreateEvent/index.js
index 4ff7174..84266a0 100644
--- a/client/src/pages/CreateEvent/index.js
+++ b/client/src/pages/CreateEvent/index.js
@@ -1,10 +1,10 @@
import { useTitle } from "../../utils/useTitle";
import { useFormik } from "formik";
-import { useContext, useState } from "react";
+import { useState } from "react";
import { Stack } from "react-bootstrap";
import { BIcon } from "../../components/BIcon";
import { useHistory } from "react-router";
-import { API_CLIENT, EVENT_CONTEXT } from "../../constants";
+import { API_CLIENT } from "../../constants";
import { container } from "../../global.module.scss";
import styles from "./index.module.scss";
import { spawnPopup } from "../../utils/popups/spawnPopup";
@@ -14,7 +14,6 @@ import { MapPopup } from "./MapPopup";
export const CreateEvent = () => {
useTitle("Tworzenie wydarzenia");
- const context = useContext(EVENT_CONTEXT);
const history = useHistory();
const [locationText, setLocationText] = useState("Brak lokalizacji");
const formik = useFormik({
@@ -46,7 +45,7 @@ export const CreateEvent = () => {
const rqObj = {
name: data.name,
type: parseInt(data.type),
- description: data.description,
+ description: data.description ?? null,
lon: mapPos?.[0] ?? null,
lat: mapPos?.[1] ?? null,
address: locationText,
@@ -54,10 +53,7 @@ export const CreateEvent = () => {
};
API_CLIENT.createEvent(rqObj)
.then(() => {
- API_CLIENT.getEvents().then((r) => {
- context.updateEvents(r);
- history.push("/");
- });
+ history.push("/");
})
.catch(async (e) => {
await spawnError(e.toString());
diff --git a/client/src/pages/Home/index.js b/client/src/pages/Home/index.js
index bc5a759..caafeed 100644
--- a/client/src/pages/Home/index.js
+++ b/client/src/pages/Home/index.js
@@ -1,32 +1,56 @@
import { useTitle } from "../../utils/useTitle";
-import { useState, useRef, useEffect, useContext } from "react";
+import { useState, useRef, useEffect } from "react";
import { Stack } from "react-bootstrap";
import { EventPreview } from "../../components/EventPreview";
import { container } from "../../global.module.scss";
import styles from "./index.module.scss";
import { BIcon } from "../../components/BIcon";
// import HoldingPlant from "../../components/Pop-up/AnimatedHand";
-import { EVENT_CONTEXT } from "../../constants";
+import { API_CLIENT } from "../../constants";
// import { calculateDistance } from "../../utils/map/calculateDistance";
import { useHistory } from "react-router";
import Button from "@restart/ui/esm/Button";
export const Home = () => {
useTitle();
- const context = useContext(EVENT_CONTEXT);
const [list, updateList] = useState(
- context.events.map((e, i) => {
+ API_CLIENT.events.map((e, i) => {
return ;
})
);
const sortDropdown = useRef(null);
useEffect(() => {
+ API_CLIENT.on("EVENT_RELOAD", (list) => {
+ updateList(
+ list.map((e, i) => {
+ return (
+
+ );
+ })
+ );
+ });
+ API_CLIENT.on("EVENT_CREATE", (list) => {
+ updateList(
+ list.map((e, i) => {
+ return (
+
+ );
+ })
+ );
+ });
+
sortDropdown.current.addEventListener("input", (e) => {
const value = e.target.value;
const type = value.split(":")[0];
const direction = value.split(":")[1];
- const newOrder = context.events.sort((a, b) => {
+ const newOrder = API_CLIENT.events.sort((a, b) => {
switch (type) {
case "event-date":
return direction === "ascending" ? a.time - b.time : b.time - a.time;
@@ -51,7 +75,7 @@ export const Home = () => {
})
);
});
- }, [context.events]);
+ }, []);
const history = useHistory();
diff --git a/client/src/utils/APIClient.js b/client/src/utils/APIClient.js
index a34bbdb..b32a7e9 100644
--- a/client/src/utils/APIClient.js
+++ b/client/src/utils/APIClient.js
@@ -1,22 +1,33 @@
import axios from "axios";
+import { EventEmitter } from "events";
-export class APIClient {
+export class APIClient extends EventEmitter {
#dbUrl = "";
+ #events = [];
constructor(dbUrl) {
+ super();
if (typeof dbUrl !== "string") throw new Error("Database URL is not a string");
this.#dbUrl = dbUrl;
}
- async getEvents() {
+
+ get events() {
+ return this.#events;
+ }
+
+ async fetchEvents() {
const rq = await axios.get(`${this.#dbUrl}/api/getEvents`);
if (rq.status !== 200) throw new Error(`Request failed with status code ${rq.status}: ${rq.statusText}`);
+ this.#events = rq.data;
+ this.emit("EVENT_RELOAD", this.#events, rq.data);
return rq.data;
}
+
async getEvent(id) {
if (typeof id !== "string") throw new TypeError("Invalid ID type");
- const events = await this.getEvents();
- return events.find((e) => e.id === id) ?? null;
+ return this.#events.find((e) => e.id === id) ?? null;
}
+
async createEvent(data) {
//Check types
if (typeof data !== "object") throw new TypeError("Data object is required");
@@ -27,6 +38,8 @@ export class APIClient {
//Make POST request
const rq = await axios.post(`${this.#dbUrl}/api/createEvent`, data);
if (rq.status !== 200) throw new Error(`Request failed with status code ${rq.status}: ${rq.statusText}`);
- return rq;
+ this.#events.push(rq.data);
+ this.emit("EVENT_CREATE", this.#events, rq.data);
+ return rq.data;
}
}
diff --git a/index.js b/index.js
index 6c27765..50ca4b0 100644
--- a/index.js
+++ b/index.js
@@ -51,10 +51,10 @@ app.post("/api/createEvent", (req, res) => {
lat: req.body.lat,
lon: req.body.lon,
};
- events.create(data, (err) => {
+ events.create(data, (err, data) => {
if (err) return res.status(400).json({ msg: err });
// saved!
- res.status(200).json("ok");
+ res.status(200).json(data);
});
});
app.use((req, res, next) => {