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 passport config

Luna b7a738a9 a0eaa56f

+257
+231
app/dashboard/[guildId]/greeting/passport/page.tsx
··· 1 + 2 + "use client"; 3 + import { useParams } from "next/navigation"; 4 + import { useEffect, useState } from "react"; 5 + import { HiFingerPrint } from "react-icons/hi"; 6 + 7 + import { guildStore } from "@/common/guilds"; 8 + import { CopyToClipboardButton } from "@/components/copyToClipboard"; 9 + import ErrorBanner from "@/components/Error"; 10 + import GoBack from "@/components/GoBack"; 11 + import SelectInput from "@/components/inputs/SelectMenu"; 12 + import Switch from "@/components/inputs/Switch"; 13 + import Modal from "@/components/Modal"; 14 + import OverviewLinkComponent from "@/components/OverviewLinkComponent"; 15 + import { ApiV1GuildsModulesPassportGetResponse, RouteErrorResponse } from "@/typings"; 16 + import { getCanonicalUrl } from "@/utils/urls"; 17 + 18 + export default function Home() { 19 + const guild = guildStore((g) => g); 20 + 21 + const [error, setError] = useState<string>(); 22 + const [passport, setPassport] = useState<ApiV1GuildsModulesPassportGetResponse>(); 23 + const [modal, setModal] = useState(false); 24 + const [punishmentRoleId, setPunishmentRoleId] = useState<string>(); 25 + 26 + const params = useParams(); 27 + 28 + useEffect(() => { 29 + 30 + fetch(`${process.env.NEXT_PUBLIC_API}/guilds/${params.guildId}/modules/passport`, { 31 + headers: { 32 + authorization: localStorage.getItem("token") as string 33 + } 34 + }) 35 + .then(async (res) => { 36 + const response = await res.json() as ApiV1GuildsModulesPassportGetResponse; 37 + if (!response) return; 38 + 39 + switch (res.status) { 40 + case 200: { 41 + setPassport(response); 42 + break; 43 + } 44 + default: { 45 + setPassport(undefined); 46 + setError((response as unknown as RouteErrorResponse).message); 47 + break; 48 + } 49 + } 50 + 51 + }) 52 + .catch(() => { 53 + setError("Error while fetching passport data"); 54 + }); 55 + 56 + }, []); 57 + 58 + useEffect(() => { 59 + if (passport?.punishment === 2 && !passport.punishmentRoleId) setModal(true); 60 + }, [passport]); 61 + 62 + if (passport === undefined) return ( 63 + <div> 64 + <GoBack url={`/dashboard/${guild?.id}/greeting`} /> 65 + {error && <ErrorBanner message={error} />} 66 + </div> 67 + ); 68 + 69 + return ( 70 + <div> 71 + 72 + <GoBack url={`/dashboard/${guild?.id}/greeting`} /> 73 + 74 + {passport.enabled && passport.punishment === 2 && !passport.punishmentRoleId && !modal && 75 + <div className="mt-6"> 76 + <ErrorBanner type="info" message="When using 'Assign role to member', a punishment role must be set." removeButton /> 77 + </div> 78 + } 79 + 80 + <Switch 81 + name="Passport module enabled." 82 + url={`/guilds/${guild?.id}/modules/passport`} 83 + dataName="enabled" 84 + defaultState={passport?.enabled || false} 85 + disabled={false} 86 + onSave={(s) => { 87 + setPassport({ 88 + ...passport, 89 + enabled: s 90 + }); 91 + }} 92 + /> 93 + 94 + <Switch 95 + name="Send direct message to member on fail." 96 + url={`/guilds/${guild?.id}/modules/passport`} 97 + dataName="sendFailedDm" 98 + defaultState={passport?.sendFailedDm || false} 99 + disabled={!passport.enabled} 100 + /> 101 + 102 + <SelectInput 103 + name="Logging channel" 104 + url={`/guilds/${guild?.id}/modules/passport`} 105 + dataName="channelId" 106 + items={guild?.channels?.sort((a, b) => a.name.localeCompare(b.name)).map((c) => { return { name: `#${c.name}`, value: c.id, error: c.missingPermissions.join(", ") }; })} 107 + description="Select the channel where verifications should be send into." 108 + __defaultState={passport?.channelId} 109 + disabled={!passport.enabled} 110 + /> 111 + 112 + <div className="lg:flex gap-3"> 113 + <div className="lg:w-1/2"> 114 + <SelectInput 115 + name="Unverified role" 116 + url={`/guilds/${guild?.id}/modules/passport`} 117 + dataName="unverifiedRoleId" 118 + items={guild?.roles?.sort((a, b) => a.name.localeCompare(b.name)).map((c) => { return { name: `#${c.name}`, value: c.id, error: c.missingPermissions.join(", ") }; })} 119 + description="Select what role members should get when joining." 120 + __defaultState={passport?.unverifiedRoleId} 121 + disabled={!passport.enabled} 122 + /> 123 + </div> 124 + 125 + <div className="lg:w-1/2"> 126 + <SelectInput 127 + name="Verified role" 128 + url={`/guilds/${guild?.id}/modules/passport`} 129 + dataName="successRoleId" 130 + items={guild?.roles?.sort((a, b) => a.name.localeCompare(b.name)).map((c) => { return { name: `#${c.name}`, value: c.id, error: c.missingPermissions.join(", ") }; })} 131 + description="Select what role members should get when completing verification." 132 + __defaultState={passport?.successRoleId} 133 + disabled={!passport.enabled} 134 + /> 135 + </div> 136 + </div> 137 + 138 + <div className="lg:flex gap-3"> 139 + <div className="lg:w-1/2"> 140 + <SelectInput 141 + name="Failed verification action" 142 + url={`/guilds/${guild?.id}/modules/passport`} 143 + dataName="punishment" 144 + items={[ 145 + { name: "Ban member", value: 0 }, 146 + { name: "Kick member", value: 1 }, 147 + { name: "Assign role to member", value: 2 } 148 + ]} 149 + description="Choose what should happen if a member failes verification." 150 + __defaultState={passport?.punishment} 151 + disabled={!passport.enabled} 152 + onSave={(o) => { 153 + 154 + setPassport({ 155 + ...passport, 156 + punishment: o.value as ApiV1GuildsModulesPassportGetResponse["punishment"] 157 + }); console.log(o.value); 158 + 159 + }} 160 + /> 161 + </div> 162 + 163 + <Modal 164 + title="Punishment role" 165 + show={modal} 166 + onClose={() => setModal(false)} 167 + onSubmit={() => { 168 + return fetch(`${process.env.NEXT_PUBLIC_API}/guilds/${guild?.id}/modules/passport`, { 169 + method: "PATCH", 170 + headers: { 171 + "Content-Type": "application/json", 172 + authorization: localStorage.getItem("token") as string 173 + }, 174 + body: JSON.stringify({ 175 + punishmentRoleId: punishmentRoleId 176 + }) 177 + }); 178 + }} 179 + onSuccess={() => { 180 + setPassport({ 181 + ...passport, 182 + punishmentRoleId 183 + }); 184 + }} 185 + > 186 + <SelectInput 187 + name="Role" 188 + dataName="punishmentRoleId" 189 + items={guild?.roles?.sort((a, b) => b.position - a.position).map((r) => { return { name: `@${r.name}`, value: r.id, error: r.missingPermissions.join(", "), color: r.color }; })} 190 + description="Select what role members should get when failing verification." 191 + __defaultState={passport.punishmentRoleId} 192 + onSave={(o) => { 193 + setPunishmentRoleId(o.value as string); 194 + }} 195 + /> 196 + </Modal> 197 + 198 + <div className="lg:w-1/2"> 199 + <SelectInput 200 + name="Punishment role" 201 + url={`/guilds/${guild?.id}/modules/passport`} 202 + dataName="punishmentRoleId" 203 + items={guild?.roles?.sort((a, b) => a.name.localeCompare(b.name)).map((c) => { return { name: `#${c.name}`, value: c.id, error: c.missingPermissions.filter((mp) => mp !== "EmbedLinks").join(", ") }; })} 204 + description="Select what role members should get when failing verification." 205 + __defaultState={passport?.punishmentRoleId} 206 + disabled={!passport.enabled || passport.punishment !== 2} 207 + onSave={(o) => { 208 + setPassport({ 209 + ...passport, 210 + punishment: o.value as ApiV1GuildsModulesPassportGetResponse["punishment"] 211 + }); 212 + }} 213 + /> 214 + </div> 215 + </div> 216 + 217 + <OverviewLinkComponent 218 + className="mt-8" 219 + title="View Passport" 220 + message="Easily verify your members with a simple and secure CAPTCHA in the web." 221 + url={`/passport/${params.guildId}`} 222 + icon={<HiFingerPrint />} 223 + /> 224 + 225 + <div className="w-fit"> 226 + <CopyToClipboardButton title="Copy link to passport" text={getCanonicalUrl("passport", guild?.id as string)} /> 227 + </div> 228 + 229 + </div> 230 + ); 231 + }
+26
typings.ts
··· 185 185 voice: GuildLeaderboardApp; 186 186 } 187 187 188 + export interface ApiV1GuildsModulesPassportGetResponse { 189 + enabled: boolean; 190 + channelId?: string; 191 + /** 192 + * We're currently on free tier 193 + */ 194 + captchaType: "slide" | "word" | "icon" | "match" | "winlinze" | "nine" | "random"; 195 + /** 196 + * 0 - Ban 197 + * 1 - Kick 198 + * 2 - Assign role 199 + */ 200 + punishment: 0 | 1 | 2; 201 + punishmentRoleId?: string; 202 + 203 + successRoleId?: string; 204 + unverifiedRoleId?: string; 205 + 206 + sendFailedDm: boolean; 207 + alsoFailIf: ("disposableEmailAddress")[] 208 + 209 + backgroundColor?: number; 210 + textColor?: number; 211 + accentColor?: number; 212 + } 213 + 188 214 export type Voice = 189 215 "en_us_001" | "en_us_002" | "en_us_006" | "en_us_007" | "en_us_008" | "en_us_009" | "en_us_010" 190 216 | "en_uk_001" | "en_uk_003"