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

fix missing greeting cache update

shi.gg fe748608 9cfbaf1d

verified
Changed files
+89 -52
app
dashboard
[guildId]
greeting
farewell
passport
welcome
components
+4 -4
app/dashboard/[guildId]/greeting/farewell/page.tsx
··· 69 69 endpoint={`/guilds/${guild?.id}/modules/bye`} 70 70 k="enabled" 71 71 defaultState={data.enabled || false} 72 - disabled={false} 73 - onSave={(s) => { 74 - edit("enabled", s); 75 - }} 72 + onSave={(s) => edit("enabled", s)} 76 73 /> 77 74 78 75 <NumberInput ··· 82 79 dataName="deleteAfter" 83 80 defaultState={data.deleteAfter ?? 0} 84 81 disabled={!data.enabled} 82 + onSave={(n) => edit("deleteAfter", n)} 85 83 /> 86 84 87 85 <div className="flex md:gap-4 gap-2"> ··· 93 91 description="Select the channel where the farewell message should be send into" 94 92 defaultState={data.channelId} 95 93 disabled={!data.enabled} 94 + onSave={(o) => edit("channelId", o.value)} 96 95 /> 97 96 98 97 <Fetch ··· 121 120 )} 122 121 showMessageAttachmentComponentInEmbed={data.card.inEmbed} 123 122 disabled={!data.enabled} 123 + onSave={(message) => edit("message", message)} 124 124 > 125 125 126 126 <div className={cn("mt-2 mb-4 border-2 dark:border-wamellow border-wamellow-100 rounded-xl p-6", !data.card.enabled && "pb-0")}>
+5 -13
app/dashboard/[guildId]/greeting/passport/complete-setup.tsx
··· 26 26 }: Props) { 27 27 const [modal, setModal] = useState<ModalType>(ModalType.None); 28 28 29 - const [roleId, setRoleId] = useState<string>(); 29 + const [roleId, setRoleId] = useState<string | null>(null); 30 30 31 31 useEffect(() => { 32 32 if (!data.enabled) return; ··· 60 60 }) 61 61 }); 62 62 }} 63 - onSuccess={() => { 64 - edit("successRoleId", roleId); 65 - }} 63 + onSuccess={() => edit("successRoleId", roleId)} 66 64 > 67 65 <SelectMenu 68 66 name="Role" 69 67 items={createSelectableItems(guild?.roles, ["RoleHirachy"])} 70 68 description="Select what role members should get when completing verification." 71 69 defaultState={data.punishmentRoleId} 72 - onSave={(o) => { 73 - setRoleId(o.value as string); 74 - }} 70 + onSave={(o) => setRoleId(o.value)} 75 71 /> 76 72 </Modal> 77 73 ··· 92 88 }) 93 89 }); 94 90 }} 95 - onSuccess={() => { 96 - edit("punishmentRoleId", roleId); 97 - }} 91 + onSuccess={() => edit("punishmentRoleId", roleId)} 98 92 > 99 93 <SelectMenu 100 94 name="Role" 101 95 items={createSelectableItems(guild?.roles, ["RoleHirachy"])} 102 96 description="Select what role members should get when failing verification." 103 97 defaultState={data.punishmentRoleId} 104 - onSave={(o) => { 105 - setRoleId(o.value as string); 106 - }} 98 + onSave={(o) => setRoleId(o.value)} 107 99 /> 108 100 </Modal> 109 101 </>);
+7 -9
app/dashboard/[guildId]/greeting/passport/page.tsx
··· 81 81 k="enabled" 82 82 defaultState={data.enabled} 83 83 disabled={false} 84 - onSave={(s) => { 85 - edit("enabled", s); 86 - }} 84 + onSave={(s) => edit("enabled", s)} 87 85 /> 88 86 89 87 <Switch ··· 92 90 k="sendFailedDm" 93 91 defaultState={data.sendFailedDm} 94 92 disabled={!data.enabled} 93 + onSave={(s) => edit("sendFailedDm", s)} 95 94 /> 96 95 97 96 <SelectInput ··· 102 101 description="Select the channel where verification logs should be send into." 103 102 defaultState={data.channelId} 104 103 disabled={!data.enabled} 104 + onSave={(o) => edit("channelId", o.value)} 105 105 /> 106 106 107 107 <div className="lg:flex gap-3"> ··· 115 115 defaultState={data.unverifiedRoleId} 116 116 showClear 117 117 disabled={!data.enabled} 118 + onSave={(o) => edit("unverifiedRoleId", o.value)} 118 119 /> 119 120 </div> 120 121 ··· 127 128 description="Select what role members should get when completing verification." 128 129 defaultState={data.successRoleId} 129 130 disabled={!data.enabled} 131 + onSave={(o) => edit("successRoleId", o.value)} 130 132 /> 131 133 </div> 132 134 </div> ··· 145 147 description="Choose what should happen if a member failes verification." 146 148 defaultState={data.punishment} 147 149 disabled={!data.enabled} 148 - onSave={(o) => { 149 - edit("punishment", o.value as ApiV1GuildsModulesPassportGetResponse["punishment"]); 150 - }} 150 + onSave={(o) => edit("punishment", o.value as ApiV1GuildsModulesPassportGetResponse["punishment"])} 151 151 /> 152 152 </div> 153 153 ··· 160 160 description="Select what role members should get when failing verification." 161 161 defaultState={data.punishmentRoleId} 162 162 disabled={!data.enabled || data.punishment !== 2} 163 - onSave={(o) => { 164 - edit("punishmentRoleId", o.value as string); 165 - }} 163 + onSave={(o) => edit("punishmentRoleId", o.value)} 166 164 /> 167 165 </div> 168 166 </div>
+53 -6
app/dashboard/[guildId]/greeting/welcome/page.tsx
··· 72 72 k="enabled" 73 73 defaultState={data.enabled || false} 74 74 disabled={false} 75 - onSave={(s) => { 76 - edit("enabled", s); 77 - }} 75 + onSave={(s) => edit("enabled", s)} 78 76 /> 79 77 80 78 <Switch ··· 83 81 k="restore" 84 82 defaultState={data.restore} 85 83 disabled={!data.enabled} 84 + onSave={(s) => edit("restore", s)} 86 85 /> 87 86 88 87 <Switch ··· 92 91 k="deleteAfterLeave" 93 92 defaultState={data.deleteAfterLeave || false} 94 93 disabled={!data.enabled} 94 + onSave={(s) => edit("deleteAfterLeave", s)} 95 95 /> 96 96 97 97 <NumberInput ··· 101 101 dataName="deleteAfter" 102 102 defaultState={data.deleteAfter ?? 0} 103 103 disabled={!data.enabled} 104 + onSave={(n) => edit("deleteAfter", n)} 104 105 /> 105 106 106 107 <div className="flex md:gap-4 gap-2"> ··· 114 115 defaultState={data.channelId} 115 116 disabled={!data.enabled} 116 117 showClear 118 + onSave={(o) => edit("channelId", o.value)} 117 119 /> 118 120 119 121 <Fetch ··· 137 139 defaultState={data.roleIds} 138 140 max={5} 139 141 disabled={!data.enabled} 142 + onSave={(o) => edit("roleIds", o.map(({ value }) => value))} 140 143 /> 141 144 </div> 142 145 ··· 150 153 defaultState={data.pingIds} 151 154 max={5} 152 155 disabled={!data.enabled} 156 + onSave={(o) => edit("pingIds", o.map(({ value }) => value))} 153 157 /> 154 158 </div> 155 159 </div> ··· 165 169 defaultState={data.reactions?.firstMessageEmojis} 166 170 max={2} 167 171 disabled={!data.enabled} 172 + onSave={(o) => { 173 + edit("reactions", { 174 + ...data.reactions, 175 + firstMessageEmojis: o.map(({ value }) => value) 176 + }); 177 + }} 168 178 /> 169 179 </div> 170 180 ··· 178 188 defaultState={data.reactions?.welcomeMessageEmojis} 179 189 max={2} 180 190 disabled={!data.enabled} 191 + onSave={(o) => { 192 + edit("reactions", { 193 + ...data.reactions, 194 + welcomeMessageEmojis: o.map(({ value }) => value) 195 + }); 196 + }} 181 197 /> 182 198 </div> 183 199 </div> ··· 189 205 defaultMessage={data.message} 190 206 messageAttachmentComponent={data.card.enabled && ( 191 207 <Image 192 - src={`https://image-api.wamellow.com/?type=join&username=${encodeURIComponent(user?.username as string)}&members=1090&hash=${encodeURIComponent(user?.id as string)}/${encodeURIComponent(user?.avatar as string)}${data.card.background ? `&background=${encodeURIComponent(data.card.background)}` : ""}`} 193 - width={1024 / 2} 208 + src={`https://image-api.wamellow.com/?type=join&username=${encodeURIComponent(user!.username)}&members=1090&hash=${encodeURIComponent(user!.id)}/${encodeURIComponent(user!.avatar!)}${data.card.background ? `&background=${encodeURIComponent(data.card.background)}` : ""}`} 209 + width={1_024 / 2} 194 210 height={(256 + 16) / 2} 195 211 loading="lazy" 196 212 alt="" ··· 198 214 )} 199 215 showMessageAttachmentComponentInEmbed={data.card.inEmbed} 200 216 disabled={!data.enabled} 217 + onSave={(message) => edit("message", message)} 201 218 > 202 219 203 220 <div className={cn("mt-2 mb-4 border-2 dark:border-wamellow border-wamellow-100 rounded-xl p-6", !data.card.enabled && "pb-0")}> ··· 257 274 defaultMessage={data.dm?.message} 258 275 isCollapseable={true} 259 276 disabled={!data.enabled} 277 + onSave={(message) => { 278 + edit("dm", { 279 + ...data.dm, 280 + message 281 + }); 282 + }} 260 283 > 261 284 262 285 <div className="m-2"> ··· 266 289 k="dm.enabled" 267 290 defaultState={data.dm?.enabled} 268 291 disabled={!data.enabled} 292 + onSave={(s) => { 293 + edit("dm", { 294 + ...data.dm, 295 + enabled: s 296 + }); 297 + }} 269 298 /> 270 299 </div> 271 300 ··· 299 328 k="button.ping" 300 329 defaultState={data.button?.ping || false} 301 330 disabled={!data.enabled || !data.button?.enabled} 331 + onSave={(s) => { 332 + edit("button", { 333 + ...data.button, 334 + ping: s 335 + }); 336 + }} 302 337 /> 303 338 304 339 <div className="lg:flex gap-3 pt-3"> ··· 321 356 })) 322 357 } 323 358 description="Select the color of the button." 324 - defaultState={data.button?.style} 359 + defaultState={data.button?.style || 1} 325 360 disabled={!data.enabled || !data.button?.enabled} 361 + onSave={(o) => { 362 + edit("button", { 363 + ...data.button, 364 + style: o.value as 1 365 + }); 366 + }} 326 367 /> 327 368 </div> 328 369 <div className="lg:w-1/2"> ··· 334 375 description="Select an emoji which will be used in the button." 335 376 defaultState={data.button?.emoji} 336 377 disabled={!data.enabled || !data.button?.enabled} 378 + onSave={(o) => { 379 + edit("button", { 380 + ...data.button, 381 + emoji: o.value 382 + }); 383 + }} 337 384 /> 338 385 </div> 339 386 </div>
+10 -10
components/inputs/multi-select-menu.tsx
··· 13 13 Success = 2 14 14 } 15 15 16 - interface Item { 16 + interface Item<T extends string | number> { 17 17 icon?: React.ReactNode; 18 18 name: string; 19 - value: string | number; 19 + value: T; 20 20 error?: string; 21 21 color?: number; 22 22 } 23 23 24 - interface Props { 24 + interface Props<T extends string | number> { 25 25 className?: string; 26 26 27 27 name: string; 28 28 url?: string; 29 29 dataName?: string; 30 - items: Item[] | undefined; 30 + items: Item<T>[]; 31 31 disabled?: boolean; 32 32 max?: number; 33 33 description?: string; 34 - defaultState?: (string | number)[]; 34 + defaultState?: T[]; 35 35 36 - onSave?: (options: { name: string; value: string | number | null; error?: string; }[]) => void; 36 + onSave?: (options: { name: string; value: T; error?: string; }[]) => void; 37 37 } 38 38 39 - export default function MultiSelectMenu({ 39 + export default function MultiSelectMenu<T extends string | number>({ 40 40 className, 41 41 name, 42 42 url, ··· 47 47 description, 48 48 defaultState, 49 49 onSave 50 - }: Props) { 50 + }: Props<T>) { 51 51 const [state, setState] = useState<State>(State.Idle); 52 52 const [error, setError] = useState<string | null>(null); 53 53 54 54 const [open, setOpen] = useState<boolean>(false); 55 - const [defaultvalue, setDefaultalue] = useState<(string | number)[]>([]); 56 - const [values, setValues] = useState<Item[]>([]); 55 + const [defaultvalue, setDefaultalue] = useState<T[]>([]); 56 + const [values, setValues] = useState<Item<T>[]>([]); 57 57 58 58 useEffect(() => { 59 59 if (!defaultState) return;
+10 -10
components/inputs/select-menu.tsx
··· 13 13 Success = 2 14 14 } 15 15 16 - interface Item { 16 + interface Item<T extends string | number> { 17 17 icon?: React.ReactNode; 18 18 name: string; 19 - value: string | number | null; 19 + value: T | null; 20 20 error?: string; 21 21 color?: number; 22 22 } 23 23 24 - interface Props { 24 + interface Props<T extends string | number> { 25 25 className?: string; 26 26 27 27 name: string; 28 28 url?: string; 29 29 dataName?: string; 30 - items: Item[] | undefined; 30 + items: Item<T>[]; 31 31 disabled?: boolean; 32 32 description?: string; 33 - defaultState?: string | number | null; 33 + defaultState?: T | null; 34 34 showClear?: boolean; 35 35 36 - onSave?: (options: { name: string; value: string | number | null; error?: string; }) => void; 36 + onSave?: (options: { name: string; value: T | null; error?: string; }) => void; 37 37 } 38 38 39 - export default function SelectMenu({ 39 + export default function SelectMenu<T extends string | number>({ 40 40 className, 41 41 name, 42 42 url, ··· 47 47 defaultState, 48 48 showClear, 49 49 onSave 50 - }: Props) { 50 + }: Props<T>) { 51 51 const [state, setState] = useState<State>(State.Idle); 52 52 const [error, setError] = useState<string | null>(null); 53 53 54 54 const [open, setOpen] = useState<boolean>(false); 55 - const [defaultvalue, setDefaultalue] = useState<string | number | null | undefined>(); 56 - const [value, setValue] = useState<Item | undefined>(); 55 + const [defaultvalue, setDefaultalue] = useState<T | null | undefined>(); 56 + const [value, setValue] = useState<Item<T> | undefined>(); 57 57 58 58 useEffect(() => { 59 59 setValue(items.find((i) => i.value === defaultState));