Skip to content

Commit

Permalink
Merge pull request #433 from COS301-SE-2024/QC/web/ip-address-revamp
Browse files Browse the repository at this point in the history
Qc/web/ip address revamp
  • Loading branch information
waveyboym authored Oct 21, 2024
2 parents 2b1d6ae + fde2487 commit 0a462bf
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 199 deletions.
Binary file modified frontend/occupi-web/bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions frontend/occupi-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@nextui-org/use-infinite-scroll": "^2.1.5",
"@passwordless-id/webauthn": "^1.6.1",
"@radix-ui/react-checkbox": "^1.1.1",
"@react-google-maps/api": "^2.20.3",
"@react-pdf/renderer": "^3.4.4",
"@react-stately/data": "^3.11.6",
"@react-three/drei": "^9.111.5",
Expand Down
6 changes: 6 additions & 0 deletions frontend/occupi-web/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ import BookingsDashboard from "./bookingsDashboardComponent/BookingsDashboard";
import HourlyPredictionGraph from "./aiDashboard/aiDashGraphs/HourlyPredictionGraph";
import HourlyComparisonGraph from "./aiDashboard/aiDashGraphs/HourlyComparisonGraph";
import RecommendationsModal from "./recommendationModal/recommendationModal";
import DeleteIPModal from './modal/DeleteIPModal';
import AddIPModal from './modal/AddIPModal';
import UnblockIPModal from './modal/UnblockIPModal';

export {
DrawerComponent,
Expand Down Expand Up @@ -142,4 +145,7 @@ export {
HourlyPredictionGraph,
HourlyComparisonGraph,
RecommendationsModal,
DeleteIPModal,
AddIPModal,
UnblockIPModal
};
100 changes: 100 additions & 0 deletions frontend/occupi-web/src/components/modal/AddIPModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React from "react";
import {
Input,
Button,
ModalBody,
ModalFooter,
ModalHeader,
} from "@nextui-org/react";
import DataService from "DataService";

const AddIPModal = ({
onClose,
view
}: {
onClose: () => void,
view: "whitelisted" | "blacklisted"
}) => {
const [form, setForm] = React.useState<{
email: string;
ip: string;
}>({ email: "", ip: "" });

const [isLoading, setIsLoading] = React.useState<boolean>(false);
const [err, setErr] = React.useState<string | null>(null);

const validateEmail = (email: string) => {
return email === "" || email.match(
/^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z-0-9]+\.)+[a-zA-Z]{2,}))$/
);
};

const validateIP = (ip: string) => {
return ip === "" || ip.match(
/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/
);
};

return (
<>
<ModalHeader className="flex flex-col gap-1">
{view === "whitelisted" ? "Add new IP address" : "Add new Blacklisted IP address"}
</ModalHeader>
<ModalBody>
<Input
value={form.email}
autoFocus
label="Email"
placeholder="Enter the users email"
variant="bordered"
errorMessage="Please enter a valid email"
isInvalid={!validateEmail(form.email)}
onChange={(e) => setForm({ ...form, email: e.target.value })}
/>
<Input
value={form.ip}
label="IP address"
placeholder="Enter the ip address"
variant="bordered"
errorMessage="Please enter a valid ip address"
isInvalid={!validateIP(form.ip)}
onChange={(e) => setForm({ ...form, ip: e.target.value })}
/>
{err && <p className="text-red-500">{err}</p>}
</ModalBody>
<ModalFooter>
<Button color="primary" variant="light" onPress={onClose}>
Close
</Button>
<Button
color="default"
isLoading={isLoading}
onPress={() => {
setIsLoading(true);
if (view === "whitelisted"){
DataService.addIP(form.ip, form.email).then(() => {
setIsLoading(false);
onClose();
}).catch((err) => {
setErr(err.message);
setIsLoading(false);
});
} else{
DataService.removeIP(form.ip, form.email).then(() => {
setIsLoading(false);
onClose();
}).catch((err) => {
setErr(err.message);
setIsLoading(false);
});
}
}}
>
{view === "whitelisted" ? "Add IP" : "Block IP"}
</Button>
</ModalFooter>
</>
);
};

export default AddIPModal;
73 changes: 73 additions & 0 deletions frontend/occupi-web/src/components/modal/DeleteIPModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from "react";
import {
Button,
User,
ModalBody,
ModalFooter,
ModalHeader,
} from "@nextui-org/react";
import DataService from "DataService";

type User = {
email: string;
name: string;
city: string;
region: string;
country: string;
location: string;
ipAddress: string;
blackListedIP: string;
};

const DeleteIPModal = ({
selectedUser,
onClose,
}: {
selectedUser: User | null;
onClose: () => void;
}) => {
const [isLoading, setIsLoading] = React.useState<boolean>(false);
const [err, setErr] = React.useState<string | null>(null);
return (
<>
<ModalHeader className="flex flex-col gap-1">
Remove IP address {selectedUser?.ipAddress}
</ModalHeader>
<ModalBody>
<h3>Are you sure you want to remove this IP address?</h3>
<h4>This will prevent {selectedUser?.email} from logging in from: </h4>
<ul>{selectedUser?.city}</ul>
<ul>{selectedUser?.region}</ul>
<ul>{selectedUser?.country}</ul>
<h4>They will recieve an email notifying them of this change</h4>
{err && <p className="text-red-500">{err}</p>}
</ModalBody>
<ModalFooter>
<Button color="primary" variant="light" onPress={onClose}>
Close
</Button>
<Button
color="danger"
isLoading={isLoading}
onPress={() => {
setIsLoading(true);
DataService.removeIP(
selectedUser?.email ?? "",
selectedUser?.ipAddress ?? ""
).then(() => {
setIsLoading(false);
onClose();
}).catch((err) => {
setErr(err.message);
setIsLoading(false);
});
}}
>
Remove IP
</Button>
</ModalFooter>
</>
);
}

export default DeleteIPModal
68 changes: 68 additions & 0 deletions frontend/occupi-web/src/components/modal/UnblockIPModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from "react";
import {
Button,
User,
ModalBody,
ModalFooter,
ModalHeader,
} from "@nextui-org/react";
import DataService from "DataService";

type User = {
email: string;
name: string;
city: string;
region: string;
country: string;
location: string;
ipAddress: string;
blackListedIP: string;
};

const UnblockIPModal = ({
selectedUser,
onClose,
}: {
selectedUser: User | null;
onClose: () => void;
}) => {
const [isLoading, setIsLoading] = React.useState<boolean>(false);
const [err, setErr] = React.useState<string | null>(null);

return (
<>
<ModalHeader className="flex flex-col gap-1">
Add new IP address
</ModalHeader>
<ModalBody>
<h3>Are you sure you want to allow this IP address?</h3>
<h4>This will allow {selectedUser?.email} to use <ul>{selectedUser?.blackListedIP}</ul> to login</h4>
<h4>They will recieve an email notifying them of this change</h4>
{err && <p className="text-red-500">{err}</p>}
</ModalBody>
<ModalFooter>
<Button color="primary" variant="light" onPress={onClose}>
Close
</Button>
<Button
color="default"
isLoading={isLoading}
onPress={() => {
setIsLoading(true);
DataService.addIP(selectedUser?.blackListedIP ?? "", selectedUser?.email ?? "").then(() => {
setIsLoading(false);
onClose();
}).catch((err) => {
setErr(err.message);
setIsLoading(false);
});
}}
>
Allow IP
</Button>
</ModalFooter>
</>
);
};

export default UnblockIPModal;
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const sidebarcontent = [
},
{
icon: Location,
text: "IP addresses",
text: "Location",
},
{
icon: Report,
Expand Down Expand Up @@ -92,7 +92,7 @@ const SideNav = () => {
else if (arg === "Booking Statistics") navigate("/booking-statistics/overview");
else if (arg === "Company Statistics") navigate("/worker-dashboard");
else if (arg === "Employees") navigate("/employees");
else if (arg === "IP addresses") navigate("/user-locations");
else if (arg === "Location") navigate("/user-locations");
else;
}

Expand All @@ -112,7 +112,7 @@ const SideNav = () => {
else if (pn.startsWith("/booking-statistics")) setSelectedPanel("Booking Statistics");
else if (pn.startsWith("/worker-dashboard")) setSelectedPanel("Company Statistics");
else if (pn.startsWith("/employees")) setSelectedPanel("Employees");
else if (pn.startsWith("/user-locations")) setSelectedPanel("IP addresses");
else if (pn.startsWith("/user-locations")) setSelectedPanel("Location");
else setSelectedPanel("");
};

Expand Down
Loading

0 comments on commit 0a462bf

Please sign in to comment.