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.

refactor: remove deprecated input props (#56)

* refactor: remove deprecated url and dataName props from input utils

* refactor: remove deprecated name prop from input components

* refactor: centralize label prop in InputProps

authored by

Luna Seemann and committed by
GitHub
8bad178b 1a1a790b

+294 -327
+6 -6
app/dashboard/[guildId]/custom-commands/page.tsx
··· 173 173 <InputText 174 174 key={tag.id} 175 175 label="Command Name" 176 - url={url + "/" + tag.id} 177 - dataName="name" 176 + endpoint={url + "/" + tag.id} 177 + k="name" 178 178 description="The name of the custom command." 179 179 defaultState={tag.name} 180 180 resetState={tag.name} ··· 187 187 <InputSelect 188 188 key={tag.id} 189 189 label="Permissions" 190 - url={url + "/" + tag.id} 190 + endpoint={url + "/" + tag.id} 191 191 items={ 192 192 Permissions.sort((a, b) => a.localeCompare(b)).map((p) => ( 193 193 { name: convertCamelCaseToSpaced(p), value: p } 194 194 )) || [] 195 195 } 196 - dataName="permission" 196 + k="permission" 197 197 description="The permissions needed to execute this tag." 198 198 defaultState={tag.permission} 199 199 onSave={(option) => editTag("permission", option)} ··· 205 205 <MessageCreatorEmbed 206 206 key={tag.id} 207 207 name="Message" 208 - url={url + "/" + tag.id} 209 - dataName="message" 208 + endpoint={url + "/" + tag.id} 209 + k="message" 210 210 defaultMessage={tag.message} 211 211 onSave={(value) => editTag("message", value)} 212 212 />
+1 -1
app/dashboard/[guildId]/dailyposts/create.component.tsx
··· 91 91 > 92 92 <InputSelect 93 93 label="Channel" 94 - dataName="channelId" 94 + k="channelId" 95 95 items={createSelectableItems(channels, ["ViewChannel", "SendMessages", "AttachFiles"])} 96 96 description="Select a channel where dailyposts should be send into." 97 97 onSave={(o) => {
+6 -6
app/dashboard/[guildId]/dailyposts/page.tsx
··· 138 138 <div className="flex md:gap-4 gap-2"> 139 139 <InputSelect 140 140 label="Channel" 141 - url={url + "/" + item.id} 142 - dataName="channelId" 141 + endpoint={url + "/" + item.id} 142 + k="channelId" 143 143 items={createSelectableItems(guild?.channels, ["ViewChannel", "SendMessages", "AttachFiles"])} 144 144 description="Select a channel where dailyposts should be send into." 145 145 defaultState={item.channelId} ··· 160 160 <InputSelect 161 161 className="lg:w-1/2 w-full" 162 162 label="Ping role" 163 - url={url + "/" + item.id} 164 - dataName="roleId" 163 + endpoint={url + "/" + item.id} 164 + k="roleId" 165 165 items={[ 166 166 { name: "@everyone (everyone in server)", value: "everyone" }, 167 167 { name: "@here (everyone online)", value: "here" }, ··· 175 175 <InputMultiSelect 176 176 className="lg:w-1/2 w-full" 177 177 label="Run at" 178 - url={url + "/" + item.id} 179 - dataName="runtimeHours" 178 + endpoint={url + "/" + item.id} 179 + k="runtimeHours" 180 180 items={hoursArray} 181 181 defaultState={item.runtimeHours.map(Number)} 182 182 description="Select one or multiple hours when posts should be made."
+8 -8
app/dashboard/[guildId]/greeting/farewell/page.tsx
··· 64 64 <InputNumber 65 65 label="After how many seconds the message should be deleted" 66 66 description="Set to 0 to disable" 67 - url={`/guilds/${guild?.id}/modules/bye`} 68 - dataName="deleteAfter" 67 + endpoint={`/guilds/${guild?.id}/modules/bye`} 68 + k="deleteAfter" 69 69 defaultState={data.deleteAfter ?? 0} 70 70 disabled={!enabled} 71 71 onSave={(n) => edit("deleteAfter", n)} ··· 74 74 <div className="flex md:gap-4 gap-2"> 75 75 <InputSelect 76 76 label="Channel" 77 - url={`/guilds/${guild?.id}/modules/bye`} 78 - dataName="channelId" 77 + endpoint={`/guilds/${guild?.id}/modules/bye`} 78 + k="channelId" 79 79 items={createSelectableItems(guild?.channels)} 80 80 description="Select the channel where the farewell message should be send into" 81 81 defaultState={data.channelId} ··· 95 95 96 96 <MessageCreatorEmbed 97 97 name="Message" 98 - url={`/guilds/${guild?.id}/modules/bye`} 99 - dataName="message" 98 + endpoint={`/guilds/${guild?.id}/modules/bye`} 99 + k="message" 100 100 defaultMessage={data.message} 101 101 messageAttachmentComponent={(guild!.flags & GuildFlags.FarewellCard) !== 0 && ( 102 102 <Image ··· 136 136 137 137 <InputImageUrl 138 138 label="Card Background" 139 - url={`/guilds/${guild?.id}/modules/bye`} 139 + endpoint={`/guilds/${guild?.id}/modules/bye`} 140 140 ratio="aspect-4/1" 141 - dataName="card.background" 141 + k="card.background" 142 142 description="Enter a url which should be the background for the image card. The recommended resolution is 906x256px." 143 143 defaultState={data.card.background || ""} 144 144 disabled={!enabled || (guild!.flags & GuildFlags.FarewellCard) === 0}
+71 -71
app/dashboard/[guildId]/greeting/passport/page.tsx
··· 62 62 onSave={(value) => guildStore.setState({ flags: transformer(value, guild!.flags, GuildFlags.PassportEnabled) })} 63 63 /> 64 64 65 - <InputSelect 66 - label="Channel" 67 - url={`/guilds/${guild?.id}/modules/passport`} 68 - dataName="channelId" 69 - items={createSelectableItems(guild?.channels)} 70 - description="Select the channel where verification logs should be send into." 71 - defaultState={data.channelId} 72 - disabled={!enabled} 73 - onSave={(o) => edit("channelId", o as string)} 74 - /> 75 - 76 - <div className="lg:flex gap-3"> 77 - <div className="lg:w-1/2"> 78 - <InputSelect 79 - label="Unverified role" 80 - url={`/guilds/${guild?.id}/modules/passport`} 81 - dataName="unverifiedRoleId" 82 - items={createSelectableItems(guild?.roles, ["RoleHirachy"])} 83 - description="Select what role members should get when joining." 84 - defaultState={data.unverifiedRoleId} 85 - showClear 86 - disabled={!enabled} 87 - onSave={(o) => edit("unverifiedRoleId", o as string)} 88 - /> 89 - </div> 90 - 91 - <div className="lg:w-1/2"> 92 - <InputSelect 93 - label="Verified role" 94 - url={`/guilds/${guild?.id}/modules/passport`} 95 - dataName="successRoleId" 96 - items={createSelectableItems(guild?.roles, ["RoleHirachy"])} 97 - description="Select what role members should get when completing verification." 98 - defaultState={data.successRoleId} 99 - disabled={!enabled} 100 - onSave={(o) => edit("successRoleId", o as string)} 101 - /> 102 - </div> 103 - </div> 104 - 105 - <div className="lg:flex gap-3"> 106 - <div className="lg:w-1/2"> 107 - <InputSelect 108 - label="Failed verification action" 109 - url={`/guilds/${guild?.id}/modules/passport`} 110 - dataName="punishment" 111 - items={[ 112 - { name: "Ban member", value: 0 }, 113 - { name: "Kick member", value: 1 }, 114 - { name: "Assign role to member", value: 2 } 115 - ]} 116 - description="Choose what should happen if a member failes verification." 117 - defaultState={data.punishment} 118 - disabled={!enabled} 119 - onSave={(o) => edit("punishment", o as ApiV1GuildsModulesPassportGetResponse["punishment"])} 120 - /> 121 - </div> 122 - 123 - <div className="lg:w-1/2"> 124 - <InputSelect 125 - label="Punishment role" 126 - url={`/guilds/${guild?.id}/modules/passport`} 127 - dataName="punishmentRoleId" 128 - items={createSelectableItems(guild?.roles, ["RoleHirachy"])} 129 - description="Select what role members should get when failing verification." 130 - defaultState={data.punishmentRoleId} 131 - disabled={!enabled || data.punishment !== 2} 132 - onSave={(o) => edit("punishmentRoleId", o as string)} 133 - /> 134 - </div> 135 - </div> 65 + <InputSelect 66 + label="Channel" 67 + endpoint={`/guilds/${guild?.id}/modules/passport`} 68 + k="channelId" 69 + items={createSelectableItems(guild?.channels)} 70 + description="Select the channel where verification logs should be send into." 71 + defaultState={data.channelId} 72 + disabled={!enabled} 73 + onSave={(o) => edit("channelId", o as string)} 74 + /> 75 + 76 + <div className="lg:flex gap-3"> 77 + <div className="lg:w-1/2"> 78 + <InputSelect 79 + label="Unverified role" 80 + endpoint={`/guilds/${guild?.id}/modules/passport`} 81 + k="unverifiedRoleId" 82 + items={createSelectableItems(guild?.roles, ["RoleHirachy"])} 83 + description="Select what role members should get when joining." 84 + defaultState={data.unverifiedRoleId} 85 + showClear 86 + disabled={!enabled} 87 + onSave={(o) => edit("unverifiedRoleId", o as string)} 88 + /> 89 + </div> 90 + 91 + <div className="lg:w-1/2"> 92 + <InputSelect 93 + label="Verified role" 94 + endpoint={`/guilds/${guild?.id}/modules/passport`} 95 + k="successRoleId" 96 + items={createSelectableItems(guild?.roles, ["RoleHirachy"])} 97 + description="Select what role members should get when completing verification" 98 + defaultState={data.successRoleId} 99 + disabled={!enabled} 100 + onSave={(o) => edit("successRoleId", o as string)} 101 + /> 102 + </div> 103 + </div> 104 + 105 + <div className="lg:flex gap-3"> 106 + <div className="lg:w-1/2"> 107 + <InputSelect 108 + label="Failed verification action" 109 + endpoint={`/guilds/${guild?.id}/modules/passport`} 110 + k="punishment" 111 + items={[ 112 + { name: "Ban member", value: 0 }, 113 + { name: "Kick member", value: 1 }, 114 + { name: "Assign role to member", value: 2 } 115 + ]} 116 + description="Choose what should happen if a member failes verification." 117 + defaultState={data.punishment} 118 + disabled={!enabled} 119 + onSave={(o) => edit("punishment", o as ApiV1GuildsModulesPassportGetResponse["punishment"])} 120 + /> 121 + </div> 122 + 123 + <div className="lg:w-1/2"> 124 + <InputSelect 125 + label="Punishment role" 126 + endpoint={`/guilds/${guild?.id}/modules/passport`} 127 + k="punishmentRoleId" 128 + items={createSelectableItems(guild?.roles, ["RoleHirachy"])} 129 + description="Select what role members should get when failing verification." 130 + defaultState={data.punishmentRoleId} 131 + disabled={!enabled || data.punishment !== 2} 132 + onSave={(o) => edit("punishmentRoleId", o as string)} 133 + /> 134 + </div> 135 + </div> 136 136 137 137 <Section 138 138 title="Verification Page"
+22 -22
app/dashboard/[guildId]/greeting/welcome/page.tsx
··· 85 85 <InputNumber 86 86 label="After how many seconds the message should be deleted" 87 87 description="Set to 0 to disable." 88 - url={`/guilds/${guild?.id}/modules/welcome`} 89 - dataName="deleteAfter" 88 + endpoint={`/guilds/${guild?.id}/modules/welcome`} 89 + k="deleteAfter" 90 90 defaultState={data.deleteAfter ?? 0} 91 91 disabled={!enabled} 92 92 onSave={(n) => edit("deleteAfter", n)} ··· 96 96 <InputSelect 97 97 className="w-2/3 md:w-5/6" 98 98 label="Channel" 99 - url={`/guilds/${guild?.id}/modules/welcome`} 100 - dataName="channelId" 99 + endpoint={`/guilds/${guild?.id}/modules/welcome`} 100 + k="channelId" 101 101 items={createSelectableItems(guild?.channels)} 102 102 description="Select the channel where the welcome message should be send into." 103 103 defaultState={data.channelId} ··· 120 120 <div className="lg:w-1/2"> 121 121 <InputMultiSelect 122 122 label="Join roles" 123 - url={`/guilds/${guild?.id}/modules/welcome`} 124 - dataName="roleIds" 123 + endpoint={`/guilds/${guild?.id}/modules/welcome`} 124 + k="roleIds" 125 125 items={createSelectableItems(guild?.roles, ["RoleHirachy"])} 126 126 description="Select roles which members should get." 127 127 defaultState={data.roleIds} ··· 134 134 <div className="lg:w-1/2"> 135 135 <InputMultiSelect 136 136 label="Channel pings" 137 - url={`/guilds/${guild?.id}/modules/welcome`} 138 - dataName="pingIds" 137 + endpoint={`/guilds/${guild?.id}/modules/welcome`} 138 + k="pingIds" 139 139 items={createSelectableItems(guild?.channels, ["ViewChannel", "SendMessages"])} 140 140 description="Select in what channels user should get ghostpinged." 141 141 defaultState={data.pingIds} ··· 150 150 <div className="lg:w-1/2"> 151 151 <InputMultiSelect 152 152 label="First user message reactions" 153 - url={`/guilds/${guild?.id}/modules/welcome`} 154 - dataName="reactions.firstMessageEmojis" 153 + endpoint={`/guilds/${guild?.id}/modules/welcome`} 154 + k="reactions.firstMessageEmojis" 155 155 items={createSelectableEmojiItems(guild?.emojis)} 156 156 description="Select emotes which will be reacted with on members first message." 157 157 defaultState={data.reactions?.firstMessageEmojis} ··· 169 169 <div className="lg:w-1/2"> 170 170 <InputMultiSelect 171 171 label="Welcome message reactions" 172 - url={`/guilds/${guild?.id}/modules/welcome`} 173 - dataName="reactions.welcomeMessageEmojis" 172 + endpoint={`/guilds/${guild?.id}/modules/welcome`} 173 + k="reactions.welcomeMessageEmojis" 174 174 items={createSelectableEmojiItems(guild?.emojis)} 175 175 description="Select emotes which will be reacted with on welcome messages." 176 176 defaultState={data.reactions?.welcomeMessageEmojis} ··· 188 188 189 189 <MessageCreatorEmbed 190 190 name="Message" 191 - url={`/guilds/${guild?.id}/modules/welcome`} 192 - dataName="message" 191 + endpoint={`/guilds/${guild?.id}/modules/welcome`} 192 + k="message" 193 193 defaultMessage={data.message} 194 194 messageAttachmentComponent={(guild!.flags & GuildFlags.WelcomeCard) !== 0 && ( 195 195 <Image ··· 229 229 230 230 <InputImageUrl 231 231 label="Card Avatar" 232 - url={`/guilds/${guild?.id}/modules/welcome`} 232 + endpoint={`/guilds/${guild?.id}/modules/welcome`} 233 233 ratio="aspect-4/1" 234 - dataName="card.background" 234 + k="card.background" 235 235 description="Enter a url which should be the background for the image card. The recommended resolution is 906x256px." 236 236 defaultState={data.card.background || ""} 237 237 disabled={!enabled || (guild!.flags & GuildFlags.WelcomeCard) === 0} ··· 249 249 250 250 <MessageCreatorEmbed 251 251 name="Direct Message" 252 - url={`/guilds/${guild?.id}/modules/welcome`} 253 - dataName="dm.message" 252 + endpoint={`/guilds/${guild?.id}/modules/welcome`} 253 + k="dm.message" 254 254 defaultMessage={data.dm?.message} 255 255 isCollapseable={true} 256 256 disabled={!enabled} ··· 308 308 <div className="lg:w-1/2"> 309 309 <InputSelect 310 310 label="Button color" 311 - url={`/guilds/${guild?.id}/modules/welcome`} 312 - dataName="button.style" 311 + endpoint={`/guilds/${guild?.id}/modules/welcome`} 312 + k="button.style" 313 313 items={ 314 314 [ 315 315 ["292b34", "Grey", 2], ··· 337 337 <div className="lg:w-1/2"> 338 338 <InputSelect 339 339 label="Webhook Profile" 340 - url={`/guilds/${guild?.id}/modules/welcome`} 341 - dataName="button.emoji" 340 + endpoint={`/guilds/${guild?.id}/modules/welcome`} 341 + k="button.emoji" 342 342 items={createSelectableEmojiItems(guild?.emojis)} 343 343 description="Select an emoji which will be used in the button." 344 344 defaultState={data.button?.emoji}
+44 -44
app/dashboard/[guildId]/leaderboards/page.tsx
··· 51 51 icon={<HiChartBar />} 52 52 /> 53 53 54 - <InputImageUrl 55 - label="Enabled" 56 - url={url} 57 - ratio="aspect-4/1" 58 - dataName="banner" 59 - description="Enter a url which should be the banner of the leaderboard web page. The recommended resolution is 906x256px." 60 - defaultState={data.bannerUrl || ""} 61 - /> 54 + <InputImageUrl 55 + label="Enabled" 56 + endpoint={url} 57 + ratio="aspect-4/1" 58 + k="banner" 59 + description="Enter a url which should be the banner of the leaderboard web page. The recommended resolution is 906x256px." 60 + defaultState={data.bannerUrl || ""} 61 + /> 62 62 </div> 63 63 64 64 <Permissions ··· 73 73 Select roles which should be assigned to the top members. (left to right - 1st to 3rd place) 74 74 </Section> 75 75 76 - <div className="lg:flex gap-3 mt-5"> 77 - <div className="lg:w-1/2"> 78 - <InputMultiSelect 79 - label="Top messager roles" 80 - url={url} 81 - dataName="roles.messages" 82 - items={createSelectableItems(guild?.roles)} 83 - description="Select roles which should be assigned to the top message members." 84 - defaultState={data.roles?.messages || []} 85 - max={3} 86 - /> 87 - </div> 88 - <div className="lg:w-1/2"> 89 - <InputMultiSelect 90 - label="Blacklisted roles" 91 - url={url} 92 - dataName="roles.voiceminutes" 93 - items={createSelectableItems(guild?.roles)} 94 - description="Select roles which should be assigned to the top voice members." 95 - defaultState={data.roles?.voiceminutes || []} 96 - max={3} 97 - /> 98 - </div> 99 - </div> 100 - 101 - <div className="lg:w-1/2"> 102 - <InputMultiSelect 103 - label="Blacklisted channels" 104 - url={url} 105 - dataName="blacklistChannelIds" 106 - items={createSelectableItems(guild?.channels, [], [ChannelType.GuildCategory, ChannelType.GuildText, ChannelType.GuildAnnouncement, ChannelType.GuildVoice])} 107 - description="Select channels which should not be counted." 108 - defaultState={data.blacklistChannelIds || []} 109 - max={500} 110 - /> 111 - </div> 76 + <div className="lg:flex gap-3 mt-5"> 77 + <div className="lg:w-1/2"> 78 + <InputMultiSelect 79 + label="Top messager roles" 80 + endpoint={url} 81 + k="roles.messages" 82 + items={createSelectableItems(guild?.roles)} 83 + description="Select roles which should be assigned to the top message members." 84 + defaultState={data.roles?.messages || []} 85 + max={3} 86 + /> 87 + </div> 88 + <div className="lg:w-1/2"> 89 + <InputMultiSelect 90 + label="Blacklisted roles" 91 + endpoint={url} 92 + k="roles.voiceminutes" 93 + items={createSelectableItems(guild?.roles)} 94 + description="Select roles which should be assigned to the top voice members." 95 + defaultState={data.roles?.voiceminutes || []} 96 + max={3} 97 + /> 98 + </div> 99 + </div> 100 + 101 + <div className="lg:w-1/2"> 102 + <InputMultiSelect 103 + label="Blacklisted channels" 104 + endpoint={url} 105 + k="blacklistChannelIds" 106 + items={createSelectableItems(guild?.channels, [], [ChannelType.GuildCategory, ChannelType.GuildText, ChannelType.GuildAnnouncement, ChannelType.GuildVoice])} 107 + description="Select channels which should not be counted." 108 + defaultState={data.blacklistChannelIds || []} 109 + max={500} 110 + /> 111 + </div> 112 112 113 113 <Section 114 114 title="Updating"
+6 -6
app/dashboard/[guildId]/moderation/page.tsx
··· 52 52 <div className="lg:w-1/2"> 53 53 <InputMultiSelect 54 54 label="Whitelist channels" 55 - url={url} 56 - dataName="whitelistChannelIds" 55 + endpoint={url} 56 + k="whitelistChannelIds" 57 57 items={createSelectableItems(guild?.channels, [], [ChannelType.GuildCategory, ChannelType.GuildText, ChannelType.GuildAnnouncement])} 58 58 description="Select channels where messages should not be moderated in." 59 59 defaultState={data.whitelistChannelIds} ··· 67 67 <div className="lg:w-1/2"> 68 68 <InputMultiSelect 69 69 label="Whitelist roles" 70 - url={url} 71 - dataName="whitelistRoleIds" 70 + endpoint={url} 71 + k="whitelistRoleIds" 72 72 items={createSelectableItems(guild?.roles)} 73 73 description="Select roles by who messages should not be moderated for." 74 74 defaultState={data.whitelistRoleIds} ··· 83 83 84 84 <InputText 85 85 label="Keyword filter" 86 - url={url} 87 - dataName="keywordFilter" 86 + endpoint={url} 87 + k="keywordFilter" 88 88 description="Separate words or phrases with a comma (dog, cat, tiger) or new line. For each word, use * at the beginning, end, or both for partial matching." 89 89 defaultState={data.keywordFilter.join(", ")} 90 90 max={Infinity}
+12 -12
app/dashboard/[guildId]/notifications/page.tsx
··· 166 166 <div className="flex md:gap-4 gap-2"> 167 167 <InputSelect 168 168 label="Channel" 169 - url={url + "/" + item.id} 170 - dataName="channelId" 169 + endpoint={url + "/" + item.id} 170 + k="channelId" 171 171 items={createSelectableItems(guild?.channels, ["ViewChannel", "SendMessages", "EmbedLinks", item.username ? "ManageWebhooks" : null, item.roleId ? "MentionEveryone" : null])} 172 172 description="Select a channel where notifications should be send into." 173 173 defaultState={item.channelId} ··· 193 193 <InputSelect 194 194 className="md:w-1/2 w-full" 195 195 label="Ping role" 196 - url={url + "/" + item.id} 197 - dataName="roleId" 196 + endpoint={url + "/" + item.id} 197 + k="roleId" 198 198 items={[ 199 199 { name: "@everyone (everyone in server)", value: "everyone" }, 200 200 { name: "@here (everyone online)", value: "here" }, ··· 210 210 ? <InputMultiSelect 211 211 className="md:w-1/2 w-full" 212 212 label="Filter" 213 - url={url + "/" + item.id} 214 - dataName="flags" 213 + endpoint={url + "/" + item.id} 214 + k="flags" 215 215 items={bitfieldToArray(platformFlags)} 216 216 description={item.type === NotificationType.Bluesky 217 217 ? "Select the types of posts to send in addition to regular posts." ··· 230 230 ? "Blacklist regex" 231 231 : "Whitelist regex" 232 232 } 233 - url={url + "/" + item.id} 234 - dataName="regex" 233 + endpoint={url + "/" + item.id} 234 + k="regex" 235 235 description={flags.has(NotificationFlags.MustNotMatchRegex) 236 236 ? "Posts that match the provided regex will be ignored." 237 237 : "Only posts that match the provided regex will be sent." ··· 249 249 ? "Blacklist regex" 250 250 : "Whitelist regex" 251 251 } 252 - url={url + "/" + item.id} 253 - dataName="regex" 252 + endpoint={url + "/" + item.id} 253 + k="regex" 254 254 description={flags.has(NotificationFlags.MustNotMatchRegex) 255 255 ? "Posts that match the provided regex will be ignored." 256 256 : "Only posts that match the provided regex will be sent." ··· 291 291 <MessageCreatorEmbed 292 292 key={item.id} 293 293 name="Message" 294 - url={url + "/" + item.id} 295 - dataName="message" 294 + endpoint={url + "/" + item.id} 295 + k="message" 296 296 defaultMessage={item.message} 297 297 user={premium && item.username 298 298 ? {
+14 -14
app/dashboard/[guildId]/starboard/page.tsx
··· 130 130 <InputNumber 131 131 label="Number of reactions required" 132 132 description="Sets the number of reactions needed to get a message onto the data." 133 - url={url} 134 - dataName="requiredEmojis" 133 + endpoint={url} 134 + k="requiredEmojis" 135 135 defaultState={data.requiredEmojis ?? 0} 136 136 disabled={!enabled} 137 137 min={2} ··· 140 140 141 141 <InputSelect 142 142 label="Channel" 143 - url={url} 144 - dataName="channelId" 143 + endpoint={url} 144 + k="channelId" 145 145 items={createSelectableItems(guild?.channels)} 146 146 description="Select the channel where the starboard messages should be send into." 147 147 defaultState={data.channelId} ··· 153 153 <div className="lg:w-1/2"> 154 154 <InputSelect 155 155 label="Emoji" 156 - url={url} 157 - dataName="emoji" 156 + endpoint={url} 157 + k="emoji" 158 158 items={[ 159 159 { icon: "⭐", name: "Star", value: "⭐" }, 160 160 { icon: "✨", name: "Sparkles", value: "✨" }, ··· 181 181 <div className="lg:w-1/2"> 182 182 <InputSelect 183 183 label="Profile display style" 184 - url={url} 185 - dataName="style" 184 + endpoint={url} 185 + k="style" 186 186 items={[ 187 187 { 188 188 name: "Username", ··· 217 217 <div className="lg:w-1/2"> 218 218 <InputMultiSelect 219 219 label="Blacklisted channels" 220 - url={url} 221 - dataName="blacklistChannelIds" 220 + endpoint={url} 221 + k="blacklistChannelIds" 222 222 items={createSelectableItems(guild?.channels)} 223 223 description="Select channels which should not be able to get into the starboard." 224 224 defaultState={data.blacklistChannelIds || []} ··· 230 230 <div className="lg:w-1/2"> 231 231 <InputMultiSelect 232 232 label="Blacklisted roles" 233 - url={url} 234 - dataName="blacklistRoleIds" 233 + endpoint={url} 234 + k="blacklistRoleIds" 235 235 items={createSelectableItems(guild?.roles)} 236 236 description="Select roles which should not be able to star or be starred." 237 237 defaultState={data.blacklistRoleIds || []} ··· 246 246 <div className="w-1/2"> 247 247 <InputColor 248 248 label="Color" 249 - url={url} 250 - dataName="embedColor" 249 + endpoint={url} 250 + k="embedColor" 251 251 description="Color used for the side of the embed." 252 252 defaultState={data.embedColor ?? 0} 253 253 onSave={(o) => edit("embedColor", o)}
+10 -10
app/dashboard/[guildId]/tts.component.tsx
··· 30 30 <div className="lg:w-1/2 flex flex-col gap-2"> 31 31 <InputSelect 32 32 label="Chat to Speech channel" 33 - url={`/guilds/${params.guildId}`} 34 - dataName="tts.channelId" 33 + endpoint={`/guilds/${params.guildId}`} 34 + k="tts.channelId" 35 35 items={createSelectableItems(guild?.channels, ["ViewChannel", "SendMessages", "EmbedLinks"], [ChannelType.GuildText, ChannelType.GuildVoice])} 36 36 description="Select a channel what channel should be used for tts." 37 37 defaultState={guild?.tts.channelId} ··· 40 40 /> 41 41 <InputSelect 42 42 label="Usage logs" 43 - url={`/guilds/${params.guildId}`} 44 - dataName="tts.logChannelId" 43 + endpoint={`/guilds/${params.guildId}`} 44 + k="tts.logChannelId" 45 45 items={createSelectableItems(guild?.channels)} 46 46 description="Select a channel where usage logs should be posted into." 47 47 defaultState={guild?.tts.logChannelId} ··· 50 50 /> 51 51 <InputSelect 52 52 label="Priority role" 53 - url={`/guilds/${params.guildId}`} 54 - dataName="tts.priorityRoleId" 53 + endpoint={`/guilds/${params.guildId}`} 54 + k="tts.priorityRoleId" 55 55 items={createSelectableItems(guild?.roles)} 56 56 description="People with this role bypass the queue and speak immediately." 57 57 defaultState={guild?.tts.priorityRoleId} ··· 60 60 /> 61 61 <InputSelect 62 62 label="Blacklist role" 63 - url={`/guilds/${params.guildId}`} 64 - dataName="tts.blacklistRoleId" 63 + endpoint={`/guilds/${params.guildId}`} 64 + k="tts.blacklistRoleId" 65 65 items={createSelectableItems(guild?.roles)} 66 66 description="People with this role are not allowed to use tts." 67 67 defaultState={guild?.tts.blacklistRoleId} ··· 96 96 <InputNumber 97 97 label="Max message length" 98 98 description="The maximum length of a message that can be spoken." 99 - url={`/guilds/${params.guildId}`} 100 - dataName="tts.maxLength" 99 + endpoint={`/guilds/${params.guildId}`} 100 + k="tts.maxLength" 101 101 defaultState={guild?.tts.maxLength || 4_000} 102 102 max={4_000} 103 103 onSave={(value) => edit("maxLength", value)}
+1 -1
app/dashboard/[guildId]/updates.component.tsx
··· 74 74 > 75 75 <InputSelect 76 76 label="Channel" 77 - dataName="channelId" 77 + k="channelId" 78 78 items={createSelectableItems(guild?.channels, ["ViewChannel", "ManageWebhooks"])} 79 79 description="Select a channel where updates should be send into." 80 80 defaultState={guild?.follownewsChannel?.id}
+2 -2
app/profile/billing/page.tsx
··· 239 239 <InputMultiSelect 240 240 className="w-full md:w-1/2 lg:w-1/3" 241 241 label="Premium Guilds" 242 - url="/users/@me/billing/premium-guilds" 243 - dataName="guildIds" 242 + endpoint="/users/@me/billing/premium-guilds" 243 + k="guildIds" 244 244 items={(data || []) 245 245 .filter((guild) => guild.bot) 246 246 .map((guild) => ({
+73 -73
app/profile/rank/page.tsx
··· 15 15 16 16 if (user?.id && !user.extended) return <></>; 17 17 18 - return (<> 19 - <div className="lg:flex gap-3"> 20 - <div className="lg:w-1/2"> 21 - <InputSelect 22 - label="Secondary text" 23 - url="/users/@me/rank" 24 - dataName="subText.type" 25 - description="This text will be displayed bellow the /rank progressbar." 26 - items={[ 27 - { 28 - name: "None", 29 - value: 0 30 - }, 31 - { 32 - name: "ETA to next milestone reach date", 33 - value: 1 34 - }, 35 - { 36 - name: "ETA to next milestone reach relative date", 37 - value: 2 38 - }, 39 - { 40 - name: "Custom text", 41 - value: 3, 42 - error: "Not done yet" 43 - } 44 - ]} 45 - defaultState={user?.extended?.rank?.subText?.type} 46 - onSave={(value) => { 47 - userStore.setState(deepMerge<User>(user, { extended: { rank: { subText: { type: Number(value) as 0 | 1 | 2 | 3 } } } })); 48 - }} 49 - /> 50 - </div> 51 - 52 - <div className="lg:w-1/2 flex gap-2 w-full"> 53 - <div className="w-1/2"> 54 - <InputColor 55 - label="Text color" 56 - url="/users/@me/rank" 57 - dataName="textColor" 58 - description="Color used for your username." 59 - defaultState={user?.extended?.rank?.textColor ?? 0} 60 - onSave={(value) => { 61 - userStore.setState(deepMerge<User>(user, { extended: { rank: { textColor: Number(value) } } })); 62 - }} 63 - /> 64 - </div> 65 - <div className="w-1/2"> 66 - <InputColor 67 - label="Bar color" 68 - url="/users/@me/rank" 69 - dataName="barColor" 70 - description="Color used for the progress bar." 71 - defaultState={user?.extended?.rank?.barColor ?? 0} 72 - onSave={(value) => { 73 - userStore.setState(deepMerge<User>(user, { extended: { rank: { barColor: Number(value) } } })); 74 - }} 75 - /> 76 - </div> 77 - </div> 78 - </div> 79 - 80 - <InputImageUrl 81 - label="Background" 82 - url="/users/@me/rank" 83 - ratio="aspect-4/1" 84 - dataName="background" 85 - description="Enter a url which should be the background of your /rank card. The recommended resolution is 906x256px." 86 - defaultState={user?.extended?.rank?.background || ""} 87 - onSave={(value) => { 88 - userStore.setState(deepMerge<User>(user, { extended: { rank: { background: value } } })); 89 - }} 90 - /> 18 + return (<> 19 + <div className="lg:flex gap-3"> 20 + <div className="lg:w-1/2"> 21 + <InputSelect 22 + label="Secondary text" 23 + endpoint="/users/@me/rank" 24 + k="subText.type" 25 + description="This text will be displayed bellow the /rank progressbar." 26 + items={[ 27 + { 28 + name: "None", 29 + value: 0 30 + }, 31 + { 32 + name: "ETA to next milestone reach date", 33 + value: 1 34 + }, 35 + { 36 + name: "ETA to next milestone reach relative date", 37 + value: 2 38 + }, 39 + { 40 + name: "Custom text", 41 + value: 3, 42 + error: "Not done yet" 43 + } 44 + ]} 45 + defaultState={user?.extended?.rank?.subText?.type} 46 + onSave={(value) => { 47 + userStore.setState(deepMerge<User>(user, { extended: { rank: { subText: { type: Number(value) as 0 | 1 | 2 | 3 } } } })); 48 + }} 49 + /> 50 + </div> 51 + 52 + <div className="lg:w-1/2 flex gap-2 w-full"> 53 + <div className="w-1/2"> 54 + <InputColor 55 + label="Text color" 56 + endpoint="/users/@me/rank" 57 + k="textColor" 58 + description="Color used for your username." 59 + defaultState={user?.extended?.rank?.textColor ?? 0} 60 + onSave={(value) => { 61 + userStore.setState(deepMerge<User>(user, { extended: { rank: { textColor: Number(value) } } })); 62 + }} 63 + /> 64 + </div> 65 + <div className="w-1/2"> 66 + <InputColor 67 + label="Bar color" 68 + endpoint="/users/@me/rank" 69 + k="barColor" 70 + description="Color used for the progress bar." 71 + defaultState={user?.extended?.rank?.barColor ?? 0} 72 + onSave={(value) => { 73 + userStore.setState(deepMerge<User>(user, { extended: { rank: { barColor: Number(value) } } })); 74 + }} 75 + /> 76 + </div> 77 + </div> 78 + </div> 79 + 80 + <InputImageUrl 81 + label="Background" 82 + endpoint="/users/@me/rank" 83 + ratio="aspect-4/1" 84 + k="background" 85 + description="Enter a url which should be the background of your /rank card. The recommended resolution is 906x256px." 86 + defaultState={user?.extended?.rank?.background || ""} 87 + onSave={(value) => { 88 + userStore.setState(deepMerge<User>(user, { extended: { rank: { background: value } } })); 89 + }} 90 + /> 91 91 92 92 <Section 93 93 title="/leaderboard style"
+2 -2
app/profile/text-to-speech/page.tsx
··· 20 20 <div className="lg:w-1/2"> 21 21 <InputSelect 22 22 label="Default Speaker" 23 - url="/users/@me/text-to-speech" 24 - dataName="voice" 23 + endpoint="/users/@me/text-to-speech" 24 + k="voice" 25 25 description="This is the default voice for any text to speech conversion." 26 26 items={voices.map((voice) => ({ 27 27 name: getVoices(voice)[0],
+8 -8
components/embed-creator.tsx
··· 22 22 children?: React.ReactNode; 23 23 24 24 name: string; 25 - url: string; 26 - dataName: string; 25 + endpoint: string; 26 + k: string; 27 27 28 28 defaultMessage?: { content?: string | null; embed?: GuildEmbed; }; 29 29 isCollapseable?: boolean; ··· 45 45 children, 46 46 47 47 name, 48 - url, 49 - dataName, 48 + endpoint, 49 + k, 50 50 51 51 defaultMessage, 52 52 isCollapseable, ··· 113 113 114 114 if (!body.embed.footer.text) body.embed.footer = { text: null }; 115 115 116 - const res = await fetch(`${process.env.NEXT_PUBLIC_API}${url}`, { 116 + const res = await fetch(`${process.env.NEXT_PUBLIC_API}${endpoint}`, { 117 117 method: "PATCH", 118 118 credentials: "include", 119 119 headers: { 120 120 "Content-Type": "application/json" 121 121 }, 122 - body: JSON.stringify(dataName.includes(".") 123 - ? { [dataName.split(".")[0]]: { [dataName.split(".")[1]]: body } } 124 - : { [dataName]: body } 122 + body: JSON.stringify(k.includes(".") 123 + ? { [k.split(".")[0]]: { [k.split(".")[1]]: body } } 124 + : { [k]: body } 125 125 ) 126 126 }) 127 127 .then((r) => r.json())
+1 -6
components/inputs/color-input.tsx
··· 21 21 className, 22 22 23 23 label, 24 - name, // @deprecated using label 25 24 link, 26 25 badge, 27 26 description, ··· 30 29 placeholder, 31 30 32 31 endpoint, 33 - url, // @deprecated - use endpoint instead 34 32 k, 35 - dataName, // @deprecated - use k instead 36 33 37 34 defaultState, 38 35 transform, ··· 47 44 reset 48 45 } = useInput({ 49 46 endpoint, 50 - url, 51 47 k, 52 - dataName, 53 48 54 49 defaultState, 55 50 transform: transform ?? ((v) => v || 0x00_00_00), ··· 69 64 <div className={cn("relative w-full", description && "mb-2", className)}> 70 65 <div className="flex items-center gap-2 mb-1"> 71 66 <span className="sm:text-lg font-medium text-neutral-100"> 72 - {label || name} 67 + {label} 73 68 </span> 74 69 75 70 {badge && (
+1 -5
components/inputs/image-url-input.tsx
··· 33 33 ratio = "aspect-[906/256]", 34 34 35 35 endpoint, 36 - url, // @deprecated - use endpoint instead 37 36 k, 38 - dataName, // @deprecated - use k instead 39 37 40 38 defaultState, 41 39 transform, ··· 50 48 save 51 49 } = useInput({ 52 50 endpoint, 53 - url, 54 51 k, 55 - dataName, 56 52 57 53 defaultState, 58 54 transform: transform ?? ((v) => v || null), 59 55 60 56 onSave, 61 - manual: true // Only save when image loads successfully 57 + manual: true 62 58 }); 63 59 64 60 const [imageState, setImageState] = useState<ImageState>(ImageState.Idle);
+2 -7
components/inputs/multi-select-menu.tsx
··· 34 34 className, 35 35 36 36 label, 37 - name, // @deprecated - use label instead 38 37 link, 39 38 badge, 40 39 description, ··· 43 42 max = Infinity, 44 43 45 44 endpoint, 46 - url, // @deprecated - use endpoint instead 47 45 k, 48 - dataName, // @deprecated - use k instead 49 46 50 47 defaultState, 51 48 transform, ··· 61 58 save 62 59 } = useInput({ 63 60 endpoint, 64 - url, 65 61 k, 66 - dataName, 67 62 68 63 defaultState, 69 64 transform, 70 65 71 66 onSave, 72 - manual: true, // Save only when menu closes or after debounce 67 + manual: true, 73 68 isEqual: (a, b) => { 74 69 if (a === b) return true; 75 70 if (a.length !== b.length) return false; ··· 155 150 <div className={cn("select-none w-full max-w-full relative", description && "mb-2", className)}> 156 151 <div className="flex items-center gap-2 mb-1"> 157 152 <span className="sm:text-lg font-medium text-neutral-100"> 158 - {label || name} 153 + {label} 159 154 </span> 160 155 161 156 {badge && (
+1 -5
components/inputs/number-input.tsx
··· 31 31 max = Infinity, 32 32 33 33 endpoint, 34 - url, // @deprecated - use endpoint instead 35 34 k, 36 - dataName, // @deprecated - use k instead 37 35 38 36 defaultState, 39 37 transform, ··· 49 47 save 50 48 } = useInput({ 51 49 endpoint, 52 - url, 53 50 k, 54 - dataName, 55 51 56 52 defaultState, 57 53 transform, 58 54 59 55 onSave, 60 - manual: true // Require explicit save 56 + manual: true 61 57 }); 62 58 63 59 const [hold, setHold] = useState<"+" | "-">();
+1 -6
components/inputs/select-menu.tsx
··· 33 33 className, 34 34 35 35 label, 36 - name, // @deprecated - use label instead 37 36 link, 38 37 badge, 39 38 description, ··· 42 41 showClear, 43 42 44 43 endpoint, 45 - url, // @deprecated - use endpoint instead 46 44 k, 47 - dataName, // @deprecated - use k instead 48 45 49 46 defaultState, 50 47 transform, ··· 58 55 update 59 56 } = useInput({ 60 57 endpoint, 61 - url, 62 58 k, 63 - dataName, 64 59 65 60 defaultState: defaultState ?? null, 66 61 transform, ··· 87 82 <div className={cn("select-none w-full max-w-full relative", description && "mb-2", className)}> 88 83 <div className="flex items-center gap-2 mb-1"> 89 84 <span className="sm:text-lg font-medium text-neutral-100"> 90 - {label || name} 85 + {label} 91 86 </span> 92 87 93 88 {badge && (
-4
components/inputs/text-input.tsx
··· 32 32 resetState, 33 33 34 34 endpoint, 35 - url, // @deprecated - use endpoint instead 36 35 k, 37 - dataName, // @deprecated - use k instead 38 36 39 37 defaultState, 40 38 transform, ··· 49 47 reset 50 48 } = useInput({ 51 49 endpoint, 52 - url, 53 50 k, 54 - dataName, 55 51 56 52 defaultState, 57 53 transform,
+2 -8
utils/input.ts
··· 10 10 11 11 interface InputOptions<T> { 12 12 endpoint?: string; 13 - /** @deprecated Use `endpoint` instead. Kept for backward compatibility. */ 14 - url?: string; 15 13 k?: string; 16 - /** @deprecated Use `k` instead. Kept for backward compatibility. */ 17 - dataName?: string; 18 14 19 15 defaultState: T; 20 16 transform?: (value: T) => unknown; ··· 28 24 } 29 25 30 26 export type InputProps<T> = InputOptions<T> & HTMLProps<HTMLDivElement> & { 31 - label?: string; 27 + label: string; 32 28 description?: string; 33 29 disabled?: boolean; 34 30 }; ··· 41 37 const timeout = useRef<NodeJS.Timeout | null>(null); 42 38 const debounceRef = useRef<NodeJS.Timeout | null>(null); 43 39 44 - const endpoint = options.endpoint || options.url; 45 - const k = options.k || options.dataName; 46 - const { onSave, transform, manual, debounceMs, defaultState, isEqual } = options; 40 + const { endpoint, k, onSave, transform, manual, debounceMs, defaultState, isEqual } = options; 47 41 48 42 const defaultStateKey = JSON.stringify(defaultState); 49 43 const [prevDefaultStateKey, setPrevDefaultStateKey] = useState(defaultStateKey);