From f012983a7c2d574996bad8142a2709a7fa7e0cff Mon Sep 17 00:00:00 2001 From: ZRunner Date: Mon, 21 Oct 2024 19:25:13 +0200 Subject: [PATCH] feat(RoleReward): improve edition UI + allow reward creation --- .../XpCategory/AddRoleRewardButton.tsx | 56 +++++++++++++++++++ .../XpCategory/RoleRewardsList.tsx | 7 +-- .../XpCategory/XpCategoryComponent.tsx | 22 ++++++++ 3 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 src/components/GuildDashboard/SpecialCategoryComponents/XpCategory/AddRoleRewardButton.tsx diff --git a/src/components/GuildDashboard/SpecialCategoryComponents/XpCategory/AddRoleRewardButton.tsx b/src/components/GuildDashboard/SpecialCategoryComponents/XpCategory/AddRoleRewardButton.tsx new file mode 100644 index 0000000..e3c96c7 --- /dev/null +++ b/src/components/GuildDashboard/SpecialCategoryComponents/XpCategory/AddRoleRewardButton.tsx @@ -0,0 +1,56 @@ +import AddIcon from "@mui/icons-material/Add"; +import { Autocomplete, Stack, TextField } from "@mui/material"; + +import { useFetchGuildRolesQuery } from "../../../../repository/redux/api/api"; +import { GuildRole } from "../../../../repository/types/guild"; +import RoleMention from "../../../common/RoleMention"; + +interface AddRoleRewardButtonProps { + guildId: string, + existingRoleIds: string[], + addNewReward: (roleId: string) => void +} +export default function AddRoleRewardButton({ guildId, existingRoleIds, addNewReward }: AddRoleRewardButtonProps) { + const { data, error } = useFetchGuildRolesQuery({ guildId }); + + if (error) { + console.error("Failed to fetch roles", error); + } + if (!data) { + return null; + } + + const roles = data.filter(role => !role.managed && role.id !== guildId && !existingRoleIds.includes(role.id)); + + const onChange = (role: GuildRole | null) => { + if (role) { + addNewReward(role.id); + } + }; + + return ( + + + onChange(newValue)} + sx={{ width: 250 }} + isOptionEqualToValue={(opt, value) => opt.id === value.id} + getOptionLabel={(role) => role.name} + renderInput={(params) => ( + + )} + renderOption={(props, opt) => ( +
  • + +
  • + )} + /> +
    + ); +} \ No newline at end of file diff --git a/src/components/GuildDashboard/SpecialCategoryComponents/XpCategory/RoleRewardsList.tsx b/src/components/GuildDashboard/SpecialCategoryComponents/XpCategory/RoleRewardsList.tsx index f0a07a7..7c1b2d0 100644 --- a/src/components/GuildDashboard/SpecialCategoryComponents/XpCategory/RoleRewardsList.tsx +++ b/src/components/GuildDashboard/SpecialCategoryComponents/XpCategory/RoleRewardsList.tsx @@ -61,9 +61,7 @@ function RoleRewardRow({ roleReward, role, editRewardLevel, deleteReward }: Role return ( - - - given at level + {isEditing ? setIsEditing(false)} /> - : {roleReward.level} + : LVL {roleReward.level} } + {!isEditing && <> diff --git a/src/components/GuildDashboard/SpecialCategoryComponents/XpCategory/XpCategoryComponent.tsx b/src/components/GuildDashboard/SpecialCategoryComponents/XpCategory/XpCategoryComponent.tsx index e7acb89..4d76316 100644 --- a/src/components/GuildDashboard/SpecialCategoryComponents/XpCategory/XpCategoryComponent.tsx +++ b/src/components/GuildDashboard/SpecialCategoryComponents/XpCategory/XpCategoryComponent.tsx @@ -6,6 +6,7 @@ import { useFetchGuildConfigCategory } from "../../../../repository/commands/use import { useGuildConfigRoleRewardsEditionContext } from "../../../../repository/context/GuildConfigEditionContext"; import { useFetchGuildConfigQuery, useFetchGuildRoleRewardsQuery } from "../../../../repository/redux/api/api"; import { ExternalRoutesURLs } from "../../../../router/router"; +import AddRoleRewardButton from "./AddRoleRewardButton"; import DownloadLeaderboardButton from "./DownloadLeaderboardButton"; import RoleRewardsList from "./RoleRewardsList"; import UploadLeaderboardButton from "./UploadLeaderboardButton"; @@ -81,6 +82,7 @@ function RolesRewardsSection({ guildId }: { guildId: string }) { title = `Role Rewards (${roleRewards.length})`; } } + const canAddMoreRoles = maxRoles !== undefined && roleRewards !== undefined && roleRewards.length < maxRoles; const editRewardLevel = (roleRewardId: string, level: number) => { if (!roleRewards) return; @@ -102,6 +104,16 @@ function RolesRewardsSection({ guildId }: { guildId: string }) { } }; + const addRoleReward = (roleId: string) => { + if (!roleRewards) return; + const newRewards = [...roleRewards, { roleId, level: findNextUnusedLevel()?.toString(), id: roleId }]; + if (roleRewardsFromApi !== undefined && compareRoleRewards(newRewards, roleRewardsFromApi)) { + resetValue(); + } else { + setValue(newRewards); + } + }; + return ( @@ -111,6 +123,7 @@ function RolesRewardsSection({ guildId }: { guildId: string }) { Roles rewards are roles given to your members when they reach a certain level of XP. This is a great way to encourage your members to be active! [Read more] + {canAddMoreRoles && rr.roleId)} addNewReward={addRoleReward} />} ); @@ -121,6 +134,15 @@ function RolesRewardsSection({ guildId }: { guildId: string }) { if (b.some((rr => !a.find(rr2 => rr2.roleId === rr.roleId && rr2.level === rr.level)))) return false; return true; } + + function findNextUnusedLevel() { + for (let i = 1; i <= 100; i++) { + if (!roleRewards?.some(rr => rr.level === String(i))) { + return i; + } + } + return 1; + } } const Description = styled(Typography)(({ theme }) => ({