diff --git a/src/components/classGroup/ClassGroupsByRaidLayoutDisplay.tsx b/src/components/classGroup/ClassGroupsByRaidLayoutDisplay.tsx
index 59fc941..6324349 100644
--- a/src/components/classGroup/ClassGroupsByRaidLayoutDisplay.tsx
+++ b/src/components/classGroup/ClassGroupsByRaidLayoutDisplay.tsx
@@ -20,7 +20,7 @@ export default function ClassGroupsByRaidLayoutDisplay({
else{
return (
{
classGroupsQuery.data.map((classGroup, index) => (
diff --git a/src/hooks/RaidInstanceHooks.ts b/src/hooks/RaidInstanceHooks.ts
new file mode 100644
index 0000000..fd3d1fc
--- /dev/null
+++ b/src/hooks/RaidInstanceHooks.ts
@@ -0,0 +1,140 @@
+import { RaidInstance } from "@/interface/RaidInstance";
+import { api } from "@/util/AxiosUtil";
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
+
+
+export function useGetRaidInstance(raidInstanceId: string, raidGroupId: string){
+ return useQuery({
+ queryKey: ["raidInstances", raidInstanceId, raidGroupId],
+ queryFn: async () => {
+ const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}`);
+
+ if(response.status !== 200){
+ throw new Error("Failed to get raid instance");
+ }
+ else if(response.data.errors){
+ throw new Error(response.data.errors.join(", "));
+ }
+
+ return response.data as RaidInstance;
+ }
+ });
+}
+
+export function useGetRaidInstancesByRaidGroup(raidGroupId: string, page: number, pageSize: number, searchTerm?: string){
+ return useQuery({
+ queryKey: ["raidInstances", raidGroupId, {page, pageSize, searchTerm}],
+ queryFn: async () => {
+ const params = new URLSearchParams();
+ params.append("page", page.toString());
+ params.append("pageSize", pageSize.toString());
+ if(searchTerm){
+ params.append("searchTerm", searchTerm);
+ }
+
+ const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance?${params}`);
+
+ if(response.status !== 200){
+ throw new Error("Failed to get accounts");
+ }
+ else if(response.data.errors){
+ throw new Error(response.data.errors.join(", "));
+ }
+
+ return response.data as RaidInstance[];
+ }
+ });
+}
+
+
+export function useGetRaidInstancesByRaidGroupCount(raidGroupId: string, searchTerm?: string){
+ return useQuery({
+ queryKey: ["raidInstances", raidGroupId, "count", {searchTerm}],
+ queryFn: async () => {
+ const params = new URLSearchParams();
+ if(searchTerm){
+ params.append("searchTerm", searchTerm);
+ }
+
+ const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/count?${params}`);
+
+ if(response.status !== 200){
+ throw new Error("Failed to get accounts");
+ }
+ else if(response.data.errors){
+ throw new Error(response.data.errors.join(", "));
+ }
+
+ return response.data.count as number;
+ }
+ });
+}
+
+
+export function useCreateRaidInstance(raidGroupId: string){
+ const queryClient = useQueryClient();
+
+
+ return useMutation({
+ mutationKey: ["createRaidInstance", raidGroupId],
+ mutationFn: async (raidInstance: RaidInstance) => {
+ const response = await api.post(`/raidGroup/${raidGroupId}/raidInstance`, raidInstance);
+
+ if(response.status !== 200){
+ throw new Error("Failed to create raid instance");
+ }
+ else if(response.data.errors){
+ throw new Error(response.data.errors.join(", "));
+ }
+ },
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ["raidInstances"] });
+ }
+ });
+}
+
+export function useUpdateRaidInstance(raidGroupId: string){
+ const queryClient = useQueryClient();
+
+
+ return useMutation({
+ mutationKey: ["updateRaidInstance", raidGroupId],
+ mutationFn: async (raidInstance: RaidInstance) => {
+ console.log("raidInstance");
+ console.log(raidInstance);
+ const response = await api.put(`/raidGroup/${raidGroupId}/raidInstance/${raidInstance.raidInstanceId}`, raidInstance);
+
+ if(response.status !== 200){
+ throw new Error("Failed to update raid instance");
+ }
+ else if(response.data.errors){
+ throw new Error(response.data.errors.join(", "));
+ }
+ },
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ["raidInstances"] });
+ }
+ });
+}
+
+export function useDeleteRaidInstance(raidGroupId: string, raidInstanceId: string){
+ const queryClient = useQueryClient();
+
+
+ return useMutation({
+ mutationKey: ["deleteRaidInstance", raidGroupId, raidInstanceId],
+ mutationFn: async () => {
+ const response = await api.delete(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}`);
+
+ if(response.status !== 200){
+ throw new Error("Failed to delete raid instance");
+ }
+ else if(response.data.errors){
+ throw new Error(response.data.errors.join(", "));
+ }
+ },
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ["raidInstances"] });
+ }
+ });
+}
diff --git a/src/interface/RaidInstance.ts b/src/interface/RaidInstance.ts
new file mode 100644
index 0000000..bce396e
--- /dev/null
+++ b/src/interface/RaidInstance.ts
@@ -0,0 +1,10 @@
+export interface RaidInstance {
+ raidInstanceId?: string;
+ raidGroupId: string;
+ raidLayoutId?: string;
+ raidInstanceName?: string;
+ raidSize?: number;
+ numberRuns: number;
+ raidStartDate: Date;
+ raidEndDate: Date;
+}
diff --git a/src/pages/protected/RaidGroupPage.tsx b/src/pages/protected/RaidGroupPage.tsx
index da9e5f3..8631f68 100644
--- a/src/pages/protected/RaidGroupPage.tsx
+++ b/src/pages/protected/RaidGroupPage.tsx
@@ -7,7 +7,7 @@ import RaidGroupHeader from "@/ui/calendar/RaidGroupHeader";
import ClassGroupsTab from "@/ui/classGroup/ClassGroupsTab";
import PersonTab from "@/ui/person/PersonTab";
import RaidGroupRequestTab from "@/ui/raidGroupRequest/RaidGroupRequestTab";
-import RaidInstancesTab from "@/ui/raidInstances/RaidInstancesTab";
+import RaidInstanceTab from "@/ui/raidInstances/RaidInstanceTab";
import RaidLayoutTab from "@/ui/raidLayout/RaidLayoutTab";
import { useEffect, useState } from "react";
import { Navigate, useParams } from "react-router";
@@ -61,7 +61,7 @@ export default function RaidGroupPage(){
},
{
tabHeader: "Raid Instances",
- tabContent:
+ tabContent:
},
{
tabHeader: "Users",
diff --git a/src/ui/game/GamesListSkeleton.tsx b/src/ui/game/GamesListSkeleton.tsx
index e754353..0fbca22 100644
--- a/src/ui/game/GamesListSkeleton.tsx
+++ b/src/ui/game/GamesListSkeleton.tsx
@@ -4,6 +4,7 @@ import { elementBg } from "@/util/SkeletonUtil";
import React from "react";
import GameAdminButtons from "./GameAdminButtons";
+
export default function GamesListSkeleton(){
const headElements: React.ReactNode[] = [
diff --git a/src/ui/raidInstances/RaidInstanceAdminButtons.tsx b/src/ui/raidInstances/RaidInstanceAdminButtons.tsx
new file mode 100644
index 0000000..c082203
--- /dev/null
+++ b/src/ui/raidInstances/RaidInstanceAdminButtons.tsx
@@ -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 (
+
+ );
+}
diff --git a/src/ui/raidInstances/RaidInstanceList.tsx b/src/ui/raidInstances/RaidInstanceList.tsx
new file mode 100644
index 0000000..30faaca
--- /dev/null
+++ b/src/ui/raidInstances/RaidInstanceList.tsx
@@ -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
();
+ const [ displayEditRaidInstanceModal, setDisplayEditRaidInstanceModal ] = useState(false);
+ const [ displayDeleteRaidInstanceModal, setDisplayDeleteRaidInstanceModal ] = useState(false);
+
+
+ const buttonProps: ButtonProps = {
+ variant: "ghost",
+ size: "md",
+ shape: "square"
+ };
+
+
+ const headElements: React.ReactNode[] = [
+
+ Raid Instance
+
,
+
+ Start Date
+
,
+
+ End Date
+
,
+
+ Size
+
,
+
+ Runs
+
,
+
+ Actions
+
+ ];
+
+ const bodyElements: React.ReactNode[][] = raidInstances.map((raidInstance) => [
+
+ {raidInstance.raidInstanceName}
+ ,
+
+ {moment(raidInstance.raidStartDate).format("MM-DD-YYYY HH:mm")}
+
,
+
+ {moment(raidInstance.raidEndDate).format("MM-DD-YYYY HH:mm")}
+
,
+
+ {raidInstance.raidSize}
+
,
+
+ {raidInstance.numberRuns}
+
,
+
+
+
+
+
{ setSelectedRaidInstance(raidInstance); setDisplayEditRaidInstanceModal(true); }}
+ showDeleteRaidInstanceModal={() => { setSelectedRaidInstance(raidInstance); setDisplayDeleteRaidInstanceModal(true); }}
+ />
+
+ ]);
+
+
+ return (
+ <>
+
+ { setDisplayEditRaidInstanceModal(false); setSelectedRaidInstance(undefined); }}
+ raidInstance={selectedRaidInstance}
+ raidGroup={raidGroup}
+ />
+ { setDisplayDeleteRaidInstanceModal(false); setSelectedRaidInstance(undefined); }}
+ raidInstance={selectedRaidInstance}
+ />
+ >
+ );
+}
diff --git a/src/ui/raidInstances/RaidInstanceListSkeleton.tsx b/src/ui/raidInstances/RaidInstanceListSkeleton.tsx
new file mode 100644
index 0000000..5a842a7
--- /dev/null
+++ b/src/ui/raidInstances/RaidInstanceListSkeleton.tsx
@@ -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[] = [
+
+ Raid Instance
+
,
+
+ Start Date
+
,
+
+ End Date
+
,
+
+ Size
+
,
+
+ Runs
+
,
+
+ Actions
+
+ ];
+
+ const bodyElements: React.ReactNode[][] = [
+ RaidInstanceSkeleton(),
+ RaidInstanceSkeleton(),
+ RaidInstanceSkeleton(),
+ RaidInstanceSkeleton(),
+ RaidInstanceSkeleton(),
+ RaidInstanceSkeleton(),
+ RaidInstanceSkeleton(),
+ RaidInstanceSkeleton(),
+ RaidInstanceSkeleton(),
+ RaidInstanceSkeleton()
+ ];
+
+
+ return (
+
+ );
+}
+
+
+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[] = [
+ ,
+ ,
+ ,
+ ,
+ ,
+
+ ];
+
+ return elements;
+}
diff --git a/src/ui/raidInstances/RaidInstanceLoader.tsx b/src/ui/raidInstances/RaidInstanceLoader.tsx
new file mode 100644
index 0000000..d528b0b
--- /dev/null
+++ b/src/ui/raidInstances/RaidInstanceLoader.tsx
@@ -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
+ }
+ else if(raidInstancesQuery.status === "error"){
+ return Error: {raidInstancesQuery.error.message}
+ }
+ else{
+ return (
+
+ );
+ }
+}
diff --git a/src/ui/raidInstances/RaidInstanceTab.tsx b/src/ui/raidInstances/RaidInstanceTab.tsx
new file mode 100644
index 0000000..672f4a5
--- /dev/null
+++ b/src/ui/raidInstances/RaidInstanceTab.tsx
@@ -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();
+ 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 (
+ <>
+
+
+
+
+ {/* Add Raid Instance Button */}
+
+
setDisplayCreateRaidInstanceModal(true)}
+ >
+ Create Raid Instance
+
+
setDisplayCreateRaidInstanceModal(false)}
+ raidInstance={undefined}
+ raidGroup={raidGroup}
+ />
+
+ {/* Raid Instance Search Box */}
+
+
+ setSearchTerm(e.target.value)}
+ placeholder="Search"
+ />
+
+
+
+ {/* Raid Layout List */}
+
+ {/* Pagination */}
+
+ >
+ );
+}
diff --git a/src/ui/raidInstances/RaidInstancesTab.tsx b/src/ui/raidInstances/RaidInstancesTab.tsx
deleted file mode 100644
index 4960708..0000000
--- a/src/ui/raidInstances/RaidInstancesTab.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-export default function RaidInstancesTab(){
- return (
-
- Raid Instances tab
-
- );
-}
diff --git a/src/ui/raidInstances/modals/DeleteRaidInstanceModal.tsx b/src/ui/raidInstances/modals/DeleteRaidInstanceModal.tsx
new file mode 100644
index 0000000..412cf24
--- /dev/null
+++ b/src/ui/raidInstances/modals/DeleteRaidInstanceModal.tsx
@@ -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 (
+
+
+ Delete
+
+
+ Cancel
+
+ >
+ }
+ />
+ );
+}
diff --git a/src/ui/raidInstances/modals/RaidInstanceModal.tsx b/src/ui/raidInstances/modals/RaidInstanceModal.tsx
new file mode 100644
index 0000000..0d660f6
--- /dev/null
+++ b/src/ui/raidInstances/modals/RaidInstanceModal.tsx
@@ -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(0);
+ const [numberRuns, setNumberRuns] = useState(0);
+ 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(0);
+ setNumberRuns(0);
+ }
+ }, [ 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 (
+
+ setRaidInstanceName(e.target.value)}
+ />
+
+ {/*
+
+ */}
+ setRaidStartDate(moment(e.target.value).toDate())}
+ />
+ setRaidEndDate(moment(e.target.value).toDate())}
+ />
+
+ }
+ modalFooter={
+ <>
+
+ {raidInstance ? "Update" : "Create"}
+
+
+ Cancel
+
+ >
+ }
+ />
+ );
+}
diff --git a/src/ui/raidLayout/RaidLayoutListSkeleton.tsx b/src/ui/raidLayout/RaidLayoutListSkeleton.tsx
new file mode 100644
index 0000000..429f4d1
--- /dev/null
+++ b/src/ui/raidLayout/RaidLayoutListSkeleton.tsx
@@ -0,0 +1,85 @@
+import { ButtonShape, ButtonSizeType, ButtonVariant } from "@/components/button/Button";
+import Table from "@/components/table/Table";
+import { elementBg } from "@/util/SkeletonUtil";
+import RaidLayoutAdminButtons from "./RaidLayoutAdminButtons";
+
+
+export default function RaidLayoutListSkeleton(){
+ const headElements: React.ReactNode[] = [
+
+ Raid Layout Name
+
,
+
+ Raid Size
+
,
+
+ Class Groups
+
,
+
+ Actions
+
+ ];
+
+ const bodyElements: React.ReactNode[][] = [
+ RaidLayoutSkeleton(),
+ RaidLayoutSkeleton(),
+ RaidLayoutSkeleton(),
+ RaidLayoutSkeleton(),
+ RaidLayoutSkeleton(),
+ RaidLayoutSkeleton(),
+ RaidLayoutSkeleton(),
+ RaidLayoutSkeleton(),
+ RaidLayoutSkeleton(),
+ RaidLayoutSkeleton()
+ ];
+
+
+ return (
+
+ );
+}
+
+
+function RaidLayoutSkeleton(){
+ const buttonsProps = {
+ buttonProps: {
+ variant: "ghost" as ButtonVariant,
+ size: "md" as ButtonSizeType,
+ shape: "square" as ButtonShape,
+ disabled: true
+ },
+ showRaidLayoutModal: () => {},
+ showDeleteRaidLayoutModal: () => {}
+ };
+
+ const elements: React.ReactNode[] = [
+ ,
+ ,
+ ,
+
+ ];
+
+ return elements;
+}
diff --git a/src/ui/raidLayout/modal/RaidLayoutModal.tsx b/src/ui/raidLayout/modal/RaidLayoutModal.tsx
index d5b74a6..a0dbf51 100644
--- a/src/ui/raidLayout/modal/RaidLayoutModal.tsx
+++ b/src/ui/raidLayout/modal/RaidLayoutModal.tsx
@@ -45,7 +45,7 @@ export default function RaidLayoutModal({
else if(newLayoutSize > classGroups.length){
setClassGroups([
...classGroups,
- null
+ ...Array(newLayoutSize - classGroups.length).fill(null)
]);
}
}
@@ -128,7 +128,7 @@ export default function RaidLayoutModal({
/>