summaryrefslogtreecommitdiff
path: root/front/src/routes/bots.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'front/src/routes/bots.jsx')
-rw-r--r--front/src/routes/bots.jsx194
1 files changed, 194 insertions, 0 deletions
diff --git a/front/src/routes/bots.jsx b/front/src/routes/bots.jsx
new file mode 100644
index 0000000..c2f1565
--- /dev/null
+++ b/front/src/routes/bots.jsx
@@ -0,0 +1,194 @@
+import Modal from "react-modal";
+import { useAuthContext } from "../context/auth_context";
+import { useEffect, useState } from "react";
+
+Modal.setAppElement("#root");
+
+const BotButton = ({ onSave, givenBot }) => {
+ const [open, setOpen] = useState(false);
+ const [name, setName] = useState(givenBot?.name || "");
+ const [webhook, setWebhook] = useState(givenBot?.webhook || "");
+ const [errors, setErrors] = useState(null);
+ const [isPublic, setIsPublic] = useState(givenBot?.public || false);
+
+ const setDefaults = () => {
+ setName("");
+ setWebhook("");
+ setErrors(null);
+ };
+
+ const close = () => {
+ if (!givenBot) {
+ setDefaults();
+ }
+ setOpen(false);
+ };
+
+ const updateBot = () => {
+ fetch(givenBot ? `/api/player/bots/${givenBot.id}` : "/api/player/bots", {
+ credentials: "same-origin",
+ method: givenBot ? "PUT" : "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ webhook: webhook.trim(),
+ name: name.trim(),
+ public: isPublic,
+ }),
+ })
+ .then((r) => r.json())
+ .then((d) => {
+ if (d.success) {
+ if (onSave) {
+ onSave();
+ }
+ close();
+ } else if (d.errors) {
+ if (typeof d.errors === "object") {
+ setErrors(
+ Object.keys(d.errors).map(
+ (field) => `${field}: ${d.errors[field].join(",")}`
+ )
+ );
+ } else {
+ setErrors([d.errors]);
+ }
+ }
+ });
+ };
+
+ return (
+ <div>
+ <button className="button" onClick={() => setOpen(true)}>
+ {givenBot ? "Update" : "+ Add"} Bot
+ </button>
+ {givenBot && (
+ <>
+ <button
+ style={{ marginLeft: "1rem" }}
+ className="button gold"
+ onClick={() => {
+ navigator.clipboard.writeText(givenBot?.token);
+ alert("Bot's token was copied to the clipboard.");
+ }}
+ >
+ Copy Token
+ </button>
+ <button
+ style={{ marginLeft: "1rem" }}
+ className="button red"
+ onClick={() =>
+ fetch(`/api/player/bots/${givenBot.id}/redrive`)
+ .then((r) => r.json())
+ .then(({ message }) => alert(message))
+ }
+ >
+ Schedule Redrive
+ </button>
+ </>
+ )}
+ <Modal
+ isOpen={open}
+ onRequestClose={close}
+ className="modal"
+ contentLabel="Add Bot"
+ >
+ <div style={{ minWidth: "20vw" }}>
+ <h3>Add Bot</h3>
+ <hr />
+ <p>Bot Name *</p>
+ <input
+ style={{ width: "100%" }}
+ value={name}
+ onChange={(e) => setName(e.target.value)}
+ required
+ />
+ </div>
+ <div>
+ <p>Webhook *</p>
+ <input
+ style={{ width: "100%" }}
+ value={webhook}
+ onChange={(e) => setWebhook(e.target.value)}
+ required
+ />
+ </div>
+ <p>
+ Public *{" "}
+ <input
+ type="checkbox"
+ value={name}
+ checked={isPublic}
+ onChange={(e) => setIsPublic(!isPublic)}
+ required
+ />
+ </p>
+ <div>
+ {errors && (
+ <div style={{ color: "red" }}>
+ {errors.map((error, i) => (
+ <p key={i}>{error}</p>
+ ))}
+ </div>
+ )}
+ </div>
+ <div className="flex-end-row">
+ <button className="button" onClick={updateBot}>
+ {givenBot ? "Update" : "+ Add"}
+ </button>
+ <button className="button red" onClick={close}>
+ Cancel
+ </button>
+ </div>
+ </Modal>
+ </div>
+ );
+};
+
+export const BotCard = ({ botStruct, onSave }) => {
+ const { name } = botStruct;
+ return (
+ <div className="key-card">
+ <h4>{name}</h4>
+ <BotButton onSave={onSave} givenBot={botStruct} />
+ </div>
+ );
+};
+
+export const Bots = () => {
+ const {
+ player: { id: userId },
+ } = useAuthContext();
+ const [bots, setBots] = useState(null);
+
+ const refreshBots = () =>
+ fetch("/api/player/bots")
+ .then((r) => r.json())
+ .then((bots) => setBots(bots));
+
+ useEffect(() => {
+ if (userId) {
+ refreshBots();
+ }
+ }, [userId]);
+
+ if (bots === null) return <p>Loading...</p>;
+
+ return (
+ <>
+ <h1>Bots</h1>
+ <BotButton onSave={refreshBots} />
+
+ <div className="key-card-collection">
+ {bots.length ? (
+ bots.map((bot) => (
+ <BotCard key={bot.id} onSave={refreshBots} botStruct={bot} />
+ ))
+ ) : (
+ <p>Looks like you've got no bots, try adding one!</p>
+ )}
+ </div>
+ </>
+ );
+};