User tab working
This commit is contained in:
41
src/components/raidGroup/RaidGroupPermissionSelector.tsx
Normal file
41
src/components/raidGroup/RaidGroupPermissionSelector.tsx
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { RaidGroupPermissionType } from "@/interface/RaidGroup";
|
||||||
|
|
||||||
|
|
||||||
|
export default function RaidGroupPermissionSelector({
|
||||||
|
value,
|
||||||
|
onChange
|
||||||
|
}:{
|
||||||
|
value?: RaidGroupPermissionType;
|
||||||
|
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||||
|
}){
|
||||||
|
const modalId = crypto.randomUUID().replaceAll("-", "");
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-row flex-wrap justify-start gap-x-4"
|
||||||
|
>
|
||||||
|
{
|
||||||
|
Object.keys(RaidGroupPermissionType).map((permissionType) => (
|
||||||
|
<label
|
||||||
|
key={permissionType}
|
||||||
|
className="whitespace-nowrap"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name={`raidGroupPermissionTypeSelector${modalId}`}
|
||||||
|
value={permissionType}
|
||||||
|
onChange={onChange}
|
||||||
|
checked={value === permissionType}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="ml-1"
|
||||||
|
>
|
||||||
|
{permissionType}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Account } from "@/interface/Account";
|
import { Account } from "@/interface/Account";
|
||||||
|
import { RaidGroupPermissionType } from "@/interface/RaidGroup";
|
||||||
import { api } from "@/util/AxiosUtil";
|
import { api } from "@/util/AxiosUtil";
|
||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
|
|
||||||
@@ -28,6 +29,51 @@ export function useGetAccounts(page: number, pageSize: number, searchTerm?: stri
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useGetAccountsByRaidGroup(raidGroupId: string, page: number, pageSize: number, searchTerm?: string){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ["accounts", "raidGroup", 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(`/account/raidGroup/${raidGroupId}?${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 Account[];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useGetRaidGroupPermissionsForAccount(raidGroupId?: string, accountId?: string){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ["accounts", "raidGroup", raidGroupId, "account", accountId],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`/account/${accountId}/raidGroup/${raidGroupId}/permission`);
|
||||||
|
|
||||||
|
if(response.status !== 200){
|
||||||
|
throw new Error("Failed to get permissions");
|
||||||
|
}
|
||||||
|
else if(response.data.errors){
|
||||||
|
throw new Error(response.data.errors.join(", "));
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.data.permission as RaidGroupPermissionType;
|
||||||
|
},
|
||||||
|
enabled: !!raidGroupId && !!accountId
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export function useGetAccountsCount(searchTerm?: string){
|
export function useGetAccountsCount(searchTerm?: string){
|
||||||
const searchParams = new URLSearchParams();
|
const searchParams = new URLSearchParams();
|
||||||
if(searchTerm){
|
if(searchTerm){
|
||||||
@@ -53,6 +99,33 @@ export function useGetAccountsCount(searchTerm?: string){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useGetAccountsByRaidGroupCount(raidGroupId: string, searchTerm?: string){
|
||||||
|
const searchParams = new URLSearchParams();
|
||||||
|
if(searchTerm){
|
||||||
|
searchParams.append("searchTerm", searchTerm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "accounts", "raidGroup", raidGroupId, "count", searchTerm],
|
||||||
|
queryFn: async () => {
|
||||||
|
|
||||||
|
const response = await api.get(`/account/raidGroup/${raidGroupId}/count?${searchParams}`);
|
||||||
|
|
||||||
|
if(response.status !== 200){
|
||||||
|
throw new Error("Failed to get accounts count");
|
||||||
|
}
|
||||||
|
else if(response.data.errors){
|
||||||
|
throw new Error(response.data.errors.join(", "));
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.data.count as number;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function useForcePasswordReset(accountId: string){
|
export function useForcePasswordReset(accountId: string){
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
@@ -165,6 +238,30 @@ export function useUpdateAccount(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useUpdateRaidGroupPermissionsForAccount(raidGroupId?: string, accountId?: string){
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: ["updateRaidGroupPermissionsForAccount", raidGroupId, accountId],
|
||||||
|
mutationFn: async (permission: RaidGroupPermissionType) => {
|
||||||
|
const response = await api.put(`/account/${accountId}/raidGroup/${raidGroupId}/permission`, {
|
||||||
|
permission
|
||||||
|
});
|
||||||
|
|
||||||
|
if(response.status !== 200){
|
||||||
|
throw new Error("Failed to update permissions");
|
||||||
|
}
|
||||||
|
else if(response.data.errors){
|
||||||
|
throw new Error(response.data.errors.join(", "));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["accounts"] });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function useDeleteAccount(accountId: string){
|
export function useDeleteAccount(accountId: string){
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
@@ -187,3 +284,26 @@ export function useDeleteAccount(accountId: string){
|
|||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function UseRemoveAccountFromRaidGroup(raidGroupId?: string, accountId?: string){
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: ["removeAccountFromRaidGroup", raidGroupId, accountId],
|
||||||
|
mutationFn: async () => {
|
||||||
|
const response = await api.delete(`/account/raidGroup/${raidGroupId}/permissions/${accountId}`);
|
||||||
|
|
||||||
|
if(response.status !== 200){
|
||||||
|
throw new Error("Failed to remove account from raid group");
|
||||||
|
}
|
||||||
|
else if(response.data.errors){
|
||||||
|
throw new Error(response.data.errors.join(", "));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["accounts"] });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
export enum RaidGroupPermissionType {
|
||||||
|
ADMIN = "ADMIN",
|
||||||
|
LEADER = "LEADER",
|
||||||
|
RAIDER = "RAIDER"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface RaidGroup {
|
export interface RaidGroup {
|
||||||
raidGroupId?: string;
|
raidGroupId?: string;
|
||||||
gameId: string;
|
gameId: string;
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import TabGroup, { Tab } from "@/components/tab/TabGroup";
|
import TabGroup, { Tab } from "@/components/tab/TabGroup";
|
||||||
import { useGetRaidGroup } from "@/hooks/RaidGroupHooks";
|
import { useGetRaidGroup } from "@/hooks/RaidGroupHooks";
|
||||||
import { RaidGroup } from "@/interface/RaidGroup";
|
import { RaidGroup } from "@/interface/RaidGroup";
|
||||||
|
import RaidGroupAccountsTab from "@/ui/account/RaidGroupAccountsTab";
|
||||||
import RaidGroupCalendarDisplay from "@/ui/calendar/RaidGroupCalendarDisplay";
|
import RaidGroupCalendarDisplay from "@/ui/calendar/RaidGroupCalendarDisplay";
|
||||||
import RaidGroupHeader from "@/ui/calendar/RaidGroupHeader";
|
import RaidGroupHeader from "@/ui/calendar/RaidGroupHeader";
|
||||||
import ClassGroupsTab from "@/ui/classGroup/ClassGroupsTab";
|
import ClassGroupsTab from "@/ui/classGroup/ClassGroupsTab";
|
||||||
import PersonTab from "@/ui/person/PersonTab";
|
import PersonTab from "@/ui/person/PersonTab";
|
||||||
|
import RaidInstancesTab from "@/ui/raidInstances/RaidInstancesTab";
|
||||||
import RaidLayoutTab from "@/ui/raidLayout/RaidLayoutTab";
|
import RaidLayoutTab from "@/ui/raidLayout/RaidLayoutTab";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Navigate, useParams } from "react-router";
|
import { Navigate, useParams } from "react-router";
|
||||||
@@ -55,6 +57,14 @@ export default function RaidGroupPage(){
|
|||||||
{
|
{
|
||||||
tabHeader: "Raid Layout",
|
tabHeader: "Raid Layout",
|
||||||
tabContent: <RaidLayoutTab raidGroup={raidGroup}/>
|
tabContent: <RaidLayoutTab raidGroup={raidGroup}/>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tabHeader: "Raid Instances",
|
||||||
|
tabContent: <RaidInstancesTab/>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tabHeader: "Users",
|
||||||
|
tabContent: <RaidGroupAccountsTab raidGroup={raidGroup}/>
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
36
src/ui/account/AccountsByRaidGroupLoader.tsx
Normal file
36
src/ui/account/AccountsByRaidGroupLoader.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import DangerMessage from "@/components/message/DangerMessage";
|
||||||
|
import { useGetAccountsByRaidGroup } from "@/hooks/AccountHooks";
|
||||||
|
import { RaidGroup } from "@/interface/RaidGroup";
|
||||||
|
import AccountsList from "./AccountsList";
|
||||||
|
import AccountsListSkeleton from "./AccountsListSkeleton";
|
||||||
|
|
||||||
|
|
||||||
|
export default function AccountsByRaidGroupLoader({
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
searchTerm,
|
||||||
|
raidGroup
|
||||||
|
}:{
|
||||||
|
page: number;
|
||||||
|
pageSize: number;
|
||||||
|
searchTerm?: string;
|
||||||
|
raidGroup: RaidGroup;
|
||||||
|
}){
|
||||||
|
const accountsQuery = useGetAccountsByRaidGroup(raidGroup.raidGroupId!, page - 1, pageSize, searchTerm);
|
||||||
|
|
||||||
|
|
||||||
|
if(accountsQuery.status === "pending"){
|
||||||
|
return <AccountsListSkeleton/>
|
||||||
|
}
|
||||||
|
else if(accountsQuery.status === "error"){
|
||||||
|
return <DangerMessage>Error: {accountsQuery.error.message}</DangerMessage>
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return (
|
||||||
|
<AccountsList
|
||||||
|
accounts={accountsQuery.data ?? []}
|
||||||
|
raidGroup={raidGroup}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,23 +1,28 @@
|
|||||||
import { ButtonProps } from "@/components/button/Button";
|
import { ButtonProps } from "@/components/button/Button";
|
||||||
import Table from "@/components/table/Table";
|
import Table from "@/components/table/Table";
|
||||||
import { Account } from "@/interface/Account";
|
import { Account } from "@/interface/Account";
|
||||||
|
import { RaidGroup } from "@/interface/RaidGroup";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import AccountAdminButtons from "./AccountAdminButtons";
|
import AccountAdminButtons from "./AccountAdminButtons";
|
||||||
import AccountModal from "./modals/AccountModal";
|
import AccountModal from "./modals/AccountModal";
|
||||||
import AccountPasswordRestModal from "./modals/AccountPasswordResetModal";
|
import AccountPasswordRestModal from "./modals/AccountPasswordResetModal";
|
||||||
|
import AccountRaidGroupPermissionsModal from "./modals/AccountRaidGroupPermissionsModal";
|
||||||
import DeleteAccountModal from "./modals/DeleteAccountModal";
|
import DeleteAccountModal from "./modals/DeleteAccountModal";
|
||||||
import ForcePasswordResetModal from "./modals/ForcePasswordResetModal";
|
import ForcePasswordResetModal from "./modals/ForcePasswordResetModal";
|
||||||
|
import RemoveAccountFromRaidGroupModal from "./modals/RemoveAccountFromRaidGroupModal";
|
||||||
import RevokeRefreshTokenModal from "./modals/RevokeRefreshTokenModal";
|
import RevokeRefreshTokenModal from "./modals/RevokeRefreshTokenModal";
|
||||||
|
import RaidGroupAccountAdminButtons from "./RaidGroupAccountAdminButtons";
|
||||||
|
|
||||||
|
|
||||||
export interface AccountsListProps {
|
export interface AccountsListProps {
|
||||||
accounts: Account[];
|
accounts: Account[];
|
||||||
|
raidGroup?: RaidGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function AccountsList(props: AccountsListProps){
|
export default function AccountsList(props: AccountsListProps){
|
||||||
const { accounts } = props;
|
const { accounts, raidGroup } = props;
|
||||||
|
|
||||||
|
|
||||||
const [ selectedAccount, setSelectedAccount ] = useState<Account | undefined>(undefined);
|
const [ selectedAccount, setSelectedAccount ] = useState<Account | undefined>(undefined);
|
||||||
@@ -26,6 +31,8 @@ export default function AccountsList(props: AccountsListProps){
|
|||||||
const [ displayRevokeRefreshTokenModal, setDisplayRevokeRefreshTokenModal ] = useState(false);
|
const [ displayRevokeRefreshTokenModal, setDisplayRevokeRefreshTokenModal ] = useState(false);
|
||||||
const [ displayAccountModal, setDisplayAccountModal ] = useState(false);
|
const [ displayAccountModal, setDisplayAccountModal ] = useState(false);
|
||||||
const [ displayDeleteAccountModal, setDisplayDeleteAccountModal ] = useState(false);
|
const [ displayDeleteAccountModal, setDisplayDeleteAccountModal ] = useState(false);
|
||||||
|
const [ displayAccountRaidGroupPermissionsModal, setDisplayAccountRaidGroupPermissionsModal ] = useState(false);
|
||||||
|
const [ displayRemoveAccountFromRaidGroupModal, setDisplayRemoveAccountFromRaidGroupModal ] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
const buttonProps: ButtonProps = {
|
const buttonProps: ButtonProps = {
|
||||||
@@ -109,6 +116,20 @@ export default function AccountsList(props: AccountsListProps){
|
|||||||
setDisplayDeleteAccountModal(true);
|
setDisplayDeleteAccountModal(true);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{
|
||||||
|
raidGroup &&
|
||||||
|
<RaidGroupAccountAdminButtons
|
||||||
|
buttonProps={buttonProps}
|
||||||
|
showRaidGroupPermissionsModal={() => {
|
||||||
|
setSelectedAccount(account);
|
||||||
|
setDisplayAccountRaidGroupPermissionsModal(true)
|
||||||
|
}}
|
||||||
|
showRemoveFromRaidGroupModal={() => {
|
||||||
|
setSelectedAccount(account);
|
||||||
|
setDisplayRemoveAccountFromRaidGroupModal(true);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -144,6 +165,17 @@ export default function AccountsList(props: AccountsListProps){
|
|||||||
close={() => {setDisplayDeleteAccountModal(false); setSelectedAccount(undefined);}}
|
close={() => {setDisplayDeleteAccountModal(false); setSelectedAccount(undefined);}}
|
||||||
account={selectedAccount}
|
account={selectedAccount}
|
||||||
/>
|
/>
|
||||||
|
<AccountRaidGroupPermissionsModal
|
||||||
|
display={displayAccountRaidGroupPermissionsModal}
|
||||||
|
close={() => {setDisplayAccountRaidGroupPermissionsModal(false); setSelectedAccount(undefined);}}
|
||||||
|
account={selectedAccount}
|
||||||
|
raidGroup={raidGroup}
|
||||||
|
/>
|
||||||
|
<RemoveAccountFromRaidGroupModal
|
||||||
|
display={displayRemoveAccountFromRaidGroupModal}
|
||||||
|
close={() => {setDisplayRemoveAccountFromRaidGroupModal(false); setSelectedAccount(undefined);}}
|
||||||
|
account={selectedAccount}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
38
src/ui/account/RaidGroupAccountAdminButtons.tsx
Normal file
38
src/ui/account/RaidGroupAccountAdminButtons.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { ButtonProps } from "@/components/button/Button";
|
||||||
|
import DangerButton from "@/components/button/DangerButton";
|
||||||
|
import WarningButton from "@/components/button/WarningButton";
|
||||||
|
import { BsKeyFill, BsTrash3 } from "react-icons/bs";
|
||||||
|
|
||||||
|
|
||||||
|
export default function RaidGroupAccountAdminButtons({
|
||||||
|
buttonProps,
|
||||||
|
showRaidGroupPermissionsModal,
|
||||||
|
showRemoveFromRaidGroupModal
|
||||||
|
}:{
|
||||||
|
buttonProps: ButtonProps;
|
||||||
|
showRaidGroupPermissionsModal: () => void;
|
||||||
|
showRemoveFromRaidGroupModal: () => void;
|
||||||
|
}){
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-row gap-2"
|
||||||
|
>
|
||||||
|
<WarningButton
|
||||||
|
{...buttonProps}
|
||||||
|
onClick={showRaidGroupPermissionsModal}
|
||||||
|
>
|
||||||
|
<BsKeyFill
|
||||||
|
size={22}
|
||||||
|
/>
|
||||||
|
</WarningButton>
|
||||||
|
<DangerButton
|
||||||
|
{...buttonProps}
|
||||||
|
onClick={showRemoveFromRaidGroupModal}
|
||||||
|
>
|
||||||
|
<BsTrash3
|
||||||
|
size={22}
|
||||||
|
/>
|
||||||
|
</DangerButton>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
90
src/ui/account/RaidGroupAccountsTab.tsx
Normal file
90
src/ui/account/RaidGroupAccountsTab.tsx
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import TextInput from "@/components/input/TextInput";
|
||||||
|
import Pagination from "@/components/pagination/Pagination";
|
||||||
|
import { useGetAccountsByRaidGroupCount } from "@/hooks/AccountHooks";
|
||||||
|
import { RaidGroup } from "@/interface/RaidGroup";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
import AccountsByRaidGroupLoader from "./AccountsByRaidGroupLoader";
|
||||||
|
|
||||||
|
|
||||||
|
export default function RaidGroupAccountsTab({
|
||||||
|
raidGroup
|
||||||
|
}:{
|
||||||
|
raidGroup: RaidGroup;
|
||||||
|
}){
|
||||||
|
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 accountsCountQuery = useGetAccountsByRaidGroupCount(raidGroup.raidGroupId ?? "", sentSearchTerm);
|
||||||
|
|
||||||
|
|
||||||
|
const updateSearchTerm = useDebouncedCallback((newSearchTerm: string) => {
|
||||||
|
setSentSearchTerm(newSearchTerm.length ? newSearchTerm : undefined);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
updateSearchTerm(searchTerm ?? "");
|
||||||
|
}, [ searchTerm, updateSearchTerm ]);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(accountsCountQuery.data){
|
||||||
|
setTotalPages(Math.ceil(accountsCountQuery.data / pageSize));
|
||||||
|
}
|
||||||
|
}, [ accountsCountQuery.data ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-between w-full"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center w-full"
|
||||||
|
>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-end w-full"
|
||||||
|
>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-end w-full"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<TextInput
|
||||||
|
id={`accountSearchBox${modalId}`}
|
||||||
|
value={searchTerm}
|
||||||
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
|
placeholder="Search"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Account List */}
|
||||||
|
<AccountsByRaidGroupLoader
|
||||||
|
page={page}
|
||||||
|
pageSize={pageSize}
|
||||||
|
searchTerm={searchTerm}
|
||||||
|
raidGroup={raidGroup}
|
||||||
|
/>
|
||||||
|
{/* Pagination */}
|
||||||
|
<div
|
||||||
|
className="my-12"
|
||||||
|
>
|
||||||
|
<Pagination
|
||||||
|
currentPage={page}
|
||||||
|
totalPages={totalPages}
|
||||||
|
onChange={setPage}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
88
src/ui/account/modals/AccountRaidGroupPermissionsModal.tsx
Normal file
88
src/ui/account/modals/AccountRaidGroupPermissionsModal.tsx
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||||
|
import SecondaryButton from "@/components/button/SecondaryButton";
|
||||||
|
import RaidBuilderModal from "@/components/modal/RaidBuilderModal";
|
||||||
|
import RaidGroupPermissionSelector from "@/components/raidGroup/RaidGroupPermissionSelector";
|
||||||
|
import { useGetRaidGroupPermissionsForAccount, useUpdateRaidGroupPermissionsForAccount } from "@/hooks/AccountHooks";
|
||||||
|
import { Account } from "@/interface/Account";
|
||||||
|
import { RaidGroup, RaidGroupPermissionType } from "@/interface/RaidGroup";
|
||||||
|
import { useTimedModal } from "@/providers/TimedModalProvider";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
|
||||||
|
export default function AccountRaidGroupPermissionsModal({
|
||||||
|
display,
|
||||||
|
close,
|
||||||
|
account,
|
||||||
|
raidGroup
|
||||||
|
}:{
|
||||||
|
display: boolean;
|
||||||
|
close: () => void;
|
||||||
|
account?: Account;
|
||||||
|
raidGroup?: RaidGroup;
|
||||||
|
}){
|
||||||
|
const [ currentPermission, setCurrentPermission ] = useState<RaidGroupPermissionType>();
|
||||||
|
|
||||||
|
|
||||||
|
const raidGroupPermissionsQuery = useGetRaidGroupPermissionsForAccount(raidGroup?.raidGroupId, account?.accountId);
|
||||||
|
const raidGroupPermissionsMutate = useUpdateRaidGroupPermissionsForAccount(raidGroup?.raidGroupId, account?.accountId);
|
||||||
|
const { addSuccessMessage, addErrorMessage } = useTimedModal();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(raidGroupPermissionsQuery.status === "success"){
|
||||||
|
setCurrentPermission(raidGroupPermissionsQuery.data);
|
||||||
|
}
|
||||||
|
else if(raidGroupPermissionsQuery.status === "error"){
|
||||||
|
addErrorMessage(`Error getting raid group permissions: ${raidGroupPermissionsQuery.error.message}`);
|
||||||
|
}
|
||||||
|
}, [raidGroupPermissionsQuery.status, raidGroupPermissionsQuery.data, addSuccessMessage, addErrorMessage, raidGroupPermissionsQuery.error?.message]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(raidGroupPermissionsMutate.status === "success"){
|
||||||
|
raidGroupPermissionsMutate.reset();
|
||||||
|
close();
|
||||||
|
addSuccessMessage("Permissions updated successfully");
|
||||||
|
}
|
||||||
|
else if(raidGroupPermissionsMutate.status === "error"){
|
||||||
|
raidGroupPermissionsMutate.reset();
|
||||||
|
addErrorMessage(`Error updating raid group permissions: ${raidGroupPermissionsMutate.error.message}`);
|
||||||
|
}
|
||||||
|
}, [ close, raidGroupPermissionsMutate, raidGroupPermissionsMutate.status, addErrorMessage, addSuccessMessage ]);
|
||||||
|
|
||||||
|
|
||||||
|
const updateRaidGroupPermissions = () => {
|
||||||
|
raidGroupPermissionsMutate.mutate(currentPermission ?? RaidGroupPermissionType.RAIDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<RaidBuilderModal
|
||||||
|
display={display}
|
||||||
|
close={close}
|
||||||
|
modalHeader={`Raid Group Permissions for ${account?.username}`}
|
||||||
|
modalBody={
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-4"
|
||||||
|
>
|
||||||
|
<RaidGroupPermissionSelector
|
||||||
|
value={currentPermission}
|
||||||
|
onChange={(e) => setCurrentPermission(e.target.value as RaidGroupPermissionType)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
modalFooter={
|
||||||
|
<>
|
||||||
|
<PrimaryButton
|
||||||
|
onClick={updateRaidGroupPermissions}
|
||||||
|
>
|
||||||
|
Update
|
||||||
|
</PrimaryButton>
|
||||||
|
<SecondaryButton
|
||||||
|
onClick={close}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</SecondaryButton>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
66
src/ui/account/modals/RemoveAccountFromRaidGroupModal.tsx
Normal file
66
src/ui/account/modals/RemoveAccountFromRaidGroupModal.tsx
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import DangerButton from "@/components/button/DangerButton";
|
||||||
|
import SecondaryButton from "@/components/button/SecondaryButton";
|
||||||
|
import RaidBuilderModal from "@/components/modal/RaidBuilderModal";
|
||||||
|
import { UseRemoveAccountFromRaidGroup } from "@/hooks/AccountHooks";
|
||||||
|
import { Account } from "@/interface/Account";
|
||||||
|
import { RaidGroup } from "@/interface/RaidGroup";
|
||||||
|
import { useTimedModal } from "@/providers/TimedModalProvider";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
|
||||||
|
export default function RemoveAccountFromRaidGroupModal({
|
||||||
|
display,
|
||||||
|
close,
|
||||||
|
account,
|
||||||
|
raidGroup
|
||||||
|
}:{
|
||||||
|
display: boolean;
|
||||||
|
close: () => void;
|
||||||
|
account?: Account;
|
||||||
|
raidGroup?: RaidGroup;
|
||||||
|
}){
|
||||||
|
const removeAccountFromRaidGroupQuery = UseRemoveAccountFromRaidGroup(raidGroup?.raidGroupId ?? "", account?.accountId ?? "");
|
||||||
|
const { addSuccessMessage, addErrorMessage } = useTimedModal();
|
||||||
|
|
||||||
|
|
||||||
|
const removeAccountFromRaidGroup = () => {
|
||||||
|
removeAccountFromRaidGroupQuery.mutate();
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(removeAccountFromRaidGroupQuery.status === "success"){
|
||||||
|
removeAccountFromRaidGroupQuery.reset();
|
||||||
|
addSuccessMessage(`Successfully removed ${account?.username} from the Raid Group`);
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
else if(removeAccountFromRaidGroupQuery.status === "error"){
|
||||||
|
removeAccountFromRaidGroupQuery.reset();
|
||||||
|
addErrorMessage(`Error removing ${account?.username} from the Raid Group: ${removeAccountFromRaidGroupQuery.error.message}`);
|
||||||
|
console.log(removeAccountFromRaidGroupQuery.error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<RaidBuilderModal
|
||||||
|
display={display}
|
||||||
|
close={close}
|
||||||
|
modalHeader="Remove Account From Raid Group"
|
||||||
|
modalBody={`Are you sure you want to remove ${account?.username} from the Raid Group?`}
|
||||||
|
modalFooter={
|
||||||
|
<>
|
||||||
|
<DangerButton
|
||||||
|
onClick={removeAccountFromRaidGroup}
|
||||||
|
>
|
||||||
|
Remove
|
||||||
|
</DangerButton>
|
||||||
|
<SecondaryButton
|
||||||
|
onClick={close}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</SecondaryButton>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
7
src/ui/raidInstances/RaidInstancesTab.tsx
Normal file
7
src/ui/raidInstances/RaidInstancesTab.tsx
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export default function RaidInstancesTab(){
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
Raid Instances tab
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user