From 9506da25c8b2baac37fd21245a7ad5dfa7251d22 Mon Sep 17 00:00:00 2001 From: Puyodead1 Date: Mon, 18 Dec 2023 11:01:46 -0500 Subject: [PATCH] implement kick/ban logic --- src/components/Button.tsx | 49 +++++++++++++++- .../contextMenus/UserContextMenu.tsx | 28 ++++++---- src/components/messaging/MessageAuthor.tsx | 16 ++++-- src/components/modals/BanMemberModal.tsx | 56 ++++++++++++++++--- src/components/modals/KickMemberModal.tsx | 46 +++++++++++++-- src/components/modals/ModalComponents.tsx | 16 ++---- src/stores/GuildMemberStore.ts | 17 +++++- src/utils/interfaces/api.ts | 28 ++++++++++ 8 files changed, 212 insertions(+), 44 deletions(-) diff --git a/src/components/Button.tsx b/src/components/Button.tsx index a944333..c0d6f6d 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -5,14 +5,15 @@ import styled, { css } from "styled-components"; export interface Props { readonly compact?: boolean | "icon"; palette?: "primary" | "secondary" | "success" | "warning" | "danger" | "accent" | "link"; + size?: "small" | "medium" | "large"; readonly disabled?: boolean; } export default styled.button` color: var(--text); - padding: 8px 16px; + padding: 2px 16px; border-radius: 8px; - font-size: 12px; + font-size: 14px; font-weight: var(--font-weight-medium); outline: none; border: none; @@ -20,6 +21,50 @@ export default styled.button` cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; opacity: ${(props) => (props.disabled ? 0.5 : 1)} font-weight: var(--font-weight-bold); + height: ${(props) => { + switch (props.size) { + default: + case "small": + return "32px;"; + case "medium": + return "40px"; + case "large": + return "45px"; + } + }}; + min-height: ${(props) => { + switch (props.size) { + default: + case "small": + return "32px;"; + case "medium": + return "40px"; + case "large": + return "45px"; + } + }}; + width: ${(props) => { + switch (props.size) { + default: + case "small": + return "96px"; + case "medium": + return "96px"; + case "large": + return "130px"; + } + }}; + min-width: ${(props) => { + switch (props.size) { + default: + case "small": + return "96px"; + case "medium": + return "96px"; + case "large": + return "130px"; + } + }}; ${(props) => { if (!props.palette) props.palette = "primary"; diff --git a/src/components/contextMenus/UserContextMenu.tsx b/src/components/contextMenus/UserContextMenu.tsx index 76c4567..d908012 100644 --- a/src/components/contextMenus/UserContextMenu.tsx +++ b/src/components/contextMenus/UserContextMenu.tsx @@ -46,21 +46,25 @@ function UserContextMenu({ user, member }: MenuProps) { Mention Message - Change Nickname + {member && Change Nickname} Add Friend Block - - Kick {member?.nick ?? user.username} - - - Ban {member?.nick ?? user.username} - - - - Roles - - + {member && ( + <> + + Kick {member?.nick ?? user.username} + + + Ban {member?.nick ?? user.username} + + + + Roles + + + + )} (undefined); - const ref = React.useRef(null); + + const onContextMenu = async (e: React.MouseEvent) => { + e.preventDefault(); + const member = await app.guilds.get(message.guild_id!)?.members.fetch(message.author.id); + contextMenu.onContextMenu(e, { user: message.author, member }); + }; React.useEffect(() => { if ("guild_id" in message && message.guild_id) { - const guild = app.guilds.get(message.guild_id); + const guild = app.guilds.get(message.guild_id!); if (!guild) return; const member = guild.members.get(message.author.id); if (!member) return; @@ -46,10 +53,11 @@ function MessageAuthor({ message }: Props) { > {message.author.username} diff --git a/src/components/modals/BanMemberModal.tsx b/src/components/modals/BanMemberModal.tsx index aea2509..46ee2c9 100644 --- a/src/components/modals/BanMemberModal.tsx +++ b/src/components/modals/BanMemberModal.tsx @@ -1,8 +1,10 @@ import { yupResolver } from "@hookform/resolvers/yup"; +import { Routes } from "@spacebarchat/spacebar-api-types/v9"; import { useForm } from "react-hook-form"; import styled from "styled-components"; import * as yup from "yup"; import { ModalProps, modalController } from "../../controllers/modals"; +import { useAppStore } from "../../stores/AppStore"; import { Modal } from "./ModalComponents"; const DescriptionText = styled.p` @@ -12,25 +14,57 @@ const DescriptionText = styled.p` margin-top: 8px; `; +const TextArea = styled.textarea` + flex: 1; + padding: 8px; + border-radius: 4px; + background-color: var(--background-secondary-alt); + border: none; + color: var(--text); + font-size: 16px; + font-weight: var(--font-weight-regular); + resize: none; + outline: none; +`; + const schema = yup .object({ - reason: yup.string(), + reason: yup.string().max(512, "Reason must be less than 512 characters"), }) .required(); -export function BanMemberModal({ target, ...props }: ModalProps<"ban_member">) { +export function BanMemberModal({ target, type, ...props }: ModalProps<"ban_member">) { + const app = useAppStore(); const { register, - control, - setError, handleSubmit, - formState: { errors, disabled, isLoading, isSubmitting }, + formState: { disabled, isLoading, isSubmitting }, } = useForm({ resolver: yupResolver(schema), }); const isDisabled = disabled || isLoading || isSubmitting; + const onSubmit = handleSubmit((data) => { + app.rest + .put( + Routes.guildBan(target.guild.id, target.user!.id), + undefined, + undefined, + data.reason + ? { + "X-Audit-Log-Reason": data.reason, + } + : undefined, + ) + .then(() => { + modalController.pop("close"); + }) + .catch((e) => { + console.error(e); + }); + }); + return ( ) { } actions={[ { - onClick: () => console.log("kick"), - children: Kick, + onClick: onSubmit, + children: Ban, palette: "danger", confirmation: true, disabled: isDisabled, + size: "small", }, { onClick: () => modalController.pop("close"), children: Cancel, palette: "link", disabled: isDisabled, + size: "small", }, ]} > @@ -63,10 +99,12 @@ export function BanMemberModal({ target, ...props }: ModalProps<"ban_member">) { alt="Thanos Snap GIF" height={300} style={{ - objectFit: "contain", + marginBottom: 20, + borderRadius: 8, }} /> - reason form + +