This commit is contained in:
jude 2023-12-14 17:14:09 +00:00
parent 4dc821bf73
commit 8b508b39c0
4 changed files with 90 additions and 11 deletions

View File

@ -26,7 +26,7 @@ export const GuildReminders = () => {
<div style={{ margin: "0 12px 12px 12px" }}> <div style={{ margin: "0 12px 12px 12px" }}>
<strong>Create Reminder</strong> <strong>Create Reminder</strong>
<div id={"reminderCreator"}> <div id={"reminderCreator"}>
<CreateReminder></CreateReminder> <CreateReminder />
</div> </div>
<br></br> <br></br>
<div class={"field"}> <div class={"field"}>

View File

@ -3,6 +3,8 @@ import { fetchGuildInfo } from "../../api";
import { useParams } from "wouter"; import { useParams } from "wouter";
import { GuildReminders } from "./GuildReminders"; import { GuildReminders } from "./GuildReminders";
import { GuildError } from "./GuildError"; import { GuildError } from "./GuildError";
import { createPortal } from "preact/compat";
import { Import } from "../Import";
export const Guild = () => { export const Guild = () => {
const { guild } = useParams(); const { guild } = useParams();
@ -13,6 +15,13 @@ export const Guild = () => {
} else if (guildInfo.error) { } else if (guildInfo.error) {
return <GuildError />; return <GuildError />;
} else { } else {
return <GuildReminders />; const importModal = createPortal(<Import />, document.getElementById("bottom-sidebar"));
return (
<>
{importModal}
<GuildReminders />
</>
);
} }
}; };

View File

@ -1,5 +1,8 @@
import { Modal } from "../Modal"; import { Modal } from "../Modal";
import { useState } from "preact/hooks"; import { useRef, useState } from "preact/hooks";
import { useParams } from "wouter";
import axios from "axios";
import { useFlash } from "../App/FlashContext";
export const Import = () => { export const Import = () => {
const [modalOpen, setModalOpen] = useState(false); const [modalOpen, setModalOpen] = useState(false);
@ -24,6 +27,14 @@ export const Import = () => {
}; };
const ImportModal = ({ setModalOpen }) => { const ImportModal = ({ setModalOpen }) => {
const { guild } = useParams();
const aRef = useRef<HTMLAnchorElement>();
const inputRef = useRef<HTMLInputElement>();
const flash = useFlash();
const [isImporting, setIsImporting] = useState(false);
return ( return (
<Modal <Modal
setModalOpen={setModalOpen} setModalOpen={setModalOpen}
@ -58,15 +69,75 @@ const ImportModal = ({ setModalOpen }) => {
<div style="color: red"> <div style="color: red">
Please first read the <a href="/help/iemanager">support page</a> Please first read the <a href="/help/iemanager">support page</a>
</div> </div>
<button class="button is-success is-outlined" id="import-data"> <button
class="button is-success is-outlined"
style={{ margin: "2px" }}
id="import-data"
disabled={isImporting}
onClick={() => {
inputRef.current.click();
}}
>
Import Data Import Data
</button> </button>
<button class="button is-success" id="export-data"> <button
class="button is-success"
style={{ margin: "2px" }}
id="export-data"
onClick={() =>
axios
.get(`/dashboard/api/guild/${guild}/export/reminders`)
.then(({ data, status }) => {
if (status === 200) {
aRef.current.href = `data:text/plain;charset=utf-8,${encodeURIComponent(
data.body,
)}`;
aRef.current.click();
} else {
flash({
message: `Unexpected status ${status}`,
type: "error",
});
}
})
}
>
Export Data Export Data
</button> </button>
</div> </div>
<a id="downloader" download="export.csv" class="is-hidden"></a> <a ref={aRef} id="downloader" download="export.csv" class="is-hidden" />
<input id="uploader" type="file" hidden></input> <input
ref={inputRef}
id="uploader"
type="file"
hidden
onChange={() => {
new Promise((resolve) => {
let fileReader = new FileReader();
fileReader.onload = (e) => resolve(fileReader.result);
fileReader.readAsDataURL(inputRef.current.files[0]);
}).then((dataUrl: string) => {
setIsImporting(true);
axios
.put(`/dashboard/api/guild/${guild}/export/reminders`, {
body: JSON.stringify({ body: dataUrl.split(",")[1] }),
})
.then(({ data }) => {
setIsImporting(false);
if (data.error) {
flash({ message: data.error, type: "error" });
} else {
flash({ message: data.message, type: "success" });
}
})
.then(() => {
delete inputRef.current.files[0];
});
});
}}
/>
</> </>
</Modal> </Modal>
); );

View File

@ -6,7 +6,6 @@ import { Wave } from "./Wave";
import { GuildEntry } from "./GuildEntry"; import { GuildEntry } from "./GuildEntry";
import { fetchUserGuilds, GuildInfo } from "../../api"; import { fetchUserGuilds, GuildInfo } from "../../api";
import { TimezonePicker } from "../TimezonePicker"; import { TimezonePicker } from "../TimezonePicker";
import { Import } from "../Import";
type ContentProps = { type ContentProps = {
guilds: GuildInfo[]; guilds: GuildInfo[];
@ -18,9 +17,9 @@ const SidebarContent = ({ guilds }: ContentProps) => {
return ( return (
<> <>
<a href="/"> <a href="/">
<Brand></Brand> <Brand />
</a> </a>
<Wave></Wave> <Wave />
<aside class="menu"> <aside class="menu">
<p class="menu-label">Servers</p> <p class="menu-label">Servers</p>
<ul class="menu-list guildList">{guildEntries}</ul> <ul class="menu-list guildList">{guildEntries}</ul>
@ -28,7 +27,7 @@ const SidebarContent = ({ guilds }: ContentProps) => {
<p class="menu-label">Options</p> <p class="menu-label">Options</p>
<ul class="menu-list"> <ul class="menu-list">
<li> <li>
<Import /> <div id="bottom-sidebar"></div>
<TimezonePicker /> <TimezonePicker />
<a href="/login/discord/logout"> <a href="/login/discord/logout">
<span class="icon"> <span class="icon">