Working on template loader
This commit is contained in:
parent
e36d2610da
commit
b83f1f2f31
67
src/api.ts
67
src/api.ts
@ -52,6 +52,26 @@ type ChannelInfo = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
type Template = {
|
||||
id: number;
|
||||
name: string;
|
||||
attachment: string | null;
|
||||
attachment_name: string | null;
|
||||
avatar: string | null;
|
||||
channel: string;
|
||||
content: string;
|
||||
embed_author: string;
|
||||
embed_author_url: string | null;
|
||||
embed_color: number;
|
||||
embed_description: string;
|
||||
embed_footer: string;
|
||||
embed_footer_url: string | null;
|
||||
embed_image_url: string | null;
|
||||
embed_thumbnail_url: string | null;
|
||||
embed_title: string;
|
||||
embed_fields: EmbedField[] | null;
|
||||
};
|
||||
|
||||
export function fetchUserInfo(): Promise<UserInfo> {
|
||||
return axios.get("/dashboard/api/user").then((resp) => resp.data) as Promise<UserInfo>;
|
||||
}
|
||||
@ -62,21 +82,34 @@ export function fetchUserGuilds(): Promise<GuildInfo[]> {
|
||||
>;
|
||||
}
|
||||
|
||||
export function fetchGuildReminders(guild: string): Promise<Reminder[]> {
|
||||
return axios
|
||||
.get(`/dashboard/api/guild/${guild}/reminders`)
|
||||
.then((resp) => resp.data)
|
||||
.then((value) =>
|
||||
value.map((reminder) => ({
|
||||
...reminder,
|
||||
utc_time: DateTime.fromISO(reminder.utc_time),
|
||||
expires: reminder.expires === null ? null : DateTime.fromISO(reminder.expires),
|
||||
})),
|
||||
) as Promise<Reminder[]>;
|
||||
}
|
||||
export const fetchGuildReminders = (guild: string) => ({
|
||||
queryKey: ["GUILD_REMINDERS", guild],
|
||||
queryFn: () =>
|
||||
axios
|
||||
.get(`/dashboard/api/guild/${guild}/reminders`)
|
||||
.then((resp) => resp.data)
|
||||
.then((value) =>
|
||||
value.map((reminder) => ({
|
||||
...reminder,
|
||||
utc_time: DateTime.fromISO(reminder.utc_time),
|
||||
expires: reminder.expires === null ? null : DateTime.fromISO(reminder.expires),
|
||||
})),
|
||||
) as Promise<Reminder[]>,
|
||||
});
|
||||
|
||||
export function fetchGuildChannels(guild: string): Promise<ChannelInfo[]> {
|
||||
return axios.get(`/dashboard/api/guild/${guild}/channels`).then((resp) => resp.data) as Promise<
|
||||
ChannelInfo[]
|
||||
>;
|
||||
}
|
||||
export const fetchGuildChannels = (guild: string) => ({
|
||||
queryKey: ["GUILD_CHANNELS", guild],
|
||||
queryFn: () =>
|
||||
axios.get(`/dashboard/api/guild/${guild}/channels`).then((resp) => resp.data) as Promise<
|
||||
ChannelInfo[]
|
||||
>,
|
||||
staleTime: 300,
|
||||
});
|
||||
|
||||
export const guildTemplatesQuery = (guild: string) => ({
|
||||
queryKey: ["GUILD_TEMPLATES", guild],
|
||||
queryFn: () =>
|
||||
axios.get(`/dashboard/api/guild/${guild}/channels`).then((resp) => resp.data) as Promise<
|
||||
Template[]
|
||||
>,
|
||||
});
|
||||
|
@ -8,10 +8,7 @@ import { CreateReminder } from "../Reminder/CreateReminder";
|
||||
export const GuildReminders = () => {
|
||||
const { guild } = useParams();
|
||||
|
||||
const { isSuccess, data } = useQuery({
|
||||
queryKey: [QueryKeys.GUILD_REMINDERS, guild],
|
||||
queryFn: () => fetchGuildReminders(guild),
|
||||
});
|
||||
const { isSuccess, data } = useQuery(fetchGuildReminders(guild));
|
||||
|
||||
return (
|
||||
<div style={{ margin: "0 12px 12px 12px" }}>
|
||||
|
57
src/components/Modal/index.tsx
Normal file
57
src/components/Modal/index.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import { JSX } from "preact";
|
||||
|
||||
type Props = {
|
||||
setModalOpen: (open: boolean) => never;
|
||||
title: string;
|
||||
onSubmitText?: string;
|
||||
onSubmit?: () => never;
|
||||
children: string | JSX.Element | JSX.Element[] | (() => JSX.Element);
|
||||
};
|
||||
|
||||
export const Modal = ({ setModalOpen, title, onSubmit, onSubmitText, children }: Props) => {
|
||||
return (
|
||||
<div class="modal is-active">
|
||||
<div
|
||||
class="modal-background"
|
||||
onClick={() => {
|
||||
setModalOpen(false);
|
||||
}}
|
||||
></div>
|
||||
<div class="modal-card">
|
||||
<header class="modal-card-head">
|
||||
<label class="modal-card-title">{title}</label>
|
||||
<button
|
||||
class="delete close-modal"
|
||||
aria-label="close"
|
||||
onClick={() => {
|
||||
setModalOpen(false);
|
||||
}}
|
||||
></button>
|
||||
</header>
|
||||
<section class="modal-card-body">{children}</section>
|
||||
{onSubmit && (
|
||||
<footer class="modal-card-foot">
|
||||
<button class="button is-success" onChange={onSubmit}>
|
||||
{onSubmitText || "Save"}
|
||||
</button>
|
||||
<button
|
||||
class="button close-modal"
|
||||
onClick={() => {
|
||||
setModalOpen(false);
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</footer>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
class="modal-close is-large close-modal"
|
||||
aria-label="close"
|
||||
onClick={() => {
|
||||
setModalOpen(false);
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -6,11 +6,7 @@ import { fetchGuildChannels } from "../../api";
|
||||
export const ChannelSelector = ({ channel }) => {
|
||||
const { guild } = useParams();
|
||||
|
||||
const { isSuccess, data } = useQuery({
|
||||
queryKey: [QueryKeys.GUILD_CHANNELS, guild],
|
||||
queryFn: () => fetchGuildChannels(guild),
|
||||
staleTime: 300,
|
||||
});
|
||||
const { isSuccess, data } = useQuery(fetchGuildChannels(guild));
|
||||
|
||||
return (
|
||||
<div class="control has-icons-left">
|
||||
|
@ -2,29 +2,56 @@ import { useParams } from "wouter";
|
||||
import { useState } from "preact/hooks";
|
||||
import { useQueries } from "react-query";
|
||||
import { QueryKeys } from "../../consts";
|
||||
import { fetchGuildChannels, fetchUserInfo } from "../../api";
|
||||
import { fetchGuildChannels, fetchUserInfo, Reminder } from "../../api";
|
||||
import { Name } from "./Name";
|
||||
import { Username } from "./Username";
|
||||
import React from "react";
|
||||
import { Content } from "./Content";
|
||||
import { Embed } from "./Embed";
|
||||
import { ChannelSelector } from "./ChannelSelector";
|
||||
import { DateTime } from "luxon";
|
||||
import { IntervalSelector } from "./IntervalSelector";
|
||||
import { LoadTemplate } from "./LoadTemplate";
|
||||
|
||||
function defaultReminder(): Reminder {
|
||||
return {
|
||||
attachment: "",
|
||||
attachment_name: "",
|
||||
avatar: "",
|
||||
channel: "",
|
||||
content: "",
|
||||
embed_author: "",
|
||||
embed_author_url: "",
|
||||
embed_color: 0,
|
||||
embed_description: "",
|
||||
embed_fields: [],
|
||||
embed_footer: "",
|
||||
embed_footer_url: "",
|
||||
embed_image_url: "",
|
||||
embed_thumbnail_url: "",
|
||||
embed_title: "",
|
||||
enabled: true,
|
||||
expires: null,
|
||||
interval_days: null,
|
||||
interval_months: null,
|
||||
interval_seconds: null,
|
||||
name: "",
|
||||
restartable: false,
|
||||
tts: false,
|
||||
uid: "",
|
||||
username: "",
|
||||
utc_time: DateTime.now(),
|
||||
};
|
||||
}
|
||||
|
||||
export const CreateReminder = () => {
|
||||
const { guild } = useParams();
|
||||
const [reminder, setReminder] = useState({});
|
||||
const [reminder, setReminder] = useState(defaultReminder);
|
||||
|
||||
const [
|
||||
{ isSuccess: channelsFetched, data: guildChannels },
|
||||
{ isSuccess: userFetched, data: userInfo },
|
||||
] = useQueries([
|
||||
{
|
||||
queryKey: [QueryKeys.GUILD_CHANNELS, guild],
|
||||
queryFn: () => fetchGuildChannels(guild),
|
||||
staleTime: 300,
|
||||
},
|
||||
fetchGuildChannels(guild),
|
||||
{
|
||||
queryKey: [QueryKeys.USER_DATA],
|
||||
queryFn: fetchUserInfo,
|
||||
@ -101,7 +128,7 @@ export const CreateReminder = () => {
|
||||
Channel*
|
||||
</label>
|
||||
</div>
|
||||
<ChannelSelector channel={null}></ChannelSelector>
|
||||
<ChannelSelector channel={reminder.channel}></ChannelSelector>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
@ -220,9 +247,7 @@ export const CreateReminder = () => {
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="button is-outlined show-modal is-pulled-right">
|
||||
Load Template
|
||||
</button>
|
||||
<LoadTemplate setReminder={setReminder}></LoadTemplate>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -23,11 +23,7 @@ export const EditReminder = ({ reminder: initialReminder }: Props) => {
|
||||
{ isSuccess: channelsFetched, data: guildChannels },
|
||||
{ isSuccess: userFetched, data: userInfo },
|
||||
] = useQueries([
|
||||
{
|
||||
queryKey: [QueryKeys.GUILD_CHANNELS, guild],
|
||||
queryFn: () => fetchGuildChannels(guild),
|
||||
staleTime: 300,
|
||||
},
|
||||
fetchGuildChannels(guild),
|
||||
{
|
||||
queryKey: [QueryKeys.USER_DATA],
|
||||
queryFn: fetchUserInfo,
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { useState } from "preact/hooks";
|
||||
import { HexColorPicker } from "react-colorful";
|
||||
import { Modal } from "../../Modal";
|
||||
|
||||
export const Color = ({ color: colorProp, onChange }) => {
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
@ -31,61 +32,19 @@ const ColorModal = ({ setModalOpen, color: colorProp, onSave }) => {
|
||||
const [color, setColor] = useState(colorProp);
|
||||
|
||||
return (
|
||||
<div class="modal is-active" id="pickColorModal">
|
||||
<div
|
||||
class="modal-background"
|
||||
onClick={() => {
|
||||
setModalOpen(false);
|
||||
}}
|
||||
></div>
|
||||
<div class="modal-card">
|
||||
<header class="modal-card-head">
|
||||
<label class="modal-card-title" for="colorInput">
|
||||
Select Color
|
||||
</label>
|
||||
<button
|
||||
class="delete close-modal"
|
||||
aria-label="close"
|
||||
onClick={() => {
|
||||
setModalOpen(false);
|
||||
}}
|
||||
></button>
|
||||
</header>
|
||||
<section class="modal-card-body">
|
||||
<div class="colorpicker-container">
|
||||
<HexColorPicker color={color} onChange={setColor}></HexColorPicker>
|
||||
</div>
|
||||
<br></br>
|
||||
<input
|
||||
class="input"
|
||||
id="colorInput"
|
||||
value={color}
|
||||
onChange={(ev) => {
|
||||
setColor(ev.currentTarget.value);
|
||||
}}
|
||||
></input>
|
||||
</section>
|
||||
<footer class="modal-card-foot">
|
||||
<button class="button is-success" onChange={onSave}>
|
||||
Save
|
||||
</button>
|
||||
<button
|
||||
class="button close-modal"
|
||||
onClick={() => {
|
||||
setModalOpen(false);
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</footer>
|
||||
<Modal setModalOpen={setModalOpen} title={"Select Color"} onSubmit={onSave}>
|
||||
<div class="colorpicker-container">
|
||||
<HexColorPicker color={color} onChange={setColor}></HexColorPicker>
|
||||
</div>
|
||||
<button
|
||||
class="modal-close is-large close-modal"
|
||||
aria-label="close"
|
||||
onClick={() => {
|
||||
setModalOpen(false);
|
||||
<br></br>
|
||||
<input
|
||||
class="input"
|
||||
id="colorInput"
|
||||
value={color}
|
||||
onChange={(ev) => {
|
||||
setColor(ev.currentTarget.value);
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
></input>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
54
src/components/Reminder/LoadTemplate.tsx
Normal file
54
src/components/Reminder/LoadTemplate.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
import { useState } from "preact/hooks";
|
||||
import { Modal } from "../Modal";
|
||||
import { useQuery } from "react-query";
|
||||
import { guildTemplatesQuery } from "../../api";
|
||||
import { useParams } from "wouter";
|
||||
|
||||
export const LoadTemplate = ({ setReminder }) => {
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
class="button is-outlined show-modal is-pulled-right"
|
||||
onClick={() => {
|
||||
setModalOpen(true);
|
||||
}}
|
||||
>
|
||||
Load Template
|
||||
</button>
|
||||
{modalOpen && <LoadTemplateModal setModalOpen={setModalOpen}></LoadTemplateModal>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const LoadTemplateModal = ({ setModalOpen }) => {
|
||||
const { guild } = useParams();
|
||||
const { status, data: templates } = useQuery(guildTemplatesQuery(guild));
|
||||
|
||||
return (
|
||||
<Modal setModalOpen={setModalOpen} title={"Load Template"}>
|
||||
<div class="control has-icons-left">
|
||||
<div class="select is-fullwidth">
|
||||
<select id="templateSelect">
|
||||
{templates.map((template) => (
|
||||
<option value={template.id}>{template.name}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div class="icon is-small is-left">
|
||||
<i class="fas fa-file-spreadsheet"></i>
|
||||
</div>
|
||||
</div>
|
||||
<br></br>
|
||||
<div class="has-text-centered">
|
||||
<button class="button is-success close-modal" id="load-template">
|
||||
Load Template
|
||||
</button>
|
||||
<button class="button is-danger" id="delete-template">
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
};
|
@ -2,5 +2,4 @@ export enum QueryKeys {
|
||||
USER_DATA = "userData",
|
||||
USER_GUILDS = "userGuilds",
|
||||
GUILD_REMINDERS = "guildReminders",
|
||||
GUILD_CHANNELS = "guildChannels",
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user