Buttons hidden by permissions
This commit is contained in:
@@ -3,10 +3,14 @@ import DangerButton from "@/components/button/DangerButton";
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import TertiaryButton from "@/components/button/TertiaryButton";
|
||||
import WarningButton from "@/components/button/WarningButton";
|
||||
import { Account } from "@/interface/Account";
|
||||
import { useTheme } from "@/providers/ThemeProvider";
|
||||
import { BsKeyFill, BsLockFill, BsPencilFill, BsTrash3, BsXCircle } from "react-icons/bs";
|
||||
import { Tooltip } from "react-tooltip";
|
||||
|
||||
|
||||
export default function AccountAdminButtons({
|
||||
account,
|
||||
buttonProps,
|
||||
showForcePasswordResetModal,
|
||||
showAccountPasswordSetModal,
|
||||
@@ -14,6 +18,7 @@ export default function AccountAdminButtons({
|
||||
showUpdateAccountModal,
|
||||
showDeleteAccountModal
|
||||
}:{
|
||||
account?: Account;
|
||||
buttonProps: ButtonProps;
|
||||
showForcePasswordResetModal: () => void;
|
||||
showAccountPasswordSetModal: () => void;
|
||||
@@ -21,13 +26,20 @@ export default function AccountAdminButtons({
|
||||
showUpdateAccountModal: () => void;
|
||||
showDeleteAccountModal: () => void;
|
||||
}){
|
||||
const { theme } = useTheme();
|
||||
const componentId = crypto.randomUUID().replaceAll("-", "");
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-row gap-2"
|
||||
>
|
||||
<WarningButton
|
||||
{...buttonProps}
|
||||
id={`accountAdminButtonsForceReset${componentId}`}
|
||||
onClick={showForcePasswordResetModal}
|
||||
aria-label={`Force Password Reset for ${account?.username}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsLockFill
|
||||
size={22}
|
||||
@@ -35,7 +47,10 @@ export default function AccountAdminButtons({
|
||||
</WarningButton>
|
||||
<DangerButton
|
||||
{...buttonProps}
|
||||
id={`accountAdminButtonsPasswordSet${componentId}`}
|
||||
onClick={showAccountPasswordSetModal}
|
||||
aria-label={`Set Password for ${account?.username}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsKeyFill
|
||||
size={22}
|
||||
@@ -43,7 +58,10 @@ export default function AccountAdminButtons({
|
||||
</DangerButton>
|
||||
<TertiaryButton
|
||||
{...buttonProps}
|
||||
id={`accountAdminButtonsRevokeRefreshToken${componentId}`}
|
||||
onClick={showRevokeRefreshTokenModal}
|
||||
aria-label={`Revoke Refresh Token for ${account?.username}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsXCircle
|
||||
size={22}
|
||||
@@ -51,7 +69,10 @@ export default function AccountAdminButtons({
|
||||
</TertiaryButton>
|
||||
<PrimaryButton
|
||||
{...buttonProps}
|
||||
id={`accountAdminButtonsUpdate${componentId}`}
|
||||
onClick={showUpdateAccountModal}
|
||||
aria-label={`Update ${account?.username}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsPencilFill
|
||||
size={22}
|
||||
@@ -59,12 +80,50 @@ export default function AccountAdminButtons({
|
||||
</PrimaryButton>
|
||||
<DangerButton
|
||||
{...buttonProps}
|
||||
id={`accountAdminButtonsDelete${componentId}`}
|
||||
onClick={showDeleteAccountModal}
|
||||
aria-label={`Delete ${account?.username}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsTrash3
|
||||
size={22}
|
||||
/>
|
||||
</DangerButton>
|
||||
<Tooltip
|
||||
anchorSelect={`#accountAdminButtonsForceReset${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Force Password Reset
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#accountAdminButtonsPasswordSet${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Set Password
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#accountAdminButtonsRevokeRefreshToken${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Revoke Refresh Token
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#accountAdminButtonsUpdate${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Update {account?.username}
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#accountAdminButtonsDelete${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Delete {account?.username}
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ import { ButtonProps } from "@/components/button/Button";
|
||||
import Table from "@/components/table/Table";
|
||||
import { Account } from "@/interface/Account";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isSiteAdmin } from "@/util/PermissionUtil";
|
||||
import moment from "moment";
|
||||
import { useState } from "react";
|
||||
import AccountAdminButtons from "./AccountAdminButtons";
|
||||
@@ -22,6 +24,7 @@ export default function AccountsList({
|
||||
accounts: Account[];
|
||||
raidGroup?: RaidGroup;
|
||||
}){
|
||||
const { accountPermissions } = useAuth();
|
||||
const [ selectedAccount, setSelectedAccount ] = useState<Account | undefined>(undefined);
|
||||
const [ displayForcePasswordResetModal, setDisplayForcePasswordResetModal ] = useState(false);
|
||||
const [ displayAccountPasswordSetModal, setDisplayAccountPasswordSetModal ] = useState(false);
|
||||
@@ -40,12 +43,10 @@ export default function AccountsList({
|
||||
|
||||
|
||||
const headElements: React.ReactNode[] = [
|
||||
<div>
|
||||
ID
|
||||
</div>,
|
||||
<div>
|
||||
Username
|
||||
</div>,
|
||||
isSiteAdmin(accountPermissions) &&
|
||||
<div>
|
||||
Email
|
||||
</div>,
|
||||
@@ -64,20 +65,18 @@ export default function AccountsList({
|
||||
|
||||
const bodyElements: React.ReactNode[][] = accounts.map((account) => [
|
||||
<div
|
||||
className="text-nowrap"
|
||||
className="text-nowrap pl-2 text-start"
|
||||
>
|
||||
{account.accountId}
|
||||
</div>,
|
||||
<div>
|
||||
{account.username}
|
||||
</div>,
|
||||
isSiteAdmin(accountPermissions) &&
|
||||
<div>
|
||||
{account.email}
|
||||
</div>,
|
||||
<div
|
||||
className="text-nowrap"
|
||||
>
|
||||
{moment(account.loginDate).format("MM-DD-YYYY HH:mm")}
|
||||
{account.loginDate ? moment(account.loginDate).format("MM-DD-YYYY HH:mm") : <> </>}
|
||||
</div>,
|
||||
<div>
|
||||
{account.accountStatus}
|
||||
@@ -90,29 +89,33 @@ export default function AccountsList({
|
||||
>
|
||||
|
||||
</div>
|
||||
<AccountAdminButtons
|
||||
buttonProps={buttonProps}
|
||||
showForcePasswordResetModal={() => {
|
||||
setSelectedAccount(account);
|
||||
setDisplayForcePasswordResetModal(true);
|
||||
}}
|
||||
showAccountPasswordSetModal={() => {
|
||||
setSelectedAccount(account);
|
||||
setDisplayAccountPasswordSetModal(true);
|
||||
}}
|
||||
showRevokeRefreshTokenModal={() => {
|
||||
setSelectedAccount(account);
|
||||
setDisplayRevokeRefreshTokenModal(true);
|
||||
}}
|
||||
showUpdateAccountModal={() => {
|
||||
setSelectedAccount(account);
|
||||
setDisplayAccountModal(true);
|
||||
}}
|
||||
showDeleteAccountModal={() => {
|
||||
setSelectedAccount(account);
|
||||
setDisplayDeleteAccountModal(true);
|
||||
}}
|
||||
/>
|
||||
{
|
||||
isSiteAdmin(accountPermissions) &&
|
||||
<AccountAdminButtons
|
||||
account={account}
|
||||
buttonProps={buttonProps}
|
||||
showForcePasswordResetModal={() => {
|
||||
setSelectedAccount(account);
|
||||
setDisplayForcePasswordResetModal(true);
|
||||
}}
|
||||
showAccountPasswordSetModal={() => {
|
||||
setSelectedAccount(account);
|
||||
setDisplayAccountPasswordSetModal(true);
|
||||
}}
|
||||
showRevokeRefreshTokenModal={() => {
|
||||
setSelectedAccount(account);
|
||||
setDisplayRevokeRefreshTokenModal(true);
|
||||
}}
|
||||
showUpdateAccountModal={() => {
|
||||
setSelectedAccount(account);
|
||||
setDisplayAccountModal(true);
|
||||
}}
|
||||
showDeleteAccountModal={() => {
|
||||
setSelectedAccount(account);
|
||||
setDisplayDeleteAccountModal(true);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
{
|
||||
raidGroup &&
|
||||
<RaidGroupAccountAdminButtons
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { ButtonProps } from "@/components/button/Button";
|
||||
import DangerButton from "@/components/button/DangerButton";
|
||||
import WarningButton from "@/components/button/WarningButton";
|
||||
import { useTheme } from "@/providers/ThemeProvider";
|
||||
import { BsKeyFill, BsTrash3 } from "react-icons/bs";
|
||||
import { Tooltip } from "react-tooltip";
|
||||
|
||||
|
||||
export default function RaidGroupAccountAdminButtons({
|
||||
@@ -13,13 +15,20 @@ export default function RaidGroupAccountAdminButtons({
|
||||
showRaidGroupPermissionsModal: () => void;
|
||||
showRemoveFromRaidGroupModal: () => void;
|
||||
}){
|
||||
const { theme } = useTheme();
|
||||
const componentId = crypto.randomUUID().replaceAll("-", "");
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-row gap-2"
|
||||
>
|
||||
<WarningButton
|
||||
{...buttonProps}
|
||||
id={`raidGroupAccountAdminButtonsPermissions${componentId}`}
|
||||
onClick={showRaidGroupPermissionsModal}
|
||||
aria-label="Edit Permissions"
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsKeyFill
|
||||
size={22}
|
||||
@@ -27,12 +36,29 @@ export default function RaidGroupAccountAdminButtons({
|
||||
</WarningButton>
|
||||
<DangerButton
|
||||
{...buttonProps}
|
||||
id={`raidGroupAccountAdminButtonsRemove${componentId}`}
|
||||
onClick={showRemoveFromRaidGroupModal}
|
||||
aria-label="Remove from Raid Group"
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsTrash3
|
||||
size={22}
|
||||
/>
|
||||
</DangerButton>
|
||||
<Tooltip
|
||||
anchorSelect={`#raidGroupAccountAdminButtonsPermissions${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Edit Permissions
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#raidGroupAccountAdminButtonsRemove${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Remove from Raid Group
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function RaidGroupAccountsTab({
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="flex flex-row items-center justify-between w-full"
|
||||
className="flex flex-row items-center justify-between w-full mb-8"
|
||||
>
|
||||
<div
|
||||
className="flex flex-row items-center justify-center w-full"
|
||||
|
||||
@@ -31,7 +31,7 @@ export default function AccountModal({
|
||||
setEmail(account?.email ?? "");
|
||||
setPassword(account?.password ?? "");
|
||||
setAccountStatus(account?.accountStatus ?? AccountStatus.ACTIVE);
|
||||
}, [ account, setUsername, setEmail, setPassword, setAccountStatus ]);
|
||||
}, [ display, account, setUsername, setEmail, setPassword, setAccountStatus ]);
|
||||
|
||||
|
||||
const updateAccountMutate = useUpdateAccount();
|
||||
@@ -103,10 +103,13 @@ export default function AccountModal({
|
||||
/>
|
||||
)
|
||||
}
|
||||
<AccountStatusSelector
|
||||
value={accountStatus}
|
||||
onChange={(e) => setAccountStatus(e.currentTarget.value as AccountStatus)}
|
||||
/>
|
||||
{
|
||||
account &&
|
||||
<AccountStatusSelector
|
||||
value={accountStatus}
|
||||
onChange={(e) => setAccountStatus(e.currentTarget.value as AccountStatus)}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
modalFooter={
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { useCreateGameCalendarEvent, useCreateRaidGroupCalendarEvent, useDeleteGameCalendarEvent, useDeleteRaidGroupCalendarEvent, useUpdateGameCalendarEvent, useUpdateRaidGroupCalendarEvent } from "@/hooks/CalendarHooks";
|
||||
import { CalendarEvent } from "@/interface/Calendar";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { calendarEventToFullCalendarEvent } from "@/util/CalendarUtil";
|
||||
import { isGameAdmin, isRaidGroupAdmin, isRaidGroupLeader } from "@/util/PermissionUtil";
|
||||
import { EventClickArg } from "@fullcalendar/core/index.js";
|
||||
import dayGridPlugin from "@fullcalendar/daygrid";
|
||||
import interactionPlugin, { DateClickArg } from "@fullcalendar/interaction";
|
||||
@@ -19,6 +21,7 @@ export default function CalendarDisplay({
|
||||
raidGroupId?: string;
|
||||
gameId?: string;
|
||||
}){
|
||||
const { accountPermissions, gamePermissions, raidGroupPermissions } = useAuth();
|
||||
const [ displayCalendarEventModal, setDisplayCalendarEventModal ] = useState(false);
|
||||
const [ alterCalendarEvent, setAlterCalendarEvent ] = useState<CalendarEvent>();
|
||||
const [ disableModal, setDisableModal ] = useState(false);
|
||||
@@ -39,6 +42,15 @@ export default function CalendarDisplay({
|
||||
eventStartDate: dateClickArg.date,
|
||||
eventEndDate: moment(dateClickArg.date).add(1, "hours").toDate()
|
||||
} as CalendarEvent);
|
||||
|
||||
if(gameId && !isGameAdmin(gameId, gamePermissions, accountPermissions)){
|
||||
setDisableModal(true);
|
||||
}
|
||||
|
||||
if(raidGroupId && !isRaidGroupAdmin(raidGroupId, raidGroupPermissions, accountPermissions) && !isRaidGroupLeader(raidGroupId, raidGroupPermissions, accountPermissions)){
|
||||
setDisableModal(true);
|
||||
}
|
||||
|
||||
setDisplayCalendarEventModal(true);
|
||||
}
|
||||
|
||||
@@ -47,6 +59,12 @@ export default function CalendarDisplay({
|
||||
if(raidGroupId && calendarEvent?.gameId){
|
||||
setDisableModal(true);
|
||||
}
|
||||
else if(calendarEvent?.gameId && !isGameAdmin(calendarEvent?.gameId, gamePermissions, accountPermissions)){
|
||||
setDisableModal(true);
|
||||
}
|
||||
else if(calendarEvent?.raidGroupId && !isRaidGroupAdmin(calendarEvent?.raidGroupId, raidGroupPermissions, accountPermissions) && !isRaidGroupLeader(calendarEvent?.raidGroupId, raidGroupPermissions, accountPermissions)){
|
||||
setDisableModal(true);
|
||||
}
|
||||
|
||||
setAlterCalendarEvent(calendarEvent);
|
||||
setDisplayCalendarEventModal(true);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { ButtonProps } from "@/components/button/Button";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isRaidGroupAdmin } from "@/util/PermissionUtil";
|
||||
import { useState } from "react";
|
||||
import RaidGroupAdminButtons from "../raidGroup/RaidGroupAdminButtons";
|
||||
import DeleteRaidGroupModal from "../raidGroup/modals/DeleteRaidGroupModal";
|
||||
@@ -11,6 +13,7 @@ export default function RaidGroupHeader({
|
||||
}:{
|
||||
raidGroup: RaidGroup;
|
||||
}){
|
||||
const { accountPermissions, raidGroupPermissions } = useAuth();
|
||||
const [ displayEditRaidGroupModal, setDisplayEditRaidGroupModal ] = useState(false);
|
||||
const [ displayDeleteRaidGroupModal, setDisplayDeleteRaidGroupModal ] = useState(false);
|
||||
|
||||
@@ -39,7 +42,11 @@ export default function RaidGroupHeader({
|
||||
</div>
|
||||
<div>
|
||||
<RaidGroupAdminButtons
|
||||
buttonProps={buttonProps}
|
||||
raidGroup={raidGroup}
|
||||
buttonProps={{
|
||||
...buttonProps,
|
||||
disabled: !isRaidGroupAdmin(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions)
|
||||
}}
|
||||
showEditRaidGroupModal={() => setDisplayEditRaidGroupModal(true)}
|
||||
showDeleteRaidGroupModal={() => setDisplayDeleteRaidGroupModal(true)}
|
||||
hasRaidGroupPermissions={true}
|
||||
|
||||
@@ -182,6 +182,7 @@ export default function CalendarEventModal({
|
||||
variant="ghost"
|
||||
shape="square"
|
||||
onClick={deleteCalendarEvent}
|
||||
disabled={disabled}
|
||||
>
|
||||
<BsTrash3
|
||||
size={22}
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
import { ButtonProps } from "@/components/button/Button";
|
||||
import DangerButton from "@/components/button/DangerButton";
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import { ClassGroup } from "@/interface/ClassGroup";
|
||||
import { useTheme } from "@/providers/ThemeProvider";
|
||||
import { BsPencilFill, BsTrash3 } from "react-icons/bs";
|
||||
import { Tooltip } from "react-tooltip";
|
||||
|
||||
|
||||
export default function ClassGroupButtons({
|
||||
classGroup,
|
||||
buttonProps,
|
||||
showClassGroupModal,
|
||||
showDeleteClassGroupModal
|
||||
}:{
|
||||
classGroup: ClassGroup;
|
||||
buttonProps: ButtonProps;
|
||||
showClassGroupModal: () => void;
|
||||
showDeleteClassGroupModal: () => void;
|
||||
}){
|
||||
const { theme } = useTheme();
|
||||
const componentId = crypto.randomUUID().replaceAll("-", "");
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-row gap-2"
|
||||
>
|
||||
<PrimaryButton
|
||||
{...buttonProps}
|
||||
id={`classGroupAdminButtonsEdit${componentId}`}
|
||||
onClick={showClassGroupModal}
|
||||
aria-label={`Edit ${classGroup.classGroupName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsPencilFill
|
||||
size={22}
|
||||
@@ -27,12 +39,29 @@ export default function ClassGroupButtons({
|
||||
</PrimaryButton>
|
||||
<DangerButton
|
||||
{...buttonProps}
|
||||
id={`classGroupAdminButtonsDelete${componentId}`}
|
||||
onClick={showDeleteClassGroupModal}
|
||||
aria-label={`Delete ${classGroup.classGroupName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsTrash3
|
||||
size={22}
|
||||
/>
|
||||
</DangerButton>
|
||||
<Tooltip
|
||||
anchorSelect={`#classGroupAdminButtonsEdit${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Edit {classGroup.classGroupName}
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#classGroupAdminButtonsDelete${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Delete {classGroup.classGroupName}
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import Table from "@/components/table/Table";
|
||||
import { useGetGameClassesByClassGroup } from "@/hooks/GameClassHooks";
|
||||
import { ClassGroup } from "@/interface/ClassGroup";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isRaidGroupAdmin, isRaidGroupLeader } from "@/util/PermissionUtil";
|
||||
import { useState } from "react";
|
||||
import ClassGroupButtons from "./ClassGroupButtons";
|
||||
import ClassGroupModal from "./modal/ClassGroupModal";
|
||||
@@ -17,6 +19,7 @@ export default function ClassGroupList({
|
||||
classGroups: ClassGroup[];
|
||||
raidGroup: RaidGroup;
|
||||
}){
|
||||
const { accountPermissions, raidGroupPermissions } = useAuth();
|
||||
const [ selectedClassGroup, setSelectedClassGroup ] = useState<ClassGroup>();
|
||||
const [ displayClassGroupModal, setDisplayClassGroupModal ] = useState(false);
|
||||
const [ displayDeleteClassGroupModal, setDisplayDeleteClassGroupModal ] = useState(false);
|
||||
@@ -26,7 +29,8 @@ export default function ClassGroupList({
|
||||
const buttonProps: ButtonProps = {
|
||||
variant: "ghost",
|
||||
size: "md",
|
||||
shape: "square"
|
||||
shape: "square",
|
||||
disabled: !isRaidGroupAdmin(raidGroup.raidGroupId!, raidGroupPermissions, accountPermissions) && !isRaidGroupLeader(raidGroup.raidGroupId!, raidGroupPermissions, accountPermissions)
|
||||
};
|
||||
|
||||
|
||||
@@ -64,6 +68,7 @@ export default function ClassGroupList({
|
||||
|
||||
</div>
|
||||
<ClassGroupButtons
|
||||
classGroup={classGroup}
|
||||
buttonProps={buttonProps}
|
||||
showClassGroupModal={() => {
|
||||
setSelectedClassGroup(classGroup);
|
||||
|
||||
@@ -3,6 +3,8 @@ import TextInput from "@/components/input/TextInput";
|
||||
import Pagination from "@/components/pagination/Pagination";
|
||||
import { useGetClassGroupsCount } from "@/hooks/ClassGroupHooks";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isRaidGroupAdmin, isRaidGroupLeader } from "@/util/PermissionUtil";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import ClassGroupsLoader from "./ClassGroupsLoader";
|
||||
@@ -14,6 +16,7 @@ export default function ClassGroupsTab({
|
||||
}:{
|
||||
raidGroup: RaidGroup;
|
||||
}){
|
||||
const { accountPermissions, raidGroupPermissions } = useAuth();
|
||||
const [ displayCreateClassGroupModal, setDisplayCreateClassGroupModal ] = useState(false);
|
||||
const [ page, setPage ] = useState(1);
|
||||
const [ totalPages, setTotalPages ] = useState(1);
|
||||
@@ -60,6 +63,7 @@ export default function ClassGroupsTab({
|
||||
<PrimaryButton
|
||||
className="text-nowrap"
|
||||
onClick={() => setDisplayCreateClassGroupModal(true)}
|
||||
disabled={!isRaidGroupAdmin(raidGroup.raidGroupId!, raidGroupPermissions, accountPermissions) && !isRaidGroupLeader(raidGroup.raidGroupId!, raidGroupPermissions, accountPermissions)}
|
||||
>
|
||||
Create Class Group
|
||||
</PrimaryButton>
|
||||
|
||||
@@ -2,6 +2,8 @@ import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import TextInput from "@/components/input/TextInput";
|
||||
import Pagination from "@/components/pagination/Pagination";
|
||||
import { useGetGamesCount } from "@/hooks/GameHooks";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isSiteAdmin } from "@/util/PermissionUtil";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import { GamesLoader } from "./GamesLoader";
|
||||
@@ -9,6 +11,7 @@ import GameModal from "./modals/GameModal";
|
||||
|
||||
|
||||
export default function AllGamesDisplay(){
|
||||
const { accountPermissions } = useAuth();
|
||||
const [ displayCreateGameModal, setDisplayCreateGameModal ] = useState(false);
|
||||
const [ page, setPage ] = useState(1);
|
||||
const [ totalPages, setTotalPages ] = useState(1);
|
||||
@@ -54,6 +57,7 @@ export default function AllGamesDisplay(){
|
||||
<PrimaryButton
|
||||
className="mb-8"
|
||||
onClick={() => setDisplayCreateGameModal(true)}
|
||||
disabled={!isSiteAdmin(accountPermissions)}
|
||||
>
|
||||
Create Game
|
||||
</PrimaryButton>
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
import { ButtonProps } from "@/components/button/Button";
|
||||
import DangerButton from "@/components/button/DangerButton";
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import { Game } from "@/interface/Game";
|
||||
import { useTheme } from "@/providers/ThemeProvider";
|
||||
import { BsPencilFill, BsTrash3 } from "react-icons/bs";
|
||||
import { Tooltip } from "react-tooltip";
|
||||
|
||||
|
||||
export default function GameAdminButtons({
|
||||
game,
|
||||
buttonProps,
|
||||
showEditGameModal,
|
||||
showDeleteGameModal
|
||||
}:{
|
||||
game: Game;
|
||||
buttonProps: ButtonProps;
|
||||
showEditGameModal: () => void;
|
||||
showDeleteGameModal: () => void;
|
||||
}){
|
||||
const { theme } = useTheme();
|
||||
const componentId = crypto.randomUUID().replaceAll("-", "");
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-row items-center justify-center gap-2"
|
||||
>
|
||||
<PrimaryButton
|
||||
{...buttonProps}
|
||||
id={`gameAdminButtonsEdit${componentId}`}
|
||||
onClick={showEditGameModal}
|
||||
aria-label={`Edit ${game.gameName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsPencilFill
|
||||
size={22}
|
||||
@@ -27,12 +39,29 @@ export default function GameAdminButtons({
|
||||
</PrimaryButton>
|
||||
<DangerButton
|
||||
{...buttonProps}
|
||||
id={`gameAdminButtonsDelete${componentId}`}
|
||||
onClick={showDeleteGameModal}
|
||||
aria-label={`Delete ${game.gameName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsTrash3
|
||||
size={22}
|
||||
/>
|
||||
</DangerButton>
|
||||
<Tooltip
|
||||
anchorSelect={`#gameAdminButtonsEdit${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Edit {game.gameName}
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#gameAdminButtonsDelete${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Delete {game.gameName}
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { ButtonProps } from "@/components/button/Button";
|
||||
import { Game } from "@/interface/Game";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isGameAdmin } from "@/util/PermissionUtil";
|
||||
import { useState } from "react";
|
||||
import GameAdminButtons from "./GameAdminButtons";
|
||||
import DeleteGameModal from "./modals/DeleteGameModal";
|
||||
@@ -11,13 +13,15 @@ export default function GameHeader({
|
||||
}:{
|
||||
game: Game;
|
||||
}){
|
||||
const { gamePermissions, accountPermissions } = useAuth();
|
||||
const [ displayEditGameModal, setDisplayEditGameModal ] = useState(false);
|
||||
const [ displayDeleteGameModal, setDisplayDeleteGameModal ] = useState(false);
|
||||
|
||||
const buttonProps: ButtonProps = {
|
||||
variant: "ghost",
|
||||
size: "md",
|
||||
shape: "square"
|
||||
shape: "square",
|
||||
disabled: !isGameAdmin(game.gameId ?? "", gamePermissions, accountPermissions)
|
||||
};
|
||||
|
||||
|
||||
@@ -39,6 +43,7 @@ export default function GameHeader({
|
||||
</div>
|
||||
<div>
|
||||
<GameAdminButtons
|
||||
game={game}
|
||||
buttonProps={buttonProps}
|
||||
showEditGameModal={() => setDisplayEditGameModal(true)}
|
||||
showDeleteGameModal={() => setDisplayDeleteGameModal(true)}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { ButtonProps } from "@/components/button/Button";
|
||||
import Table from "@/components/table/Table";
|
||||
import { Game } from "@/interface/Game";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isGameAdmin } from "@/util/PermissionUtil";
|
||||
import { useState } from "react";
|
||||
import { Link } from "react-router";
|
||||
import GameAdminButtons from "./GameAdminButtons";
|
||||
@@ -13,6 +15,7 @@ export default function GamesList({
|
||||
}:{
|
||||
games: Game[];
|
||||
}){
|
||||
const { accountPermissions, gamePermissions } = useAuth();
|
||||
const [ selectedGame, setSelectedGame ] = useState<Game>();
|
||||
const [ displayEditGameModal, setDisplayEditGameModal ] = useState(false);
|
||||
const [ displayDeleteGameModal, setDisplayDeleteGameModal ] = useState(false);
|
||||
@@ -68,7 +71,11 @@ export default function GamesList({
|
||||
|
||||
</div>
|
||||
<GameAdminButtons
|
||||
buttonProps={buttonProps}
|
||||
game={game}
|
||||
buttonProps={{
|
||||
...buttonProps,
|
||||
disabled: !isGameAdmin(game.gameId ?? "", gamePermissions, accountPermissions)
|
||||
}}
|
||||
showEditGameModal={() => {
|
||||
setSelectedGame(game);
|
||||
setDisplayEditGameModal(true);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ButtonShape, ButtonSizeType, ButtonVariant } from "@/components/button/Button";
|
||||
import Table from "@/components/table/Table";
|
||||
import { Game } from "@/interface/Game";
|
||||
import { elementBg } from "@/util/SkeletonUtil";
|
||||
import React from "react";
|
||||
import GameAdminButtons from "./GameAdminButtons";
|
||||
@@ -64,7 +65,7 @@ function GameSkeleton(): React.ReactNode[]{
|
||||
className={`flex flex-row items-center justify-center gap-2 pl-16`}
|
||||
>
|
||||
<div className="py-4 border-l border-neutral-500"> </div>
|
||||
<GameAdminButtons {...buttonsProps}/>
|
||||
<GameAdminButtons game={{} as Game} {...buttonsProps}/>
|
||||
</div>
|
||||
];
|
||||
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
import { ButtonProps } from "@/components/button/Button";
|
||||
import DangerButton from "@/components/button/DangerButton";
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import { GameClass } from "@/interface/GameClass";
|
||||
import { useTheme } from "@/providers/ThemeProvider";
|
||||
import { BsPencilFill, BsTrash3 } from "react-icons/bs";
|
||||
import { Tooltip } from "react-tooltip";
|
||||
|
||||
|
||||
export default function GameClassAdminButtons({
|
||||
gameClass,
|
||||
buttonProps,
|
||||
showEditGameClassModal,
|
||||
showDeleteGameClassModal
|
||||
}:{
|
||||
gameClass: GameClass;
|
||||
buttonProps: ButtonProps;
|
||||
showEditGameClassModal: () => void;
|
||||
showDeleteGameClassModal: () => void;
|
||||
}){
|
||||
const { theme } = useTheme();
|
||||
const componentId = crypto.randomUUID().replaceAll("-", "");
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-row items-center justify-center gap-2"
|
||||
>
|
||||
<PrimaryButton
|
||||
{...buttonProps}
|
||||
id={`gameClassAdminButtonsEdit${componentId}`}
|
||||
onClick={showEditGameClassModal}
|
||||
aria-label={`Edit ${gameClass.gameClassName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsPencilFill
|
||||
size={22}
|
||||
@@ -27,12 +39,29 @@ export default function GameClassAdminButtons({
|
||||
</PrimaryButton>
|
||||
<DangerButton
|
||||
{...buttonProps}
|
||||
id={`gameClassAdminButtonsDelete${componentId}`}
|
||||
onClick={showDeleteGameClassModal}
|
||||
aria-label={`Delete ${gameClass.gameClassName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsTrash3
|
||||
size={22}
|
||||
/>
|
||||
</DangerButton>
|
||||
<Tooltip
|
||||
anchorSelect={`#gameClassAdminButtonsEdit${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Edit {gameClass.gameClassName}
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#gameClassAdminButtonsDelete${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Delete {gameClass.gameClassName}
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import TextInput from "@/components/input/TextInput";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isGameAdmin } from "@/util/PermissionUtil";
|
||||
import { useState } from "react";
|
||||
import GameClassModal from "./modals/GameClassModal";
|
||||
|
||||
@@ -13,6 +15,7 @@ export default function GameClassCreateAndSearch({
|
||||
searchTerm: string;
|
||||
setSearchTerm: (searchTerm: string) => void;
|
||||
}){
|
||||
const { gamePermissions, accountPermissions } = useAuth();
|
||||
const [ displayGameClassModal, setDisplayGameClassModal ] = useState(false);
|
||||
const modalId = crypto.randomUUID().replaceAll("-", "");
|
||||
|
||||
@@ -33,6 +36,7 @@ export default function GameClassCreateAndSearch({
|
||||
<PrimaryButton
|
||||
className="mb-8"
|
||||
onClick={() => setDisplayGameClassModal(true)}
|
||||
disabled={!isGameAdmin(gameId, gamePermissions, accountPermissions)}
|
||||
>
|
||||
Create Game Class
|
||||
</PrimaryButton>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { ButtonProps } from "@/components/button/Button";
|
||||
import Table from "@/components/table/Table";
|
||||
import { GameClass } from "@/interface/GameClass";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isGameAdmin } from "@/util/PermissionUtil";
|
||||
import { useState } from "react";
|
||||
import GameClassAdminButtons from "./GameClassAdminButtons";
|
||||
import DeleteGameClassModal from "./modals/DeleteGameClassModal";
|
||||
@@ -12,6 +14,7 @@ export default function GameClassList({
|
||||
}:{
|
||||
gameClasses: GameClass[];
|
||||
}){
|
||||
const { gamePermissions, accountPermissions } = useAuth();
|
||||
const [ selectedGameClass, setSelectedGameClass ] = useState<GameClass>();
|
||||
const [ displayGameClassModal, setDisplayGameClassModal ] = useState(false);
|
||||
const [ displayDeleteGameClassModal, setDisplayDeleteGameClassModal ] = useState(false);
|
||||
@@ -65,7 +68,11 @@ export default function GameClassList({
|
||||
|
||||
</div>
|
||||
<GameClassAdminButtons
|
||||
buttonProps={buttonProps}
|
||||
gameClass={gameClass}
|
||||
buttonProps={{
|
||||
...buttonProps,
|
||||
disabled: !isGameAdmin(gameClass.gameId, gamePermissions, accountPermissions)
|
||||
}}
|
||||
showEditGameClassModal={() => {
|
||||
setSelectedGameClass(gameClass);
|
||||
setDisplayGameClassModal(true);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ButtonShape, ButtonSizeType, ButtonVariant } from "@/components/button/Button";
|
||||
import Table from "@/components/table/Table";
|
||||
import { GameClass } from "@/interface/GameClass";
|
||||
import { elementBg } from "@/util/SkeletonUtil";
|
||||
import GameClassAdminButtons from "./GameClassAdminButtons";
|
||||
|
||||
@@ -49,6 +50,7 @@ function GameClassSkeleton(): React.ReactNode[]{
|
||||
shape: "square" as ButtonShape,
|
||||
disabled: true
|
||||
},
|
||||
gameClass:{} as GameClass,
|
||||
showEditGameClassModal: () => {},
|
||||
showDeleteGameClassModal: () => {}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,29 @@ import { ButtonProps } from "@/components/button/Button";
|
||||
import DangerButton from "@/components/button/DangerButton";
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import SuccessButton from "@/components/button/SuccessButton";
|
||||
import { Person } from "@/interface/Person";
|
||||
import { useTheme } from "@/providers/ThemeProvider";
|
||||
import { BsPencilFill, BsPlusLg, BsTrash3 } from "react-icons/bs";
|
||||
import { Tooltip } from "react-tooltip";
|
||||
|
||||
|
||||
export default function PersonAdminButtons({
|
||||
person,
|
||||
buttonProps,
|
||||
showUpdatePersonModal,
|
||||
showDeletePersonModal,
|
||||
showCreatePersonCharacterModal
|
||||
}:{
|
||||
person?: Person;
|
||||
buttonProps: ButtonProps;
|
||||
showUpdatePersonModal: () => void;
|
||||
showDeletePersonModal: () => void;
|
||||
showCreatePersonCharacterModal?: () => void;
|
||||
}){
|
||||
const { theme } = useTheme();
|
||||
const componentId = crypto.randomUUID().replaceAll("-", "");
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-row gap-2"
|
||||
@@ -24,8 +33,11 @@ export default function PersonAdminButtons({
|
||||
showCreatePersonCharacterModal &&
|
||||
<SuccessButton
|
||||
{...buttonProps}
|
||||
id={`personAdminButtonsAddCharacter${componentId}`}
|
||||
size="sm"
|
||||
onClick={showCreatePersonCharacterModal}
|
||||
aria-label={`Add Character to ${person?.personName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsPlusLg
|
||||
size={30}
|
||||
@@ -35,7 +47,10 @@ export default function PersonAdminButtons({
|
||||
}
|
||||
<PrimaryButton
|
||||
{...buttonProps}
|
||||
id={`personAdminButtonsEdit${componentId}`}
|
||||
onClick={showUpdatePersonModal}
|
||||
aria-label={`Edit ${person?.personName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsPencilFill
|
||||
size={22}
|
||||
@@ -43,12 +58,36 @@ export default function PersonAdminButtons({
|
||||
</PrimaryButton>
|
||||
<DangerButton
|
||||
{...buttonProps}
|
||||
id={`personAdminButtonsDelete${componentId}`}
|
||||
onClick={showDeletePersonModal}
|
||||
aria-label={`Delete ${person?.personName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsTrash3
|
||||
size={22}
|
||||
/>
|
||||
</DangerButton>
|
||||
<Tooltip
|
||||
anchorSelect={`#personAdminButtonsAddCharacter${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Add Character to {person?.personName}
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#personAdminButtonsEdit${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Edit {person?.personName}
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#personAdminButtonsDelete${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Delete {person?.personName}
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ import PersonCharacterDisplay from "@/components/personCharacter/PersonCharacter
|
||||
import Table from "@/components/table/Table";
|
||||
import { Person } from "@/interface/Person";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isRaidGroupAdmin, isRaidGroupLeader } from "@/util/PermissionUtil";
|
||||
import { useState } from "react";
|
||||
import { Link } from "react-router";
|
||||
import PersonCharacterModal from "../personCharacter/modal/PersonCharacterModal";
|
||||
@@ -18,6 +20,7 @@ export default function PersonList({
|
||||
people: Person[];
|
||||
raidGroup: RaidGroup;
|
||||
}){
|
||||
const { accountPermissions, raidGroupPermissions } = useAuth();
|
||||
const [ selectedPerson, setSelectedPerson ] = useState<Person>();
|
||||
const [ displayUpdatePersonModal, setDisplayUpdatePersonModal ] = useState(false);
|
||||
const [ displayDeletePersonModal, setDisplayDeletePersonModal ] = useState(false);
|
||||
@@ -27,7 +30,8 @@ export default function PersonList({
|
||||
const buttonProps: ButtonProps = {
|
||||
variant: "ghost",
|
||||
size: "md",
|
||||
shape: "square"
|
||||
shape: "square",
|
||||
disabled: !isRaidGroupAdmin(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions) && !isRaidGroupLeader(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions)
|
||||
};
|
||||
|
||||
|
||||
@@ -78,6 +82,7 @@ export default function PersonList({
|
||||
|
||||
</div>
|
||||
<PersonAdminButtons
|
||||
person={person}
|
||||
buttonProps={buttonProps}
|
||||
showUpdatePersonModal={() => {
|
||||
setSelectedPerson(person);
|
||||
|
||||
@@ -3,6 +3,8 @@ import TextInput from "@/components/input/TextInput";
|
||||
import Pagination from "@/components/pagination/Pagination";
|
||||
import { useGetPeopleByRaidGroupCount } from "@/hooks/PersonHooks";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isRaidGroupAdmin, isRaidGroupLeader } from "@/util/PermissionUtil";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import PersonModal from "./modals/PersonModal";
|
||||
@@ -14,6 +16,7 @@ export default function PersonTab({
|
||||
}:{
|
||||
raidGroup: RaidGroup;
|
||||
}){
|
||||
const { accountPermissions, raidGroupPermissions } = useAuth();
|
||||
const [ displayCreatePersonModal, setDisplayCreatePersonModal ] = useState(false);
|
||||
const [ page, setPage ] = useState(1);
|
||||
const [ totalPages, setTotalPages ] = useState(1);
|
||||
@@ -60,6 +63,7 @@ export default function PersonTab({
|
||||
<PrimaryButton
|
||||
className="text-nowrap"
|
||||
onClick={() => setDisplayCreatePersonModal(true)}
|
||||
disabled={!isRaidGroupAdmin(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions) && !isRaidGroupLeader(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions)}
|
||||
>
|
||||
Create Person
|
||||
</PrimaryButton>
|
||||
|
||||
@@ -2,10 +2,14 @@ import { ButtonProps } from "@/components/button/Button";
|
||||
import DangerButton from "@/components/button/DangerButton";
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import TertiaryButton from "@/components/button/TertiaryButton";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { useTheme } from "@/providers/ThemeProvider";
|
||||
import { BsChatRightText, BsPencilFill, BsTrash3 } from "react-icons/bs";
|
||||
import { Tooltip } from "react-tooltip";
|
||||
|
||||
|
||||
export default function RaidGroupAdminButtons({
|
||||
raidGroup,
|
||||
buttonProps,
|
||||
showRaidGroupRequestModal,
|
||||
showEditRaidGroupModal,
|
||||
@@ -13,6 +17,7 @@ export default function RaidGroupAdminButtons({
|
||||
hasRaidGroupPermissions,
|
||||
hasRaidGroupRequest
|
||||
}:{
|
||||
raidGroup: RaidGroup;
|
||||
buttonProps: ButtonProps;
|
||||
showRaidGroupRequestModal?: () => void;
|
||||
showEditRaidGroupModal: () => void;
|
||||
@@ -20,6 +25,10 @@ export default function RaidGroupAdminButtons({
|
||||
hasRaidGroupPermissions: boolean;
|
||||
hasRaidGroupRequest: boolean;
|
||||
}){
|
||||
const { theme } = useTheme();
|
||||
const componentId = crypto.randomUUID().replaceAll("-", "");
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-row items-center justify-center gap-2"
|
||||
@@ -27,9 +36,12 @@ export default function RaidGroupAdminButtons({
|
||||
{
|
||||
!hasRaidGroupPermissions &&
|
||||
<TertiaryButton
|
||||
id={`raidGroupRequestButton${componentId}`}
|
||||
{...buttonProps}
|
||||
onClick={showRaidGroupRequestModal}
|
||||
disabled={hasRaidGroupRequest}
|
||||
aria-label={`Request to join ${raidGroup.raidGroupName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsChatRightText
|
||||
size={22}
|
||||
@@ -37,21 +49,48 @@ export default function RaidGroupAdminButtons({
|
||||
</TertiaryButton>
|
||||
}
|
||||
<PrimaryButton
|
||||
id={`raidGroupEditButton${componentId}`}
|
||||
{...buttonProps}
|
||||
onClick={showEditRaidGroupModal}
|
||||
aria-label={`Edit ${raidGroup.raidGroupName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsPencilFill
|
||||
size={22}
|
||||
/>
|
||||
</PrimaryButton>
|
||||
<DangerButton
|
||||
id={`raidGroupDeleteButton${componentId}`}
|
||||
{...buttonProps}
|
||||
onClick={showDeleteRaidGroupModal}
|
||||
aria-label={`Delete ${raidGroup.raidGroupName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsTrash3
|
||||
size={22}
|
||||
/>
|
||||
</DangerButton>
|
||||
<Tooltip
|
||||
anchorSelect={`#raidGroupRequestButton${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Request to join {raidGroup.raidGroupName}
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#raidGroupEditButton${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Edit {raidGroup.raidGroupName}
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#raidGroupDeleteButton${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Delete {raidGroup.raidGroupName}
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ButtonProps } from "@/components/button/Button";
|
||||
import Table from "@/components/table/Table";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { containsRaidGroupPermission, containsRaidGroupRequest } from "@/util/PermissionUtil";
|
||||
import { containsRaidGroupPermission, containsRaidGroupRequest, isRaidGroupAdmin } from "@/util/PermissionUtil";
|
||||
import { useState } from "react";
|
||||
import { Link } from "react-router";
|
||||
import RaidGroupRequestModal from "../raidGroupRequest/modal/RaidGroupRequestModal";
|
||||
@@ -20,7 +20,7 @@ export default function RaidGroupsList({
|
||||
const [ displayRaidGroupRequestModal, setDisplayRaidGroupRequestModal ] = useState(false);
|
||||
const [ displayEditRaidGroupModal, setDisplayEditRaidGroupModal ] = useState(false);
|
||||
const [ displayDeleteRaidGroupModal, setDisplayDeleteRaidGroupModal ] = useState(false);
|
||||
const { raidGroupPermissions, raidGroupRequests } = useAuth();
|
||||
const { accountPermissions, raidGroupPermissions, raidGroupRequests } = useAuth();
|
||||
|
||||
|
||||
const buttonProps: ButtonProps = {
|
||||
@@ -73,7 +73,11 @@ export default function RaidGroupsList({
|
||||
|
||||
</div>
|
||||
<RaidGroupAdminButtons
|
||||
buttonProps={buttonProps}
|
||||
raidGroup={raidGroup}
|
||||
buttonProps={{
|
||||
...buttonProps,
|
||||
disabled: !isRaidGroupAdmin(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions) && !containsRaidGroupRequest(raidGroup.raidGroupId ?? "", raidGroupRequests)
|
||||
}}
|
||||
showRaidGroupRequestModal={() => {
|
||||
setSelectedRaidGroup(raidGroup);
|
||||
setDisplayRaidGroupRequestModal(true);
|
||||
@@ -86,7 +90,7 @@ export default function RaidGroupsList({
|
||||
setSelectedRaidGroup(raidGroup);
|
||||
setDisplayDeleteRaidGroupModal(true);
|
||||
}}
|
||||
hasRaidGroupPermissions={containsRaidGroupPermission(raidGroup.raidGroupId ?? "", raidGroupPermissions)}
|
||||
hasRaidGroupPermissions={containsRaidGroupPermission(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions)}
|
||||
hasRaidGroupRequest={containsRaidGroupRequest(raidGroup.raidGroupId ?? "", raidGroupRequests)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ButtonShape, ButtonSizeType, ButtonVariant } from "@/components/button/Button";
|
||||
import Table from "@/components/table/Table";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { elementBg } from "@/util/SkeletonUtil";
|
||||
import RaidGroupAdminButtons from "./RaidGroupAdminButtons";
|
||||
|
||||
@@ -49,8 +50,11 @@ function RaidGroupSkeleton(): React.ReactNode[]{
|
||||
shape: "square" as ButtonShape,
|
||||
disabled: true
|
||||
},
|
||||
showRaidGroupRequestModal: () => {},
|
||||
showEditRaidGroupModal: () => {},
|
||||
showDeleteRaidGroupModal: () => {}
|
||||
showDeleteRaidGroupModal: () => {},
|
||||
hasRaidGroupPermissions: false,
|
||||
hasRaidGroupRequest: false
|
||||
}
|
||||
const elements: React.ReactNode[] = [
|
||||
<div
|
||||
@@ -63,7 +67,7 @@ function RaidGroupSkeleton(): React.ReactNode[]{
|
||||
className={`flex flex-row items-center justify-center gap-2 pl-16`}
|
||||
>
|
||||
<div className="py-4 border-l border-neutral-500"> </div>
|
||||
<RaidGroupAdminButtons {...buttonsProps}/>
|
||||
<RaidGroupAdminButtons raidGroup={{} as RaidGroup} {...buttonsProps}/>
|
||||
</div>
|
||||
];
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ export default function RaidGroupModal({
|
||||
setRaidGroupName(raidGroup?.raidGroupName ?? "");
|
||||
setRaidGroupIcon(raidGroup?.raidGroupIcon ?? "");
|
||||
setIconFile(null);
|
||||
}, [ raidGroup, setRaidGroupName, setRaidGroupIcon ]);
|
||||
}, [ display, raidGroup, setRaidGroupName, setRaidGroupIcon ]);
|
||||
|
||||
|
||||
const updateRaidGroupMutate = useUpdateRaidGroup();
|
||||
@@ -47,25 +47,25 @@ export default function RaidGroupModal({
|
||||
useEffect(() => {
|
||||
if(updateRaidGroupMutate.status === "success"){
|
||||
updateRaidGroupMutate.reset();
|
||||
addSuccessMessage(`Updated raid group ${raidGroupName}`);
|
||||
addSuccessMessage(`Updated raid group ${raidGroup?.raidGroupName}`);
|
||||
close();
|
||||
}
|
||||
else if(updateRaidGroupMutate.status === "error"){
|
||||
updateRaidGroupMutate.reset();
|
||||
addErrorMessage(`Error updating raid group ${raidGroupName}: ${updateRaidGroupMutate.error.message}`);
|
||||
addErrorMessage(`Error updating raid group ${raidGroup?.raidGroupName}: ${updateRaidGroupMutate.error.message}`);
|
||||
console.log(updateRaidGroupMutate.error);
|
||||
}
|
||||
else if(createRaidGroupMutate.status === "success"){
|
||||
createRaidGroupMutate.reset();
|
||||
addSuccessMessage(`Created raid group ${raidGroupName}`);
|
||||
addSuccessMessage(`Created raid group ${raidGroup?.raidGroupName}`);
|
||||
close();
|
||||
}
|
||||
else if(createRaidGroupMutate.status === "error"){
|
||||
createRaidGroupMutate.reset();
|
||||
addErrorMessage(`Error creating raid group ${raidGroupName}: ${createRaidGroupMutate.error.message}`);
|
||||
addErrorMessage(`Error creating raid group ${raidGroup?.raidGroupName}: ${createRaidGroupMutate.error.message}`);
|
||||
console.log(createRaidGroupMutate.error);
|
||||
}
|
||||
}, [ updateRaidGroupMutate, createRaidGroupMutate, raidGroupName, close, addSuccessMessage, addErrorMessage ]);
|
||||
}, [ updateRaidGroupMutate, createRaidGroupMutate, raidGroup, close, addSuccessMessage, addErrorMessage ]);
|
||||
|
||||
|
||||
const updateRaidGroup = () => {
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
import { ButtonProps } from "@/components/button/Button";
|
||||
import DangerButton from "@/components/button/DangerButton";
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import { RaidGroupRequest } from "@/interface/RaidGroupRequest";
|
||||
import { useTheme } from "@/providers/ThemeProvider";
|
||||
import { BsPencilFill, BsTrash3 } from "react-icons/bs";
|
||||
import { Tooltip } from "react-tooltip";
|
||||
|
||||
|
||||
export default function RaidGroupRequestButtons({
|
||||
request,
|
||||
buttonProps,
|
||||
showRaidGroupRequestModal,
|
||||
showDeleteRaidGroupRequestModal
|
||||
}:{
|
||||
request: RaidGroupRequest;
|
||||
buttonProps: ButtonProps;
|
||||
showRaidGroupRequestModal: () => void;
|
||||
showDeleteRaidGroupRequestModal: () => void;
|
||||
}){
|
||||
const { theme } = useTheme();
|
||||
const componentId = crypto.randomUUID().replaceAll("-", "");
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-row items-center justify-center w-full gap-2"
|
||||
>
|
||||
<PrimaryButton
|
||||
{...buttonProps}
|
||||
id={`raidGroupRequestButtonsResolve${componentId}`}
|
||||
onClick={showRaidGroupRequestModal}
|
||||
aria-label={`Resolve raid group request from ${request.username}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsPencilFill
|
||||
size={22}
|
||||
@@ -27,12 +39,29 @@ export default function RaidGroupRequestButtons({
|
||||
</PrimaryButton>
|
||||
<DangerButton
|
||||
{...buttonProps}
|
||||
id={`raidGroupRequestButtonsDelete${componentId}`}
|
||||
onClick={showDeleteRaidGroupRequestModal}
|
||||
aria-label={`Delete raid group request from ${request.username}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsTrash3
|
||||
size={22}
|
||||
/>
|
||||
</DangerButton>
|
||||
<Tooltip
|
||||
anchorSelect={`#raidGroupRequestButtonsResolve${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Resolve raid group request from {request.username}
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#raidGroupRequestButtonsDelete${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Delete raid group request from {request.username}
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -31,14 +31,22 @@ export default function RaidGroupRequestList({
|
||||
<div>
|
||||
Username
|
||||
</div>,
|
||||
<div>
|
||||
Message
|
||||
</div>,
|
||||
<div>
|
||||
Actions
|
||||
</div>
|
||||
];
|
||||
const bodyElements: React.ReactNode[][] = raidGroupRequests.map((request) => [
|
||||
<div>
|
||||
<div
|
||||
className="text-nowrap"
|
||||
>
|
||||
{request.username}
|
||||
</div>,
|
||||
<div>
|
||||
{request.requestMessage || <> </>}
|
||||
</div>,
|
||||
<div
|
||||
className="flex flex-row items-center justify-center gap-2"
|
||||
>
|
||||
@@ -50,6 +58,7 @@ export default function RaidGroupRequestList({
|
||||
{
|
||||
raidGroup &&
|
||||
<RaidGroupRequestButtons
|
||||
request={request}
|
||||
buttonProps={buttonProps}
|
||||
showRaidGroupRequestModal={() => { setSelectedRequest(request); setDisplayRequestModal(true); }}
|
||||
showDeleteRaidGroupRequestModal={() => { setSelectedRequest(request); setDisplayDeleteRequestModal(true); }}
|
||||
|
||||
@@ -42,7 +42,7 @@ export default function RaidGroupRequestTab({
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="flex flex-row items-center justify-between w-full"
|
||||
className="flex flex-row items-center justify-between w-full mb-8"
|
||||
>
|
||||
<div
|
||||
className="flex flex-row items-center justify-start w-full"
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
import { ButtonProps } from "@/components/button/Button";
|
||||
import DangerButton from "@/components/button/DangerButton";
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import { RaidInstance } from "@/interface/RaidInstance";
|
||||
import { useTheme } from "@/providers/ThemeProvider";
|
||||
import { BsPencilFill, BsTrash3 } from "react-icons/bs";
|
||||
import { Tooltip } from "react-tooltip";
|
||||
|
||||
|
||||
export default function RaidInstanceAdminButtons({
|
||||
raidInstance,
|
||||
buttonProps,
|
||||
showRaidInstanceModal,
|
||||
showDeleteRaidInstanceModal
|
||||
}:{
|
||||
raidInstance?: RaidInstance;
|
||||
buttonProps: ButtonProps;
|
||||
showRaidInstanceModal: () => void;
|
||||
showDeleteRaidInstanceModal: () => void;
|
||||
}){
|
||||
const { theme } = useTheme();
|
||||
const componentId = crypto.randomUUID().replaceAll("-", "");
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-row gap-2"
|
||||
>
|
||||
<PrimaryButton
|
||||
{...buttonProps}
|
||||
id={`raidInstanceAdminButtonsEdit${componentId}`}
|
||||
onClick={showRaidInstanceModal}
|
||||
aria-label={`Edit ${raidInstance?.raidInstanceName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsPencilFill
|
||||
size={22}
|
||||
@@ -27,12 +39,29 @@ export default function RaidInstanceAdminButtons({
|
||||
</PrimaryButton>
|
||||
<DangerButton
|
||||
{...buttonProps}
|
||||
id={`raidInstanceAdminButtonsDelete${componentId}`}
|
||||
onClick={showDeleteRaidInstanceModal}
|
||||
aria-label={`Delete ${raidInstance?.raidInstanceName}`}
|
||||
data-tooltip-delay-show={750}
|
||||
>
|
||||
<BsTrash3
|
||||
size={22}
|
||||
/>
|
||||
</DangerButton>
|
||||
<Tooltip
|
||||
anchorSelect={`#raidInstanceAdminButtonsEdit${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Edit {raidInstance?.raidInstanceName}
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#raidInstanceAdminButtonsDelete${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Delete {raidInstance?.raidInstanceName}
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ import { ButtonProps } from "@/components/button/Button";
|
||||
import Table from "@/components/table/Table";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { RaidInstance } from "@/interface/RaidInstance";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isRaidGroupAdmin, isRaidGroupLeader } from "@/util/PermissionUtil";
|
||||
import moment from "moment";
|
||||
import { useState } from "react";
|
||||
import { Link } from "react-router";
|
||||
@@ -17,6 +19,7 @@ export default function RaidInstanceList({
|
||||
raidInstances: RaidInstance[];
|
||||
raidGroup: RaidGroup;
|
||||
}){
|
||||
const { accountPermissions, raidGroupPermissions } = useAuth();
|
||||
const [ selectedRaidInstance, setSelectedRaidInstance ] = useState<RaidInstance>();
|
||||
const [ displayEditRaidInstanceModal, setDisplayEditRaidInstanceModal ] = useState(false);
|
||||
const [ displayDeleteRaidInstanceModal, setDisplayDeleteRaidInstanceModal ] = useState(false);
|
||||
@@ -25,7 +28,8 @@ export default function RaidInstanceList({
|
||||
const buttonProps: ButtonProps = {
|
||||
variant: "ghost",
|
||||
size: "md",
|
||||
shape: "square"
|
||||
shape: "square",
|
||||
disabled: !isRaidGroupAdmin(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions) || !isRaidGroupLeader(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions)
|
||||
};
|
||||
|
||||
|
||||
@@ -94,6 +98,7 @@ export default function RaidInstanceList({
|
||||
|
||||
</div>
|
||||
<RaidInstanceAdminButtons
|
||||
raidInstance={raidInstance}
|
||||
buttonProps={buttonProps}
|
||||
showRaidInstanceModal={() => { setSelectedRaidInstance(raidInstance); setDisplayEditRaidInstanceModal(true); }}
|
||||
showDeleteRaidInstanceModal={() => { setSelectedRaidInstance(raidInstance); setDisplayDeleteRaidInstanceModal(true); }}
|
||||
|
||||
@@ -3,6 +3,8 @@ import TextInput from "@/components/input/TextInput";
|
||||
import Pagination from "@/components/pagination/Pagination";
|
||||
import { useGetRaidInstancesByRaidGroupCount } from "@/hooks/RaidInstanceHooks";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isRaidGroupAdmin, isRaidGroupLeader } from "@/util/PermissionUtil";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import RaidInstanceLoader from "./RaidInstanceLoader";
|
||||
@@ -14,6 +16,7 @@ export default function RaidInstanceTab({
|
||||
}:{
|
||||
raidGroup: RaidGroup;
|
||||
}){
|
||||
const { accountPermissions, raidGroupPermissions } = useAuth();
|
||||
const [ displayCreateRaidInstanceModal, setDisplayCreateRaidInstanceModal ] = useState(false);
|
||||
const [ page, setPage ] = useState(1);
|
||||
const [ totalPages, setTotalPages ] = useState(1);
|
||||
@@ -59,6 +62,7 @@ export default function RaidInstanceTab({
|
||||
<PrimaryButton
|
||||
className="text-nowrap"
|
||||
onClick={() => setDisplayCreateRaidInstanceModal(true)}
|
||||
disabled={!isRaidGroupAdmin(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions) && !isRaidGroupLeader(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions)}
|
||||
>
|
||||
Create Raid Instance
|
||||
</PrimaryButton>
|
||||
|
||||
@@ -1,24 +1,37 @@
|
||||
import { ButtonProps } from "@/components/button/Button";
|
||||
import DangerButton from "@/components/button/DangerButton";
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import { RaidLayout } from "@/interface/RaidLayout";
|
||||
import { useTheme } from "@/providers/ThemeProvider";
|
||||
import { BsPencilFill, BsTrash3 } from "react-icons/bs";
|
||||
import { Tooltip } from "react-tooltip";
|
||||
|
||||
|
||||
export default function RaidLayoutAdminButtons({
|
||||
raidLayout,
|
||||
buttonProps,
|
||||
showRaidLayoutModal,
|
||||
showDeleteRaidLayoutModal
|
||||
}:{
|
||||
raidLayout: RaidLayout;
|
||||
buttonProps: ButtonProps;
|
||||
showRaidLayoutModal: () => void;
|
||||
showDeleteRaidLayoutModal: () => void;
|
||||
}){
|
||||
const { theme } = useTheme();
|
||||
const componentId = crypto.randomUUID().replaceAll("-", "");
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-row gap-2"
|
||||
>
|
||||
<PrimaryButton
|
||||
{...buttonProps}
|
||||
id={`raidLayoutAdminButtonsEdit${componentId}`}
|
||||
onClick={showRaidLayoutModal}
|
||||
aria-label={`Edit ${raidLayout.raidLayoutName}`}
|
||||
data-tooltip-id={`raidLayoutAdminButtonsEdit${componentId}`}
|
||||
>
|
||||
<BsPencilFill
|
||||
size={22}
|
||||
@@ -26,12 +39,29 @@ export default function RaidLayoutAdminButtons({
|
||||
</PrimaryButton>
|
||||
<DangerButton
|
||||
{...buttonProps}
|
||||
id={`raidLayoutAdminButtonsDelete${componentId}`}
|
||||
onClick={showDeleteRaidLayoutModal}
|
||||
aria-label={`Delete ${raidLayout.raidLayoutName}`}
|
||||
data-tooltip-id={`raidLayoutAdminButtonsDelete${componentId}`}
|
||||
>
|
||||
<BsTrash3
|
||||
size={22}
|
||||
/>
|
||||
</DangerButton>
|
||||
<Tooltip
|
||||
anchorSelect={`#raidLayoutAdminButtonsEdit${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Edit {raidLayout.raidLayoutName}
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
anchorSelect={`#raidLayoutAdminButtonsDelete${componentId}`}
|
||||
place="top"
|
||||
variant={theme === "dark" ? "light" : "dark"}
|
||||
>
|
||||
Delete {raidLayout.raidLayoutName}
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import { useGetClassGroupsByRaidLayout } from "@/hooks/ClassGroupHooks";
|
||||
import { ClassGroup } from "@/interface/ClassGroup";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { RaidLayout } from "@/interface/RaidLayout";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isRaidGroupAdmin, isRaidGroupLeader } from "@/util/PermissionUtil";
|
||||
import { useEffect, useState } from "react";
|
||||
import DeleteRaidLayoutModal from "./modal/DeleteRaidLayoutModal";
|
||||
import RaidLayoutModal from "./modal/RaidLayoutModal";
|
||||
@@ -18,6 +20,7 @@ export default function RaidLayoutList({
|
||||
raidLayouts: RaidLayout[];
|
||||
raidGroup: RaidGroup;
|
||||
}){
|
||||
const { accountPermissions, raidGroupPermissions } = useAuth();
|
||||
const [ selectedRaidLayout, setSelectedRaidLayout ] = useState<RaidLayout>();
|
||||
const [ displayEditRaidLayoutModal, showEditRaidLayoutModal ] = useState(false);
|
||||
const [ displayDeleteRaidLayoutModal, showDeleteRaidLayoutModal ] = useState(false);
|
||||
@@ -32,7 +35,8 @@ export default function RaidLayoutList({
|
||||
const buttonProps: ButtonProps = {
|
||||
variant: "ghost",
|
||||
size: "md",
|
||||
shape: "square"
|
||||
shape: "square",
|
||||
disabled: !isRaidGroupAdmin(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions) && !isRaidGroupLeader(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions)
|
||||
};
|
||||
|
||||
|
||||
@@ -78,6 +82,7 @@ export default function RaidLayoutList({
|
||||
|
||||
</div>
|
||||
<RaidLayoutAdminButtons
|
||||
raidLayout={raidLayout}
|
||||
buttonProps={buttonProps}
|
||||
showRaidLayoutModal={() => { setSelectedRaidLayout(raidLayout); showEditRaidLayoutModal(true); }}
|
||||
showDeleteRaidLayoutModal={() => { setSelectedRaidLayout(raidLayout); showDeleteRaidLayoutModal(true); }}
|
||||
|
||||
@@ -3,6 +3,8 @@ import TextInput from "@/components/input/TextInput";
|
||||
import Pagination from "@/components/pagination/Pagination";
|
||||
import { useGetRaidLayoutsByRaidGroupCount } from "@/hooks/RaidLayoutHooks";
|
||||
import { RaidGroup } from "@/interface/RaidGroup";
|
||||
import { useAuth } from "@/providers/AuthProvider";
|
||||
import { isRaidGroupAdmin, isRaidGroupLeader } from "@/util/PermissionUtil";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import RaidLayoutModal from "./modal/RaidLayoutModal";
|
||||
@@ -14,6 +16,7 @@ export default function RaidLayoutTab({
|
||||
}:{
|
||||
raidGroup: RaidGroup;
|
||||
}){
|
||||
const { accountPermissions, raidGroupPermissions } = useAuth();
|
||||
const [ displayCreateRaidLayoutModal, setDisplayCreateRaidLayoutModal ] = useState(false);
|
||||
const [ page, setPage ] = useState(1);
|
||||
const [ totalPages, setTotalPages ] = useState(1);
|
||||
@@ -59,6 +62,7 @@ export default function RaidLayoutTab({
|
||||
<PrimaryButton
|
||||
className="text-nowrap"
|
||||
onClick={() => setDisplayCreateRaidLayoutModal(true)}
|
||||
disabled={!isRaidGroupAdmin(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions) && !isRaidGroupLeader(raidGroup.raidGroupId ?? "", raidGroupPermissions, accountPermissions)}
|
||||
>
|
||||
Create Raid Layout
|
||||
</PrimaryButton>
|
||||
|
||||
Reference in New Issue
Block a user