From 81507afbcc3f3faf3225757a67eac061e26193ed Mon Sep 17 00:00:00 2001 From: Mattrixwv Date: Fri, 21 Mar 2025 20:10:15 -0400 Subject: [PATCH] Updated input validation --- src/components/game/GameSelector.tsx | 8 +- src/pages/protected/GamePage.tsx | 21 ++-- src/pages/protected/GamesPage.tsx | 13 +- src/pages/protected/RaidGroupPage.tsx | 21 ++-- src/pages/protected/RaidGroupsPage.tsx | 13 +- src/pages/protected/RaidInstancePage.tsx | 21 ++-- src/ui/account/AccountsList.tsx | 12 +- src/ui/account/modals/AccountModal.tsx | 46 ++++++- .../modals/AccountPasswordResetModal.tsx | 9 ++ .../AccountRaidGroupPermissionsModal.tsx | 10 ++ src/ui/calendar/modals/CalendarEventModal.tsx | 32 +++++ src/ui/classGroup/modal/ClassGroupModal.tsx | 20 +++ src/ui/game/AllGamesDisplay.tsx | 3 +- src/ui/game/modals/GameModal.tsx | 36 +++++- src/ui/gameClass/modals/GameClassModal.tsx | 32 ++++- src/ui/person/modals/PersonModal.tsx | 36 +++++- .../modal/PersonCharacterModal.tsx | 30 +++++ src/ui/raidGroup/RaidGroupCreateAndSearch.tsx | 3 +- src/ui/raidGroup/RaidGroupsList.tsx | 4 +- src/ui/raidGroup/modals/RaidGroupModal.tsx | 21 ++++ .../modal/RaidGroupRequestModal.tsx | 28 +++++ .../raidInstance/modals/RaidInstanceModal.tsx | 117 ++++++++++++++---- src/ui/raidLayout/modal/RaidLayoutModal.tsx | 42 ++++++- src/util/PermissionUtil.ts | 44 +++---- 24 files changed, 510 insertions(+), 112 deletions(-) diff --git a/src/components/game/GameSelector.tsx b/src/components/game/GameSelector.tsx index 31869e9..ccb86c8 100644 --- a/src/components/game/GameSelector.tsx +++ b/src/components/game/GameSelector.tsx @@ -24,9 +24,9 @@ export default function GameSelector({ const gameSearchQuery = useGetGames(0, 5, gameSearch); const games = gameSearchQuery.data; - const setGame = (selectedGame: Game) => { - setSearchTerm(selectedGame.gameName ?? ""); - setGameSearch(selectedGame.gameName ?? ""); + const setGame = (selectedGame?: Game) => { + setSearchTerm(selectedGame?.gameName ?? ""); + setGameSearch(selectedGame?.gameName ?? ""); setSearching(false); onChange?.(selectedGame); } @@ -49,7 +49,7 @@ export default function GameSelector({ { setSearchTerm(e.target.value); setSearching(true); }} + onChange={(e) => { setSearchTerm(e.target.value); onChange?.(undefined); setSearching(true); }} value={searchTerm} disabled={disabled} /> diff --git a/src/pages/protected/GamePage.tsx b/src/pages/protected/GamePage.tsx index b3e56c1..fbb6aa0 100644 --- a/src/pages/protected/GamePage.tsx +++ b/src/pages/protected/GamePage.tsx @@ -81,15 +81,18 @@ export default function GamePage(){ className="flex flex-col items-center justify-center" > {/* Tutorials */} - + { + tutorialsStatus.gameTutorialStatus === TutorialStatus.NOT_COMPLETED && + + } diff --git a/src/pages/protected/GamesPage.tsx b/src/pages/protected/GamesPage.tsx index baf1851..eaab11e 100644 --- a/src/pages/protected/GamesPage.tsx +++ b/src/pages/protected/GamesPage.tsx @@ -25,11 +25,14 @@ export default function GamesPage(){
- + { + tutorialsStatus.gamesTutorialStatus === TutorialStatus.NOT_COMPLETED && + + }

diff --git a/src/pages/protected/RaidGroupPage.tsx b/src/pages/protected/RaidGroupPage.tsx index 5843f53..ff9e299 100644 --- a/src/pages/protected/RaidGroupPage.tsx +++ b/src/pages/protected/RaidGroupPage.tsx @@ -109,15 +109,18 @@ export default function RaidGroupPage(){
- + { + tutorialsStatus.raidGroupTutorialStatus === TutorialStatus.NOT_COMPLETED && + + } diff --git a/src/pages/protected/RaidGroupsPage.tsx b/src/pages/protected/RaidGroupsPage.tsx index b978012..e8f9a39 100644 --- a/src/pages/protected/RaidGroupsPage.tsx +++ b/src/pages/protected/RaidGroupsPage.tsx @@ -25,11 +25,14 @@ export default function RaidGroupsPage(){
- + { + tutorialsStatus.raidGroupsTutorialStatus === TutorialStatus.NOT_COMPLETED && + + }

diff --git a/src/pages/protected/RaidInstancePage.tsx b/src/pages/protected/RaidInstancePage.tsx index fbe7acb..9ed7d37 100644 --- a/src/pages/protected/RaidInstancePage.tsx +++ b/src/pages/protected/RaidInstancePage.tsx @@ -35,15 +35,18 @@ export default function RaidInstancePage(){
- + { + tutorialsStatus.instanceTutorialStatus === TutorialStatus.NOT_COMPLETED && + + } {/* Back to Raid Group Button */}
(undefined); const [ displayForcePasswordResetModal, setDisplayForcePasswordResetModal ] = useState(false); const [ displayAccountPasswordSetModal, setDisplayAccountPasswordSetModal ] = useState(false); @@ -53,6 +53,10 @@ export default function AccountsList({
Login Date
, + raidGroup && isRaidGroupAdmin(raidGroup?.raidGroupId ?? "", raidGroupPermissions ?? [], accountPermissions) && +
+ Raid Group Permission +
,
Status
, @@ -78,6 +82,10 @@ export default function AccountsList({ > {account.loginDate ? moment(account.loginDate).format("MM-DD-YYYY hh:mm a") : <> }
, + raidGroup && isRaidGroupAdmin(raidGroup?.raidGroupId ?? "", raidGroupPermissions ?? [], accountPermissions) && +
+ {raidGroupPermissions.find((perm) => (perm.raidGroupId === raidGroup?.raidGroupId))?.permission} +
,
{account.accountStatus}
, diff --git a/src/ui/account/modals/AccountModal.tsx b/src/ui/account/modals/AccountModal.tsx index 0995ef0..11563b9 100644 --- a/src/ui/account/modals/AccountModal.tsx +++ b/src/ui/account/modals/AccountModal.tsx @@ -63,12 +63,50 @@ export default function AccountModal({ }); - const updateAccount = () => { - updateAccountMutate.mutate({accountId: account?.accountId, username, email, password, accountStatus} as Account); + const createAccount = () => { + if(!username || username.trim().length <= 0){ + addErrorMessage("Error creating account: Username must contain at least 1 letter"); + return; + } + else if(!email || email.trim().length <= 0){ + addErrorMessage("Error creating account: Email must contain at least 1 letter"); + return; + } + else if(!password || password.trim().length <= 0){ + addErrorMessage("Error creating account: Password must contain at least 1 letter"); + return; + } + + + createAccountMutate.mutate({ + username, + email, + password, + accountStatus + } as Account); } - const createAccount = () => { - createAccountMutate.mutate({username, email, password, accountStatus} as Account); + const updateAccount = () => { + if(!account?.accountId || account?.accountId.trim() === ""){ + addErrorMessage("Account ID is required"); + return; + } + else if(!username || username.trim().length <= 0){ + addErrorMessage("Error creating account: Username must contain at least 1 letter"); + return; + } + else if(!email || email.trim().length <= 0){ + addErrorMessage("Error creating account: Email must contain at least 1 letter"); + return; + } + + + updateAccountMutate.mutate({ + accountId: account?.accountId, + username, + email, + accountStatus + } as Account); } diff --git a/src/ui/account/modals/AccountPasswordResetModal.tsx b/src/ui/account/modals/AccountPasswordResetModal.tsx index e1654fa..df3f642 100644 --- a/src/ui/account/modals/AccountPasswordResetModal.tsx +++ b/src/ui/account/modals/AccountPasswordResetModal.tsx @@ -26,6 +26,15 @@ export default function AccountPasswordRestModal({ const resetPassword = () => { + if(!account?.accountId || account.accountId.trim().length <= 0){ + addErrorMessage("Error resetting password: Account ID not found"); + return; + } + else if(!newPassword || newPassword.trim().length <= 0){ + addErrorMessage("Error resetting password: Password must contain at least 1 letter"); + return; + } + passwordResetMutate.mutate(newPassword); } diff --git a/src/ui/account/modals/AccountRaidGroupPermissionsModal.tsx b/src/ui/account/modals/AccountRaidGroupPermissionsModal.tsx index 91c38e7..0ec9d45 100644 --- a/src/ui/account/modals/AccountRaidGroupPermissionsModal.tsx +++ b/src/ui/account/modals/AccountRaidGroupPermissionsModal.tsx @@ -50,6 +50,16 @@ export default function AccountRaidGroupPermissionsModal({ const updateRaidGroupPermissions = () => { + if(!raidGroup?.raidGroupId || !account?.accountId){ + addErrorMessage("Error updating raid group permissions: Raid group and account are required"); + return; + } + if(!currentPermission){ + addErrorMessage("Error updating raid group permissions: Permission is required"); + return; + } + + raidGroupPermissionsMutate.mutate(currentPermission ?? RaidGroupPermissionType.RAIDER); } diff --git a/src/ui/calendar/modals/CalendarEventModal.tsx b/src/ui/calendar/modals/CalendarEventModal.tsx index 6252236..19c955c 100644 --- a/src/ui/calendar/modals/CalendarEventModal.tsx +++ b/src/ui/calendar/modals/CalendarEventModal.tsx @@ -74,14 +74,46 @@ export default function CalendarEventModal({ }); const createCalendarEvent = () => { + if(!eventName || eventName.trim().length <= 0){ + addErrorMessage("Event name is required"); + return; + } + else if(!eventStartDate || !eventEndDate){ + addErrorMessage("Event start and end dates are required"); + return; + } + else if(eventStartDate > eventEndDate){ + addErrorMessage("Event start date must be before end date"); + return; + } createCalendarEventMutate.mutate({eventName, eventDescription, eventStartDate, eventEndDate}); } const updateCalendarEvent = () => { + if(!calendarEvent?.calendarEventId){ + addErrorMessage("Calendar event ID is required"); + return; + } + else if(!eventName || eventName.trim().length <= 0){ + addErrorMessage("Event name is required"); + return; + } + else if(!eventStartDate || !eventEndDate){ + addErrorMessage("Event start and end dates are required"); + return; + } + else if(eventStartDate > eventEndDate){ + addErrorMessage("Event start date must be before end date"); + return; + } updateCalendarEventMutate.mutate({calendarEventId: calendarEvent?.calendarEventId, eventName, eventDescription, eventStartDate, eventEndDate}); } const deleteCalendarEvent = () => { + if(!calendarEvent?.calendarEventId){ + addErrorMessage("Calendar event ID is required"); + return; + } deleteCalendarEventMutate.mutate(calendarEvent as CalendarEvent); } diff --git a/src/ui/classGroup/modal/ClassGroupModal.tsx b/src/ui/classGroup/modal/ClassGroupModal.tsx index 51076fd..605be4f 100644 --- a/src/ui/classGroup/modal/ClassGroupModal.tsx +++ b/src/ui/classGroup/modal/ClassGroupModal.tsx @@ -65,10 +65,30 @@ export default function ClassGroupModal({ const createClassGroup = () => { + if(!classGroupName || classGroupName.trim().length <= 0){ + addErrorMessage("Class Group name is required"); + return; + } + else if(!raidGroup.raidGroupId || raidGroup.raidGroupId.trim().length <= 0){ + addErrorMessage("Raid group ID is required"); + return; + } createClassGroupMutate.mutate({ classGroupName, gameClassIds: selectedGameClassIds }); } const updateClassGroup = () => { + if(!classGroup?.classGroupId || classGroup.classGroupId.trim().length <= 0){ + addErrorMessage("Class Group ID is required"); + return; + } + else if(!classGroupName || classGroupName.trim().length <= 0){ + addErrorMessage("Class Group name is required"); + return; + } + else if(!raidGroup.raidGroupId || raidGroup.raidGroupId.trim().length <= 0){ + addErrorMessage("Raid group ID is required"); + return; + } updateClassGroupMutate.mutate({ classGroup: { classGroupId: classGroup?.classGroupId, diff --git a/src/ui/game/AllGamesDisplay.tsx b/src/ui/game/AllGamesDisplay.tsx index 60b888a..041bc31 100644 --- a/src/ui/game/AllGamesDisplay.tsx +++ b/src/ui/game/AllGamesDisplay.tsx @@ -43,7 +43,7 @@ export default function AllGamesDisplay(){ return ( <>
setDisplayCreateGameModal(true)} disabled={!isSiteAdmin(accountPermissions)} > diff --git a/src/ui/game/modals/GameModal.tsx b/src/ui/game/modals/GameModal.tsx index 2e0e0c3..dca54fa 100644 --- a/src/ui/game/modals/GameModal.tsx +++ b/src/ui/game/modals/GameModal.tsx @@ -59,12 +59,40 @@ export default function GameModal({ }, [ updateGameMutate, createGameMutate, gameName, close, addSuccessMessage, addErrorMessage ]); - const updateGame = () => { - updateGameMutate.mutate({game: {gameId: game?.gameId, gameName, gameIcon} as Game, iconFile}); + const createGame = () => { + if(!gameName || gameName.trim().length <= 0){ + addErrorMessage("Error updating game: Game name must contain at least 1 letter"); + return; + } + else if(iconFile && !iconFile.type.startsWith("image/")){ + addErrorMessage("Error updating game: Icon must be an image"); + return; + } + else if(iconFile && iconFile.size > 10485760){ + addErrorMessage("Error updating game: Icon must be less than 10MB"); + return; + } + createGameMutate.mutate({gameName: gameName ?? "", iconFile}); } - const createGame = () => { - createGameMutate.mutate({gameName: gameName ?? "", iconFile}); + const updateGame = () => { + if(!game?.gameId || game.gameId.trim().length <= 0){ + addErrorMessage("Error updating game: Game ID not found"); + return; + } + else if(!gameName || gameName.trim().length <= 0){ + addErrorMessage("Error updating game: Game name must contain at least 1 letter"); + return; + } + else if(iconFile && !iconFile.type.startsWith("image/")){ + addErrorMessage("Error updating game: Icon must be an image"); + return; + } + else if(iconFile && iconFile.size > 10485760){ + addErrorMessage("Error updating game: Icon must be less than 10MB"); + return; + } + updateGameMutate.mutate({game: {gameId: game?.gameId, gameName, gameIcon} as Game, iconFile}); } diff --git a/src/ui/gameClass/modals/GameClassModal.tsx b/src/ui/gameClass/modals/GameClassModal.tsx index 11aeb97..5a60290 100644 --- a/src/ui/gameClass/modals/GameClassModal.tsx +++ b/src/ui/gameClass/modals/GameClassModal.tsx @@ -62,12 +62,36 @@ export default function GameClassModal({ }, [ updateGameClassMutate, createGameClassMutate, gameClassName, close, addSuccessMessage, addErrorMessage ]); - const updateGameClass = () => { - updateGameClassMutate.mutate({ gameClass: {gameClassId: gameClass?.gameClassId, gameId, gameClassName, gameClassIcon}, iconFile}); + const createGameClass = () => { + if(!gameClassName || gameClassName.trim().length <= 0){ + addErrorMessage("Game class name is required"); + return; + } + else if(iconFile && !iconFile.type.startsWith("image/")){ + addErrorMessage("Error creating game class: Icon must be an image"); + } + else if(iconFile && iconFile.size > 10485760){ + addErrorMessage("Error creating game class: Icon must be less than 10MB"); + } + createGameClassMutate.mutate({ gameId, gameClassName, iconFile}); } - const createGameClass = () => { - createGameClassMutate.mutate({ gameId, gameClassName, iconFile}); + const updateGameClass = () => { + if(!gameClass?.gameClassId || gameClass.gameClassId.trim().length <= 0){ + addErrorMessage("Error updating game class: Game class ID not found"); + return; + } + else if(!gameClassName || gameClassName.trim().length <= 0){ + addErrorMessage("Game class name is required"); + return; + } + else if(iconFile && !iconFile.type.startsWith("image/")){ + addErrorMessage("Error creating game class: Icon must be an image"); + } + else if(iconFile && iconFile.size > 10485760){ + addErrorMessage("Error creating game class: Icon must be less than 10MB"); + } + updateGameClassMutate.mutate({ gameClass: {gameClassId: gameClass?.gameClassId, gameId, gameClassName, gameClassIcon}, iconFile}); } diff --git a/src/ui/person/modals/PersonModal.tsx b/src/ui/person/modals/PersonModal.tsx index 7539440..8cff730 100644 --- a/src/ui/person/modals/PersonModal.tsx +++ b/src/ui/person/modals/PersonModal.tsx @@ -59,12 +59,40 @@ export default function PersonModal({ }); - const updatePerson = () => { - updatePersonMutate.mutate({raidGroupId, personId: person?.personId, personName, discordId} as Person); + const createPerson = () => { + if(!personName || personName.trim().length <= 0){ + addErrorMessage("Person name is required"); + return; + } + else if(!raidGroupId || raidGroupId.trim().length <= 0){ + addErrorMessage("Raid group ID is required"); + return; + } + else if(discordId && discordId.trim().length <= 0){ + addErrorMessage("Discord ID must be a valid length"); + return; + } + createPersonMutate.mutate({raidGroupId, personName, discordId} as Person); } - const createPerson = () => { - createPersonMutate.mutate({raidGroupId, personName, discordId} as Person); + const updatePerson = () => { + if(!person?.personId || person.personId.trim().length <= 0){ + addErrorMessage("Person ID not found"); + return; + } + else if(!personName || personName.trim().length <= 0){ + addErrorMessage("Person name is required"); + return; + } + else if(!raidGroupId || raidGroupId.trim().length <= 0){ + addErrorMessage("Raid group ID is required"); + return; + } + else if(discordId && discordId.trim().length <= 0){ + addErrorMessage("Discord ID must be a valid length"); + return; + } + updatePersonMutate.mutate({raidGroupId, personId: person?.personId, personName, discordId} as Person); } diff --git a/src/ui/personCharacter/modal/PersonCharacterModal.tsx b/src/ui/personCharacter/modal/PersonCharacterModal.tsx index e145e91..342a84b 100644 --- a/src/ui/personCharacter/modal/PersonCharacterModal.tsx +++ b/src/ui/personCharacter/modal/PersonCharacterModal.tsx @@ -70,10 +70,40 @@ export default function PersonCharacterModal({ const createPersonCharacter = () => { + if(!personId || personId.trim().length <= 0){ + addErrorMessage("Person ID not found"); + return; + } + else if(!characterName || characterName.trim().length <= 0){ + addErrorMessage("Character name is required"); + return; + } + else if(!gameClassId || gameClassId.trim().length <= 0){ + addErrorMessage("Game class is required"); + return; + } + createPersonCharacterMutate.mutate({personId, characterName, gameClassId, characterRating, characterComments} as PersonCharacter); } const updatePersonCharacter = () => { + if(!personCharacter || !personCharacter.personCharacterId || personCharacter.personCharacterId.trim().length <= 0){ + addErrorMessage("Character ID not found"); + return; + } + else if(!personId || personId.trim().length <= 0){ + addErrorMessage("Person ID not found"); + return; + } + else if(!characterName || characterName.trim().length <= 0){ + addErrorMessage("Character name is required"); + return; + } + else if(!gameClassId || gameClassId.trim().length <= 0){ + addErrorMessage("Game class is required"); + return; + } + updatePersonCharacterMutate.mutate({personCharacterId: personCharacter?.personCharacterId, personId, characterName, gameClassId, characterRating, characterComments} as PersonCharacter); } diff --git a/src/ui/raidGroup/RaidGroupCreateAndSearch.tsx b/src/ui/raidGroup/RaidGroupCreateAndSearch.tsx index 3b73050..2a4145d 100644 --- a/src/ui/raidGroup/RaidGroupCreateAndSearch.tsx +++ b/src/ui/raidGroup/RaidGroupCreateAndSearch.tsx @@ -17,7 +17,7 @@ export default function RaidGroupCreateAndSearch({ return (
setDisplayRaidGroupModal(true)} > Create Raid Group diff --git a/src/ui/raidGroup/RaidGroupsList.tsx b/src/ui/raidGroup/RaidGroupsList.tsx index 88a4307..22ba5b3 100644 --- a/src/ui/raidGroup/RaidGroupsList.tsx +++ b/src/ui/raidGroup/RaidGroupsList.tsx @@ -2,7 +2,7 @@ import { ButtonProps } from "@/components/button/Button"; import Table from "@/components/table/Table"; import { RaidGroup } from "@/interface/RaidGroup"; import { useAuth } from "@/providers/AuthProvider"; -import { containsRaidGroupPermission, containsRaidGroupRequest, isRaidGroupAdmin } from "@/util/PermissionUtil"; +import { containsRaidGroupRequest, isRaidGroupAdmin, isRaidGroupMember } from "@/util/PermissionUtil"; import { useState } from "react"; import { Link } from "react-router"; import RaidGroupRequestModal from "../raidGroupRequest/modal/RaidGroupRequestModal"; @@ -90,7 +90,7 @@ export default function RaidGroupsList({ setSelectedRaidGroup(raidGroup); setDisplayDeleteRaidGroupModal(true); }} - hasRaidGroupPermissions={containsRaidGroupPermission(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions)} + hasRaidGroupPermissions={isRaidGroupMember(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions)} hasRaidGroupRequest={containsRaidGroupRequest(raidGroup.raidGroupId ?? "", raidGroupRequests)} />
diff --git a/src/ui/raidGroup/modals/RaidGroupModal.tsx b/src/ui/raidGroup/modals/RaidGroupModal.tsx index 433bedd..67963e6 100644 --- a/src/ui/raidGroup/modals/RaidGroupModal.tsx +++ b/src/ui/raidGroup/modals/RaidGroupModal.tsx @@ -31,6 +31,7 @@ export default function RaidGroupModal({ useEffect(() => { setRaidGroupName(raidGroup?.raidGroupName ?? ""); setRaidGroupIcon(raidGroup?.raidGroupIcon ?? ""); + setGame(undefined); setIconFile(null); }, [ display, raidGroup, setRaidGroupName, setRaidGroupIcon ]); @@ -69,10 +70,30 @@ export default function RaidGroupModal({ const updateRaidGroup = () => { + if(!raidGroup?.raidGroupId || raidGroup.raidGroupId.trim().length <= 0){ + addErrorMessage("Raid group ID not found"); + return; + } + else if(!raidGroupName || raidGroupName.trim().length <= 0){ + addErrorMessage("Raid group name is required"); + return; + } + else if(!game){ + addErrorMessage("Game is required"); + return; + } updateRaidGroupMutate.mutate({raidGroup: {raidGroupId: raidGroup?.raidGroupId, raidGroupName, gameId: game?.gameId, raidGroupIcon} as RaidGroup, iconFile}); } const createRaidGroup = () => { + if(!raidGroupName || raidGroupName.trim().length <= 0){ + addErrorMessage("Raid group name is required"); + return; + } + else if(!game){ + addErrorMessage("Game is required"); + return; + } createRaidGroupMutate.mutate({raidGroupName: raidGroupName ?? "", gameId: game?.gameId ?? "", iconFile}); } diff --git a/src/ui/raidGroupRequest/modal/RaidGroupRequestModal.tsx b/src/ui/raidGroupRequest/modal/RaidGroupRequestModal.tsx index bd74fbe..d99f39e 100644 --- a/src/ui/raidGroupRequest/modal/RaidGroupRequestModal.tsx +++ b/src/ui/raidGroupRequest/modal/RaidGroupRequestModal.tsx @@ -65,10 +65,38 @@ export default function RaidGroupRequestModal({ const createRaidGroupRequest = () => { + if(raidGroupId.trim() === ""){ + addErrorMessage("Raid Group ID is required"); + return; + } + else if(!account?.accountId || account?.accountId.trim() === ""){ + addErrorMessage("Account ID is required"); + return; + } + + createRaidGroupRequestMutate.mutate(requestMessage); } const resolveRaidGroupRequest = () => { + if(!raidGroupRequest?.raidGroupRequestId || raidGroupRequest?.raidGroupRequestId.trim() === ""){ + addErrorMessage("Raid Group Request ID is required"); + return; + } + else if(raidGroupId.trim() === ""){ + addErrorMessage("Raid Group ID is required"); + return; + } + else if(!account?.accountId || account?.accountId.trim() === ""){ + addErrorMessage("Account ID is required"); + return; + } + else if(!currentPermission || currentPermission.trim() === ""){ + addErrorMessage("Permission is required"); + return; + } + + resolveRaidGroupRequestMutate.mutate(currentPermission); } diff --git a/src/ui/raidInstance/modals/RaidInstanceModal.tsx b/src/ui/raidInstance/modals/RaidInstanceModal.tsx index c4bb618..9a5ece9 100644 --- a/src/ui/raidInstance/modals/RaidInstanceModal.tsx +++ b/src/ui/raidInstance/modals/RaidInstanceModal.tsx @@ -1,6 +1,7 @@ import PrimaryButton from "@/components/button/PrimaryButton"; import SecondaryButton from "@/components/button/SecondaryButton"; import DateInput from "@/components/input/DateInput"; +import NumberInput from "@/components/input/NumberInput"; import TextInput from "@/components/input/TextInput"; import RaidBuilderModal from "@/components/modal/RaidBuilderModal"; import { useCreateRaidInstance, useUpdateRaidInstance } from "@/hooks/RaidInstanceHooks"; @@ -77,26 +78,82 @@ export default function RaidInstanceModal({ }); const createRaidInstance = () => { + if(!raidInstanceName || raidInstanceName.trim().length <= 0){ + addErrorMessage("Error creating raid instance: Raid instance name must contain at least 1 letter"); + return; + } + else if(raidSize <= 0){ + addErrorMessage("Error creating raid instance: Raid size must be greater than 0"); + return; + } + else if(numberRuns <= 0){ + addErrorMessage("Error creating raid instance: Number of runs must be greater than 0"); + return; + } + else if(!raidGroup?.raidGroupId || raidGroup?.raidGroupId.trim() === ""){ + addErrorMessage("Error creating raid instance: Raid group is required"); + return; + } + else if(raidStartDate > raidEndDate){ + addErrorMessage("Error creating raid instance: Raid start date must be before raid end date"); + return; + } + else if(raidStartDate < new Date()){ + addErrorMessage("Error creating raid instance: Raid start date must be in the future"); + return; + } + + createRaidInstanceMutate.mutate({ - raidInstanceName, - raidStartDate, - raidEndDate, - raidSize, - numberRuns, - raidGroupId: raidGroup.raidGroupId ?? "" - }); + raidInstanceName, + raidStartDate, + raidEndDate, + raidSize, + numberRuns, + raidGroupId: raidGroup.raidGroupId ?? "" + }); } const updateRaidInstance = () => { + if(!raidInstance?.raidInstanceId || raidInstance?.raidInstanceId.trim() === ""){ + addErrorMessage("Raid Instance ID is required"); + return; + } + else if(!raidInstanceName || raidInstanceName.trim().length <= 0){ + addErrorMessage("Error creating raid instance: Raid instance name must contain at least 1 letter"); + return; + } + else if(raidSize <= 0){ + addErrorMessage("Error creating raid instance: Raid size must be greater than 0"); + return; + } + else if(numberRuns <= 0){ + addErrorMessage("Error creating raid instance: Number of runs must be greater than 0"); + return; + } + else if(!raidGroup?.raidGroupId || raidGroup?.raidGroupId.trim() === ""){ + addErrorMessage("Error creating raid instance: Raid group is required"); + return; + } + else if(raidStartDate > raidEndDate){ + addErrorMessage("Error creating raid instance: Raid start date must be before raid end date"); + return; + } + else if(raidStartDate < new Date()){ + addErrorMessage("Error creating raid instance: Raid start date must be in the future"); + return; + } + + updateRaidInstanceMutate.mutate({ - raidInstanceId: raidInstance?.raidInstanceId, - raidInstanceName, - raidStartDate, - raidEndDate, - raidSize, - numberRuns, - raidGroupId: raidGroup.raidGroupId ?? "" - }); + raidInstanceId: raidInstance?.raidInstanceId, + raidInstanceName, + raidStartDate, + raidEndDate, + raidSize, + numberRuns, + raidGroupId: raidGroup.raidGroupId ?? "" + }); } @@ -115,16 +172,26 @@ export default function RaidInstanceModal({ value={raidInstanceName} onChange={(e) => setRaidInstanceName(e.target.value)} /> -
- {/* - - */} +
+ + +
{ + if(!raidLayoutName || raidLayoutName.trim().length <= 0){ + addErrorMessage("Raid Layout Name is required"); + return; + } + else if(raidLayoutSize <= 0){ + addErrorMessage("Raid Layout Size must be greater than 0"); + return; + } + else if(!raidGroup?.raidGroupId || raidGroup?.raidGroupId.trim() === ""){ + addErrorMessage("Raid Group is required"); + return; + } + else if(raidLayoutSize !== classGroups.length){ + addErrorMessage("Raid Layout Size must match the number of class groups"); + return; + } + + createRaidLayoutMutate.mutate({ raidLayout: { raidLayoutName, @@ -87,7 +105,7 @@ export default function RaidLayoutModal({ raidGroupId: raidGroup.raidGroupId ?? "" }, raidLayoutClassGroupXrefs: classGroups.map((cg, index) => ({ - raidLayoutId: raidLayout?.raidLayoutId ?? "", + raidLayoutId: "", classGroupId: cg?.classGroupId, layoutLocation: index } as RaidLayoutClassGroupXref)) @@ -95,6 +113,28 @@ export default function RaidLayoutModal({ } const updateRaidLayout = () => { + if(!raidLayout?.raidLayoutId || raidLayout?.raidLayoutId.trim() === "") { + addErrorMessage("Raid Layout ID is required"); + return; + } + else if(!raidLayoutName || raidLayoutName.trim().length <= 0){ + addErrorMessage("Raid Layout Name is required"); + return; + } + else if(raidLayoutSize <= 0){ + addErrorMessage("Raid Layout Size must be greater than 0"); + return; + } + else if(!raidGroup?.raidGroupId || raidGroup?.raidGroupId.trim() === ""){ + addErrorMessage("Raid Group is required"); + return; + } + else if(raidLayoutSize !== classGroups.length){ + addErrorMessage("Raid Layout Size must match the number of class groups"); + return; + } + + updateRaidLayoutMutate.mutate({ raidLayout: { raidLayoutId: raidLayout?.raidLayoutId, diff --git a/src/util/PermissionUtil.ts b/src/util/PermissionUtil.ts index 3ce5f37..177043b 100644 --- a/src/util/PermissionUtil.ts +++ b/src/util/PermissionUtil.ts @@ -14,27 +14,6 @@ export function isSiteAdmin(accountPermissions: AccountPermission[]): boolean{ //! Raid Group -export function containsRaidGroupPermission(raidGroupId: string, permissions: RaidGroupPermission[], accountPermissions: AccountPermission[]): boolean{ - if(accountPermissions.find((permission) => permission.accountPermissionType === AccountPermissionType.ADMIN)){ - return true; - } - for(const permission of permissions){ - if(permission.raidGroupId === raidGroupId){ - return true; - } - } - return false; -} - -export function containsRaidGroupRequest(raidGroupId: string, requests: RaidGroupRequest[]): boolean{ - for(const request of requests){ - if(request.raidGroupId === raidGroupId){ - return true; - } - } - return false; -} - export function isRaidGroupAdmin(raidGroupId: string, permissions: RaidGroupPermission[], accountPermissions: AccountPermission[]): boolean{ if(accountPermissions.find((permission) => permission.accountPermissionType === AccountPermissionType.ADMIN)){ return true; @@ -51,6 +30,29 @@ export function isRaidGroupLeader(raidGroupId: string, permissions: RaidGroupPer return raidGroupPermission?.permission === RaidGroupPermissionType.LEADER; } +export function isRaidGroupMember(raidGroupId: string, permissions: RaidGroupPermission[], accountPermissions: AccountPermission[]): boolean{ + if(accountPermissions.find((permission) => permission.accountPermissionType === AccountPermissionType.ADMIN)){ + return true; + } + for(const permission of permissions){ + if(permission.raidGroupId === raidGroupId){ + return true; + } + } + return false; +} + + +//! Requests +export function containsRaidGroupRequest(raidGroupId: string, requests: RaidGroupRequest[]): boolean{ + for(const request of requests){ + if(request.raidGroupId === raidGroupId){ + return true; + } + } + return false; +} + //! Game