Update eslint to type check

This commit is contained in:
2025-05-25 13:34:23 -04:00
parent c4265bbcad
commit 8b5efb0879
68 changed files with 2420 additions and 2015 deletions

View File

@@ -1,28 +1,42 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import js from "@eslint/js";
import react from "eslint-plugin-react";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import globals from "globals";
import tseslint from "typescript-eslint";
export default tseslint.config(
{ ignores: ['dist'] },
{ ignores: ["dist"] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
extends: [js.configs.recommended, ...tseslint.configs.recommendedTypeChecked],
files: ["**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parserOptions: {
project: ["./tsconfig.node.json", "./tsconfig.app.json"],
tsconfigRootDir: import.meta.dirname
}
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
react: react
},
rules: {
...react.configs.recommended.rules,
...react.configs["jsx-runtime"].rules,
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true }
]
},
},
)
settings: {
react: {
version: "detect"
}
}
}
);

1718
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"build": "tsc -b && eslint && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
@@ -19,12 +19,13 @@
"@types/node": "^22.15.21",
"axios": "^1.9.0",
"clsx": "^2.1.1",
"eslint-plugin-react": "^7.37.5",
"moment": "^2.30.1",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-icons": "^5.5.0",
"react-joyride": "^3.0.0-7",
"react-router": "^7.6.0",
"react-router": "^7.6.1",
"react-tooltip": "^5.28.1",
"tailwindcss": "^4.1.7",
"use-debounce": "^10.0.4",
@@ -38,7 +39,7 @@
"eslint": "^9.27.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.1.0",
"globals": "^16.2.0",
"typescript": "^5.8.3",
"typescript-eslint": "^8.32.1",
"vite": "^6.3.5"

View File

@@ -16,8 +16,8 @@ import ForgotTokenPage from "./pages/public/ForgotTokenPage";
import HomePage from "./pages/public/HomePage";
import LoginPage from "./pages/public/LoginPage";
import SignupPage from "./pages/public/SignupPage";
import { ProtectedRoute } from "./providers/AuthProvider";
import ErrorBoundary from "./providers/ErrorBoundary";
import { ProtectedRoute } from "./providers/components/AuthProviderComponent";
import ErrorBoundary from "./providers/components/ErrorBoundary";
const routes = createBrowserRouter([

View File

@@ -26,7 +26,7 @@ export default function AccountStatusSelector({
name={`accountStatusSelector${modalId}`}
value={status}
onChange={onChange}
checked={value === status}
checked={value === status as AccountStatus}
/>
<span
className="ml-1"

View File

@@ -11,12 +11,8 @@ interface TextInputProps extends ComponentProps<"input">{
}
export default function TextInput(inProps: TextInputProps){
const props = {...inProps};
export default function TextInput(props: TextInputProps){
const { id, placeholder, name, inputClasses, labelClasses, accepted } = props;
delete props.inputClasses;
delete props.labelClasses;
delete props.accepted;
return (

View File

@@ -26,7 +26,7 @@ export default function RaidGroupPermissionSelector({
name={`raidGroupPermissionTypeSelector${modalId}`}
value={permissionType}
onChange={onChange}
checked={value === permissionType}
checked={value === permissionType as RaidGroupPermissionType}
/>
<span
className="ml-1"

View File

@@ -1,9 +1,9 @@
import { Account } from "@/interface/Account";
import { AccountTutorialStatus } from "@/interface/AccountTutorialStatus";
import { Counter } from "@/interface/Counters";
import { RaidGroupPermissionType } from "@/interface/RaidGroup";
import { api } from "@/util/AxiosUtil";
import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetAccounts(page: number, pageSize: number, searchTerm?: string){
@@ -17,23 +17,9 @@ export function useGetAccounts(page: number, pageSize: number, searchTerm?: stri
params.append("searchTerm", searchTerm ?? "");
}
try{
const response = await api.get(`/account?${params}`);
const response = await api.get(`/account?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as Account[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as Account[];
}
});
}
@@ -49,23 +35,9 @@ export function useGetAccountsByRaidGroup(raidGroupId: string, page: number, pag
params.append("searchTerm", searchTerm ?? "");
}
try{
const response = await api.get(`/account/raidGroup/${raidGroupId}?${params}`);
const response = await api.get(`/account/raidGroup/${raidGroupId}?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as Account[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as Account[];
}
});
}
@@ -74,23 +46,9 @@ export function useGetRaidGroupPermissionsForAccount(raidGroupId?: string, accou
return useQuery({
queryKey: ["accounts", "raidGroup", raidGroupId, "account", accountId],
queryFn: async () => {
try{
const response = await api.get(`/account/${accountId}/raidGroup/${raidGroupId}/permission`);
const response = await api.get(`/account/${accountId}/raidGroup/${raidGroupId}/permission`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.permission as RaidGroupPermissionType;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as {permission: RaidGroupPermissionType;}).permission;
},
enabled: !!raidGroupId && !!accountId
});
@@ -107,23 +65,9 @@ export function useGetAccountsCount(searchTerm?: string){
return useQuery({
queryKey: [ "accounts", "count", searchTerm],
queryFn: async () => {
try{
const response = await api.get(`/account/count?${searchParams}`);
const response = await api.get(`/account/count?${searchParams}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.count as number;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Counter).count;
}
});
}
@@ -138,23 +82,9 @@ export function useGetAccountsByRaidGroupCount(raidGroupId: string, searchTerm?:
return useQuery({
queryKey: [ "accounts", "raidGroup", raidGroupId, "count", searchTerm],
queryFn: async () => {
try{
const response = await api.get(`/account/raidGroup/${raidGroupId}/count?${searchParams}`);
const response = await api.get(`/account/raidGroup/${raidGroupId}/count?${searchParams}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.count as number;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Counter).count;
}
});
}
@@ -163,23 +93,9 @@ export function useGetTutorialsStatus(accountId: string | null){
return useQuery({
queryKey: ["tutorials", "account", accountId],
queryFn: async () => {
try{
const response = await api.get(`/account/tutorial`);
const response = await api.get(`/account/tutorial`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as AccountTutorialStatus;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as AccountTutorialStatus;
},
enabled: !!accountId
});
@@ -189,21 +105,7 @@ export function useUpdateTutorialsStatus(){
return useMutation({
mutationKey: ["tutorials", "accounts"],
mutationFn: async (tutorials: AccountTutorialStatus) => {
try{
const response = await api.put(`/account/tutorial`, tutorials);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/account/tutorial`, tutorials);
}
});
}
@@ -212,20 +114,10 @@ export function useUpdatePassword(){
return useMutation({
mutationKey: ["updatePassword"],
mutationFn: async ({currentPassword, newPassword}:{currentPassword: string; newPassword: string;}) => {
try{
await api.post("/auth/resetPassword", {
currentPassword,
newPassword
});
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post("/auth/resetPassword", {
currentPassword,
newPassword
});
}
});
}
@@ -239,24 +131,10 @@ export function useForcePasswordReset(accountId: string){
return useMutation({
mutationKey: ["forcePasswordReset", accountId],
mutationFn: async () => {
try{
const response = await api.put(`/account/${accountId}/forcePasswordReset`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/account/${accountId}/forcePasswordReset`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["accounts"] });
void queryClient.invalidateQueries({ queryKey: ["accounts"] });
}
});
}
@@ -268,26 +146,12 @@ export function useResetPassword(accountId: string){
return useMutation({
mutationKey: ["resetPassword", accountId],
mutationFn: async (password: string) => {
try{
const response = await api.put(`/account/${accountId}/resetPassword`, {
password
});
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/account/${accountId}/resetPassword`, {
password
});
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["accounts"] });
void queryClient.invalidateQueries({ queryKey: ["accounts"] });
}
});
}
@@ -299,24 +163,10 @@ export function useRevokeRefreshToken(accountId: string){
return useMutation({
mutationKey: ["revokeRefreshToken", accountId],
mutationFn: async () => {
try{
const response = await api.put(`/account/${accountId}/revokeRefreshToken`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/account/${accountId}/revokeRefreshToken`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["accounts"] });
void queryClient.invalidateQueries({ queryKey: ["accounts"] });
}
});
}
@@ -328,24 +178,10 @@ export function useCreateAccount(){
return useMutation({
mutationKey: ["createAccount"],
mutationFn: async (account: Account) => {
try{
const response = await api.post("/account", account);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post("/account", account);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["accounts"] });
void queryClient.invalidateQueries({ queryKey: ["accounts"] });
}
});
}
@@ -357,24 +193,10 @@ export function useUpdateAccount(){
return useMutation({
mutationKey: ["updateAccount"],
mutationFn: async (account: Account) => {
try{
const response = await api.put(`/account/${account.accountId}`, account);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/account/${account.accountId}`, account);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["accounts"] });
void queryClient.invalidateQueries({ queryKey: ["accounts"] });
}
});
}
@@ -386,26 +208,12 @@ export function useUpdateRaidGroupPermissionsForAccount(raidGroupId?: string, ac
return useMutation({
mutationKey: ["updateRaidGroupPermissionsForAccount", raidGroupId, accountId],
mutationFn: async (permission: RaidGroupPermissionType) => {
try{
const response = await api.put(`/account/${accountId}/raidGroup/${raidGroupId}/permission`, {
permission
});
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/account/${accountId}/raidGroup/${raidGroupId}/permission`, {
permission
});
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["accounts"] });
void queryClient.invalidateQueries({ queryKey: ["accounts"] });
}
});
}
@@ -417,24 +225,10 @@ export function useDeleteAccount(accountId: string){
return useMutation({
mutationKey: ["deleteAccount", accountId],
mutationFn: async () => {
try{
const response = await api.delete(`/account/${accountId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.delete(`/account/${accountId}`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["accounts"] });
void queryClient.invalidateQueries({ queryKey: ["accounts"] });
}
});
@@ -447,24 +241,10 @@ export function useRemoveAccountFromRaidGroup(raidGroupId?: string, accountId?:
return useMutation({
mutationKey: ["removeAccountFromRaidGroup", raidGroupId, accountId],
mutationFn: async () => {
try{
const response = await api.delete(`/account/${accountId}/raidGroup/${raidGroupId}/permission`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.delete(`/account/${accountId}/raidGroup/${raidGroupId}/permission`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["accounts"] });
void queryClient.invalidateQueries({ queryKey: ["accounts"] });
}
});
}

View File

@@ -1,28 +1,13 @@
import { Account } from "@/interface/Account";
import { api } from "@/util/AxiosUtil";
import api from "@/util/AxiosUtil";
import { useMutation } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useSignup(){
return useMutation({
mutationKey: ["signup"],
mutationFn: async (account: Account) => {
try{
const response = await api.post("/auth/signup", account);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post("/auth/signup", account);
}
});
}
@@ -32,21 +17,7 @@ export function useConfirm(){
return useMutation({
mutationKey: ["confirm"],
mutationFn: async (confirmToken: string) => {
try{
const response = await api.post(`/auth/confirm/${confirmToken}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post(`/auth/confirm/${confirmToken}`);
}
});
}
@@ -59,21 +30,7 @@ export function useForgotPassword(){
params.append("username", username);
try{
const response = await api.post(`/auth/forgot?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post(`/auth/forgot?${params}`);
}
});
}
@@ -82,21 +39,7 @@ export function useForgotResetPassword(forgotToken: string){
return useMutation({
mutationKey: ["forgotResetPassword"],
mutationFn: async (password: string) => {
try{
const response = await api.post(`/auth/forgot/${forgotToken}`, {password});
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post(`/auth/forgot/${forgotToken}`, {password});
}
});
}

View File

@@ -1,30 +1,15 @@
import { CalendarEvent } from "@/interface/Calendar";
import { api } from "@/util/AxiosUtil";
import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetGameCalendar(gameId: string){
return useQuery({
queryKey: ["gameCalendar", gameId],
queryFn: async () => {
try{
const response = await api.get(`/calendar/game/${gameId}`);
const response = await api.get(`/calendar/game/${gameId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as CalendarEvent[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as CalendarEvent[];
}
});
}
@@ -33,23 +18,9 @@ export function useGetRaidGroupCalendar(raidGroupId: string){
return useQuery({
queryKey: ["raidGroupCalendar", raidGroupId],
queryFn: async () => {
try{
const response = await api.get(`/calendar/raidGroup/${raidGroupId}`);
const response = await api.get(`/calendar/raidGroup/${raidGroupId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as CalendarEvent[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as CalendarEvent[];
}
});
}
@@ -61,24 +32,10 @@ export function useCreateGameCalendarEvent(gameId: string){
return useMutation({
mutationFn: async (calendarEvent: CalendarEvent) => {
try{
const response = await api.post(`/calendar/game/${gameId}`, {...calendarEvent, gameCalendarEventId: calendarEvent.calendarEventId, calendarEventId: undefined});
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post(`/calendar/game/${gameId}`, {...calendarEvent, gameCalendarEventId: calendarEvent.calendarEventId, calendarEventId: undefined});
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["gameCalendar"]})
void queryClient.invalidateQueries({ queryKey: ["gameCalendar"]})
}
});
}
@@ -89,29 +46,15 @@ export function useUpdateGameCalendarEvent(gameId: string){
return useMutation({
mutationFn: async (calendarEvent: CalendarEvent) => {
try{
const response = await api.put(`/calendar/game/${gameId}`,
{
...calendarEvent,
gameCalendarEventId: calendarEvent.calendarEventId,
calendarEventId: undefined
});
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/calendar/game/${gameId}`,
{
...calendarEvent,
gameCalendarEventId: calendarEvent.calendarEventId,
calendarEventId: undefined
});
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["gameCalendar"]})
void queryClient.invalidateQueries({ queryKey: ["gameCalendar"]})
}
});
}
@@ -122,24 +65,10 @@ export function useDeleteGameCalendarEvent(gameId: string){
return useMutation({
mutationFn: async (calendarEvent: CalendarEvent) => {
try{
const response = await api.delete(`/calendar/game/${gameId}/${calendarEvent.calendarEventId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.delete(`/calendar/game/${gameId}/${calendarEvent.calendarEventId}`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["gameCalendar"]})
void queryClient.invalidateQueries({ queryKey: ["gameCalendar"]})
}
});
}
@@ -150,29 +79,15 @@ export function useCreateRaidGroupCalendarEvent(raidGroupId: string){
return useMutation({
mutationFn: async (calendarEvent: CalendarEvent) => {
try{
const response = await api.post(`/calendar/raidGroup/${raidGroupId}`,
{
...calendarEvent,
raidGroupCalendarEventId: calendarEvent.calendarEventId,
calendarEventId: undefined
});
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post(`/calendar/raidGroup/${raidGroupId}`,
{
...calendarEvent,
raidGroupCalendarEventId: calendarEvent.calendarEventId,
calendarEventId: undefined
});
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidGroupCalendar"]})
void queryClient.invalidateQueries({ queryKey: ["raidGroupCalendar"]})
}
});
}
@@ -183,24 +98,10 @@ export function useUpdateRaidGroupCalendarEvent(raidGroupId: string){
return useMutation({
mutationFn: async (calendarEvent: CalendarEvent) => {
try{
const response = await api.put(`/calendar/raidGroup/${raidGroupId}`, {...calendarEvent, raidGroupCalendarEventId: calendarEvent.calendarEventId, calendarEventId: undefined});
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/calendar/raidGroup/${raidGroupId}`, {...calendarEvent, raidGroupCalendarEventId: calendarEvent.calendarEventId, calendarEventId: undefined});
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidGroupCalendar"]})
void queryClient.invalidateQueries({ queryKey: ["raidGroupCalendar"]})
}
});
}
@@ -211,24 +112,10 @@ export function useDeleteRaidGroupCalendarEvent(raidGroupId: string){
return useMutation({
mutationFn: async (calendarEvent: CalendarEvent) => {
try{
const response = await api.delete(`/calendar/raidGroup/${raidGroupId}/${calendarEvent.calendarEventId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.delete(`/calendar/raidGroup/${raidGroupId}/${calendarEvent.calendarEventId}`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidGroupCalendar"]})
void queryClient.invalidateQueries({ queryKey: ["raidGroupCalendar"]})
}
});
}
@@ -237,23 +124,9 @@ export function useGetRaidInstanceCalendarEvents(raidGroupId?: string){
return useQuery({
queryKey: ["raidInstanceCalendarEvents", raidGroupId],
queryFn: async () => {
try{
const response = await api.get(`/calendar/raidGroup/${raidGroupId}/raidInstance`);
const response = await api.get(`/calendar/raidGroup/${raidGroupId}/raidInstance`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as CalendarEvent[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as CalendarEvent[];
},
enabled: !!raidGroupId && raidGroupId !== ""
});

View File

@@ -1,7 +1,7 @@
import { ClassGroup } from "@/interface/ClassGroup";
import { api } from "@/util/AxiosUtil";
import { Counter } from "@/interface/Counters";
import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetClassGroups(raidGroupId: string, page: number, pageSize: number, searchTerm?: string){
@@ -15,23 +15,9 @@ export function useGetClassGroups(raidGroupId: string, page: number, pageSize: n
params.append("searchTerm", searchTerm);
}
try{
const response = await api.get(`/raidGroup/${raidGroupId}/classGroup?${params}`);
const response = await api.get(`/raidGroup/${raidGroupId}/classGroup?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as ClassGroup[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as ClassGroup[];
},
enabled: !!raidGroupId
});
@@ -47,23 +33,9 @@ export function useGetClassGroupsCount(raidGroupId: string, searchTerm?: string)
return useQuery({
queryKey: ["classGroups", "count", searchTerm],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}/classGroup/count?${searchParams}`);
const response = await api.get(`/raidGroup/${raidGroupId}/classGroup/count?${searchParams}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.count as number;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Counter).count;
}
});
}
@@ -72,23 +44,9 @@ export function useGetClassGroupsByRaidLayout(raidGroupId: string, raidLayoutId:
return useQuery({
queryKey: ["classGroups", "raidLayout", raidLayoutId],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}/classGroup/raidLayout/${raidLayoutId}`);
const response = await api.get(`/raidGroup/${raidGroupId}/classGroup/raidLayout/${raidLayoutId}`);
if(response.data.error){
throw new Error(response.data.errors.join(", "));
}
return response.data as (ClassGroup | null)[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as (ClassGroup | null)[];
},
enabled: !!raidGroupId && !!raidLayoutId
})
@@ -102,31 +60,17 @@ export function useCreateClassGroup(raidGroupId: string){
return useMutation({
mutationKey: ["createClassGroup"],
mutationFn: async ({classGroupName, gameClassIds}:{classGroupName: string; gameClassIds: string[];}) => {
try{
const response = await api.post(`/raidGroup/${raidGroupId}/classGroup`,
{
classGroup: {
classGroupName: classGroupName,
raidGroupId: raidGroupId
},
gameClassIds
});
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post(`/raidGroup/${raidGroupId}/classGroup`,
{
classGroup: {
classGroupName: classGroupName,
raidGroupId: raidGroupId
},
gameClassIds
});
},
onSuccess: () => {
queryClient.invalidateQueries({queryKey: ["classGroups"]});
void queryClient.invalidateQueries({queryKey: ["classGroups"]});
}
});
}
@@ -138,30 +82,16 @@ export function useUpdateClassGroup(raidGroupId: string){
return useMutation({
mutationKey: ["updateClassGroup"],
mutationFn: async ({classGroup, gameClassIds}:{classGroup: ClassGroup; gameClassIds: string[];}) => {
try{
const response = await api.put(`/raidGroup/${raidGroupId}/classGroup/${classGroup.classGroupId}`,
{
classGroup,
gameClassIds
}
);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
await api.put(`/raidGroup/${raidGroupId}/classGroup/${classGroup.classGroupId}`,
{
classGroup,
gameClassIds
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
);
},
onSuccess: () => {
queryClient.invalidateQueries({queryKey: ["gameClasses", "classGroups"]});
queryClient.invalidateQueries({queryKey: ["classGroups"]});
void queryClient.invalidateQueries({queryKey: ["gameClasses", "classGroups"]});
void queryClient.invalidateQueries({queryKey: ["classGroups"]});
}
});
}
@@ -173,24 +103,10 @@ export function useDeleteClassGroup(raidGroupId: string, classGroupId: string){
return useMutation({
mutationKey: ["deleteClassGroup", classGroupId, raidGroupId],
mutationFn: async () => {
try{
const response = await api.delete(`/raidGroup/${raidGroupId}/classGroup/${classGroupId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.delete(`/raidGroup/${raidGroupId}/classGroup/${classGroupId}`);
},
onSuccess: () => {
queryClient.invalidateQueries({queryKey: ["classGroups"]});
void queryClient.invalidateQueries({queryKey: ["classGroups"]});
}
});
}

View File

@@ -1,30 +1,16 @@
import { Counter } from "@/interface/Counters";
import { GameClass } from "@/interface/GameClass";
import { api } from "@/util/AxiosUtil";
import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetGameClass(gameClassId: string){
return useQuery({
queryKey: ["gameClasses", gameClassId],
queryFn: async () => {
try{
const response = await api.get(`/gameClass/${gameClassId}`);
const response = await api.get(`/gameClass/${gameClassId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as GameClass;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as GameClass;
},
enabled: !!gameClassId
})
@@ -41,23 +27,9 @@ export function useGetGameClasses(gameId: string, page: number, pageSize: number
params.append("searchTerm", searchTerm);
}
try{
const response = await api.get(`/gameClass/game/${gameId}?${params}`);
const response = await api.get(`/gameClass/game/${gameId}?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as GameClass[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as GameClass[];
}
});
}
@@ -66,23 +38,9 @@ export function useGetGameClassesByClassGroup(classGroupId?: string){
return useQuery({
queryKey: ["gameClasses", "classGroups", classGroupId],
queryFn: async () => {
try{
const response = await api.get(`/gameClass/classGroup/${classGroupId}`);
const response = await api.get(`/gameClass/classGroup/${classGroupId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as GameClass[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as GameClass[];
},
enabled: !!classGroupId
});
@@ -99,23 +57,9 @@ export function useGetGameClassesCount(gameId: string, searchTerm?: string){
return useQuery({
queryKey: ["gameClasses", gameId, "count", searchTerm],
queryFn: async () => {
try{
const response = await api.get(`/gameClass/game/${gameId}/count?${searchParams}`);
const response = await api.get(`/gameClass/game/${gameId}/count?${searchParams}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.count as number;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Counter).count;
}
});
}
@@ -135,27 +79,13 @@ export function useCreateGameClass(){
formData.append("gameClassName", gameClassName);
formData.append("gameId", gameId);
try{
const response = await api.post(
`/gameClass/game/${gameId}`,
formData
);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post(
`/gameClass/game/${gameId}`,
formData
);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["gameClasses"] });
void queryClient.invalidateQueries({ queryKey: ["gameClasses"] });
}
});
}
@@ -177,24 +107,10 @@ export function useUpdateGameClass(){
formData.append("gameClassIcon", gameClass.gameClassIcon);
}
try{
const response = await api.put(`/gameClass/${gameClass.gameClassId}/game/${gameClass.gameId}`, formData);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/gameClass/${gameClass.gameClassId}/game/${gameClass.gameId}`, formData);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["gameClasses"] });
void queryClient.invalidateQueries({ queryKey: ["gameClasses"] });
}
});
}
@@ -206,24 +122,10 @@ export function useDeleteGameClass(){
return useMutation({
mutationKey: ["deleteGameClass"],
mutationFn: async (gameClass: GameClass) => {
try{
const response = await api.delete(`/gameClass/${gameClass.gameClassId}/game/${gameClass.gameId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.delete(`/gameClass/${gameClass.gameClassId}/game/${gameClass.gameId}`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["gameClasses"] });
void queryClient.invalidateQueries({ queryKey: ["gameClasses"] });
}
});
}

View File

@@ -1,30 +1,16 @@
import { Counter } from "@/interface/Counters";
import { Game } from "@/interface/Game";
import { api } from "@/util/AxiosUtil";
import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetGame(gameId: string, disabled: boolean){
return useQuery({
queryKey: ["games", gameId],
queryFn: async () => {
try{
const response = await api.get(`/game/${gameId}`);
const response = await api.get(`/game/${gameId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data?.gameId ? response.data as Game : undefined;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Game)?.gameId ? response.data as Game : undefined;
},
enabled: !disabled
});
@@ -41,19 +27,9 @@ export function useGetGames(page: number, pageSize: number, searchTerm?: string)
params.append("searchTerm", searchTerm);
}
try{
const response = await api.get(`/game?${params}`);
const response = await api.get(`/game?${params}`);
return response.data as Game[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as Game[];
}
});
}
@@ -68,23 +44,9 @@ export function useGetGamesCount(searchTerm?: string){
return useQuery({
queryKey: ["games", "count", searchTerm],
queryFn: async () => {
try{
const response = await api.get(`/game/count?${searchParams}`);
const response = await api.get(`/game/count?${searchParams}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.count as number;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Counter).count;
}
});
}
@@ -102,27 +64,13 @@ export function useCreateGame(){
}
formData.append("gameName", gameName);
try{
const response = await api.post(
"/game",
formData
);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post(
"/game",
formData
);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["games"] });
void queryClient.invalidateQueries({ queryKey: ["games"] });
}
});
}
@@ -143,24 +91,10 @@ export function useUpdateGame(){
formData.append("gameIcon", game.gameIcon);
}
try{
const response = await api.put(`/game/${game.gameId}`, formData);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/game/${game.gameId}`, formData);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["games"] });
void queryClient.invalidateQueries({ queryKey: ["games"] });
}
});
}
@@ -172,24 +106,10 @@ export function useDeleteGame(){
return useMutation({
mutationKey: ["deleteGame"],
mutationFn: async (gameId: string) => {
try{
const response = await api.delete(`/game/${gameId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.delete(`/game/${gameId}`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["games"] });
void queryClient.invalidateQueries({ queryKey: ["games"] });
}
});
}

View File

@@ -1,30 +1,16 @@
import { Counter } from "@/interface/Counters";
import { PersonCharacter } from "@/interface/PersonCharacter";
import { api } from "@/util/AxiosUtil";
import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetPersonCharactersByPersonId(personId: string, raidGroupId: string){
return useQuery({
queryKey: ["personCharacters", personId],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}/character`);
const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}/character`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as PersonCharacter[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as PersonCharacter[];
}
});
}
@@ -41,23 +27,9 @@ export function useGetPersonCharactersByPersonIdSearch(personId: string, raidGro
return useQuery({
queryKey: ["personCharacters", personId, { page, pageSize, searchTerm }],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}/character/page?${params}`);
const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}/character/page?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as PersonCharacter[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as PersonCharacter[];
}
});
}
@@ -71,23 +43,9 @@ export function useGetPersonCharactersCountByPersonIdSearch(personId: string, ra
return useQuery({
queryKey: ["personCharactersCount", personId, { searchTerm }],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}/character/count?${params}`);
const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}/character/count?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.count as number;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Counter).count;
}
});
}
@@ -96,23 +54,9 @@ export function useGetPersonCharactersByRaidGroup(raidGroupId: string){
return useQuery({
queryKey: ["personCharacters", raidGroupId],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}/person/character`);
const response = await api.get(`/raidGroup/${raidGroupId}/person/character`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as PersonCharacter[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as PersonCharacter[];
},
enabled: !!raidGroupId
});
@@ -125,24 +69,10 @@ export function useCreatePersonCharacter(raidGroupId: string, personId: string){
return useMutation({
mutationKey: ["createPersonCharacter"],
mutationFn: async (personCharacter: PersonCharacter) => {
try{
const response = await api.post(`/raidGroup/${raidGroupId}/person/${personId}/character`, personCharacter);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post(`/raidGroup/${raidGroupId}/person/${personId}/character`, personCharacter);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["personCharacters"] });
void queryClient.invalidateQueries({ queryKey: ["personCharacters"] });
}
});
}
@@ -154,24 +84,10 @@ export function useUpdatePersonCharacter(raidGroupId: string, personId: string){
return useMutation({
mutationKey: ["updatePersonCharacter"],
mutationFn: async (personCharacter: PersonCharacter) => {
try{
const response = await api.put(`/raidGroup/${raidGroupId}/person/${personId}/character/${personCharacter.personCharacterId}`, personCharacter);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/raidGroup/${raidGroupId}/person/${personId}/character/${personCharacter.personCharacterId}`, personCharacter);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["personCharacters"] });
void queryClient.invalidateQueries({ queryKey: ["personCharacters"] });
}
});
}
@@ -183,24 +99,10 @@ export function useDeletePersonCharacter(raidGroupId: string, personId: string){
return useMutation({
mutationKey: ["deletePersonCharacter"],
mutationFn: async (personCharacterId: string) => {
try{
const response = await api.delete(`/raidGroup/${raidGroupId}/person/${personId}/character/${personCharacterId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.delete(`/raidGroup/${raidGroupId}/person/${personId}/character/${personCharacterId}`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["personCharacters"] });
void queryClient.invalidateQueries({ queryKey: ["personCharacters"] });
}
});
}

View File

@@ -1,30 +1,16 @@
import { Counter } from "@/interface/Counters";
import { Person } from "@/interface/Person";
import { api } from "@/util/AxiosUtil";
import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetPerson(raidGroupId: string, personId: string, disabled: boolean){
return useQuery({
queryKey: ["people", raidGroupId, personId],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}`);
const response = await api.get(`/raidGroup/${raidGroupId}/person/${personId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as Person;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as Person;
},
enabled: !disabled
});
@@ -41,23 +27,9 @@ export function useGetPeopleByRaidGroup(raidGroupId: string, page: number, pageS
searchParams.append("searchTerm", searchTerm);
}
try{
const response = await api.get(`/raidGroup/${raidGroupId}/person?${searchParams}`);
const response = await api.get(`/raidGroup/${raidGroupId}/person?${searchParams}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as Person[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as Person[];
}
});
}
@@ -72,23 +44,9 @@ export function useGetPeopleByRaidGroupCount(raidGroupId: string, searchTerm?: s
return useQuery({
queryKey: ["people", raidGroupId, "count", searchTerm],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}/person/count?${searchParams}`);
const response = await api.get(`/raidGroup/${raidGroupId}/person/count?${searchParams}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.count as number;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Counter).count;
}
});
}
@@ -100,24 +58,10 @@ export function useCreatePerson(){
return useMutation({
mutationKey: ["createPerson"],
mutationFn: async ({raidGroupId, personName, discordId}:{raidGroupId: string; personName: string; discordId?: string;}) => {
try{
const response = await api.post(`/raidGroup/${raidGroupId}/person`, {raidGroupId, personName, discordId});
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post(`/raidGroup/${raidGroupId}/person`, {raidGroupId, personName, discordId});
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["people"] });
void queryClient.invalidateQueries({ queryKey: ["people"] });
}
});
}
@@ -129,24 +73,10 @@ export function useUpdatePerson(){
return useMutation({
mutationKey: ["updatePerson"],
mutationFn: async (person: Person) => {
try{
const response = await api.put(`/raidGroup/${person.raidGroupId}/person/${person.personId}`, person);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/raidGroup/${person.raidGroupId}/person/${person.personId}`, person);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["people"] });
void queryClient.invalidateQueries({ queryKey: ["people"] });
}
});
}
@@ -158,24 +88,10 @@ export function useDeletePerson(){
return useMutation({
mutationKey: ["deletePerson"],
mutationFn: async ({raidGroupId, personId}:{raidGroupId: string; personId: string;}) => {
try{
const response = await api.delete(`/raidGroup/${raidGroupId}/person/${personId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.delete(`/raidGroup/${raidGroupId}/person/${personId}`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["people"] });
void queryClient.invalidateQueries({ queryKey: ["people"] });
}
});
}

View File

@@ -1,30 +1,16 @@
import { Counter } from "@/interface/Counters";
import { RaidGroup } from "@/interface/RaidGroup";
import { api } from "@/util/AxiosUtil";
import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetRaidGroup(raidGroupId: string, disabled: boolean){
return useQuery({
queryKey: ["raidGroups", raidGroupId],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}`);
const response = await api.get(`/raidGroup/${raidGroupId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data?.raidGroupId ? response.data as RaidGroup : undefined;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as RaidGroup)?.raidGroupId ? response.data as RaidGroup : undefined;
},
enabled: !disabled
});
@@ -41,23 +27,9 @@ export function useGetRaidGroups(page: number, pageSize: number, searchTerm?: st
params.append("searchTerm", searchTerm);
}
try{
const response = await api.get(`/raidGroup?${params}`);
const response = await api.get(`/raidGroup?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as RaidGroup[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as RaidGroup[];
}
});
}
@@ -72,23 +44,9 @@ export function useGetRaidGroupsCount(searchTerm?: string){
return useQuery({
queryKey: ["raidGroups", "count", searchTerm],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/count?${searchParams}`);
const response = await api.get(`/raidGroup/count?${searchParams}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.count as number;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Counter).count;
}
});
}
@@ -104,23 +62,9 @@ export function useGetRaidGroupsByGame(gameId: string, page: number, pageSize: n
params.append("searchTerm", searchTerm);
}
try{
const response = await api.get(`/raidGroup/game/${gameId}?${params}`);
const response = await api.get(`/raidGroup/game/${gameId}?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as RaidGroup[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as RaidGroup[];
}
});
}
@@ -135,23 +79,9 @@ export function useGetRaidGroupsByGameCount(gameId: string, searchTerm?: string)
return useQuery({
queryKey: ["raidGroups", gameId, "count", searchTerm],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/game/${gameId}/count?${searchParams}`);
const response = await api.get(`/raidGroup/game/${gameId}/count?${searchParams}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.count as number;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Counter).count;
}
});
}
@@ -167,23 +97,9 @@ export function useGetRaidGroupsByAccount(accountId: string, page: number, pageS
params.append("searchTerm", searchTerm);
}
try{
const response = await api.get(`/raidGroup/account/${accountId}?${params}`);
const response = await api.get(`/raidGroup/account/${accountId}?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as RaidGroup[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as RaidGroup[];
}
});
}
@@ -198,23 +114,9 @@ export function useGetRaidGroupsCountByAccount(accountId: string, searchTerm?: s
return useQuery({
queryKey: ["raidGroups", accountId, "count", searchTerm],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/account/${accountId}/count?${searchParams}`);
const response = await api.get(`/raidGroup/account/${accountId}/count?${searchParams}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.count as number;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Counter).count;
}
});
@@ -235,27 +137,13 @@ export function useCreateRaidGroup(){
formData.append("raidGroupName", raidGroupName);
formData.append("gameId", gameId);
try{
const response = await api.post(
"/raidGroup",
formData
);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post(
"/raidGroup",
formData
);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidGroups"] });
void queryClient.invalidateQueries({ queryKey: ["raidGroups"] });
}
});
}
@@ -277,24 +165,10 @@ export function useUpdateRaidGroup(){
formData.append("raidGroupIcon", raidGroup.raidGroupIcon);
}
try{
const response = await api.put(`/raidGroup/${raidGroup.raidGroupId}`, formData);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/raidGroup/${raidGroup.raidGroupId}`, formData);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidGroups"] });
void queryClient.invalidateQueries({ queryKey: ["raidGroups"] });
}
});
}
@@ -306,24 +180,10 @@ export function useDeleteRaidGroup(){
return useMutation({
mutationKey: ["deleteRaidGroup"],
mutationFn: async (raidGroupId: string) => {
try{
const response = await api.delete(`/raidGroup/${raidGroupId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.delete(`/raidGroup/${raidGroupId}`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidGroups"] });
void queryClient.invalidateQueries({ queryKey: ["raidGroups"] });
}
});
}

View File

@@ -1,8 +1,8 @@
import { Counter } from "@/interface/Counters";
import { RaidGroupPermissionType } from "@/interface/RaidGroup";
import { RaidGroupRequest } from "@/interface/RaidGroupRequest";
import { api } from "@/util/AxiosUtil";
import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetRaidGroupRequests(raidGroupId: string, page: number, pageSize: number, searchTerm?: string){
@@ -16,23 +16,9 @@ export function useGetRaidGroupRequests(raidGroupId: string, page: number, pageS
return useQuery({
queryKey: ["raidGroupRequest", raidGroupId, {page, pageSize, searchTerm}],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}/raidGroupRequest?${searchParams}`);
const response = await api.get(`/raidGroup/${raidGroupId}/raidGroupRequest?${searchParams}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as RaidGroupRequest[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as RaidGroupRequest[];
},
enabled: !!raidGroupId && raidGroupId !== ""
});
@@ -47,23 +33,9 @@ export function useGetRaidGroupRequestCount(raidGroupId?: string, searchTerm?: s
return useQuery({
queryKey: ["raidGroupRequest", raidGroupId, "count", searchTerm],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}/raidGroupRequest/count?${searchParams}`);
const response = await api.get(`/raidGroup/${raidGroupId}/raidGroupRequest/count?${searchParams}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.count as number;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Counter).count;
},
enabled: !!raidGroupId && raidGroupId !== ""
});
@@ -76,24 +48,10 @@ export function useCreateRaidGroupRequest(raidGroupId: string){
return useMutation({
mutationKey: ["raidGroupRequest", raidGroupId],
mutationFn: async (requestMessage: string) => {
try{
const response = await api.post(`/raidGroup/${raidGroupId}/raidGroupRequest`, {requestMessage});
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post(`/raidGroup/${raidGroupId}/raidGroupRequest`, {requestMessage});
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] });
void queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] });
}
});
}
@@ -104,24 +62,10 @@ export function useResolveRaidGroupRequest(raidGroupId: string, raidGroupRequest
return useMutation({
mutationKey: ["raidGroupRequest", raidGroupId, raidGroupRequestId],
mutationFn: async (permission: RaidGroupPermissionType) => {
try{
const response = await api.put(`/raidGroup/${raidGroupId}/raidGroupRequest/${raidGroupRequestId}/resolve`, {resolution: permission});
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/raidGroup/${raidGroupId}/raidGroupRequest/${raidGroupRequestId}/resolve`, {resolution: permission});
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] });
void queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] });
}
});
@@ -133,24 +77,10 @@ export function useDeleteRaidGroupRequest(raidGroupId: string, raidGroupRequestI
return useMutation({
mutationKey: ["raidGroupRequest", raidGroupId, raidGroupRequestId],
mutationFn: async () => {
try{
const response = await api.delete(`/raidGroup/${raidGroupId}/raidGroupRequest/${raidGroupRequestId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.delete(`/raidGroup/${raidGroupId}/raidGroupRequest/${raidGroupRequestId}`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] });
void queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] });
}
});
}

View File

@@ -1,31 +1,17 @@
import { Counter } from "@/interface/Counters";
import { RaidInstance } from "@/interface/RaidInstance";
import { RaidInstancePersonCharacterXref } from "@/interface/RaidInstancePersonCharacterXref";
import { api } from "@/util/AxiosUtil";
import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetRaidInstance(raidInstanceId: string, raidGroupId: string){
return useQuery({
queryKey: ["raidInstances", raidInstanceId, raidGroupId],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}`);
const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as RaidInstance;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as RaidInstance;
},
enabled: !!raidInstanceId && !!raidGroupId
});
@@ -42,23 +28,9 @@ export function useGetRaidInstancesByRaidGroup(raidGroupId: string, page: number
params.append("searchTerm", searchTerm);
}
try{
const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance?${params}`);
const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as RaidInstance[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as RaidInstance[];
}
});
}
@@ -73,23 +45,9 @@ export function useGetRaidInstancesByRaidGroupCount(raidGroupId: string, searchT
params.append("searchTerm", searchTerm);
}
try{
const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/count?${params}`);
const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/count?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.count as number;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Counter).count;
}
});
}
@@ -102,26 +60,12 @@ export function useCreateRaidInstance(raidGroupId: string){
return useMutation({
mutationKey: ["createRaidInstance", raidGroupId],
mutationFn: async (raidInstance: RaidInstance) => {
try{
const response = await api.post(`/raidGroup/${raidGroupId}/raidInstance`, raidInstance);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.raidInstanceId as string;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as RaidInstance).raidInstanceId;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidInstances"] });
void queryClient.invalidateQueries({ queryKey: ["raidInstances"] });
}
});
}
@@ -133,24 +77,10 @@ export function useUpdateRaidInstance(raidGroupId: string){
return useMutation({
mutationKey: ["updateRaidInstance", raidGroupId],
mutationFn: async (raidInstance: RaidInstance) => {
try{
const response = await api.put(`/raidGroup/${raidGroupId}/raidInstance/${raidInstance.raidInstanceId}`, raidInstance);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/raidGroup/${raidGroupId}/raidInstance/${raidInstance.raidInstanceId}`, raidInstance);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidInstances"] });
void queryClient.invalidateQueries({ queryKey: ["raidInstances"] });
}
});
}
@@ -159,21 +89,7 @@ export function useUpdateRaidInstanceNoInvalidation(raidGroupId: string){
return useMutation({
mutationKey: ["updateRaidInstance", raidGroupId],
mutationFn: async (raidInstance: RaidInstance) => {
try{
const response = await api.put(`/raidGroup/${raidGroupId}/raidInstance/${raidInstance.raidInstanceId}`, raidInstance);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.put(`/raidGroup/${raidGroupId}/raidInstance/${raidInstance.raidInstanceId}`, raidInstance);
}
});
}
@@ -185,24 +101,10 @@ export function useDeleteRaidInstance(raidGroupId: string, raidInstanceId: strin
return useMutation({
mutationKey: ["deleteRaidInstance", raidGroupId, raidInstanceId],
mutationFn: async () => {
try{
const response = await api.delete(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.delete(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidInstances"] });
void queryClient.invalidateQueries({ queryKey: ["raidInstances"] });
}
});
}
@@ -212,23 +114,9 @@ export function useGetRaidInstancePersonCharacterXrefs(raidGroupId?: string, rai
return useQuery({
queryKey: ["raidInstancePersonCharacterXrefs", raidGroupId, raidInstanceId],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}/personCharacterXref`);
const response = await api.get(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}/personCharacterXref`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as RaidInstancePersonCharacterXref[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as RaidInstancePersonCharacterXref[];
},
enabled: !!raidGroupId && !!raidInstanceId
});
@@ -241,24 +129,10 @@ export function useUpdateRaidInstancePersonCharacterXrefs(raidGroupId?: string,
return useMutation({
mutationKey: ["updateRaidInstancePersonCharacterXrefs", raidGroupId, raidInstanceId],
mutationFn: async (raidInstancePersonCharacterXrefs: RaidInstancePersonCharacterXref[]) => {
try{
const response = await api.post(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}/personCharacterXref`, raidInstancePersonCharacterXrefs);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.post(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}/personCharacterXref`, raidInstancePersonCharacterXrefs);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidInstancePersonCharacterXrefs", raidGroupId, raidInstanceId] });
void queryClient.invalidateQueries({ queryKey: ["raidInstancePersonCharacterXrefs", raidGroupId, raidInstanceId] });
}
});
}

View File

@@ -1,30 +1,16 @@
import { Counter } from "@/interface/Counters";
import { RaidLayout, RaidLayoutClassGroupXref } from "@/interface/RaidLayout";
import { api } from "@/util/AxiosUtil";
import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetRaidLayout(raidGroupId?: string, raidLayoutId?: string){
return useQuery({
queryKey: ["raidLayout", raidGroupId, raidLayoutId],
queryFn: async () => {
try{
const response = await api.get(`/raidGroup/${raidGroupId}/raidLayout/${raidLayoutId}`);
const response = await api.get(`/raidGroup/${raidGroupId}/raidLayout/${raidLayoutId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as RaidLayout;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as RaidLayout;
},
enabled: !!raidGroupId && !!raidLayoutId
});
@@ -41,23 +27,9 @@ export function useGetRaidLayoutsByRaidGroup(raidGroupId: string, page: number,
params.append("searchTerm", searchTerm);
}
try{
const response = await api.get(`/raidGroup/${raidGroupId}/raidLayout?${params}`);
const response = await api.get(`/raidGroup/${raidGroupId}/raidLayout?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data as RaidLayout[];
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return response.data as RaidLayout[];
}
});
}
@@ -71,23 +43,9 @@ export function useGetRaidLayoutsByRaidGroupCount(raidGroupId: string, searchTer
params.append("searchTerm", searchTerm);
}
try{
const response = await api.get(`/raidGroup/${raidGroupId}/raidLayout/count?${params}`);
const response = await api.get(`/raidGroup/${raidGroupId}/raidLayout/count?${params}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
return response.data.count as number;
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
return (response.data as Counter).count;
}
});
}
@@ -99,29 +57,15 @@ export function useCreateRaidLayout(raidGroupId: string){
return useMutation({
mutationKey: ["createRaidLayout", raidGroupId],
mutationFn: async ({raidLayout, raidLayoutClassGroupXrefs}:{raidLayout: RaidLayout; raidLayoutClassGroupXrefs: RaidLayoutClassGroupXref[];}) => {
try{
const response = await api.post(`/raidGroup/${raidGroupId}/raidLayout`,
{
raidLayout,
raidLayoutClassGroupXrefs
}
);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
await api.post(`/raidGroup/${raidGroupId}/raidLayout`,
{
raidLayout,
raidLayoutClassGroupXrefs
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] });
void queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] });
}
});
}
@@ -133,30 +77,16 @@ export function useUpdateRaidLayout(raidGroupId: string){
return useMutation({
mutationKey: ["updateRaidLayout", raidGroupId],
mutationFn: async ({raidLayout, raidLayoutClassGroupXrefs}:{raidLayout: RaidLayout; raidLayoutClassGroupXrefs: RaidLayoutClassGroupXref[];}) => {
try{
const response = await api.put(`/raidGroup/${raidGroupId}/raidLayout/${raidLayout.raidLayoutId}`,
{
raidLayout,
raidLayoutClassGroupXrefs
}
);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
await api.put(`/raidGroup/${raidGroupId}/raidLayout/${raidLayout.raidLayoutId}`,
{
raidLayout,
raidLayoutClassGroupXrefs
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] });
queryClient.invalidateQueries({ queryKey: ["classGroups", "raidLayout"] });
void queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] });
void queryClient.invalidateQueries({ queryKey: ["classGroups", "raidLayout"] });
}
});
}
@@ -168,24 +98,10 @@ export function useDeleteRaidLayout(raidGroupId: string, raidLayoutId: string){
return useMutation({
mutationKey: ["deleteRaidLayout", raidGroupId, raidLayoutId],
mutationFn: async () => {
try{
const response = await api.delete(`/raidGroup/${raidGroupId}/raidLayout/${raidLayoutId}`);
if(response.data.errors){
throw new Error(response.data.errors.join(", "));
}
}
catch(error){
if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
}
await api.delete(`/raidGroup/${raidGroupId}/raidLayout/${raidLayoutId}`)
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] });
void queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] });
}
});
}

View File

@@ -22,4 +22,5 @@ export interface Account {
refreshToken?: string;
refreshTokenExpiration?: Date;
accountStatus: AccountStatus;
token?: string;
}

View File

@@ -0,0 +1,3 @@
export interface Counter {
count: number;
}

4
src/interface/Errors.ts Normal file
View File

@@ -0,0 +1,4 @@
export interface ResponseError {
status: string;
errors: string[];
}

11
src/interface/Token.ts Normal file
View File

@@ -0,0 +1,11 @@
export interface AuthToken {
iss: string;
iat: number;
exp: number;
sub: string;
accountId: string;
accountPermissions: string;
raidGroupPermissions: string;
gamePermissions: string;
raidGroupRequests: string;
}

View File

@@ -1,11 +1,11 @@
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import { AuthProvider } from './providers/AuthProvider.tsx'
import { ThemeProvider } from './providers/ThemeProvider.tsx'
import { TimedModalProvider } from "./providers/TimedModalProvider.tsx"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
import { AuthProvider } from "./providers/components/AuthProviderComponent.tsx";
import { ThemeProvider } from "./providers/components/ThemeProviderComponent.tsx";
import { TimedModalProvider } from "./providers/components/TimedModalProviderComponent.tsx";
const queryClient = new QueryClient();

View File

@@ -1,6 +1,6 @@
import PrimaryButton from "@/components/button/PrimaryButton";
import { useAuth } from "@/providers/AuthProvider";
import { api } from "@/util/AxiosUtil";
import api from "@/util/AxiosUtil";
import { useNavigate } from "react-router";
@@ -10,14 +10,9 @@ export default function LogoutPage(){
const logout = async () => {
const response = await api.get("/auth/logout");
if(response.status === 200){
reset();
navigate("/");
}
else{
//TODO: Handle error
}
await api.get("/auth/logout");
reset();
void navigate("/");
}
@@ -26,7 +21,7 @@ export default function LogoutPage(){
className="mt-8"
>
<PrimaryButton
onClick={logout}
onClick={() => void logout}
>
Logout
</PrimaryButton>

View File

@@ -2,7 +2,7 @@ import PrimaryButton from "@/components/button/PrimaryButton";
import TutorialComponent from "@/components/TutorialComponent";
import { TutorialStatus } from "@/interface/AccountTutorialStatus";
import { useAuth } from "@/providers/AuthProvider";
import RaidInstanceLayoutProvider from "@/providers/RaidInstanceLayoutProvider";
import RaidInstanceLayoutProvider from "@/providers/components/RaidInstanceLayoutProviderComponent";
import RaidInstanceCreatorUI from "@/ui/raidInstance/creator/RaidInstanceCreatorUI";
import { instanceTutorialSteps } from "@/util/TutorialUtil";
import { BsArrowLeft } from "react-icons/bs";
@@ -53,7 +53,7 @@ export default function RaidInstancePage(){
>
<PrimaryButton
shape="square"
onClick={() => navigator(`/raidGroup/${raidGroupId}`)}
onClick={() => void navigator(`/raidGroup/${raidGroupId}`)}
>
<BsArrowLeft
size={22}

View File

@@ -25,7 +25,7 @@ export default function ConfirmPage(){
else if(confirmQueryStatus === "success"){
addSuccessMessage("Email confirmed. Please Login.");
confirmQueryReset();
navigate("/login");
void navigate("/login");
}
}, [ confirmToken, confirmQueryMutate, confirmQueryStatus, confirmQueryError, confirmQueryReset, navigate, addSuccessMessage, addErrorMessage ]);

View File

@@ -18,7 +18,7 @@ export default function ForgotPasswordPage(){
if(forgotEmailStatus === "success"){
addSuccessMessage("Email sent successfully");
forgotEmailReset();
navigate("/login");
void navigate("/login");
}
else if(forgotEmailStatus === "error"){
addErrorMessage("Failed to send email: " + forgotEmailError?.message);

View File

@@ -21,7 +21,7 @@ export default function ForgotTokenPage(){
if(forgotQueryStatus === "success"){
addSuccessMessage("Password reset. Please login.");
forgotQueryReset();
navigate("/login");
void navigate("/login");
}
else if(forgotQueryStatus === "error"){
addErrorMessage("Error resetting password: " + forgotQueryError.message);

View File

@@ -1,6 +1,8 @@
import PrimaryButton from "@/components/button/PrimaryButton";
import PasswordInput from "@/components/input/PasswordInput";
import TextInput from "@/components/input/TextInput";
import { Account } from "@/interface/Account";
import { ResponseError } from "@/interface/Errors";
import { useAuth } from "@/providers/AuthProvider";
import { useTimedModal } from "@/providers/TimedModalProvider";
import { Link, Navigate, useNavigate } from "react-router";
@@ -27,12 +29,12 @@ export default function LoginPage(){
.then(async (response) => {
if(response.status === 200){
addSuccessMessage("Logged in successfully");
const json = await response.json();
const json = await response.json() as Account;
setTokenData(json);
navigate("/raidGroup");
void navigate("/raidGroup");
}
else{
addErrorMessage("Failed to log in: " + ((await response.json()).errors as string[]).join(",\n"));
addErrorMessage("Failed to log in: " + (await response.json() as ResponseError).errors.join(",\n"));
}
})
.catch(error => {

View File

@@ -48,7 +48,7 @@ export default function SignupPage(){
if(signupQuery.status === "success"){
addSuccessMessage("Signed up successfully");
navigate("/login");
void navigate("/login");
}
else if(signupQuery.status === "error"){
addErrorMessage("Failed to signup: " + signupQuery.error.message);

View File

@@ -1,23 +1,21 @@
import { useGetTutorialsStatus, useUpdateTutorialsStatus } from "@/hooks/AccountHooks";
import { Account } from "@/interface/Account";
import { AccountPermission } from "@/interface/AccountPermission";
import { AccountTutorialStatus } from "@/interface/AccountTutorialStatus";
import { GamePermission } from "@/interface/GamePermission";
import { RaidGroupPermission } from "@/interface/RaidGroupPermission";
import { RaidGroupRequest } from "@/interface/RaidGroupRequest";
import { api } from "@/util/AxiosUtil";
import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useState } from "react";
import { Navigate, Outlet } from "react-router";
import { createContext, useContext } from "react";
type AuthProviderProps = {
export type AuthProviderProps = {
children: React.ReactNode;
jwtStorageKey?: string;
refreshTokenStorageKey?: string;
}
type AuthProviderState = {
jwt: string | null;
setJwt: (token: string | null) => void;
export type AuthProviderState = {
jwt: string | null | undefined;
setJwt: (token: string | null | undefined) => void;
expiration: Date | null;
setExpiration: (expiration: Date | null) => void;
accountId: string | null;
@@ -28,9 +26,7 @@ type AuthProviderState = {
tutorialsStatus: AccountTutorialStatus;
setTutorialsStatus: (tutorialsStatus: AccountTutorialStatus) => void;
reset: () => void;
/* eslint-disable @typescript-eslint/no-explicit-any */
setTokenData: (data: any) => void;
/* eslint-enable @typescript-eslint/no-explicit-any */
setTokenData: (data: Account) => void;
}
const initialState: AuthProviderState = {
@@ -49,159 +45,7 @@ const initialState: AuthProviderState = {
setTokenData: () => null
}
const AuthContext = createContext<AuthProviderState>(initialState);
export function AuthProvider({
children
}: AuthProviderProps){
const [ jwt, setJwt ] = useState<string | null>(null);
const [ expiration, setExpiration ] = useState<Date | null>(null);
const [ firstFetch, setFirstFetch ] = useState(true);
const [ accountId, setAccountId ] = useState<string | null>(null);
const [ accountPermissions, setAccountPermissions ] = useState<AccountPermission[]>([]);
const [ raidGroupPermissions, setRaidGroupPermissions ] = useState<RaidGroupPermission[]>([]);
const [ gamePermissions, setGamePermissions ] = useState<GamePermission[]>([]);
const [ raidGroupRequests, setRaidGroupRequests ] = useState<RaidGroupRequest[]>([]);
const [ tutorialsStatus, setTutorialsStatus ] = useState<AccountTutorialStatus>({} as AccountTutorialStatus);
const tutorialsStatusQuery = useGetTutorialsStatus(accountId);
const { mutate: tutorialsStatusMutation } = useUpdateTutorialsStatus();
/* eslint-disable @typescript-eslint/no-explicit-any */
const setTokenData = useCallback((data: any) => {
setJwt(data.token);
const decodedToken = JSON.parse(atob(data.token.split(".")[1]));
//console.log("decodedToken = ");
//console.log(decodedToken);
setExpiration(new Date(decodedToken.exp * 1000));
setFirstFetch(false);
setAccountId(decodedToken.accountId);
setAccountPermissions(JSON.parse(decodedToken.accountPermissions));
setRaidGroupPermissions(JSON.parse(decodedToken.raidGroupPermissions));
setGamePermissions(JSON.parse(decodedToken.gamePermissions));
setRaidGroupRequests(JSON.parse(decodedToken.raidGroupRequests));
}, [ setJwt, setExpiration, setFirstFetch, setAccountId, setAccountPermissions, setRaidGroupPermissions, setGamePermissions, setRaidGroupRequests ]);
/* eslint-enable @typescript-eslint/no-explicit-any */
const fetchToken = useCallback(async () => {
//console.log("Fetching token");
try{
const response = await api.get("/auth/refresh");
//If the token is retrieved
if((response.status === 200) && (!response.data.errors)){
setTokenData(response.data);
return response.data.token;
}
//If the token cannot be retrieved
else{
setJwt(null);
setExpiration(null);
setFirstFetch(false);
}
}
//If the token cannot be retrieved
catch{
setJwt(null);
setExpiration(null);
setFirstFetch(false);
}
}, [ setJwt, setExpiration, setFirstFetch, setTokenData ]);
//Add the token to all queries
useLayoutEffect(() => {
const authInterceptor = api.interceptors.request.use(async (config) => {
if(config.url?.endsWith("/auth/refresh")){
return config;
}
let currentJwt = jwt;
const currentTime = new Date();
currentTime.setSeconds(currentTime.getSeconds() + 5);
if((expiration) && (expiration <= currentTime) && (!config.url?.endsWith("/auth/refresh"))){
currentJwt = await fetchToken();
config.headers.Authorization = jwt ? `Bearer ${currentJwt}` : config.headers.Authorization;
}
config.headers.Authorization = jwt ? `Bearer ${currentJwt}` : config.headers.Authorization;
return config;
});
return () => { api.interceptors.request.eject(authInterceptor); };
}, [ jwt, expiration, fetchToken ]);
//Try to get the token on page load
useEffect(() => {
fetchToken();
}, [ fetchToken ]);
//Update the tutorial status when fetched
useEffect(() => {
if(tutorialsStatusQuery.status === "success"){
setTutorialsStatus(tutorialsStatusQuery.data);
}
}, [ tutorialsStatusQuery.status, tutorialsStatusQuery.data ]);
const updateTutorialsStatus = useCallback((newTutorialsStatus: AccountTutorialStatus) => {
setTutorialsStatus(newTutorialsStatus);
tutorialsStatusMutation(newTutorialsStatus);
}, [ setTutorialsStatus, tutorialsStatusMutation ]);
const reset = useCallback(() => {
setJwt(null);
setExpiration(null);
setAccountId(null);
setAccountPermissions([]);
setRaidGroupPermissions([]);
setGamePermissions([]);
setRaidGroupRequests([]);
setTutorialsStatus({} as AccountTutorialStatus);
}, [ setJwt, setExpiration, setAccountId, setAccountPermissions, setRaidGroupPermissions, setGamePermissions, setRaidGroupRequests, setTutorialsStatus ]);
const currentTokens = useMemo(() => ({
jwt, setJwt,
expiration, setExpiration,
accountId,
accountPermissions,
raidGroupPermissions,
gamePermissions,
raidGroupRequests,
tutorialsStatus, setTutorialsStatus: updateTutorialsStatus,
reset, setTokenData
}), [ jwt, expiration, accountId, accountPermissions, raidGroupPermissions, gamePermissions, raidGroupRequests, tutorialsStatus, updateTutorialsStatus, reset, setTokenData ]);
//TODO: Return a spinner while the first token is being fetched
if(firstFetch){
return (
<main
className="text-4xl"
>
Loading...
</main>
);
}
return (
<AuthContext.Provider value={currentTokens}>
{children}
</AuthContext.Provider>
);
}
export function ProtectedRoute(){
const { jwt } = useAuth();
if(!jwt){
return <Navigate to="/login"/>;
}
return <Outlet/>;
}
export const AuthContext = createContext<AuthProviderState>(initialState);
export const useAuth = () => {

View File

@@ -0,0 +1,58 @@
import { ClassGroup } from "@/interface/ClassGroup";
import { Person } from "@/interface/Person";
import { PersonCharacter } from "@/interface/PersonCharacter";
import { RaidGroup } from "@/interface/RaidGroup";
import { RaidInstance } from "@/interface/RaidInstance";
import { RaidInstancePersonCharacterXref } from "@/interface/RaidInstancePersonCharacterXref";
import { RaidLayout } from "@/interface/RaidLayout";
import { createContext, useContext } from "react";
export interface RaidInstanceContextState {
raidInstance?: RaidInstance;
setRaidInstance: React.Dispatch<React.SetStateAction<RaidInstance | undefined>>;
raidGroup?: RaidGroup;
classGroups: ClassGroup[];
selectedClassGroups: (ClassGroup | null)[];
setSelectedClassGroups: React.Dispatch<React.SetStateAction<(ClassGroup | null)[]>>;
raidLayout?: RaidLayout;
setRaidLayout: React.Dispatch<React.SetStateAction<RaidLayout | undefined>>;
raidLayouts: RaidLayout[];
people: Person[];
roster: Person[];
setRoster: React.Dispatch<React.SetStateAction<Person[]>>;
personCharacters: PersonCharacter[];
setPersonCharacters: React.Dispatch<React.SetStateAction<PersonCharacter[]>>;
personCharacterXrefs: RaidInstancePersonCharacterXref[];
setPersonCharacterXrefs: React.Dispatch<React.SetStateAction<RaidInstancePersonCharacterXref[]>>;
}
export const RaidInstanceContext = createContext<RaidInstanceContextState>({
raidInstance: {} as RaidInstance,
setRaidInstance: () => {},
raidGroup: {} as RaidGroup,
classGroups: [],
selectedClassGroups: [],
setSelectedClassGroups: () => {},
raidLayout: {} as RaidLayout,
setRaidLayout: () => {},
raidLayouts: [],
people: [],
roster: [],
setRoster: () => {},
personCharacters: [],
setPersonCharacters: () => {},
personCharacterXrefs: [],
setPersonCharacterXrefs: () => {}
});
export function useRaidInstanceContext(){
const context = useContext(RaidInstanceContext);
if(!context){
throw new Error("useRaidInstanceContext must be used within a RaidInstanceLayoutProvider");
}
return context;
}

View File

@@ -0,0 +1,33 @@
import { createContext, useContext } from "react";
export type Theme = "dark" | "light" | "system";
export type ThemeProviderProps = {
children: React.ReactNode;
defaultTheme?: Theme;
storageKey?: string;
}
type ThemeProviderState = {
theme: Theme;
setTheme: (theme: Theme) => void;
}
const initialState: ThemeProviderState = {
theme: "system",
setTheme: () => null
}
export const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
export const useTheme = () => {
const context = useContext(ThemeProviderContext);
if(context === undefined){
throw new Error("useTheme must be used within a ThemeProvider");
}
return context;
}

View File

@@ -0,0 +1,28 @@
import { createContext, useContext } from "react";
type TimedModalProviderState = {
addMessage: (message: React.ReactNode, timeout: number) => void;
addSuccessMessage: (message: string) => void;
addErrorMessage: (message: string) => void;
}
const initialState: TimedModalProviderState = {
addMessage: () => null,
addSuccessMessage: () => null,
addErrorMessage: () => null
}
export const TimedModalProviderContext = createContext<TimedModalProviderState>(initialState);
export const useTimedModal = () => {
const context = useContext(TimedModalProviderContext);
if(context === undefined){
throw new Error("useTimeModal must be used within a TimedModalProvider");
}
return context;
}

View File

@@ -0,0 +1,154 @@
import { useGetTutorialsStatus, useUpdateTutorialsStatus } from "@/hooks/AccountHooks";
import { Account } from "@/interface/Account";
import { AccountPermission } from "@/interface/AccountPermission";
import { AccountTutorialStatus } from "@/interface/AccountTutorialStatus";
import { GamePermission } from "@/interface/GamePermission";
import { RaidGroupPermission } from "@/interface/RaidGroupPermission";
import { RaidGroupRequest } from "@/interface/RaidGroupRequest";
import { AuthToken } from "@/interface/Token";
import api from "@/util/AxiosUtil";
import { useCallback, useEffect, useLayoutEffect, useMemo, useState } from "react";
import { Navigate, Outlet } from "react-router";
import { AuthContext, AuthProviderProps, useAuth } from "../AuthProvider";
export function AuthProvider({
children
}: AuthProviderProps){
const [ jwt, setJwt ] = useState<string | null | undefined>(null);
const [ expiration, setExpiration ] = useState<Date | null>(null);
const [ firstFetch, setFirstFetch ] = useState(true);
const [ accountId, setAccountId ] = useState<string | null>(null);
const [ accountPermissions, setAccountPermissions ] = useState<AccountPermission[]>([]);
const [ raidGroupPermissions, setRaidGroupPermissions ] = useState<RaidGroupPermission[]>([]);
const [ gamePermissions, setGamePermissions ] = useState<GamePermission[]>([]);
const [ raidGroupRequests, setRaidGroupRequests ] = useState<RaidGroupRequest[]>([]);
const [ tutorialsStatus, setTutorialsStatus ] = useState<AccountTutorialStatus>({} as AccountTutorialStatus);
const tutorialsStatusQuery = useGetTutorialsStatus(accountId);
const { mutate: tutorialsStatusMutation } = useUpdateTutorialsStatus();
const setTokenData = useCallback((data: Account) => {
setJwt(data.token);
const decodedToken = JSON.parse(atob(data.token!.split(".")[1])) as AuthToken;
//console.log("decodedToken = ");
//console.log(decodedToken);
setExpiration(new Date(decodedToken.exp * 1000));
setFirstFetch(false);
setAccountId(decodedToken.accountId);
setAccountPermissions(JSON.parse(decodedToken.accountPermissions) as AccountPermission[]);
setRaidGroupPermissions(JSON.parse(decodedToken.raidGroupPermissions) as RaidGroupPermission[]);
setGamePermissions(JSON.parse(decodedToken.gamePermissions) as GamePermission[]);
setRaidGroupRequests(JSON.parse(decodedToken.raidGroupRequests) as RaidGroupRequest[]);
}, [ setJwt, setExpiration, setFirstFetch, setAccountId, setAccountPermissions, setRaidGroupPermissions, setGamePermissions, setRaidGroupRequests ]);
const fetchToken = useCallback(async () => {
//console.log("Fetching token");
try{
const response = await api.get("/auth/refresh");
//If the token is retrieved
setTokenData(response.data as Account);
return (response.data as Account).token;
}
//If the token cannot be retrieved
catch{
setJwt(null);
setExpiration(null);
setFirstFetch(false);
}
}, [ setJwt, setExpiration, setFirstFetch, setTokenData ]);
//Add the token to all queries
useLayoutEffect(() => {
const authInterceptor = api.interceptors.request.use(async (config) => {
if(config.url?.endsWith("/auth/refresh")){
return config;
}
let currentJwt = jwt;
const currentTime = new Date();
currentTime.setSeconds(currentTime.getSeconds() + 5);
if((expiration) && (expiration <= currentTime) && (!config.url?.endsWith("/auth/refresh"))){
currentJwt = await fetchToken();
config.headers.Authorization = jwt ? `Bearer ${currentJwt}` : config.headers.Authorization;
}
config.headers.Authorization = jwt ? `Bearer ${currentJwt}` : config.headers.Authorization;
return config;
});
return () => { api.interceptors.request.eject(authInterceptor); };
}, [ jwt, expiration, fetchToken ]);
//Try to get the token on page load
useEffect(() => {
void fetchToken();
}, [ fetchToken ]);
//Update the tutorial status when fetched
useEffect(() => {
if(tutorialsStatusQuery.status === "success"){
setTutorialsStatus(tutorialsStatusQuery.data);
}
}, [ tutorialsStatusQuery.status, tutorialsStatusQuery.data ]);
const updateTutorialsStatus = useCallback((newTutorialsStatus: AccountTutorialStatus) => {
setTutorialsStatus(newTutorialsStatus);
tutorialsStatusMutation(newTutorialsStatus);
}, [ setTutorialsStatus, tutorialsStatusMutation ]);
const reset = useCallback(() => {
setJwt(null);
setExpiration(null);
setAccountId(null);
setAccountPermissions([]);
setRaidGroupPermissions([]);
setGamePermissions([]);
setRaidGroupRequests([]);
setTutorialsStatus({} as AccountTutorialStatus);
}, [ setJwt, setExpiration, setAccountId, setAccountPermissions, setRaidGroupPermissions, setGamePermissions, setRaidGroupRequests, setTutorialsStatus ]);
const currentTokens = useMemo(() => ({
jwt, setJwt,
expiration, setExpiration,
accountId,
accountPermissions,
raidGroupPermissions,
gamePermissions,
raidGroupRequests,
tutorialsStatus, setTutorialsStatus: updateTutorialsStatus,
reset, setTokenData
}), [ jwt, expiration, accountId, accountPermissions, raidGroupPermissions, gamePermissions, raidGroupRequests, tutorialsStatus, updateTutorialsStatus, reset, setTokenData ]);
//TODO: Return a spinner while the first token is being fetched
if(firstFetch){
return (
<main
className="text-4xl"
>
Loading...
</main>
);
}
return (
<AuthContext.Provider value={currentTokens}>
{children}
</AuthContext.Provider>
);
}
export function ProtectedRoute(){
const { jwt } = useAuth();
if(!jwt){
return <Navigate to="/login"/>;
}
return <Outlet/>;
}

View File

@@ -11,46 +11,8 @@ import { RaidGroup } from "@/interface/RaidGroup";
import { RaidInstance } from "@/interface/RaidInstance";
import { RaidInstancePersonCharacterXref } from "@/interface/RaidInstancePersonCharacterXref";
import { RaidLayout } from "@/interface/RaidLayout";
import { createContext, useContext, useEffect, useMemo, useState } from "react";
interface RaidInstanceContextState {
raidInstance?: RaidInstance;
setRaidInstance: React.Dispatch<React.SetStateAction<RaidInstance | undefined>>;
raidGroup?: RaidGroup;
classGroups: ClassGroup[];
selectedClassGroups: (ClassGroup | null)[];
setSelectedClassGroups: React.Dispatch<React.SetStateAction<(ClassGroup | null)[]>>;
raidLayout?: RaidLayout;
setRaidLayout: React.Dispatch<React.SetStateAction<RaidLayout | undefined>>;
raidLayouts: RaidLayout[];
people: Person[];
roster: Person[];
setRoster: React.Dispatch<React.SetStateAction<Person[]>>;
personCharacters: PersonCharacter[];
setPersonCharacters: React.Dispatch<React.SetStateAction<PersonCharacter[]>>;
personCharacterXrefs: RaidInstancePersonCharacterXref[];
setPersonCharacterXrefs: React.Dispatch<React.SetStateAction<RaidInstancePersonCharacterXref[]>>;
}
const RaidInstanceContext = createContext<RaidInstanceContextState>({
raidInstance: {} as RaidInstance,
setRaidInstance: () => {},
raidGroup: {} as RaidGroup,
classGroups: [],
selectedClassGroups: [],
setSelectedClassGroups: () => {},
raidLayout: {} as RaidLayout,
setRaidLayout: () => {},
raidLayouts: [],
people: [],
roster: [],
setRoster: () => {},
personCharacters: [],
setPersonCharacters: () => {},
personCharacterXrefs: [],
setPersonCharacterXrefs: () => {}
});
import { useEffect, useMemo, useState } from "react";
import { RaidInstanceContext, RaidInstanceContextState } from "../RaidInstanceLayoutProvider";
export default function RaidInstanceLayoutProvider({
@@ -181,14 +143,3 @@ export default function RaidInstanceLayoutProvider({
</RaidInstanceContext.Provider>
);
}
export function useRaidInstanceContext(){
const context = useContext(RaidInstanceContext);
if(!context){
throw new Error("useRaidInstanceContext must be used within a RaidInstanceLayoutProvider");
}
return context;
}

View File

@@ -1,25 +1,5 @@
import { createContext, useContext, useEffect, useMemo, useState } from "react";
type Theme = "dark" | "light" | "system";
type ThemeProviderProps = {
children: React.ReactNode;
defaultTheme?: Theme;
storageKey?: string;
}
type ThemeProviderState = {
theme: Theme;
setTheme: (theme: Theme) => void;
}
const initialState: ThemeProviderState = {
theme: "system",
setTheme: () => null
}
const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
import { useEffect, useMemo, useState } from "react";
import { Theme, ThemeProviderContext, ThemeProviderProps } from "../ThemeProvider";
export function ThemeProvider({
@@ -59,13 +39,3 @@ export function ThemeProvider({
</ThemeProviderContext.Provider>
);
}
export const useTheme = () => {
const context = useContext(ThemeProviderContext);
if(context === undefined){
throw new Error("useTheme must be used within a ThemeProvider");
}
return context;
}

View File

@@ -2,23 +2,8 @@ import DangerMessage from "@/components/message/DangerMessage";
import SuccessMessage from "@/components/message/SuccessMessage";
import Modal from "@/components/modal/Modal";
import ModalBody from "@/components/modal/ModalBody";
import { createContext, useContext, useEffect, useRef, useState } from "react";
type TimedModalProviderState = {
addMessage: (message: React.ReactNode, timeout: number) => void;
addSuccessMessage: (message: string) => void;
addErrorMessage: (message: string) => void;
}
const initialState: TimedModalProviderState = {
addMessage: () => null,
addSuccessMessage: () => null,
addErrorMessage: () => null
}
const TimedModalProviderContext = createContext<TimedModalProviderState>(initialState);
import { useEffect, useRef, useState } from "react";
import { TimedModalProviderContext } from "../TimedModalProvider";
export function TimedModalProvider({
@@ -92,13 +77,3 @@ export function TimedModalProvider({
</TimedModalProviderContext.Provider>
);
}
export const useTimedModal = () => {
const context = useContext(TimedModalProviderContext);
if(context === undefined){
throw new Error("useTimeModal must be used within a TimedModalProvider");
}
return context;
}

View File

@@ -43,24 +43,25 @@ export default function AccountsList({
const headElements: React.ReactNode[] = [
<div>
<div key="username">
Username
</div>,
isSiteAdmin(accountPermissions) &&
<div>
<div key="email">
Email
</div>,
<div>
<div key="loginDate">
Login Date
</div>,
raidGroup && isRaidGroupAdmin(raidGroup?.raidGroupId ?? "", raidGroupPermissions ?? [], accountPermissions) &&
<div>
<div key="raidGroupPermission">
Raid Group Permission
</div>,
<div>
<div key="status">
Status
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -69,27 +70,30 @@ export default function AccountsList({
const bodyElements: React.ReactNode[][] = accounts.map((account) => [
<div
key={`username-${account.accountId}`}
className="text-nowrap pl-2 text-start"
>
{account.username}
</div>,
isSiteAdmin(accountPermissions) &&
<div>
<div key={`email-${account.accountId}`}>
{account.email}
</div>,
<div
key={`loginDate-${account.accountId}`}
className="text-nowrap"
>
{account.loginDate ? moment(account.loginDate).format("MM-DD-YYYY hh:mm a") : <>&nbsp;</>}
</div>,
raidGroup && isRaidGroupAdmin(raidGroup?.raidGroupId ?? "", raidGroupPermissions ?? [], accountPermissions) &&
<div>
<div key={`raidGroupPermission-${account.accountId}`}>
{raidGroupPermissions.find((perm) => (perm.raidGroupId === raidGroup?.raidGroupId))?.permission}
</div>,
<div>
<div key={`status-${account.accountId}`}>
{account.accountStatus}
</div>,
<div
key={`actions-${account.accountId}`}
className="flex flex-row items-center justify-center gap-2 pl-16"
>
<div

View File

@@ -6,22 +6,23 @@ import AccountAdminButtons from "./AccountAdminButtons";
export default function AccountsListSkeleton(){
const headElements: React.ReactNode[] = [
<div>
<div key="id">
ID
</div>,
<div>
<div key="username">
Username
</div>,
<div>
<div key="email">
Email
</div>,
<div>
<div key="loginDate">
Login Date
</div>,
<div>
<div key="status'">
Status
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -65,21 +66,27 @@ function AccountSkeleton(): React.ReactNode[]{
}
const elements: React.ReactNode[] = [
<div
key="id"
className={`h-6 w-72 mr-1 ${elementBg}`}
/>,
<div
key="username"
className={`h-6 w-48 ${elementBg}`}
/>,
<div
key="email"
className={`h-6 w-80 ${elementBg}`}
/>,
<div
key="loginDate"
className={`h-6 w-64 ${elementBg}`}
/>,
<div
key="status"
className={`h-6 w-28 ${elementBg}`}
/>,
<div
key="actions"
className={`flex flex-row items-center justify-center gap-2 pl-16`}
>
<div className="py-4 border-l border-neutral-500">&nbsp;</div>

View File

@@ -114,7 +114,7 @@ export default function CalendarEventModal({
addErrorMessage("Calendar event ID is required");
return;
}
deleteCalendarEventMutate.mutate(calendarEvent as CalendarEvent);
deleteCalendarEventMutate.mutate(calendarEvent);
}

View File

@@ -35,13 +35,14 @@ export default function ClassGroupList({
const headElements: React.ReactNode[] = [
<div>
<div key="name">
Name
</div>,
<div>
<div key="classes">
Classes
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -50,16 +51,18 @@ export default function ClassGroupList({
const bodyElements: React.ReactNode[][] = classGroups.map((classGroup) => [
<div
key="name"
className="text-nowrap"
>
{classGroup.classGroupName}
</div>,
<div>
<div key="classes">
<GameClassByClassGroupDisplay
classGroupId={classGroup.classGroupId ?? ""}
/>
</div>,
<div
key="actions"
className="flex flex-row items-center justify-center gap-2 pl-16"
>
<div

View File

@@ -6,13 +6,14 @@ import ClassGroupButtons from "./ClassGroupButtons";
export default function ClassGroupListSkeleton(){
const headerElements: React.ReactElement[] = [
<div>
<div key="name">
Name
</div>,
<div>
<div key="classes">
Classes
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -57,12 +58,15 @@ function ClassGroupSkeleton(): React.ReactNode[]{
const elements: React.ReactNode[] = [
<div
key="name"
className={`h-6 w-72 mr-2 ${elementBg}`}
/>,
<div
key="classes"
className={`h-6 w-[64rem] ${elementBg}`}
/>,
<div
key="actions"
className={`flex flex-row items-center justify-center gap-2 pl-16`}
>
<div className="py-4 border-l border-neutral-500">&nbsp;</div>

View File

@@ -17,7 +17,7 @@ export default function SelectClassGroupModal({
display: boolean;
close: () => void;
selectedClassGroup?: ClassGroup | null | undefined;
onChange: (classGroup?: ClassGroup | null | undefined) => void;
onChange: (classGroup?: ClassGroup | null) => void;
raidGroupId: string;
}){
const [ currentClassGroup, setCurrentClassGroup ] = useState(selectedClassGroup);

View File

@@ -29,13 +29,14 @@ export default function GamesList({
const headElements: React.ReactNode[] = [
<div>
<div key="icon">
Icon
</div>,
<div>
<div key="name">
Name
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -43,7 +44,7 @@ export default function GamesList({
];
const bodyElements: React.ReactNode[][] = games.map((game) => [
<div>
<div key="icon">
{
game.gameIcon &&
<div
@@ -58,11 +59,13 @@ export default function GamesList({
&nbsp;
</div>,
<Link
key="name"
to={`/game/${game.gameId}`}
>
{game.gameName}
</Link>,
<div
key="actions"
className="flex flex-row items-center justify-center gap-2 pl-16"
>
<div

View File

@@ -8,13 +8,14 @@ import GameAdminButtons from "./GameAdminButtons";
export default function GamesListSkeleton(){
const headElements: React.ReactNode[] = [
<div>
<div key="icon">
Icon
</div>,
<div>
<div key="name">
Name
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -56,12 +57,15 @@ function GameSkeleton(): React.ReactNode[]{
}
const elements: React.ReactNode[] = [
<div
key="icon"
className={`h-8 w-8 -my-1 mr-4 ${elementBg}`}
/>,
<div
key="name"
className={`h-6 w-full ${elementBg}`}
/>,
<div
key="actions"
className={`flex flex-row items-center justify-center gap-2 pl-16`}
>
<div className="py-4 border-l border-neutral-500">&nbsp;</div>

View File

@@ -28,13 +28,14 @@ export default function GameClassList({
const headElements: React.ReactNode[] = [
<div>
<div key="icon">
Icon
</div>,
<div>
<div key="name">
Name
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -42,7 +43,7 @@ export default function GameClassList({
];
const bodyElements: React.ReactNode[][] = gameClasses.map((gameClass) => [
<div>
<div key="icon">
{
gameClass.gameClassIcon &&
<div
@@ -56,10 +57,11 @@ export default function GameClassList({
}
&nbsp;
</div>,
<div>
<div key="name">
{gameClass.gameClassName}
</div>,
<div
key="actions"
className="flex flex-row items-center justify-center gap-2 pl-16"
>
<div

View File

@@ -7,13 +7,14 @@ import GameClassAdminButtons from "./GameClassAdminButtons";
export default function GameClassListSkeleton(){
const headElements: React.ReactNode[] = [
<div>
<div key="icon">
Icon
</div>,
<div>
<div key="name">
Name
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -57,12 +58,15 @@ function GameClassSkeleton(): React.ReactNode[]{
const elements: React.ReactNode[] = [
<div
key="icon"
className={`h-8 w-8 -my-1 mr-4 ${elementBg}`}
/>,
<div
key="name"
className={`h-6 w-full ${elementBg}`}
/>,
<div
key="actions"
className={`flex flex-row items-center justify-center gap-2 pl-16`}
>
<div className="py-4 border-l border-neutral-500">&nbsp;</div>

View File

@@ -60,7 +60,7 @@ export default function PersonDisplay({
>
<PrimaryButton
shape="square"
onClick={() => navigate(`/raidGroup/${raidGroup.raidGroupId}`)}
onClick={() => void navigate(`/raidGroup/${raidGroup.raidGroupId}`)}
>
<BsArrowLeft
size={22}

View File

@@ -37,19 +37,22 @@ export default function PersonList({
const headElements: React.ReactNode[] = [
<div
key="name"
className="text-nowrap"
>
Person Name
</div>,
<div
key="discordId"
className="text-nowrap"
>
Discord ID
</div>,
<div>
<div key="characters">
Characters
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -58,15 +61,17 @@ export default function PersonList({
const bodyElements: React.ReactNode[][] = people.map((person) => [
<Link
key="name"
to={`/raidGroup/${raidGroup.raidGroupId}/person/${person.personId}`}
className="text-nowrap"
>
{person.personName}
</Link>,
<div>
<div key="discordId">
{person.discordId}
</div>,
<Link
key="characters"
to={`/raidGroup/${raidGroup.raidGroupId}/person/${person.personId}`}
className="text-nowrap"
>
@@ -76,6 +81,7 @@ export default function PersonList({
/>
</Link>,
<div
key="actions"
className="flex flex-row items-center justify-center gap-2 pl-16"
>
<div

View File

@@ -7,16 +7,17 @@ import PersonAdminButtons from "./PersonAdminButtons";
export default function PersonListSkeleton(){
const headElements: React.ReactNode[] = [
<div>
<div key="name">
Person Name
</div>,
<div>
<div key="discordId">
Discord ID
</div>,
<div>
<div key="characters">
Characters
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -59,15 +60,19 @@ export function PersonSkeleton(): React.ReactNode[]{
}
const elements: React.ReactNode[] = [
<div
key="name"
className={`h-6 w-64 mr-1 ${elementBg}`}
/>,
<div
key="discordId"
className={`h-6 w-48 ml-2 ${elementBg}`}
/>,
<div
key="characters"
className={`h-6 w-[48rem] ${elementBg}`}
/>,
<div
key="actions"
className={`flex flex-row items-center justify-center gap-2 pl-16`}
>
<div className="py-4 border-l border-neutral-500">&nbsp;</div>

View File

@@ -33,20 +33,22 @@ export default function PersonCharacterList({
const headElements: React.ReactNode[] = [
<div
key="name"
className="text-nowrap"
>
Character Name
</div>,
<div>
<div key="class">
Class
</div>,
<div>
<div key="rating">
Rating
</div>,
<div>
<div key="comments">
Comments
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -55,30 +57,33 @@ export default function PersonCharacterList({
const bodyElements: React.ReactNode[][] = personCharacters.map((personCharacter) => [
<div
key="name"
className="text-nowrap"
>
{personCharacter.characterName}
</div>,
<div
key="class"
className="flex flex-row items-center justify-center h-full"
>
<GameClassCellDisplay
gameClassId={personCharacter.gameClassId}
/>
</div>,
<div>
<div key="rating">
{
personCharacter.characterRating && personCharacter.characterRating > 0 ?
personCharacter.characterRating :
<>&nbsp;</>
}
</div>,
<div>
<div key="comments">
{
personCharacter.characterComments || <>&nbsp;</>
}
</div>,
<div
key="actions"
className="flex flex-row flex-nowrap items-center justify-center gap-2 pl-16"
>
<div

View File

@@ -6,19 +6,20 @@ import PersonCharacterAdminButtons from "./PersonCharacterAdminButtons";
export default function PersonCharacterListSkeleton(){
const headElements: React.ReactNode[] = [
<div>
<div key="name">
Character Name
</div>,
<div>
<div key="class">
Class
</div>,
<div>
<div key="rating">
Rating
</div>,
<div>
<div key="comments">
Comments
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -61,18 +62,23 @@ function PersonCharacterSkeleton(): React.ReactNode[]{
const elements: React.ReactNode[] = [
<div
key="name"
className={`h-6 w-96 mr-1 ${elementBg}`}
/>,
<div
key="class"
className={`h-6 w-72 ml-2 ${elementBg}`}
/>,
<div
key="rating"
className={`h-6 w-32 ${elementBg}`}
/>,
<div
key="comments"
className={`h-6 w-[32rem] ${elementBg}`}
/>,
<div
key="actions"
className={`flex flex-row items-center justify-center gap-2 pl-16`}
>
<div className="py-4 border-l border-neutral-500">&nbsp;</div>

View File

@@ -31,13 +31,14 @@ export default function RaidGroupsList({
const headElements: React.ReactNode[] = [
<div>
<div key="icon">
Icon
</div>,
<div>
<div key="name">
Name
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -45,7 +46,7 @@ export default function RaidGroupsList({
];
const bodyElements: React.ReactNode[][] = raidGroups.map((raidGroup) => [
<div>
<div key="icon">
{
raidGroup.raidGroupIcon &&
<div
@@ -60,11 +61,13 @@ export default function RaidGroupsList({
&nbsp;
</div>,
<Link
key="name"
to={`/raidGroup/${raidGroup.raidGroupId}`}
>
{raidGroup.raidGroupName}
</Link>,
<div
key="actions"
className="flex flex-row items-center justify-center gap-2 pl-16"
>
<div

View File

@@ -7,13 +7,14 @@ import RaidGroupAdminButtons from "./RaidGroupAdminButtons";
export default function RaidGroupsListSkeleton(){
const headElements: React.ReactNode[] = [
<div>
<div key="icon">
Icon
</div>,
<div>
<div key="name">
Name
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -58,12 +59,15 @@ function RaidGroupSkeleton(): React.ReactNode[]{
}
const elements: React.ReactNode[] = [
<div
key="icon"
className={`h-8 w-8 -my-1 mr-4 ${elementBg}`}
/>,
<div
key="name"
className={`h-6 w-full ${elementBg}`}
/>,
<div
key="actions"
className={`flex flex-row items-center justify-center gap-2 pl-16`}
>
<div className="py-4 border-l border-neutral-500">&nbsp;</div>

View File

@@ -28,26 +28,28 @@ export default function RaidGroupRequestList({
const headElements: React.ReactNode[] = [
<div>
<div key="username">
Username
</div>,
<div>
<div key="message">
Message
</div>,
<div>
<div key="actions">
Actions
</div>
];
const bodyElements: React.ReactNode[][] = raidGroupRequests.map((request) => [
<div
key="username"
className="text-nowrap"
>
{request.username}
</div>,
<div>
<div key="message">
{request.requestMessage || <>&nbsp;</>}
</div>,
<div
key="actions"
className="flex flex-row items-center justify-center gap-2"
>
<div

View File

@@ -78,7 +78,7 @@ export default function RaidInstanceHeader(){
});
}
else{
updateRaidInstanceMutate(raidInstance!);
updateRaidInstanceMutate(raidInstance);
updatePersonCharacterXrefsMutate(personCharacterXrefs);
}
}
@@ -99,7 +99,7 @@ export default function RaidInstanceHeader(){
updateRaidInstanceReset();
updatePersonCharacterXrefsReset();
if(updateRaidInstanceStatus !== "success"){
navigate(`/raidGroup/${raidGroup?.raidGroupId}/raidInstance/${raidInstance?.raidInstanceId}`)
void navigate(`/raidGroup/${raidGroup?.raidGroupId}/raidInstance/${raidInstance?.raidInstanceId}`)
}
}
else if(createRaidInstanceStatus === "error"){

View File

@@ -35,31 +35,37 @@ export default function RaidInstanceList({
const headElements: React.ReactNode[] = [
<div
key="name"
className="text-nowrap"
>
Raid Instance
</div>,
<div
key="startDate"
className="text-nowrap"
>
Start Date
</div>,
<div
key="endDate"
className="text-nowrap"
>
End Date
</div>,
<div
key="size"
className="text-nowrap"
>
Size
</div>,
<div
key="runs"
className="text-nowrap"
>
Runs
</div>,
<div
key="actions"
className="text-nowrap pl-16"
>
Actions
@@ -68,28 +74,32 @@ export default function RaidInstanceList({
const bodyElements: React.ReactNode[][] = raidInstances.map((raidInstance) => [
<Link
key="name"
to={`/raidGroup/${raidInstance.raidGroupId}/raidInstance/${raidInstance.raidInstanceId}`}
className="text-nowrap"
>
{raidInstance.raidInstanceName}
</Link>,
<div
key="startDate"
className="text-nowrap"
>
{moment(raidInstance.raidStartDate).format("MM-DD-YYYY hh:mm a")}
</div>,
<div
key="endDate"
className="text-nowrap"
>
{moment(raidInstance.raidEndDate).format("MM-DD-YYYY hh:mm a")}
</div>,
<div>
<div key="size">
{raidInstance.raidSize}
</div>,
<div>
<div key="runs">
{raidInstance.numberRuns}
</div>,
<div
key="actions"
className="flex flex-row items-center justify-center gap-2 pl-16"
>
<div

View File

@@ -7,27 +7,30 @@ import RaidInstanceAdminButtons from "./RaidInstanceAdminButtons";
export default function RaidInstanceListSkeleton(){
const headElements: React.ReactNode[] = [
<div
key="name"
className="text-nowrap"
>
Raid Instance
</div>,
<div
key="startDate"
className="text-nowrap"
>
Start Date
</div>,
<div
key="endDate"
className="text-nowrap"
>
End Date
</div>,
<div>
<div key="size">
Size
</div>,
<div>
<div key="runs">
Runs
</div>,
<div>
<div key="actions">
Actions
</div>
];
@@ -69,21 +72,27 @@ function RaidInstanceSkeleton(){
const elements: React.ReactNode[] = [
<div
key="name"
className={`h-6 w-32 mr-2 ${elementBg}`}
/>,
<div
key="startDate"
className={`h-6 w-[26rem] mr-2 ${elementBg}`}
/>,
<div
key="endDate"
className={`h-6 w-[26rem] mr-2 ${elementBg}`}
/>,
<div
key="size"
className={`h-6 w-32 mr-2 ${elementBg}`}
/>,
<div
key="runs"
className={`h-6 w-32 mr-2 ${elementBg}`}
/>,
<div
key="actions"
className="flex flex-row items-center justify-center gap-2 pl-16"
>
<div className="py-4 border-l border-neutral-500">&nbsp;</div>

View File

@@ -63,7 +63,7 @@ export default function RaidInstanceTab({
>
<PrimaryButton
className="text-nowrap"
onClick={() => navigate(`/raidGroup/${raidGroup.raidGroupId}/raidInstance`)}
onClick={() => void navigate(`/raidGroup/${raidGroup.raidGroupId}/raidInstance`)}
>
Create Adhoc Raid Instance
</PrimaryButton>

View File

@@ -63,7 +63,7 @@ export default function RaidInstanceCreatorTableBody({
discordString += "\n";
});
navigator.clipboard.writeText(discordString);
void navigator.clipboard.writeText(discordString);
}

View File

@@ -42,21 +42,25 @@ export default function RaidLayoutList({
const headElements: React.ReactNode[] = [
<div
key="name"
className="text-nowrap"
>
Raid Layout Name
</div>,
<div
key="size"
className="text-nowrap"
>
Raid Size
</div>,
<div
key="classGroups"
className="text-nowrap"
>
Class Groups
</div>,
<div
key="actions"
className="pl-16"
>
Actions
@@ -64,16 +68,17 @@ export default function RaidLayoutList({
];
const bodyElements: React.ReactNode[][] = raidLayouts.map((raidLayout) => [
<div>
<div key="name">
{raidLayout.raidLayoutName}
</div>,
<div>
<div key="size">
{raidLayout.raidSize}
</div>,
<div>
<div key="classGroups">
<ClassGroupsByRaidLayoutDisplay raidGroupId={raidGroup.raidGroupId ?? ""} raidLayoutId={raidLayout.raidLayoutId ?? ""}/>
</div>,
<div
key="actions"
className="flex flex-row items-center justify-center gap-2 pl-16"
>
<div

View File

@@ -8,21 +8,25 @@ import RaidLayoutAdminButtons from "./RaidLayoutAdminButtons";
export default function RaidLayoutListSkeleton(){
const headElements: React.ReactNode[] = [
<div
key="name"
className="text-nowrap"
>
Raid Layout Name
</div>,
<div
key="size"
className="text-nowrap"
>
Raid Size
</div>,
<div
key="classGroups"
className="text-nowrap"
>
Class Groups
</div>,
<div
key="actions"
className="text-nowrap"
>
Actions
@@ -67,15 +71,19 @@ function RaidLayoutSkeleton(){
const elements: React.ReactNode[] = [
<div
key="name"
className={`h-6 w-64 mr-1 ${elementBg}`}
/>,
<div
key="size"
className={`h-6 w-24 ml-2 ${elementBg}`}
/>,
<div
key="classGroups"
className={`h-6 w-[56rem] ml-2 ${elementBg}`}
/>,
<div
key="actions"
className="flex flex-row items-center justify-center gap-2 pl-16"
>
<div className="py-4 border-l border-neutral-500">&nbsp;</div>

View File

@@ -45,7 +45,7 @@ export default function RaidLayoutModal({
else if(newLayoutSize > classGroups.length){
setClassGroups([
...classGroups,
...Array(newLayoutSize - classGroups.length).fill(null)
...(Array(newLayoutSize - classGroups.length).fill(null) as null[])
]);
}
}

View File

@@ -1,8 +1,28 @@
import axios from "axios";
import { ResponseError } from "@/interface/Errors";
import axios, { AxiosError } from "axios";
export const api = axios.create({
const api = axios.create({
baseURL: `${import.meta.env.VITE_API_URL}`,
timeout: 10000,
withCredentials: true
});
api.interceptors.response.use(
(response) => {
if((response.data as ResponseError).errors){
throw new Error((response.data as ResponseError).errors.join(", "));
}
return response;
},
(error) => {
if(error instanceof AxiosError && (error.response?.data as ResponseError).errors){
throw new Error((error.response?.data as ResponseError).errors.join(", "));
}
else{
throw error;
}
}
);
export default api;

View File

@@ -1,7 +1,7 @@
import tailwindcss from "@tailwindcss/vite";
import react from '@vitejs/plugin-react';
import { resolve } from 'path';
import { defineConfig } from 'vite';
import react from "@vitejs/plugin-react";
import { resolve } from "path";
import { defineConfig } from "vite";
// https://vite.dev/config/
@@ -15,5 +15,8 @@ export default defineConfig({
"@": resolve(__dirname, "./src"),
"#root": resolve(__dirname)
}
},
build: {
chunkSizeWarningLimit: 1024
}
});