Start work on todo list support for dashboard
This commit is contained in:
parent
b951db3f55
commit
9989ab3b35
@ -49,6 +49,12 @@ export type Reminder = {
|
|||||||
utc_time: string;
|
utc_time: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type Todo = {
|
||||||
|
id: string;
|
||||||
|
channel_id: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type ChannelInfo = {
|
export type ChannelInfo = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
@ -190,6 +196,33 @@ export const deleteGuildTemplate = (guild: string) => ({
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const fetchGuildTodos = (guild: string) => ({
|
||||||
|
queryKey: ["GUILD_TODOS", guild],
|
||||||
|
queryFn: () =>
|
||||||
|
axios.get(`/dashboard/api/guild/${guild}/todos`).then((resp) => resp.data) as Promise<
|
||||||
|
Todo[]
|
||||||
|
>,
|
||||||
|
staleTime: OTHER_STALE_TIME,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const patchGuildTodo = (guild: string) => ({
|
||||||
|
mutationFn: (todo: Todo) => axios.patch(`/dashboard/api/guild/${guild}/todos`, todo),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const postGuildTodo = (guild: string) => ({
|
||||||
|
mutationFn: (reminder: Reminder) =>
|
||||||
|
axios.post(`/dashboard/api/guild/${guild}/todos`, reminder).then((resp) => resp.data),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const deleteGuildTodo = () => ({
|
||||||
|
mutationFn: (todo: Todo) =>
|
||||||
|
axios.delete(`/dashboard/api/todos`, {
|
||||||
|
data: {
|
||||||
|
id: todo.id,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
export const fetchUserReminders = () => ({
|
export const fetchUserReminders = () => ({
|
||||||
queryKey: ["USER_REMINDERS"],
|
queryKey: ["USER_REMINDERS"],
|
||||||
queryFn: () =>
|
queryFn: () =>
|
||||||
|
@ -6,6 +6,8 @@ import { Guild } from "../Guild";
|
|||||||
import { FlashProvider } from "./FlashProvider";
|
import { FlashProvider } from "./FlashProvider";
|
||||||
import { TimezoneProvider } from "./TimezoneProvider";
|
import { TimezoneProvider } from "./TimezoneProvider";
|
||||||
import { User } from "../User";
|
import { User } from "../User";
|
||||||
|
import { GuildReminders } from "../Guild/GuildReminders";
|
||||||
|
import { GuildTodos } from "../Guild/GuildTodos";
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
@ -20,7 +22,22 @@ export function App() {
|
|||||||
<div class="column is-main-content">
|
<div class="column is-main-content">
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path={"/@me/reminders"} component={User}></Route>
|
<Route path={"/@me/reminders"} component={User}></Route>
|
||||||
<Route path={"/:guild/reminders"} component={Guild}></Route>
|
<Route
|
||||||
|
path={"/:guild/reminders"}
|
||||||
|
component={() => (
|
||||||
|
<Guild>
|
||||||
|
<GuildReminders />
|
||||||
|
</Guild>
|
||||||
|
)}
|
||||||
|
></Route>
|
||||||
|
<Route
|
||||||
|
path={"/:guild/todos"}
|
||||||
|
component={
|
||||||
|
<Guild>
|
||||||
|
<GuildTodos />
|
||||||
|
</Guild>
|
||||||
|
}
|
||||||
|
></Route>
|
||||||
<Route>
|
<Route>
|
||||||
<Welcome />
|
<Welcome />
|
||||||
</Route>
|
</Route>
|
||||||
|
21
reminder-dashboard/src/components/Guild/GuildTodos.tsx
Normal file
21
reminder-dashboard/src/components/Guild/GuildTodos.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { useQuery, useQueryClient } from "react-query";
|
||||||
|
import { fetchGuildChannels, fetchGuildTodos } from "../../api";
|
||||||
|
import { useState } from "preact/hooks";
|
||||||
|
import { useGuild } from "../App/useGuild";
|
||||||
|
|
||||||
|
export const GuildTodos = () => {
|
||||||
|
const guild = useGuild();
|
||||||
|
|
||||||
|
const {
|
||||||
|
isSuccess,
|
||||||
|
isFetching,
|
||||||
|
isFetched,
|
||||||
|
data: guildReminders,
|
||||||
|
} = useQuery(fetchGuildTodos(guild));
|
||||||
|
const { data: channels } = useQuery(fetchGuildChannels(guild));
|
||||||
|
|
||||||
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
};
|
@ -1,12 +1,11 @@
|
|||||||
import { useQuery } from "react-query";
|
import { useQuery } from "react-query";
|
||||||
import { fetchGuildInfo } from "../../api";
|
import { fetchGuildInfo } from "../../api";
|
||||||
import { GuildReminders } from "./GuildReminders";
|
|
||||||
import { GuildError } from "./GuildError";
|
import { GuildError } from "./GuildError";
|
||||||
import { createPortal } from "preact/compat";
|
import { createPortal, PropsWithChildren } from "preact/compat";
|
||||||
import { Import } from "../Import";
|
import { Import } from "../Import";
|
||||||
import { useGuild } from "../App/useGuild";
|
import { useGuild } from "../App/useGuild";
|
||||||
|
|
||||||
export const Guild = () => {
|
export const Guild = ({ children }: PropsWithChildren) => {
|
||||||
const guild = useGuild();
|
const guild = useGuild();
|
||||||
const { isSuccess, data: guildInfo } = useQuery(fetchGuildInfo(guild));
|
const { isSuccess, data: guildInfo } = useQuery(fetchGuildInfo(guild));
|
||||||
|
|
||||||
@ -20,7 +19,7 @@ export const Guild = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{importModal}
|
{importModal}
|
||||||
<GuildReminders />
|
{children}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
23
reminder-dashboard/src/components/Todo/index.tsx
Normal file
23
reminder-dashboard/src/components/Todo/index.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { Todo as TodoT } from "../../api";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
todo: TodoT;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Todo = ({ todo }: Props) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<textarea value={todo.value} onInput={() => null} />
|
||||||
|
<button onClick={() => null} class="btn save-btn">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa fa-save"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button onClick={() => null} class="btn delete-btn">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -145,6 +145,10 @@ pub async fn initialize(
|
|||||||
routes::dashboard::api::guild::create_guild_reminder,
|
routes::dashboard::api::guild::create_guild_reminder,
|
||||||
routes::dashboard::api::guild::get_reminders,
|
routes::dashboard::api::guild::get_reminders,
|
||||||
routes::dashboard::api::guild::edit_reminder,
|
routes::dashboard::api::guild::edit_reminder,
|
||||||
|
routes::dashboard::api::guild::create_todo,
|
||||||
|
routes::dashboard::api::guild::get_todo,
|
||||||
|
routes::dashboard::api::guild::update_todo,
|
||||||
|
routes::dashboard::api::guild::delete_todo,
|
||||||
routes::dashboard::export::export_reminders,
|
routes::dashboard::export::export_reminders,
|
||||||
routes::dashboard::export::export_reminder_templates,
|
routes::dashboard::export::export_reminder_templates,
|
||||||
routes::dashboard::export::export_todos,
|
routes::dashboard::export::export_todos,
|
||||||
|
@ -3,6 +3,7 @@ mod emojis;
|
|||||||
mod reminders;
|
mod reminders;
|
||||||
mod roles;
|
mod roles;
|
||||||
mod templates;
|
mod templates;
|
||||||
|
mod todos;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
@ -16,6 +17,7 @@ use serenity::{
|
|||||||
model::id::{GuildId, RoleId},
|
model::id::{GuildId, RoleId},
|
||||||
};
|
};
|
||||||
pub use templates::*;
|
pub use templates::*;
|
||||||
|
pub use todos::{create_todo, delete_todo, get_todo, update_todo};
|
||||||
|
|
||||||
use crate::web::{check_authorization, routes::JsonResult};
|
use crate::web::{check_authorization, routes::JsonResult};
|
||||||
|
|
||||||
|
66
src/web/routes/dashboard/api/guild/todos.rs
Normal file
66
src/web/routes/dashboard/api/guild/todos.rs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
use rocket::{
|
||||||
|
delete, get,
|
||||||
|
http::CookieJar,
|
||||||
|
patch, post,
|
||||||
|
serde::json::{json, Json},
|
||||||
|
State,
|
||||||
|
};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use serenity::prelude::Context;
|
||||||
|
|
||||||
|
use crate::web::{check_authorization, guards::transaction::Transaction, routes::JsonResult};
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct CreateTodo {
|
||||||
|
channel_id: Option<u64>,
|
||||||
|
value: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/api/guild/<id>/todos", data = "<todo>")]
|
||||||
|
pub async fn create_todo(
|
||||||
|
id: u64,
|
||||||
|
todo: Json<CreateTodo>,
|
||||||
|
cookies: &CookieJar<'_>,
|
||||||
|
ctx: &State<Context>,
|
||||||
|
mut transaction: Transaction<'_>,
|
||||||
|
) -> JsonResult {
|
||||||
|
check_authorization(cookies, ctx.inner(), id).await?;
|
||||||
|
|
||||||
|
Ok(json!({}))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/api/guild/<id>/todos")]
|
||||||
|
pub async fn get_todo(
|
||||||
|
id: u64,
|
||||||
|
cookies: &CookieJar<'_>,
|
||||||
|
ctx: &State<Context>,
|
||||||
|
mut transaction: Transaction<'_>,
|
||||||
|
) -> JsonResult {
|
||||||
|
check_authorization(cookies, ctx.inner(), id).await?;
|
||||||
|
|
||||||
|
Ok(json!([]))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[patch("/api/guild/<id>/todos")]
|
||||||
|
pub async fn update_todo(
|
||||||
|
id: u64,
|
||||||
|
cookies: &CookieJar<'_>,
|
||||||
|
ctx: &State<Context>,
|
||||||
|
mut transaction: Transaction<'_>,
|
||||||
|
) -> JsonResult {
|
||||||
|
check_authorization(cookies, ctx.inner(), id).await?;
|
||||||
|
|
||||||
|
Ok(json!({}))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[delete("/api/guild/<id>/todos")]
|
||||||
|
pub async fn delete_todo(
|
||||||
|
id: u64,
|
||||||
|
cookies: &CookieJar<'_>,
|
||||||
|
ctx: &State<Context>,
|
||||||
|
mut transaction: Transaction<'_>,
|
||||||
|
) -> JsonResult {
|
||||||
|
check_authorization(cookies, ctx.inner(), id).await?;
|
||||||
|
|
||||||
|
Ok(json!({}))
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user