The weeb for the next gen discord boat - Wamellow wamellow.com
bot discord
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

add delete notification style button

Luna f0e1babf b10fe7a9

+73 -4
+73 -4
app/dashboard/[guildId]/notifications/style.component.tsx
··· 1 1 "use client"; 2 2 import Link from "next/link"; 3 - import { useMemo, useRef, useState } from "react"; 3 + import { useCallback, useMemo, useRef, useState } from "react"; 4 4 import { HiOutlineUpload, HiPencil, HiSparkles, HiX } from "react-icons/hi"; 5 5 6 6 import { guildStore } from "@/common/guilds"; ··· 10 10 import { Section } from "@/components/section"; 11 11 import { UserAvatar } from "@/components/ui/avatar"; 12 12 import { Button } from "@/components/ui/button"; 13 - import type { ApiV1GuildsModulesNotificationsGetResponse, ApiV1GuildsModulesNotificationStylePatchResponse } from "@/typings"; 13 + import type { ApiError, ApiV1GuildsModulesNotificationsGetResponse, ApiV1GuildsModulesNotificationStylePatchResponse } from "@/typings"; 14 + import { State } from "@/utils/captcha"; 14 15 import { cn } from "@/utils/cn"; 15 16 16 17 const ALLOWED_FILE_TYPES = ["image/png", "image/jpeg", "image/webp"]; ··· 23 24 }: { 24 25 item: ApiV1GuildsModulesNotificationsGetResponse; 25 26 premium: boolean; 26 - onEdit: (opts: ApiV1GuildsModulesNotificationStylePatchResponse) => void; 27 + onEdit: (opts: { username: string | null; avatar: string | null; }) => void; 27 28 }) { 29 + const guildId = guildStore((g) => g!.id); 30 + 28 31 const [open, setOpen] = useState(false); 29 32 30 33 return (<> ··· 58 61 </Link> 59 62 </Button> 60 63 } 64 + {premium && (item.username || item.avatar) && ( 65 + <DeleteStyleButton 66 + id={item.id} 67 + guildId={guildId} 68 + onDelete={() => onEdit({ username: null, avatar: null })} 69 + /> 70 + )} 61 71 </div> 62 72 </div> 63 73 ··· 67 77 68 78 <ChangeStyleModal 69 79 id={item.id} 80 + guildId={guildId} 81 + 70 82 username={item.username || null} 71 83 avatarUrl={item.avatar ? `https://r2.wamellow.com/avatars/webhooks/${item.avatar}` : null} 72 84 ··· 113 125 114 126 interface Props { 115 127 id: string; 128 + guildId: string; 129 + 116 130 username: string | null; 117 131 avatarUrl: string | null; 118 132 ··· 123 137 124 138 export function ChangeStyleModal({ 125 139 id, 140 + guildId, 141 + 126 142 username, 127 143 avatarUrl, 128 144 ··· 130 146 onClose, 131 147 onEdit 132 148 }: Props) { 133 - const guildId = guildStore((g) => g?.id); 134 149 const avatarRef = useRef<HTMLInputElement | null>(null); 135 150 136 151 const [name, setName] = useState(username); ··· 241 256 </Section> 242 257 243 258 </Modal> 259 + </>); 260 + } 261 + 262 + function DeleteStyleButton({ 263 + id, 264 + guildId, 265 + onDelete 266 + }: { 267 + id: string; 268 + guildId: string; 269 + onDelete: () => void; 270 + }) { 271 + const [state, setState] = useState<State>(State.Idle); 272 + const [error, setError] = useState<string | null>(null); 273 + 274 + const del = useCallback( 275 + async () => { 276 + setState(State.Loading); 277 + 278 + const response = await fetch(`${process.env.NEXT_PUBLIC_API}/guilds/${guildId}/modules/notifications/${id}/style`, { 279 + method: "DELETE", 280 + credentials: "include" 281 + }); 282 + 283 + if (response.ok) { 284 + onDelete(); 285 + setState(State.Success); 286 + return; 287 + } 288 + 289 + setState(State.Idle); 290 + 291 + const res = await response.json() as ApiError | null; 292 + if (res && "message" in res) { 293 + setError(res.message); 294 + return; 295 + } 296 + 297 + setError("An unknown error occurred"); 298 + }, 299 + [guildId, id, onDelete] 300 + ); 301 + 302 + return (<> 303 + <Button 304 + className="text-red-400" 305 + variant="link" 306 + onClick={del} 307 + icon={<HiX />} 308 + loading={state === State.Loading} 309 + > 310 + Delete 311 + </Button> 312 + {error && <p className="text-red-400">{error}</p>} 244 313 </>); 245 314 }