working distance sorting

This commit is contained in:
Maciej Kotowski committed 2021-10-06 17:39:59 +02:00
1 parent becdf573dc
commit e8e049c342
7 files changed
+137 -77

No files matched your search

+2
View File
@@ -1,9 +1,11 @@
import { APIClient } from "./utils/APIClient";
import { LoginManager } from "./utils/LoginManager";
require("dotenv").config();
export const APP_NAME = "eco-meet";
export const BACKEND_URL = "http://localhost:5000";
export const API_CLIENT = new APIClient(process.env.DEPLOY ? "" : BACKEND_URL);
export const LOGIN_MANAGER = new LoginManager(process.env.DEPLOY ? "" : BACKEND_URL);
export const EVENT_TYPES = {
colors: {
1: "#53d188",
+77 -48
View File
@@ -7,8 +7,10 @@ import styles from "./index.module.scss";
import { BIcon } from "../../components/BIcon";
// import HoldingPlant from "../../components/Pop-up/AnimatedHand";
import { API_CLIENT } from "../../constants";
// import { calculateDistance } from "../../utils/map/calculateDistance";
import { calculateDistance } from "../../utils/map/calculateDistance";
import { useHistory } from "react-router";
import { spawnPopup } from "../../utils/popups/spawnPopup";
import { spawnError } from "../../utils/popups/spawnError";
export const Home = () => {
useTitle();
@@ -18,9 +20,75 @@ export const Home = () => {
})
);
const sortDropdown = useRef(null);
const history = useHistory();
const sortingFn = async (e) => {
const [type, direction] = e.target.value.split(":");
let userPos;
if (type === "distance") {
const permissions = await window.navigator.permissions.query({ name: "geolocation" });
if (permissions.state === "granted") {
await window.navigator.geolocation.getCurrentPosition(
(pos) => {
userPos = [pos.coords.longitude, pos.coords.latitude];
},
async (e) => {
console.error(e);
await spawnError(e.toString());
userPos = null;
}
);
} else if (permissions.state === "prompt") {
userPos = await spawnPopup((c) => {
window.navigator.geolocation.getCurrentPosition(
(pos) => {
c([pos.coords.longitude, pos.coords.latitude]);
},
async (e) => {
console.error(e);
await spawnError("Brak dostępu do lokalizacji");
c(null);
}
);
return <h1>Oczekiwanie na przyznanie uprawnień</h1>;
});
} else if (permissions.state === "denied") {
await spawnError("Odmówiono aplikacji dostępu do lokalizacji urządzenia");
userPos = null;
}
if (!userPos) {
sortDropdown.current.value = "event-date:ascending";
return;
}
}
const newOrder = API_CLIENT.events.sort((a, b) => {
switch (type) {
case "event-date":
return direction === "ascending" ? a.time - b.time : b.time - a.time;
case "creation-date":
return direction === "ascending" ? b.created.time - a.created.time : a.created.time - b.created.time;
case "alphabetic":
return direction === "ascending" ? (a.name > b.name ? -1 : 1) : a.name > b.name ? 1 : -1;
case "distance":
if (userPos !== [null, null]) {
const aDistance = a.lon && a.lat ? calculateDistance(userPos, [a.lon, a.lat]) : -1;
const bDistance = b.lon && b.lat ? calculateDistance(userPos, [b.lon, b.lat]) : -1;
return direction === "ascending" ? aDistance - bDistance : bDistance - aDistance;
} else return 0;
default:
return 0;
}
});
updateList(
newOrder.map((e, i) => {
return (
<EventPreview data={{ name: e.name, type: e.type, lon: e.lon, lat: e.lat, createdTime: e.created.time, time: e.time, id: e._id, address: e.address }} key={i} />
);
})
);
};
useEffect(() => {
API_CLIENT.on("EVENT_RELOAD", (list) => {
const apiClientCallback = (list) => {
updateList(
list.map((e, i) => {
return (
@@ -31,53 +99,14 @@ export const Home = () => {
);
})
);
});
API_CLIENT.on("EVENT_CREATE", (list) => {
updateList(
list.map((e, i) => {
return (
<EventPreview
data={{ name: e.name, type: e.type, lon: e.lon, lat: e.lat, createdTime: e.created.time, time: e.time, id: e._id, address: e.address }}
key={i}
/>
);
})
);
});
};
API_CLIENT.on("EVENT_RELOAD", apiClientCallback);
API_CLIENT.on("EVENT_CREATE", apiClientCallback);
sortDropdown.current.addEventListener("input", (e) => {
const value = e.target.value;
const type = value.split(":")[0];
const direction = value.split(":")[1];
const newOrder = API_CLIENT.events.sort((a, b) => {
switch (type) {
case "event-date":
return direction === "ascending" ? a.time - b.time : b.time - a.time;
case "creation-date":
return direction === "ascending" ? b.created.time - a.created.time : a.created.time - b.created.time;
case "alphabetic":
return direction === "ascending" ? (a.name > b.name ? -1 : 1) : a.name > b.name ? 1 : -1;
case "distance":
return 0;
default:
return 0;
}
});
updateList(
newOrder.map((e, i) => {
return (
<EventPreview
data={{ name: e.name, type: e.type, lon: e.lon, lat: e.lat, createdTime: e.created.time, time: e.time, id: e._id, address: e.address }}
key={i}
/>
);
})
);
});
sortDropdown.current.addEventListener("input", sortingFn);
sortingFn({ target: sortDropdown.current });
}, []);
const history = useHistory();
return (
<div className={container}>
{/* <div className={styles.hand}>
@@ -95,8 +124,8 @@ export const Home = () => {
<option value="creation-date:descending">Data utworzenia: od najstarszych</option>
<option value="alphabetic:ascending">Alfabetycznie: A-Z</option>
<option value="alphabetic:descending">Alfabetycznie: Z-A</option>
<option value="distance:ascending">Odległość: najbliżej [NIE DZIAŁA]</option>
<option value="distance:descending">Odległość: najdalej [NIE DZIAŁA]</option>
<option value="distance:ascending">Odległość: najbliżej</option>
<option value="distance:descending">Odległość: najdalej</option>
</select>
<button
onClick={() => {
+2 -2
View File
@@ -3,7 +3,7 @@ import styles from "./index.module.scss";
import { container } from "../../global.module.scss";
import { Stack } from "react-bootstrap";
import { useEffect, useRef } from "react";
import { API_CLIENT } from "../../constants";
import { LOGIN_MANAGER } from "../../constants";
import { useHistory } from "react-router";
import { spawnError } from "../../utils/popups/spawnError";
@@ -14,7 +14,7 @@ export const LoginPage = () => {
useEffect(() => {
form.current.addEventListener("submit", (e) => {
e.preventDefault();
API_CLIENT.loginUser({ email: e.srcElement[0].value, password: e.srcElement[1].value })
LOGIN_MANAGER.login({ email: e.srcElement[0].value, password: e.srcElement[1].value })
.then((r) => {
console.log(r);
history.push("/");
+37
View File
@@ -0,0 +1,37 @@
import axios from "axios";
import { EventEmitter } from "events";
export class LoginManager extends EventEmitter {
#dbUrl = "";
#loginState = null;
get state() {
return this.#loginState;
}
constructor(dbUrl) {
super();
if (typeof dbUrl !== "string") throw new TypeError("dbUrl must be a string");
this.#dbUrl = dbUrl;
}
async login(data) {
if (!data) throw new Error("Missing required parameter");
if (typeof data.email !== "string") throw new TypeError("name param is a required string");
if (typeof data.password !== "string") throw new TypeError("name param is a required string");
const rq = await axios.post(`${this.#dbUrl}/api/auth/register_login`, data);
if (rq.status !== 200) throw new Error(`Request failed with status code ${rq.status}: ${rq.statusText}`);
this.#loginState = rq.data;
this.emit("STATE_CHANGE", this.#loginState);
return rq.data;
}
async logout() {
const rq = await axios.get(`${this.#dbUrl}/api/logout`);
if (rq.status !== 200) throw new Error(`Request failed with status code ${rq.status}: ${rq.statusText}`);
this.#loginState = null;
this.emit("STATE_CHANGE", null);
return null;
}
}
-1
View File
@@ -1,6 +1,5 @@
import ReactDOM from "react-dom";
import { Window } from "../../components/Window";
import { window as windowClass } from "../../components/Window/index.module.scss";
export const spawnPopup = async (elements, windowStyles) => {
const container = document.createElement("div");
+16 -23
View File
@@ -15,13 +15,12 @@ app.use(
})
);
const MongoStore = require("connect-mongo")
const MongoStore = require("connect-mongo");
// Passport middleware
mongoose
.connect(process.env.MONGO_URI, { useNewUrlParser: true })
.then(console.log(`MongoDB connected ${process.env.MONGO_URI}`))
.catch(err => console.log(err));
.catch((err) => console.log(err));
// Bodyparser middleware, extended false does not allow nested payloads
app.use(express.json());
@@ -33,7 +32,7 @@ app.use(
secret: "very secret this is",
resave: false,
saveUninitialized: true,
store: MongoStore.create({ mongoUrl:process.env.MONGO_URI, })
store: MongoStore.create({ mongoUrl: process.env.MONGO_URI }),
})
);
@@ -44,32 +43,20 @@ app.use(passport.session());
// Routes
app.use("/api/auth", auth);
app.get('/logout', function(req, res){
app.get("/logout", function (req, res) {
req.logout();
res.redirect('/');
});
res.status(200).join({ successful: true });
// res.redirect('/');
});
//deploy
app.use(express.static(path.join(__dirname, "client/build")));
//routes
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname + "/client/build/index.html"));
});
app.get("/api/getEvents", async (req, res) => {
try {
const event = await events.find();
@@ -81,6 +68,15 @@ app.get("/api/getEvents", async (req, res) => {
}
});
app.get("/api/isLogged", async (req, res) => {
if (req.user) {
res.status(200).json({ id: req.user.id, email: req.user.email });
} else {
res.redirect('/login');
}
});
@@ -103,9 +99,6 @@ app.post("/api/createEvent", (req, res) => {
});
});
app.use((req, res, next) => {
res.sendFile(path.join(__dirname + "/client/build/index.html"));
});
+3 -3
View File
@@ -3,18 +3,18 @@ const router = express.Router();
const passport = require("passport");
router.post("/register_login", (req, res, next) => {
passport.authenticate("local", function(err, user, info) {
passport.authenticate("local", function (err, user, info) {
if (err) {
return res.status(400).json({ errors: err });
}
if (!user) {
return res.status(400).json({ errors: "No user found" });
}
req.logIn(user, function(err) {
req.logIn(user, function (err) {
if (err) {
return res.status(400).json({ errors: err });
}
return res.status(200).json({ success: `logged in ${user.id}` });
return res.status(200).json(user);
});
})(req, res, next);
});