Updated input validation

This commit is contained in:
2025-03-21 20:10:15 -04:00
parent 031184b666
commit 81507afbcc
24 changed files with 510 additions and 112 deletions

View File

@@ -24,9 +24,9 @@ export default function GameSelector({
const gameSearchQuery = useGetGames(0, 5, gameSearch); const gameSearchQuery = useGetGames(0, 5, gameSearch);
const games = gameSearchQuery.data; const games = gameSearchQuery.data;
const setGame = (selectedGame: Game) => { const setGame = (selectedGame?: Game) => {
setSearchTerm(selectedGame.gameName ?? ""); setSearchTerm(selectedGame?.gameName ?? "");
setGameSearch(selectedGame.gameName ?? ""); setGameSearch(selectedGame?.gameName ?? "");
setSearching(false); setSearching(false);
onChange?.(selectedGame); onChange?.(selectedGame);
} }
@@ -49,7 +49,7 @@ export default function GameSelector({
<TextInput <TextInput
id={`gameSearchTextInput${modalId}`} id={`gameSearchTextInput${modalId}`}
placeholder="Game Search" placeholder="Game Search"
onChange={(e) => { setSearchTerm(e.target.value); setSearching(true); }} onChange={(e) => { setSearchTerm(e.target.value); onChange?.(undefined); setSearching(true); }}
value={searchTerm} value={searchTerm}
disabled={disabled} disabled={disabled}
/> />

View File

@@ -81,6 +81,8 @@ export default function GamePage(){
className="flex flex-col items-center justify-center" className="flex flex-col items-center justify-center"
> >
{/* Tutorials */} {/* Tutorials */}
{
tutorialsStatus.gameTutorialStatus === TutorialStatus.NOT_COMPLETED &&
<TutorialComponent <TutorialComponent
steps={gameTutorialSteps} steps={gameTutorialSteps}
run={tutorialsStatus.gameTutorialStatus === TutorialStatus.NOT_COMPLETED} run={tutorialsStatus.gameTutorialStatus === TutorialStatus.NOT_COMPLETED}
@@ -90,6 +92,7 @@ export default function GamePage(){
disableScrolling={true} disableScrolling={true}
updateFunction={updateGameTutorialStatus} updateFunction={updateGameTutorialStatus}
/> />
}
<GameHeader <GameHeader
game={game} game={game}
/> />

View File

@@ -25,11 +25,14 @@ export default function GamesPage(){
<main <main
className="flex flex-col items-center justify-center gap-y-8 w-full" className="flex flex-col items-center justify-center gap-y-8 w-full"
> >
{
tutorialsStatus.gamesTutorialStatus === TutorialStatus.NOT_COMPLETED &&
<TutorialComponent <TutorialComponent
steps={gamesTutorialSteps} steps={gamesTutorialSteps}
run={tutorialsStatus.gamesTutorialStatus === TutorialStatus.NOT_COMPLETED} run={tutorialsStatus.gamesTutorialStatus === TutorialStatus.NOT_COMPLETED}
updateFunction={updateGamesTutorialStatus} updateFunction={updateGamesTutorialStatus}
/> />
}
<h1 <h1
className="text-4xl" className="text-4xl"
> >

View File

@@ -109,6 +109,8 @@ export default function RaidGroupPage(){
<main <main
className="flex flex-col items-center justify-center gap-y-8" className="flex flex-col items-center justify-center gap-y-8"
> >
{
tutorialsStatus.raidGroupTutorialStatus === TutorialStatus.NOT_COMPLETED &&
<TutorialComponent <TutorialComponent
steps={raidGroupTutorialSteps} steps={raidGroupTutorialSteps}
run={tutorialsStatus.raidGroupTutorialStatus === TutorialStatus.NOT_COMPLETED} run={tutorialsStatus.raidGroupTutorialStatus === TutorialStatus.NOT_COMPLETED}
@@ -118,6 +120,7 @@ export default function RaidGroupPage(){
disableScrolling={true} disableScrolling={true}
updateFunction={updateRaidGroupTutorialStatus} updateFunction={updateRaidGroupTutorialStatus}
/> />
}
<RaidGroupHeader <RaidGroupHeader
raidGroup={raidGroup} raidGroup={raidGroup}
/> />

View File

@@ -25,11 +25,14 @@ export default function RaidGroupsPage(){
<main <main
className="flex flex-col items-center justify-center gap-8" className="flex flex-col items-center justify-center gap-8"
> >
{
tutorialsStatus.raidGroupsTutorialStatus === TutorialStatus.NOT_COMPLETED &&
<TutorialComponent <TutorialComponent
steps={raidGroupsTutorialSteps} steps={raidGroupsTutorialSteps}
run={tutorialsStatus.raidGroupsTutorialStatus === TutorialStatus.NOT_COMPLETED} run={tutorialsStatus.raidGroupsTutorialStatus === TutorialStatus.NOT_COMPLETED}
updateFunction={updateRaidGroupsTutorialStatus} updateFunction={updateRaidGroupsTutorialStatus}
/> />
}
<h1 <h1
className="text-4xl" className="text-4xl"
> >

View File

@@ -35,6 +35,8 @@ export default function RaidInstancePage(){
<main <main
className="flex flex-col items-center justify-center" className="flex flex-col items-center justify-center"
> >
{
tutorialsStatus.instanceTutorialStatus === TutorialStatus.NOT_COMPLETED &&
<TutorialComponent <TutorialComponent
steps={instanceTutorialSteps} steps={instanceTutorialSteps}
run={tutorialsStatus.instanceTutorialStatus === TutorialStatus.NOT_COMPLETED} run={tutorialsStatus.instanceTutorialStatus === TutorialStatus.NOT_COMPLETED}
@@ -44,6 +46,7 @@ export default function RaidInstancePage(){
disableScrolling={true} disableScrolling={true}
updateFunction={updateGamesTutorialStatus} updateFunction={updateGamesTutorialStatus}
/> />
}
{/* Back to Raid Group Button */} {/* Back to Raid Group Button */}
<div <div
className="flex flex-row items-center justify-start w-full my-8" className="flex flex-row items-center justify-start w-full my-8"

View File

@@ -3,7 +3,7 @@ import Table from "@/components/table/Table";
import { Account } from "@/interface/Account"; import { Account } from "@/interface/Account";
import { RaidGroup } from "@/interface/RaidGroup"; import { RaidGroup } from "@/interface/RaidGroup";
import { useAuth } from "@/providers/AuthProvider"; import { useAuth } from "@/providers/AuthProvider";
import { isSiteAdmin } from "@/util/PermissionUtil"; import { isRaidGroupAdmin, isSiteAdmin } from "@/util/PermissionUtil";
import moment from "moment"; import moment from "moment";
import { useState } from "react"; import { useState } from "react";
import AccountAdminButtons from "./AccountAdminButtons"; import AccountAdminButtons from "./AccountAdminButtons";
@@ -24,7 +24,7 @@ export default function AccountsList({
accounts: Account[]; accounts: Account[];
raidGroup?: RaidGroup; raidGroup?: RaidGroup;
}){ }){
const { accountPermissions } = useAuth(); const { raidGroupPermissions, accountPermissions } = useAuth();
const [ selectedAccount, setSelectedAccount ] = useState<Account | undefined>(undefined); const [ selectedAccount, setSelectedAccount ] = useState<Account | undefined>(undefined);
const [ displayForcePasswordResetModal, setDisplayForcePasswordResetModal ] = useState(false); const [ displayForcePasswordResetModal, setDisplayForcePasswordResetModal ] = useState(false);
const [ displayAccountPasswordSetModal, setDisplayAccountPasswordSetModal ] = useState(false); const [ displayAccountPasswordSetModal, setDisplayAccountPasswordSetModal ] = useState(false);
@@ -53,6 +53,10 @@ export default function AccountsList({
<div> <div>
Login Date Login Date
</div>, </div>,
raidGroup && isRaidGroupAdmin(raidGroup?.raidGroupId ?? "", raidGroupPermissions ?? [], accountPermissions) &&
<div>
Raid Group Permission
</div>,
<div> <div>
Status Status
</div>, </div>,
@@ -78,6 +82,10 @@ export default function AccountsList({
> >
{account.loginDate ? moment(account.loginDate).format("MM-DD-YYYY hh:mm a") : <>&nbsp;</>} {account.loginDate ? moment(account.loginDate).format("MM-DD-YYYY hh:mm a") : <>&nbsp;</>}
</div>, </div>,
raidGroup && isRaidGroupAdmin(raidGroup?.raidGroupId ?? "", raidGroupPermissions ?? [], accountPermissions) &&
<div>
{raidGroupPermissions.find((perm) => (perm.raidGroupId === raidGroup?.raidGroupId))?.permission}
</div>,
<div> <div>
{account.accountStatus} {account.accountStatus}
</div>, </div>,

View File

@@ -63,12 +63,50 @@ export default function AccountModal({
}); });
const updateAccount = () => { const createAccount = () => {
updateAccountMutate.mutate({accountId: account?.accountId, username, email, password, accountStatus} as Account); 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;
} }
const createAccount = () => {
createAccountMutate.mutate({username, email, password, accountStatus} as Account); 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);
} }

View File

@@ -26,6 +26,15 @@ export default function AccountPasswordRestModal({
const resetPassword = () => { 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); passwordResetMutate.mutate(newPassword);
} }

View File

@@ -50,6 +50,16 @@ export default function AccountRaidGroupPermissionsModal({
const updateRaidGroupPermissions = () => { 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); raidGroupPermissionsMutate.mutate(currentPermission ?? RaidGroupPermissionType.RAIDER);
} }

View File

@@ -74,14 +74,46 @@ export default function CalendarEventModal({
}); });
const createCalendarEvent = () => { 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}); createCalendarEventMutate.mutate({eventName, eventDescription, eventStartDate, eventEndDate});
} }
const updateCalendarEvent = () => { 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}); updateCalendarEventMutate.mutate({calendarEventId: calendarEvent?.calendarEventId, eventName, eventDescription, eventStartDate, eventEndDate});
} }
const deleteCalendarEvent = () => { const deleteCalendarEvent = () => {
if(!calendarEvent?.calendarEventId){
addErrorMessage("Calendar event ID is required");
return;
}
deleteCalendarEventMutate.mutate(calendarEvent as CalendarEvent); deleteCalendarEventMutate.mutate(calendarEvent as CalendarEvent);
} }

View File

@@ -65,10 +65,30 @@ export default function ClassGroupModal({
const createClassGroup = () => { 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 }); createClassGroupMutate.mutate({ classGroupName, gameClassIds: selectedGameClassIds });
} }
const updateClassGroup = () => { 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({ updateClassGroupMutate.mutate({
classGroup: { classGroup: {
classGroupId: classGroup?.classGroupId, classGroupId: classGroup?.classGroupId,

View File

@@ -43,7 +43,7 @@ export default function AllGamesDisplay(){
return ( return (
<> <>
<div <div
className="flex flex-row justify-between items-center w-full" className="flex flex-row justify-between items-center w-full mb-8"
> >
<div <div
className="flex flex-row items-center justify-start w-full" className="flex flex-row items-center justify-start w-full"
@@ -55,7 +55,6 @@ export default function AllGamesDisplay(){
className="flex flex-row items-center justify-center w-full" className="flex flex-row items-center justify-center w-full"
> >
<PrimaryButton <PrimaryButton
className="mb-8"
onClick={() => setDisplayCreateGameModal(true)} onClick={() => setDisplayCreateGameModal(true)}
disabled={!isSiteAdmin(accountPermissions)} disabled={!isSiteAdmin(accountPermissions)}
> >

View File

@@ -59,12 +59,40 @@ export default function GameModal({
}, [ updateGameMutate, createGameMutate, gameName, close, addSuccessMessage, addErrorMessage ]); }, [ updateGameMutate, createGameMutate, gameName, close, addSuccessMessage, addErrorMessage ]);
const updateGame = () => { const createGame = () => {
updateGameMutate.mutate({game: {gameId: game?.gameId, gameName, gameIcon} as Game, iconFile}); 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 = () => { const updateGame = () => {
createGameMutate.mutate({gameName: gameName ?? "", iconFile}); 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});
} }

View File

@@ -62,12 +62,36 @@ export default function GameClassModal({
}, [ updateGameClassMutate, createGameClassMutate, gameClassName, close, addSuccessMessage, addErrorMessage ]); }, [ updateGameClassMutate, createGameClassMutate, gameClassName, close, addSuccessMessage, addErrorMessage ]);
const updateGameClass = () => { const createGameClass = () => {
updateGameClassMutate.mutate({ gameClass: {gameClassId: gameClass?.gameClassId, gameId, gameClassName, gameClassIcon}, iconFile}); 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 = () => { const updateGameClass = () => {
createGameClassMutate.mutate({ gameId, gameClassName, iconFile}); 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});
} }

View File

@@ -59,12 +59,40 @@ export default function PersonModal({
}); });
const updatePerson = () => { const createPerson = () => {
updatePersonMutate.mutate({raidGroupId, personId: person?.personId, personName, discordId} as Person); 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 = () => { const updatePerson = () => {
createPersonMutate.mutate({raidGroupId, personName, discordId} as Person); 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);
} }

View File

@@ -70,10 +70,40 @@ export default function PersonCharacterModal({
const createPersonCharacter = () => { 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); createPersonCharacterMutate.mutate({personId, characterName, gameClassId, characterRating, characterComments} as PersonCharacter);
} }
const updatePersonCharacter = () => { 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); updatePersonCharacterMutate.mutate({personCharacterId: personCharacter?.personCharacterId, personId, characterName, gameClassId, characterRating, characterComments} as PersonCharacter);
} }

View File

@@ -17,7 +17,7 @@ export default function RaidGroupCreateAndSearch({
return ( return (
<div <div
className="flex flex-row justify-between items-center w-full" className="flex flex-row justify-between items-center w-full mb-8"
> >
<div <div
className="flex flex-row items-center justify-start w-full" className="flex flex-row items-center justify-start w-full"
@@ -29,7 +29,6 @@ export default function RaidGroupCreateAndSearch({
className="flex flex-row items-center justify-center w-full" className="flex flex-row items-center justify-center w-full"
> >
<PrimaryButton <PrimaryButton
className="mb-8"
onClick={() => setDisplayRaidGroupModal(true)} onClick={() => setDisplayRaidGroupModal(true)}
> >
Create Raid Group Create Raid Group

View File

@@ -2,7 +2,7 @@ import { ButtonProps } from "@/components/button/Button";
import Table from "@/components/table/Table"; import Table from "@/components/table/Table";
import { RaidGroup } from "@/interface/RaidGroup"; import { RaidGroup } from "@/interface/RaidGroup";
import { useAuth } from "@/providers/AuthProvider"; import { useAuth } from "@/providers/AuthProvider";
import { containsRaidGroupPermission, containsRaidGroupRequest, isRaidGroupAdmin } from "@/util/PermissionUtil"; import { containsRaidGroupRequest, isRaidGroupAdmin, isRaidGroupMember } from "@/util/PermissionUtil";
import { useState } from "react"; import { useState } from "react";
import { Link } from "react-router"; import { Link } from "react-router";
import RaidGroupRequestModal from "../raidGroupRequest/modal/RaidGroupRequestModal"; import RaidGroupRequestModal from "../raidGroupRequest/modal/RaidGroupRequestModal";
@@ -90,7 +90,7 @@ export default function RaidGroupsList({
setSelectedRaidGroup(raidGroup); setSelectedRaidGroup(raidGroup);
setDisplayDeleteRaidGroupModal(true); setDisplayDeleteRaidGroupModal(true);
}} }}
hasRaidGroupPermissions={containsRaidGroupPermission(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions)} hasRaidGroupPermissions={isRaidGroupMember(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions)}
hasRaidGroupRequest={containsRaidGroupRequest(raidGroup.raidGroupId ?? "", raidGroupRequests)} hasRaidGroupRequest={containsRaidGroupRequest(raidGroup.raidGroupId ?? "", raidGroupRequests)}
/> />
</div> </div>

View File

@@ -31,6 +31,7 @@ export default function RaidGroupModal({
useEffect(() => { useEffect(() => {
setRaidGroupName(raidGroup?.raidGroupName ?? ""); setRaidGroupName(raidGroup?.raidGroupName ?? "");
setRaidGroupIcon(raidGroup?.raidGroupIcon ?? ""); setRaidGroupIcon(raidGroup?.raidGroupIcon ?? "");
setGame(undefined);
setIconFile(null); setIconFile(null);
}, [ display, raidGroup, setRaidGroupName, setRaidGroupIcon ]); }, [ display, raidGroup, setRaidGroupName, setRaidGroupIcon ]);
@@ -69,10 +70,30 @@ export default function RaidGroupModal({
const updateRaidGroup = () => { 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}); updateRaidGroupMutate.mutate({raidGroup: {raidGroupId: raidGroup?.raidGroupId, raidGroupName, gameId: game?.gameId, raidGroupIcon} as RaidGroup, iconFile});
} }
const createRaidGroup = () => { 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}); createRaidGroupMutate.mutate({raidGroupName: raidGroupName ?? "", gameId: game?.gameId ?? "", iconFile});
} }

View File

@@ -65,10 +65,38 @@ export default function RaidGroupRequestModal({
const createRaidGroupRequest = () => { 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); createRaidGroupRequestMutate.mutate(requestMessage);
} }
const resolveRaidGroupRequest = () => { 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); resolveRaidGroupRequestMutate.mutate(currentPermission);
} }

View File

@@ -1,6 +1,7 @@
import PrimaryButton from "@/components/button/PrimaryButton"; import PrimaryButton from "@/components/button/PrimaryButton";
import SecondaryButton from "@/components/button/SecondaryButton"; import SecondaryButton from "@/components/button/SecondaryButton";
import DateInput from "@/components/input/DateInput"; import DateInput from "@/components/input/DateInput";
import NumberInput from "@/components/input/NumberInput";
import TextInput from "@/components/input/TextInput"; import TextInput from "@/components/input/TextInput";
import RaidBuilderModal from "@/components/modal/RaidBuilderModal"; import RaidBuilderModal from "@/components/modal/RaidBuilderModal";
import { useCreateRaidInstance, useUpdateRaidInstance } from "@/hooks/RaidInstanceHooks"; import { useCreateRaidInstance, useUpdateRaidInstance } from "@/hooks/RaidInstanceHooks";
@@ -77,6 +78,32 @@ export default function RaidInstanceModal({
}); });
const createRaidInstance = () => { 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({ createRaidInstanceMutate.mutate({
raidInstanceName, raidInstanceName,
raidStartDate, raidStartDate,
@@ -88,6 +115,36 @@ export default function RaidInstanceModal({
} }
const updateRaidInstance = () => { 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({ updateRaidInstanceMutate.mutate({
raidInstanceId: raidInstance?.raidInstanceId, raidInstanceId: raidInstance?.raidInstanceId,
raidInstanceName, raidInstanceName,
@@ -115,16 +172,26 @@ export default function RaidInstanceModal({
value={raidInstanceName} value={raidInstanceName}
onChange={(e) => setRaidInstanceName(e.target.value)} onChange={(e) => setRaidInstanceName(e.target.value)}
/> />
<br/> <div
{/* className="flex flex-row items-center justify-center gap-4"
>
<NumberInput <NumberInput
id="raidSizeInput" id="raidSizeInput"
label="Size"
min={1} min={1}
max={100} max={100}
value={raidSize} value={raidSize}
onChange={setRaidSize} onChange={setRaidSize}
/> />
*/} <NumberInput
id="numberRunsInput"
label="Runs"
min={1}
max={100}
value={numberRuns}
onChange={setNumberRuns}
/>
</div>
<DateInput <DateInput
id="raidStartDateInput" id="raidStartDateInput"
value={moment(raidStartDate).format("YYYY-MM-DDTHH:mm")} value={moment(raidStartDate).format("YYYY-MM-DDTHH:mm")}

View File

@@ -80,6 +80,24 @@ export default function RaidLayoutModal({
}); });
const createRaidLayout = () => { const createRaidLayout = () => {
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({ createRaidLayoutMutate.mutate({
raidLayout: { raidLayout: {
raidLayoutName, raidLayoutName,
@@ -87,7 +105,7 @@ export default function RaidLayoutModal({
raidGroupId: raidGroup.raidGroupId ?? "" raidGroupId: raidGroup.raidGroupId ?? ""
}, },
raidLayoutClassGroupXrefs: classGroups.map((cg, index) => ({ raidLayoutClassGroupXrefs: classGroups.map((cg, index) => ({
raidLayoutId: raidLayout?.raidLayoutId ?? "", raidLayoutId: "",
classGroupId: cg?.classGroupId, classGroupId: cg?.classGroupId,
layoutLocation: index layoutLocation: index
} as RaidLayoutClassGroupXref)) } as RaidLayoutClassGroupXref))
@@ -95,6 +113,28 @@ export default function RaidLayoutModal({
} }
const updateRaidLayout = () => { 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({ updateRaidLayoutMutate.mutate({
raidLayout: { raidLayout: {
raidLayoutId: raidLayout?.raidLayoutId, raidLayoutId: raidLayout?.raidLayoutId,

View File

@@ -14,27 +14,6 @@ export function isSiteAdmin(accountPermissions: AccountPermission[]): boolean{
//! Raid Group //! 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{ export function isRaidGroupAdmin(raidGroupId: string, permissions: RaidGroupPermission[], accountPermissions: AccountPermission[]): boolean{
if(accountPermissions.find((permission) => permission.accountPermissionType === AccountPermissionType.ADMIN)){ if(accountPermissions.find((permission) => permission.accountPermissionType === AccountPermissionType.ADMIN)){
return true; return true;
@@ -51,6 +30,29 @@ export function isRaidGroupLeader(raidGroupId: string, permissions: RaidGroupPer
return raidGroupPermission?.permission === RaidGroupPermissionType.LEADER; 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 //! Game