Raid Instance Creator working
This commit is contained in:
38
src/ui/raidInstance/RaidInstanceAdminButtons.tsx
Normal file
38
src/ui/raidInstance/RaidInstanceAdminButtons.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { ButtonProps } from "@/components/button/Button";
|
||||
import DangerButton from "@/components/button/DangerButton";
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import { BsPencilFill, BsTrash3 } from "react-icons/bs";
|
||||
|
||||
|
||||
export default function RaidInstanceAdminButtons({
|
||||
buttonProps,
|
||||
showRaidInstanceModal,
|
||||
showDeleteRaidInstanceModal
|
||||
}:{
|
||||
buttonProps: ButtonProps;
|
||||
showRaidInstanceModal: () => void;
|
||||
showDeleteRaidInstanceModal: () => void;
|
||||
}){
|
||||
return (
|
||||
<div
|
||||
className="flex flex-row gap-2"
|
||||
>
|
||||
<PrimaryButton
|
||||
{...buttonProps}
|
||||
onClick={showRaidInstanceModal}
|
||||
>
|
||||
<BsPencilFill
|
||||
size={22}
|
||||
/>
|
||||
</PrimaryButton>
|
||||
<DangerButton
|
||||
{...buttonProps}
|
||||
onClick={showDeleteRaidInstanceModal}
|
||||
>
|
||||
<BsTrash3
|
||||
size={22}
|
||||
/>
|
||||
</DangerButton>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
207
src/ui/raidInstance/RaidInstanceHeader.tsx
Normal file
207
src/ui/raidInstance/RaidInstanceHeader.tsx
Normal file
@@ -0,0 +1,207 @@
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import DateInput from "@/components/input/DateInput";
|
||||
import NumberInput from "@/components/input/NumberInput";
|
||||
import TextInput from "@/components/input/TextInput";
|
||||
import { useUpdateRaidInstanceNoInvalidation, useUpdateRaidInstancePersonCharacterXrefs } from "@/hooks/RaidInstanceHooks";
|
||||
import { RaidInstance } from "@/interface/RaidInstance";
|
||||
import { useRaidInstanceContext } from "@/providers/RaidInstanceLayoutProvider";
|
||||
import { useTimedModal } from "@/providers/TimedModalProvider";
|
||||
import clsx from "clsx";
|
||||
import moment from "moment";
|
||||
import { useEffect, useState } from "react";
|
||||
import PersonSelectorModal from "../person/modals/PersonSelectorModal";
|
||||
import RaidLayoutSelectorModal from "../raidLayout/modal/RaidLayoutSelectorModal";
|
||||
|
||||
|
||||
export default function RaidInstanceHeader(){
|
||||
const {
|
||||
raidInstance, setRaidInstance,
|
||||
raidGroup,
|
||||
selectedClassGroups, setSelectedClassGroups,
|
||||
raidLayout, setRaidLayout,
|
||||
raidLayouts,
|
||||
people,
|
||||
roster, setRoster,
|
||||
personCharacterXrefs, setPersonCharacterXrefs
|
||||
} = useRaidInstanceContext();
|
||||
|
||||
const [ displayRaidLayoutSelectorModal, setDisplayRaidLayoutSelectorModal ] = useState(false);
|
||||
const [ displayRosterSelectorModal, setDisplayRosterSelectorModal ] = useState(false);
|
||||
const { addSuccessMessage, addErrorMessage } = useTimedModal();
|
||||
|
||||
|
||||
const updateRaidLayout = (newRaidLayoutId?: string) => {
|
||||
const newRaidLayout = raidLayouts.find((rl) => rl.raidLayoutId === newRaidLayoutId);
|
||||
|
||||
setRaidInstance({...raidInstance, raidLayoutId: newRaidLayoutId, raidSize: newRaidLayout?.raidSize ?? raidInstance?.raidSize} as RaidInstance);
|
||||
setRaidLayout(newRaidLayout);
|
||||
}
|
||||
|
||||
const updateRaidSize = (newRaidSize: number) => {
|
||||
if(newRaidSize > (raidInstance?.raidSize ?? 0)){
|
||||
setSelectedClassGroups([...selectedClassGroups, null]);
|
||||
}
|
||||
else{
|
||||
setSelectedClassGroups(selectedClassGroups.slice(0, newRaidSize));
|
||||
}
|
||||
const newXrefs = personCharacterXrefs.filter((xref) => xref.positionNumber < newRaidSize);
|
||||
setPersonCharacterXrefs(newXrefs);
|
||||
setRaidInstance({...raidInstance, raidSize: newRaidSize, raidLayoutId: undefined} as RaidInstance);
|
||||
setRaidLayout(undefined);
|
||||
}
|
||||
|
||||
//Mutations
|
||||
const { mutate: updateRaidInstanceMutate, status: updateRaidInstanceStatus, reset: updateRaidInstanceReset, error: updateRaidInstanceError } = useUpdateRaidInstanceNoInvalidation(raidGroup?.raidGroupId ?? "");
|
||||
const { mutate: updatePersonCharacterXrefsMutate, status: updatePersonCharacterXrefsStatus, reset: updatePersonCharacterXrefsReset, error: updatePersonCharacterXrefsError } = useUpdateRaidInstancePersonCharacterXrefs(raidGroup?.raidGroupId ?? "", raidInstance?.raidInstanceId ?? "");
|
||||
|
||||
const saveRaidInstance = () => {
|
||||
updateRaidInstanceMutate(raidInstance!);
|
||||
updatePersonCharacterXrefsMutate(personCharacterXrefs);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if((updateRaidInstanceStatus === "success") && (updatePersonCharacterXrefsStatus === "success")){
|
||||
addSuccessMessage("Raid Instance Saved");
|
||||
updateRaidInstanceReset();
|
||||
updatePersonCharacterXrefsReset();
|
||||
}
|
||||
else if(updateRaidInstanceStatus === "error"){
|
||||
addErrorMessage("Error Saving Raid Instance: " + updateRaidInstanceError.message);
|
||||
updateRaidInstanceReset();
|
||||
}
|
||||
else if(updatePersonCharacterXrefsStatus === "error"){
|
||||
addErrorMessage("Error Saving Raid Instance: " + updatePersonCharacterXrefsError.message);
|
||||
updatePersonCharacterXrefsReset();
|
||||
}
|
||||
}, [ addErrorMessage, addSuccessMessage, updatePersonCharacterXrefsError?.message, updatePersonCharacterXrefsReset, updatePersonCharacterXrefsStatus, updateRaidInstanceError?.message, updateRaidInstanceReset, updateRaidInstanceStatus ]);
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-col items-center justify-center w-full h-full mb-16"
|
||||
>
|
||||
{/* Raid Instance Name */}
|
||||
<div
|
||||
className="flex flex-col justify-center items-center min-w-[60rem] text-center"
|
||||
>
|
||||
<h1
|
||||
className="flex flex-row items-center justify-center text-4xl"
|
||||
>
|
||||
<TextInput
|
||||
id={`raidInstance${raidInstance?.raidInstanceId}Name`}
|
||||
inputClasses="text-center"
|
||||
placeholder="Raid Instance Name"
|
||||
value={raidInstance?.raidInstanceName ?? ""}
|
||||
onChange={(e) =>
|
||||
setRaidInstance({
|
||||
...raidInstance,
|
||||
raidInstanceName: e.target.value
|
||||
} as RaidInstance)
|
||||
}
|
||||
//disabled={}
|
||||
/>
|
||||
</h1>
|
||||
</div>
|
||||
{/* Start and End Dates */}
|
||||
<div
|
||||
className="flex flex-row justify-center mt-4"
|
||||
>
|
||||
<DateInput
|
||||
id={`raidInstance${raidInstance?.raidInstanceId}StartDate`}
|
||||
placeholder="Start Date"
|
||||
value={moment(raidInstance?.raidStartDate ?? new Date()).format("YYYY-MM-DDTHH:mm")}
|
||||
onChange={(e) => setRaidInstance({...raidInstance, raidStartDate: moment(e.target.value).toDate()} as RaidInstance)}
|
||||
/>
|
||||
<DateInput
|
||||
id={`raidInstance${raidInstance?.raidInstanceId}EndDate`}
|
||||
placeholder="End Date"
|
||||
value={moment(raidInstance?.raidEndDate).format("YYYY-MM-DDTHH:mm")}
|
||||
onChange={(e) => setRaidInstance({...raidInstance, raidEndDate: moment(e.target.value).toDate()} as RaidInstance)}
|
||||
/>
|
||||
</div>
|
||||
{/* Raid Size & Layout */}
|
||||
<div
|
||||
className="flex flex-row items-center justify-center gap-x-4 mt-4"
|
||||
>
|
||||
{/* Raid Size */}
|
||||
<div
|
||||
className="flex flex-row items-center justify-center"
|
||||
>
|
||||
<NumberInput
|
||||
id={`raidInstance${raidInstance?.raidInstanceId}Size`}
|
||||
label="Raid Size"
|
||||
value={raidInstance?.raidSize ?? 0}
|
||||
onChange={updateRaidSize}
|
||||
min={0}
|
||||
max={100}
|
||||
/>
|
||||
</div>
|
||||
{/* Raid Layout */}
|
||||
<div
|
||||
className="flex flex-row items-center justify-center"
|
||||
>
|
||||
<div
|
||||
className="bg-inherit px-4 rounded-sm w-auto"
|
||||
onClick={() => setDisplayRaidLayoutSelectorModal(true)}
|
||||
>
|
||||
<div
|
||||
className="relative bg-inherit"
|
||||
>
|
||||
<div
|
||||
id="selectRaidLayoutButton"
|
||||
className="px-4 py-2 rounded-lg whitespace-nowrap cursor-pointer ring-2 ring-gray-500"
|
||||
>
|
||||
{raidLayout?.raidLayoutId ? raidLayout.raidLayoutName : "Select Raid Layout"}
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"absolute cursor-text left-0 -top-3 mx-1 px-1 whitespace-nowrap",
|
||||
"bg-white dark:bg-neutral-800 text-sm text-gray-500"
|
||||
)}
|
||||
style={{transitionProperty: "top, font-size, line-height", transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)", transitionDuration: "150ms"}}
|
||||
>
|
||||
Raid Layout
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<RaidLayoutSelectorModal
|
||||
raidLayouts={raidLayouts}
|
||||
selectedRaidLayoutId={raidLayout?.raidLayoutId}
|
||||
display={displayRaidLayoutSelectorModal}
|
||||
close={() => setDisplayRaidLayoutSelectorModal(false)}
|
||||
onSubmit={updateRaidLayout}
|
||||
/>
|
||||
</div>
|
||||
{/* Roster */}
|
||||
<div
|
||||
className="flex flex-row items-center justify-center"
|
||||
>
|
||||
<PrimaryButton
|
||||
onClick={() => setDisplayRosterSelectorModal(true)}
|
||||
>
|
||||
Roster
|
||||
</PrimaryButton>
|
||||
<PersonSelectorModal
|
||||
display={displayRosterSelectorModal}
|
||||
close={() => setDisplayRosterSelectorModal(false)}
|
||||
onSubmit={(newRosterIds) => setRoster(people.filter(person => newRosterIds.includes(person.personId ?? "")))}
|
||||
people={people}
|
||||
selectedPersonIds={roster.map(person => person.personId ?? "")}
|
||||
/>
|
||||
</div>
|
||||
{/* Save Button */}
|
||||
<div
|
||||
className="flex flex-row items-center justify-center ml-4"
|
||||
>
|
||||
{
|
||||
<PrimaryButton
|
||||
onClick={saveRaidInstance}
|
||||
>
|
||||
Save
|
||||
</PrimaryButton>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
124
src/ui/raidInstance/RaidInstanceList.tsx
Normal file
124
src/ui/raidInstance/RaidInstanceList.tsx
Normal file
@@ -0,0 +1,124 @@
|
||||
import { ButtonProps } from "@/components/button/Button";
|
||||
import Table from "@/components/table/Table";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { RaidInstance } from "@/interface/RaidInstance";
|
||||
import moment from "moment";
|
||||
import { useState } from "react";
|
||||
import { Link } from "react-router";
|
||||
import DeleteRaidInstanceModal from "./modals/DeleteRaidInstanceModal";
|
||||
import RaidInstanceModal from "./modals/RaidInstanceModal";
|
||||
import RaidInstanceAdminButtons from "./RaidInstanceAdminButtons";
|
||||
|
||||
|
||||
export default function RaidInstanceList({
|
||||
raidInstances,
|
||||
raidGroup
|
||||
}:{
|
||||
raidInstances: RaidInstance[];
|
||||
raidGroup: RaidGroup;
|
||||
}){
|
||||
const [ selectedRaidInstance, setSelectedRaidInstance ] = useState<RaidInstance>();
|
||||
const [ displayEditRaidInstanceModal, setDisplayEditRaidInstanceModal ] = useState(false);
|
||||
const [ displayDeleteRaidInstanceModal, setDisplayDeleteRaidInstanceModal ] = useState(false);
|
||||
|
||||
|
||||
const buttonProps: ButtonProps = {
|
||||
variant: "ghost",
|
||||
size: "md",
|
||||
shape: "square"
|
||||
};
|
||||
|
||||
|
||||
const headElements: React.ReactNode[] = [
|
||||
<div
|
||||
className="text-nowrap"
|
||||
>
|
||||
Raid Instance
|
||||
</div>,
|
||||
<div
|
||||
className="text-nowrap"
|
||||
>
|
||||
Start Date
|
||||
</div>,
|
||||
<div
|
||||
className="text-nowrap"
|
||||
>
|
||||
End Date
|
||||
</div>,
|
||||
<div
|
||||
className="text-nowrap"
|
||||
>
|
||||
Size
|
||||
</div>,
|
||||
<div
|
||||
className="text-nowrap"
|
||||
>
|
||||
Runs
|
||||
</div>,
|
||||
<div
|
||||
className="text-nowrap pl-16"
|
||||
>
|
||||
Actions
|
||||
</div>
|
||||
];
|
||||
|
||||
const bodyElements: React.ReactNode[][] = raidInstances.map((raidInstance) => [
|
||||
<Link
|
||||
to={`/raidGroup/${raidInstance.raidGroupId}/raidInstance/${raidInstance.raidInstanceId}`}
|
||||
className="text-nowrap"
|
||||
>
|
||||
{raidInstance.raidInstanceName}
|
||||
</Link>,
|
||||
<div
|
||||
className="text-nowrap"
|
||||
>
|
||||
{moment(raidInstance.raidStartDate).format("MM-DD-YYYY HH:mm")}
|
||||
</div>,
|
||||
<div
|
||||
className="text-nowrap"
|
||||
>
|
||||
{moment(raidInstance.raidEndDate).format("MM-DD-YYYY HH:mm")}
|
||||
</div>,
|
||||
<div>
|
||||
{raidInstance.raidSize}
|
||||
</div>,
|
||||
<div>
|
||||
{raidInstance.numberRuns}
|
||||
</div>,
|
||||
<div
|
||||
className="flex flex-row items-center justify-center gap-2 pl-16"
|
||||
>
|
||||
<div
|
||||
className="py-4 border-l border-neutral-500"
|
||||
>
|
||||
|
||||
</div>
|
||||
<RaidInstanceAdminButtons
|
||||
buttonProps={buttonProps}
|
||||
showRaidInstanceModal={() => { setSelectedRaidInstance(raidInstance); setDisplayEditRaidInstanceModal(true); }}
|
||||
showDeleteRaidInstanceModal={() => { setSelectedRaidInstance(raidInstance); setDisplayDeleteRaidInstanceModal(true); }}
|
||||
/>
|
||||
</div>
|
||||
]);
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Table
|
||||
tableHeadElements={headElements}
|
||||
tableBodyElements={bodyElements}
|
||||
/>
|
||||
<RaidInstanceModal
|
||||
display={displayEditRaidInstanceModal}
|
||||
close={() => { setDisplayEditRaidInstanceModal(false); setSelectedRaidInstance(undefined); }}
|
||||
raidInstance={selectedRaidInstance}
|
||||
raidGroup={raidGroup}
|
||||
/>
|
||||
<DeleteRaidInstanceModal
|
||||
display={displayDeleteRaidInstanceModal}
|
||||
close={() => { setDisplayDeleteRaidInstanceModal(false); setSelectedRaidInstance(undefined); }}
|
||||
raidInstance={selectedRaidInstance}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
95
src/ui/raidInstance/RaidInstanceListSkeleton.tsx
Normal file
95
src/ui/raidInstance/RaidInstanceListSkeleton.tsx
Normal file
@@ -0,0 +1,95 @@
|
||||
import { ButtonShape, ButtonSizeType, ButtonVariant } from "@/components/button/Button";
|
||||
import Table from "@/components/table/Table";
|
||||
import { elementBg } from "@/util/SkeletonUtil";
|
||||
import RaidInstanceAdminButtons from "./RaidInstanceAdminButtons";
|
||||
|
||||
|
||||
export default function RaidInstanceListSkeleton(){
|
||||
const headElements: React.ReactNode[] = [
|
||||
<div
|
||||
className="text-nowrap"
|
||||
>
|
||||
Raid Instance
|
||||
</div>,
|
||||
<div
|
||||
className="text-nowrap"
|
||||
>
|
||||
Start Date
|
||||
</div>,
|
||||
<div
|
||||
className="text-nowrap"
|
||||
>
|
||||
End Date
|
||||
</div>,
|
||||
<div>
|
||||
Size
|
||||
</div>,
|
||||
<div>
|
||||
Runs
|
||||
</div>,
|
||||
<div>
|
||||
Actions
|
||||
</div>
|
||||
];
|
||||
|
||||
const bodyElements: React.ReactNode[][] = [
|
||||
RaidInstanceSkeleton(),
|
||||
RaidInstanceSkeleton(),
|
||||
RaidInstanceSkeleton(),
|
||||
RaidInstanceSkeleton(),
|
||||
RaidInstanceSkeleton(),
|
||||
RaidInstanceSkeleton(),
|
||||
RaidInstanceSkeleton(),
|
||||
RaidInstanceSkeleton(),
|
||||
RaidInstanceSkeleton(),
|
||||
RaidInstanceSkeleton()
|
||||
];
|
||||
|
||||
|
||||
return (
|
||||
<Table
|
||||
tableHeadElements={headElements}
|
||||
tableBodyElements={bodyElements}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function RaidInstanceSkeleton(){
|
||||
const buttonsProps = {
|
||||
buttonProps: {
|
||||
variant: "ghost" as ButtonVariant,
|
||||
size: "md" as ButtonSizeType,
|
||||
shape: "square" as ButtonShape,
|
||||
disabled: true
|
||||
},
|
||||
showRaidInstanceModal: () => {},
|
||||
showDeleteRaidInstanceModal: () => {}
|
||||
};
|
||||
|
||||
const elements: React.ReactNode[] = [
|
||||
<div
|
||||
className={`h-6 w-32 mr-2 ${elementBg}`}
|
||||
/>,
|
||||
<div
|
||||
className={`h-6 w-[26rem] mr-2 ${elementBg}`}
|
||||
/>,
|
||||
<div
|
||||
className={`h-6 w-[26rem] mr-2 ${elementBg}`}
|
||||
/>,
|
||||
<div
|
||||
className={`h-6 w-32 mr-2 ${elementBg}`}
|
||||
/>,
|
||||
<div
|
||||
className={`h-6 w-32 mr-2 ${elementBg}`}
|
||||
/>,
|
||||
<div
|
||||
className="flex flex-row items-center justify-center gap-2 pl-16"
|
||||
>
|
||||
<div className="py-4 border-l border-neutral-500"> </div>
|
||||
<RaidInstanceAdminButtons {...buttonsProps}/>
|
||||
</div>
|
||||
];
|
||||
|
||||
return elements;
|
||||
}
|
||||
36
src/ui/raidInstance/RaidInstanceLoader.tsx
Normal file
36
src/ui/raidInstance/RaidInstanceLoader.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import DangerMessage from "@/components/message/DangerMessage";
|
||||
import { useGetRaidInstancesByRaidGroup } from "@/hooks/RaidInstanceHooks";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import RaidInstanceList from "./RaidInstanceList";
|
||||
import RaidInstanceListSkeleton from "./RaidInstanceListSkeleton";
|
||||
|
||||
|
||||
export default function RaidInstanceLoader({
|
||||
raidGroup,
|
||||
page,
|
||||
pageSize,
|
||||
searchTerm
|
||||
}:{
|
||||
raidGroup: RaidGroup;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
searchTerm?: string;
|
||||
}){
|
||||
const raidInstancesQuery = useGetRaidInstancesByRaidGroup(raidGroup.raidGroupId ?? "", page - 1, pageSize, searchTerm);
|
||||
|
||||
|
||||
if(raidInstancesQuery.status === "pending"){
|
||||
return <RaidInstanceListSkeleton/>
|
||||
}
|
||||
else if(raidInstancesQuery.status === "error"){
|
||||
return <DangerMessage>Error: {raidInstancesQuery.error.message}</DangerMessage>
|
||||
}
|
||||
else{
|
||||
return (
|
||||
<RaidInstanceList
|
||||
raidInstances={raidInstancesQuery.data ?? []}
|
||||
raidGroup={raidGroup}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
105
src/ui/raidInstance/RaidInstanceTab.tsx
Normal file
105
src/ui/raidInstance/RaidInstanceTab.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import TextInput from "@/components/input/TextInput";
|
||||
import Pagination from "@/components/pagination/Pagination";
|
||||
import { useGetRaidInstancesByRaidGroupCount } from "@/hooks/RaidInstanceHooks";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import RaidInstanceLoader from "./RaidInstanceLoader";
|
||||
import RaidInstanceModal from "./modals/RaidInstanceModal";
|
||||
|
||||
|
||||
export default function RaidInstanceTab({
|
||||
raidGroup
|
||||
}:{
|
||||
raidGroup: RaidGroup;
|
||||
}){
|
||||
const [ displayCreateRaidInstanceModal, setDisplayCreateRaidInstanceModal ] = useState(false);
|
||||
const [ page, setPage ] = useState(1);
|
||||
const [ totalPages, setTotalPages ] = useState(1);
|
||||
const [ searchTerm, setSearchTerm ] = useState("");
|
||||
const [ sentSearchTerm, setSentSearchTerm ] = useState<string>();
|
||||
const pageSize = 10;
|
||||
const modalId = crypto.randomUUID().replaceAll("-", "");
|
||||
|
||||
|
||||
const updateSearchTerm = useDebouncedCallback((newSearchTerm: string) => {
|
||||
setSentSearchTerm(newSearchTerm);
|
||||
}, 1000);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
updateSearchTerm(searchTerm);
|
||||
}, [ searchTerm, updateSearchTerm ]);
|
||||
|
||||
|
||||
const raidInstanceCountQuery = useGetRaidInstancesByRaidGroupCount(raidGroup.raidGroupId!, sentSearchTerm);
|
||||
|
||||
useEffect(() => {
|
||||
if(raidInstanceCountQuery.status === "success"){
|
||||
setTotalPages(Math.ceil(raidInstanceCountQuery.data / pageSize));
|
||||
}
|
||||
}, [ raidInstanceCountQuery ]);
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="flex flex-row items-center justify-between w-full mb-8"
|
||||
>
|
||||
<div
|
||||
className="flex flex-row items-center justify-start w-full"
|
||||
>
|
||||
|
||||
</div>
|
||||
{/* Add Raid Instance Button */}
|
||||
<div
|
||||
className="flex flex-row items-center justify-center w-full"
|
||||
>
|
||||
<PrimaryButton
|
||||
className="text-nowrap"
|
||||
onClick={() => setDisplayCreateRaidInstanceModal(true)}
|
||||
>
|
||||
Create Raid Instance
|
||||
</PrimaryButton>
|
||||
<RaidInstanceModal
|
||||
display={displayCreateRaidInstanceModal}
|
||||
close={() => setDisplayCreateRaidInstanceModal(false)}
|
||||
raidInstance={undefined}
|
||||
raidGroup={raidGroup}
|
||||
/>
|
||||
</div>
|
||||
{/* Raid Instance Search Box */}
|
||||
<div
|
||||
className="flex flex-row items-center justify-end w-full"
|
||||
>
|
||||
<div>
|
||||
<TextInput
|
||||
id={`raidInstanceSearchBox${modalId}`}
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
placeholder="Search"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Raid Layout List */}
|
||||
<RaidInstanceLoader
|
||||
page={page}
|
||||
pageSize={pageSize}
|
||||
searchTerm={sentSearchTerm}
|
||||
raidGroup={raidGroup}
|
||||
/>
|
||||
{/* Pagination */}
|
||||
<div
|
||||
className="my-12"
|
||||
>
|
||||
<Pagination
|
||||
currentPage={page}
|
||||
totalPages={totalPages}
|
||||
onChange={setPage}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
129
src/ui/raidInstance/creator/RaidInstanceCreator.tsx
Normal file
129
src/ui/raidInstance/creator/RaidInstanceCreator.tsx
Normal file
@@ -0,0 +1,129 @@
|
||||
import { ClassGroup } from "@/interface/ClassGroup";
|
||||
import { GridLocation } from "@/interface/GridLocation";
|
||||
import { PersonCharacter } from "@/interface/PersonCharacter";
|
||||
import { RaidInstance } from "@/interface/RaidInstance";
|
||||
import { RaidInstancePersonCharacterXref } from "@/interface/RaidInstancePersonCharacterXref";
|
||||
import { useRaidInstanceContext } from "@/providers/RaidInstanceLayoutProvider";
|
||||
import SelectClassGroupModal from "@/ui/classGroup/modal/SelectClassGroupModal";
|
||||
import PersonCharacterSelectorModal from "@/ui/personCharacter/modal/PersonCharacterSelectorModal";
|
||||
import { useState } from "react";
|
||||
import RaidInstanceCreatorTable from "./RaidInstanceCreatorTable";
|
||||
|
||||
|
||||
export default function RaidInstanceCreator(){
|
||||
const {
|
||||
raidGroup,
|
||||
classGroups,
|
||||
raidInstance, setRaidInstance,
|
||||
roster,
|
||||
setRaidLayout,
|
||||
selectedClassGroups, setSelectedClassGroups,
|
||||
personCharacters,
|
||||
personCharacterXrefs, setPersonCharacterXrefs
|
||||
} = useRaidInstanceContext();
|
||||
const [ displayClassGroupsSelectorModal, setDisplayClassGroupsSelectorModal ] = useState(false);
|
||||
const [ displayPersonCharacterSelectorModal, setDisplayPersonCharacterSelectorModal ] = useState(false);
|
||||
const [ currentLocation, setCurrentLocation ] = useState<GridLocation>({row: 0, col: 0});
|
||||
|
||||
|
||||
const updateClassGroupsLayout = (newSelectedClassGroup: ClassGroup | null | undefined) => {
|
||||
//Get all existing xrefs, leaving out the current xref it it's been removed
|
||||
const newClassGroups = selectedClassGroups;
|
||||
newClassGroups[currentLocation.col] = newSelectedClassGroup ?? null;
|
||||
|
||||
//Update the raid layout to persist the changes
|
||||
setSelectedClassGroups(newClassGroups);
|
||||
|
||||
setRaidInstance({...raidInstance, raidLayoutId: undefined} as RaidInstance);
|
||||
setRaidLayout(undefined);
|
||||
|
||||
//Hide modal
|
||||
setDisplayClassGroupsSelectorModal(false);
|
||||
}
|
||||
|
||||
const setCharacterIdInCurrentSlot = (newPersonCharacterId: string | undefined) => {
|
||||
let newPersonCharacterXrefs: RaidInstancePersonCharacterXref[] = personCharacterXrefs;
|
||||
//Step through this to make sure it's working as expected
|
||||
if(newPersonCharacterId && (newPersonCharacterId !== "")){
|
||||
const existingXref = personCharacterXrefs?.find((xref) => xref.groupNumber === currentLocation.row && xref.positionNumber == currentLocation.col);
|
||||
//If the ID exists and the xref also exists then update the xref
|
||||
if(existingXref){
|
||||
newPersonCharacterXrefs = personCharacterXrefs?.map((xref) => {
|
||||
if((xref.groupNumber === currentLocation.row) && (xref.positionNumber === currentLocation.col)){
|
||||
xref.personCharacterId = newPersonCharacterId;
|
||||
}
|
||||
return xref;
|
||||
});
|
||||
}
|
||||
//If the ID exists and the xref doesn't add a new xref
|
||||
else{
|
||||
newPersonCharacterXrefs.push(
|
||||
{
|
||||
raidInstanceId: raidInstance?.raidInstanceId ?? "",
|
||||
personCharacterId: newPersonCharacterId,
|
||||
groupNumber: currentLocation.row,
|
||||
positionNumber: currentLocation.col
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
else{
|
||||
//If the ID doesn't exist then remove the xref if it exists
|
||||
newPersonCharacterXrefs = personCharacterXrefs?.filter((xref) => !(xref.groupNumber === currentLocation.row && xref.positionNumber == currentLocation.col));
|
||||
}
|
||||
setPersonCharacterXrefs(newPersonCharacterXrefs);
|
||||
}
|
||||
|
||||
const getCurrentRunCharacters = (): PersonCharacter[] => {
|
||||
const characterIds = personCharacterXrefs?.filter((xref) => xref.groupNumber === currentLocation.row).map((xref) => xref.personCharacterId);
|
||||
return personCharacters.filter((personCharacter) => characterIds.includes(personCharacter.personCharacterId ?? ""));
|
||||
}
|
||||
|
||||
const getCharactersFromOtherRuns = (): PersonCharacter[] => {
|
||||
const characterIds = personCharacterXrefs?.filter((xref) => xref.groupNumber !== currentLocation.row).map((xref) => xref.personCharacterId);
|
||||
return personCharacters.filter((personCharacter) => characterIds.includes(personCharacter.personCharacterId ?? ""));
|
||||
}
|
||||
|
||||
const getCharacterFromCell = () => {
|
||||
const xref = personCharacterXrefs.find((xref) => xref.groupNumber === currentLocation.row && xref.positionNumber === currentLocation.col);
|
||||
return personCharacters.find((personCharacter) => personCharacter.personCharacterId === xref?.personCharacterId);
|
||||
}
|
||||
|
||||
const getPersonCharactersFromRoster = (): PersonCharacter[] => {
|
||||
const personIds = roster.map((person) => person.personId);
|
||||
return personCharacters.filter((personCharacter) => personIds.includes(personCharacter.personId));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-col items-center justify-center"
|
||||
>
|
||||
{/* Main Content */}
|
||||
<RaidInstanceCreatorTable
|
||||
onClickHeaderCell={(col) => { setCurrentLocation({row: 0, col: col}); setDisplayClassGroupsSelectorModal(true); }}
|
||||
onClickBodyCell={(row, col) => { setCurrentLocation({row: row, col: col}); setDisplayPersonCharacterSelectorModal(true); }}
|
||||
/>
|
||||
{/* Modals */}
|
||||
<SelectClassGroupModal
|
||||
display={displayClassGroupsSelectorModal}
|
||||
close={() => setDisplayClassGroupsSelectorModal(false)}
|
||||
onChange={updateClassGroupsLayout}
|
||||
selectedClassGroup={selectedClassGroups[currentLocation.col]}
|
||||
raidGroupId={raidGroup?.raidGroupId ?? ""}
|
||||
/>
|
||||
<PersonCharacterSelectorModal
|
||||
display={displayPersonCharacterSelectorModal}
|
||||
close={() => setDisplayPersonCharacterSelectorModal(false)}
|
||||
currentSlotClassGroup={classGroups[currentLocation.col]}
|
||||
currentRunCharacters={getCurrentRunCharacters()}
|
||||
otherRunsCharacters={getCharactersFromOtherRuns()}
|
||||
personCharacters={getPersonCharactersFromRoster()}
|
||||
selectedCharacterId={getCharacterFromCell()?.personCharacterId}
|
||||
setInput={setCharacterIdInCurrentSlot}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
51
src/ui/raidInstance/creator/RaidInstanceCreatorTable.tsx
Normal file
51
src/ui/raidInstance/creator/RaidInstanceCreatorTable.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import { RaidInstance } from "@/interface/RaidInstance";
|
||||
import { useRaidInstanceContext } from "@/providers/RaidInstanceLayoutProvider";
|
||||
import RaidInstanceCreatorTableBody from "./RaidInstanceCreatorTableBody";
|
||||
import RaidInstanceCreatorTableHeader from "./RaidInstanceCreatorTableHeader";
|
||||
|
||||
|
||||
export default function RaidInstanceCreatorTable({
|
||||
onClickHeaderCell,
|
||||
onClickBodyCell
|
||||
}:{
|
||||
onClickHeaderCell: (col: number) => void;
|
||||
onClickBodyCell: (row: number, col: number) => void;
|
||||
}){
|
||||
const { raidInstance, setRaidInstance } = useRaidInstanceContext();
|
||||
|
||||
|
||||
const addRun = () => {
|
||||
const newRaidInstance = {...raidInstance};
|
||||
newRaidInstance.numberRuns = (newRaidInstance.numberRuns ?? 0) + 1;
|
||||
setRaidInstance(newRaidInstance as RaidInstance);
|
||||
}
|
||||
|
||||
|
||||
return(
|
||||
<div
|
||||
className="flex flex-col items-center justify-center"
|
||||
>
|
||||
<div
|
||||
className="flex flex-col items-start justify-start max-w-full overflow-auto pb-16"
|
||||
>
|
||||
<table>
|
||||
{/* Header */}
|
||||
<RaidInstanceCreatorTableHeader
|
||||
onClickHeaderCell={onClickHeaderCell}
|
||||
/>
|
||||
{/* Body */}
|
||||
<RaidInstanceCreatorTableBody
|
||||
onClickBodyCell={onClickBodyCell}
|
||||
/>
|
||||
</table>
|
||||
</div>
|
||||
{/* Buttons */}
|
||||
<PrimaryButton
|
||||
onClick={addRun}
|
||||
>
|
||||
Add Run
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
132
src/ui/raidInstance/creator/RaidInstanceCreatorTableBody.tsx
Normal file
132
src/ui/raidInstance/creator/RaidInstanceCreatorTableBody.tsx
Normal file
@@ -0,0 +1,132 @@
|
||||
import DangerButton from "@/components/button/DangerButton";
|
||||
import TertiaryButton from "@/components/button/TertiaryButton";
|
||||
import { PersonCharacter } from "@/interface/PersonCharacter";
|
||||
import { RaidInstance } from "@/interface/RaidInstance";
|
||||
import { useRaidInstanceContext } from "@/providers/RaidInstanceLayoutProvider";
|
||||
import { getPersonCharactersFromXrefs } from "@/util/PersonCharacterUtil";
|
||||
import moment from "moment";
|
||||
import { BsDiscord, BsXLg } from "react-icons/bs";
|
||||
|
||||
|
||||
export default function RaidInstanceCreatorTableBody({
|
||||
onClickBodyCell
|
||||
}:{
|
||||
onClickBodyCell: (run: number, slot: number) => void;
|
||||
}){
|
||||
const {
|
||||
raidInstance, setRaidInstance,
|
||||
people,
|
||||
personCharacterXrefs, setPersonCharacterXrefs,
|
||||
personCharacters,
|
||||
selectedClassGroups
|
||||
} = useRaidInstanceContext();
|
||||
|
||||
|
||||
const characterGrid: (PersonCharacter | null)[][] = getPersonCharactersFromXrefs(personCharacterXrefs, personCharacters, raidInstance);
|
||||
|
||||
|
||||
const removeRun = (runNumber: number) => {
|
||||
const newXrefs = personCharacterXrefs.filter((xref) => xref.groupNumber !== runNumber)?.map((xref) => {return {...xref, groupNumber: xref.groupNumber >= runNumber ? xref.groupNumber - 1 : xref.groupNumber}});
|
||||
setPersonCharacterXrefs(newXrefs);
|
||||
setRaidInstance({...raidInstance, numberRuns: (raidInstance?.numberRuns ?? 1) - 1} as RaidInstance);
|
||||
}
|
||||
|
||||
const copyDiscordStringToClipBoard = (run: number) => {
|
||||
let discordString = "";
|
||||
//Instance name
|
||||
discordString += `${raidInstance?.raidInstanceName}\n`;
|
||||
|
||||
//Start time
|
||||
discordString += moment(raidInstance?.raidStartDate).format("MM/DD/YYYY HH:mm") + " - ";
|
||||
//End time
|
||||
discordString += moment(raidInstance?.raidEndDate).format("MM/DD/YYYY HH:mm") + "\n";
|
||||
|
||||
//Characters
|
||||
characterGrid[run].forEach((ch, index) => {
|
||||
const person = people.find((p) => p.personId === ch?.personId);
|
||||
if(person){
|
||||
//Discord ID / name
|
||||
discordString += (person.discordId && (person.discordId !== "")) ? "@" + person.discordId : person.personName;
|
||||
discordString += ": ";
|
||||
//Character Name
|
||||
discordString += ch?.characterName;
|
||||
}
|
||||
else{
|
||||
const classGroup = selectedClassGroups[index];
|
||||
//Class Group
|
||||
discordString += classGroup?.classGroupName ?? "Any Class";
|
||||
discordString += ": ";
|
||||
//Any
|
||||
discordString += "None";
|
||||
}
|
||||
discordString += "\n";
|
||||
});
|
||||
|
||||
navigator.clipboard.writeText(discordString);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<tbody
|
||||
id="instanceTableBody"
|
||||
>
|
||||
{
|
||||
characterGrid.map((run, runIndex) => (
|
||||
<tr
|
||||
key={runIndex}
|
||||
>
|
||||
{
|
||||
run.map((ch, chIndex) => (
|
||||
<td
|
||||
key={chIndex}
|
||||
className="px-4 py-2 border-2 cursor-default"
|
||||
onClick={() => onClickBodyCell(runIndex, chIndex)}
|
||||
>
|
||||
<div
|
||||
className="flex flex-row justify-start flex-nowrap"
|
||||
>
|
||||
{
|
||||
ch?.gameClassId &&
|
||||
<img
|
||||
className="mr-2 max-h-8 max-w-8"
|
||||
src={`${import.meta.env.VITE_ICON_URL}/gameClass/id/${ch.gameClassId}`}
|
||||
/>
|
||||
}
|
||||
{ch ? ch.characterName : "None"}
|
||||
</div>
|
||||
</td>
|
||||
))
|
||||
}
|
||||
<td
|
||||
className="pl-2"
|
||||
>
|
||||
<div
|
||||
className="flex flex-row justify-center items-center cursor-pointer p-2 space-x-2"
|
||||
>
|
||||
<DangerButton
|
||||
variant="ghost"
|
||||
shape="square"
|
||||
onClick={() => removeRun(runIndex)}
|
||||
>
|
||||
<BsXLg
|
||||
size={22}
|
||||
strokeWidth={2}
|
||||
/>
|
||||
</DangerButton>
|
||||
<TertiaryButton
|
||||
variant="ghost"
|
||||
shape="square"
|
||||
onClick={() => copyDiscordStringToClipBoard(runIndex)}
|
||||
>
|
||||
<BsDiscord
|
||||
size={22}
|
||||
/>
|
||||
</TertiaryButton>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
</tbody>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { useRaidInstanceContext } from "@/providers/RaidInstanceLayoutProvider";
|
||||
|
||||
|
||||
export default function RaidInstanceCreatorTableHeader({
|
||||
onClickHeaderCell
|
||||
}:{
|
||||
onClickHeaderCell: (slot: number) => void;
|
||||
}){
|
||||
const { selectedClassGroups } = useRaidInstanceContext();
|
||||
|
||||
|
||||
return (
|
||||
<thead>
|
||||
<tr
|
||||
id="instanceTableHead"
|
||||
>
|
||||
{
|
||||
selectedClassGroups.map((classGroup, index) => (
|
||||
<th
|
||||
key={index}
|
||||
className="px-4 py-2 border-2 cursor-pointer"
|
||||
onClick={() => onClickHeaderCell(index)}
|
||||
>
|
||||
{classGroup?.classGroupName ?? "Any"}
|
||||
</th>
|
||||
))
|
||||
}
|
||||
<th
|
||||
className="px-4 py-2"
|
||||
>
|
||||
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
);
|
||||
}
|
||||
12
src/ui/raidInstance/creator/RaidInstanceCreatorUI.tsx
Normal file
12
src/ui/raidInstance/creator/RaidInstanceCreatorUI.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import RaidInstanceHeader from "../RaidInstanceHeader";
|
||||
import RaidInstanceCreator from "./RaidInstanceCreator";
|
||||
|
||||
|
||||
export default function RaidInstanceCreatorUI(){
|
||||
return (
|
||||
<>
|
||||
<RaidInstanceHeader/>
|
||||
<RaidInstanceCreator/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
64
src/ui/raidInstance/modals/DeleteRaidInstanceModal.tsx
Normal file
64
src/ui/raidInstance/modals/DeleteRaidInstanceModal.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import DangerButton from "@/components/button/DangerButton";
|
||||
import SecondaryButton from "@/components/button/SecondaryButton";
|
||||
import RaidBuilderModal from "@/components/modal/RaidBuilderModal";
|
||||
import { useDeleteRaidInstance } from "@/hooks/RaidInstanceHooks";
|
||||
import { RaidInstance } from "@/interface/RaidInstance";
|
||||
import { useTimedModal } from "@/providers/TimedModalProvider";
|
||||
import { useEffect } from "react";
|
||||
|
||||
|
||||
export default function DeleteRaidInstanceModal({
|
||||
display,
|
||||
close,
|
||||
raidInstance
|
||||
}:{
|
||||
display: boolean;
|
||||
close: () => void;
|
||||
raidInstance?: RaidInstance;
|
||||
}){
|
||||
const deleteRaidInstanceMutate = useDeleteRaidInstance(raidInstance?.raidGroupId ?? "", raidInstance?.raidInstanceId ?? "");
|
||||
const { addSuccessMessage, addErrorMessage } = useTimedModal();
|
||||
|
||||
|
||||
const deleteRaidInstance = () => {
|
||||
deleteRaidInstanceMutate.mutate();
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if(deleteRaidInstanceMutate.status === "success"){
|
||||
deleteRaidInstanceMutate.reset();
|
||||
addSuccessMessage("Raid Instance Deleted");
|
||||
close();
|
||||
}
|
||||
else if(deleteRaidInstanceMutate.status === "error"){
|
||||
deleteRaidInstanceMutate.reset();
|
||||
addErrorMessage(`Error deleting raid instance ${raidInstance?.raidInstanceName}: ${deleteRaidInstanceMutate.error.message}`);
|
||||
console.log(deleteRaidInstanceMutate.error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return (
|
||||
<RaidBuilderModal
|
||||
display={display}
|
||||
close={close}
|
||||
modalHeader={`Delete Raid Instance`}
|
||||
modalBody={`Are you sure you want to delete ${raidInstance?.raidInstanceName}`}
|
||||
modalFooter={
|
||||
<>
|
||||
<DangerButton
|
||||
onClick={deleteRaidInstance}
|
||||
>
|
||||
Delete
|
||||
</DangerButton>
|
||||
<SecondaryButton
|
||||
onClick={close}
|
||||
>
|
||||
Cancel
|
||||
</SecondaryButton>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
156
src/ui/raidInstance/modals/RaidInstanceModal.tsx
Normal file
156
src/ui/raidInstance/modals/RaidInstanceModal.tsx
Normal file
@@ -0,0 +1,156 @@
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import SecondaryButton from "@/components/button/SecondaryButton";
|
||||
import DateInput from "@/components/input/DateInput";
|
||||
import TextInput from "@/components/input/TextInput";
|
||||
import RaidBuilderModal from "@/components/modal/RaidBuilderModal";
|
||||
import { useCreateRaidInstance, useUpdateRaidInstance } from "@/hooks/RaidInstanceHooks";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { RaidInstance } from "@/interface/RaidInstance";
|
||||
import { useTimedModal } from "@/providers/TimedModalProvider";
|
||||
import moment from "moment";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
|
||||
export default function RaidInstanceModal({
|
||||
display,
|
||||
close,
|
||||
raidInstance,
|
||||
raidGroup
|
||||
}:{
|
||||
display: boolean;
|
||||
close: () => void;
|
||||
raidInstance?: RaidInstance;
|
||||
raidGroup: RaidGroup;
|
||||
}){
|
||||
const [raidInstanceName, setRaidInstanceName] = useState("");
|
||||
const [raidStartDate, setRaidStartDate] = useState(new Date());
|
||||
const [raidEndDate, setRaidEndDate] = useState(new Date());
|
||||
const [raidSize, setRaidSize] = useState(3);
|
||||
const [numberRuns, setNumberRuns] = useState(1);
|
||||
const modalId = crypto.randomUUID().replaceAll("-", "");
|
||||
|
||||
const createRaidInstanceMutate = useCreateRaidInstance(raidGroup.raidGroupId ?? "");
|
||||
const updateRaidInstanceMutate = useUpdateRaidInstance(raidGroup.raidGroupId ?? "");
|
||||
const { addSuccessMessage, addErrorMessage } = useTimedModal();
|
||||
|
||||
useEffect(() => {
|
||||
if(raidInstance){
|
||||
setRaidInstanceName(raidInstance.raidInstanceName ?? "");
|
||||
setRaidStartDate(raidInstance.raidStartDate);
|
||||
setRaidEndDate(raidInstance.raidEndDate);
|
||||
setRaidSize(raidInstance.raidSize ?? 0);
|
||||
setNumberRuns(raidInstance.numberRuns);
|
||||
}
|
||||
else{
|
||||
const currentDate = new Date();
|
||||
const futureDate = new Date();
|
||||
futureDate.setHours(futureDate.getHours() + 1);
|
||||
setRaidInstanceName("");
|
||||
setRaidStartDate(currentDate);
|
||||
setRaidEndDate(futureDate);
|
||||
setRaidSize(3);
|
||||
setNumberRuns(1);
|
||||
}
|
||||
}, [ display, raidInstance ]);
|
||||
|
||||
useEffect(() => {
|
||||
if(createRaidInstanceMutate.status === "success"){
|
||||
createRaidInstanceMutate.reset();
|
||||
addSuccessMessage("Raid Instance Created");
|
||||
close();
|
||||
}
|
||||
else if(createRaidInstanceMutate.status === "error"){
|
||||
createRaidInstanceMutate.reset();
|
||||
addErrorMessage(`Error creating raid instance ${raidInstanceName}: ${createRaidInstanceMutate.error.message}`);
|
||||
console.log(createRaidInstanceMutate.error);
|
||||
}
|
||||
else if(updateRaidInstanceMutate.status === "success"){
|
||||
updateRaidInstanceMutate.reset();
|
||||
addSuccessMessage("Raid Instance Updated");
|
||||
close();
|
||||
}
|
||||
else if(updateRaidInstanceMutate.status === "error"){
|
||||
updateRaidInstanceMutate.reset();
|
||||
addErrorMessage(`Error updating raid instance ${raidInstanceName}: ${updateRaidInstanceMutate.error.message}`);
|
||||
console.log(updateRaidInstanceMutate.error);
|
||||
}
|
||||
});
|
||||
|
||||
const createRaidInstance = () => {
|
||||
createRaidInstanceMutate.mutate({
|
||||
raidInstanceName,
|
||||
raidStartDate,
|
||||
raidEndDate,
|
||||
raidSize,
|
||||
numberRuns,
|
||||
raidGroupId: raidGroup.raidGroupId ?? ""
|
||||
});
|
||||
}
|
||||
|
||||
const updateRaidInstance = () => {
|
||||
updateRaidInstanceMutate.mutate({
|
||||
raidInstanceId: raidInstance?.raidInstanceId,
|
||||
raidInstanceName,
|
||||
raidStartDate,
|
||||
raidEndDate,
|
||||
raidSize,
|
||||
numberRuns,
|
||||
raidGroupId: raidGroup.raidGroupId ?? ""
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<RaidBuilderModal
|
||||
display={display}
|
||||
close={close}
|
||||
modalHeader={raidInstance ? "Update Raid Instance" : "Create Raid Instance"}
|
||||
modalBody={
|
||||
<div
|
||||
className="flex flex-col items-center justify-center gap-4"
|
||||
>
|
||||
<TextInput
|
||||
id={`raidInstanceName${modalId}`}
|
||||
placeholder="Raid Instance Name"
|
||||
value={raidInstanceName}
|
||||
onChange={(e) => setRaidInstanceName(e.target.value)}
|
||||
/>
|
||||
<br/>
|
||||
{/*
|
||||
<NumberInput
|
||||
id="raidSizeInput"
|
||||
min={1}
|
||||
max={100}
|
||||
value={raidSize}
|
||||
onChange={setRaidSize}
|
||||
/>
|
||||
*/}
|
||||
<DateInput
|
||||
id="raidStartDateInput"
|
||||
value={moment(raidStartDate).format("YYYY-MM-DDTHH:mm")}
|
||||
onChange={(e) => setRaidStartDate(moment(e.target.value).toDate())}
|
||||
/>
|
||||
<DateInput
|
||||
id="raidEndDateInput"
|
||||
value={moment(raidEndDate).format("YYYY-MM-DDTHH:mm")}
|
||||
onChange={(e) => setRaidEndDate(moment(e.target.value).toDate())}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
modalFooter={
|
||||
<>
|
||||
<PrimaryButton
|
||||
onClick={raidInstance ? updateRaidInstance : createRaidInstance}
|
||||
>
|
||||
{raidInstance ? "Update" : "Create"}
|
||||
</PrimaryButton>
|
||||
<SecondaryButton
|
||||
onClick={close}
|
||||
>
|
||||
Cancel
|
||||
</SecondaryButton>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user