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 js from "@eslint/js";
import globals from 'globals' import react from "eslint-plugin-react";
import reactHooks from 'eslint-plugin-react-hooks' import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from 'eslint-plugin-react-refresh' import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from 'typescript-eslint' import globals from "globals";
import tseslint from "typescript-eslint";
export default tseslint.config( export default tseslint.config(
{ ignores: ['dist'] }, { ignores: ["dist"] },
{ {
extends: [js.configs.recommended, ...tseslint.configs.recommended], extends: [js.configs.recommended, ...tseslint.configs.recommendedTypeChecked],
files: ['**/*.{ts,tsx}'], files: ["**/*.{ts,tsx}"],
languageOptions: { languageOptions: {
ecmaVersion: 2020, ecmaVersion: 2020,
globals: globals.browser, globals: globals.browser,
parserOptions: {
project: ["./tsconfig.node.json", "./tsconfig.app.json"],
tsconfigRootDir: import.meta.dirname
}
}, },
plugins: { plugins: {
'react-hooks': reactHooks, "react-hooks": reactHooks,
'react-refresh': reactRefresh, "react-refresh": reactRefresh,
react: react
}, },
rules: { rules: {
...react.configs.recommended.rules,
...react.configs["jsx-runtime"].rules,
...reactHooks.configs.recommended.rules, ...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [ "react-refresh/only-export-components": [
'warn', "warn",
{ allowConstantExport: true }, { 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", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "tsc -b && vite build", "build": "tsc -b && eslint && vite build",
"lint": "eslint .", "lint": "eslint .",
"preview": "vite preview" "preview": "vite preview"
}, },
@@ -19,12 +19,13 @@
"@types/node": "^22.15.21", "@types/node": "^22.15.21",
"axios": "^1.9.0", "axios": "^1.9.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"eslint-plugin-react": "^7.37.5",
"moment": "^2.30.1", "moment": "^2.30.1",
"react": "^19.1.0", "react": "^19.1.0",
"react-dom": "^19.1.0", "react-dom": "^19.1.0",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",
"react-joyride": "^3.0.0-7", "react-joyride": "^3.0.0-7",
"react-router": "^7.6.0", "react-router": "^7.6.1",
"react-tooltip": "^5.28.1", "react-tooltip": "^5.28.1",
"tailwindcss": "^4.1.7", "tailwindcss": "^4.1.7",
"use-debounce": "^10.0.4", "use-debounce": "^10.0.4",
@@ -38,7 +39,7 @@
"eslint": "^9.27.0", "eslint": "^9.27.0",
"eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20", "eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.1.0", "globals": "^16.2.0",
"typescript": "^5.8.3", "typescript": "^5.8.3",
"typescript-eslint": "^8.32.1", "typescript-eslint": "^8.32.1",
"vite": "^6.3.5" "vite": "^6.3.5"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,28 +1,13 @@
import { Account } from "@/interface/Account"; import { Account } from "@/interface/Account";
import { api } from "@/util/AxiosUtil"; import api from "@/util/AxiosUtil";
import { useMutation } from "@tanstack/react-query"; import { useMutation } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useSignup(){ export function useSignup(){
return useMutation({ return useMutation({
mutationKey: ["signup"], mutationKey: ["signup"],
mutationFn: async (account: Account) => { mutationFn: async (account: Account) => {
try{ await api.post("/auth/signup", account);
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;
}
}
} }
}); });
} }
@@ -32,21 +17,7 @@ export function useConfirm(){
return useMutation({ return useMutation({
mutationKey: ["confirm"], mutationKey: ["confirm"],
mutationFn: async (confirmToken: string) => { mutationFn: async (confirmToken: string) => {
try{ await api.post(`/auth/confirm/${confirmToken}`);
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;
}
}
} }
}); });
} }
@@ -59,21 +30,7 @@ export function useForgotPassword(){
params.append("username", username); params.append("username", username);
try{ await api.post(`/auth/forgot?${params}`);
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;
}
}
} }
}); });
} }
@@ -82,21 +39,7 @@ export function useForgotResetPassword(forgotToken: string){
return useMutation({ return useMutation({
mutationKey: ["forgotResetPassword"], mutationKey: ["forgotResetPassword"],
mutationFn: async (password: string) => { mutationFn: async (password: string) => {
try{ await api.post(`/auth/forgot/${forgotToken}`, {password});
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;
}
}
} }
}); });
} }

View File

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

View File

@@ -1,7 +1,7 @@
import { ClassGroup } from "@/interface/ClassGroup"; 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 { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetClassGroups(raidGroupId: string, page: number, pageSize: number, searchTerm?: string){ 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); 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){ return response.data as ClassGroup[];
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;
}
}
}, },
enabled: !!raidGroupId enabled: !!raidGroupId
}); });
@@ -47,23 +33,9 @@ export function useGetClassGroupsCount(raidGroupId: string, searchTerm?: string)
return useQuery({ return useQuery({
queryKey: ["classGroups", "count", searchTerm], queryKey: ["classGroups", "count", searchTerm],
queryFn: async () => { 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){ return (response.data as Counter).count;
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;
}
}
} }
}); });
} }
@@ -72,23 +44,9 @@ export function useGetClassGroupsByRaidLayout(raidGroupId: string, raidLayoutId:
return useQuery({ return useQuery({
queryKey: ["classGroups", "raidLayout", raidLayoutId], queryKey: ["classGroups", "raidLayout", raidLayoutId],
queryFn: async () => { 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){ return response.data as (ClassGroup | null)[];
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;
}
}
}, },
enabled: !!raidGroupId && !!raidLayoutId enabled: !!raidGroupId && !!raidLayoutId
}) })
@@ -102,31 +60,17 @@ export function useCreateClassGroup(raidGroupId: string){
return useMutation({ return useMutation({
mutationKey: ["createClassGroup"], mutationKey: ["createClassGroup"],
mutationFn: async ({classGroupName, gameClassIds}:{classGroupName: string; gameClassIds: string[];}) => { mutationFn: async ({classGroupName, gameClassIds}:{classGroupName: string; gameClassIds: string[];}) => {
try{ await api.post(`/raidGroup/${raidGroupId}/classGroup`,
const response = await api.post(`/raidGroup/${raidGroupId}/classGroup`, {
{ classGroup: {
classGroup: { classGroupName: classGroupName,
classGroupName: classGroupName, raidGroupId: raidGroupId
raidGroupId: raidGroupId },
}, gameClassIds
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({queryKey: ["classGroups"]}); void queryClient.invalidateQueries({queryKey: ["classGroups"]});
} }
}); });
} }
@@ -138,30 +82,16 @@ export function useUpdateClassGroup(raidGroupId: string){
return useMutation({ return useMutation({
mutationKey: ["updateClassGroup"], mutationKey: ["updateClassGroup"],
mutationFn: async ({classGroup, gameClassIds}:{classGroup: ClassGroup; gameClassIds: string[];}) => { mutationFn: async ({classGroup, gameClassIds}:{classGroup: ClassGroup; gameClassIds: string[];}) => {
try{ await api.put(`/raidGroup/${raidGroupId}/classGroup/${classGroup.classGroupId}`,
const response = await api.put(`/raidGroup/${raidGroupId}/classGroup/${classGroup.classGroupId}`, {
{ classGroup,
classGroup, gameClassIds
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({queryKey: ["gameClasses", "classGroups"]}); void queryClient.invalidateQueries({queryKey: ["gameClasses", "classGroups"]});
queryClient.invalidateQueries({queryKey: ["classGroups"]}); void queryClient.invalidateQueries({queryKey: ["classGroups"]});
} }
}); });
} }
@@ -173,24 +103,10 @@ export function useDeleteClassGroup(raidGroupId: string, classGroupId: string){
return useMutation({ return useMutation({
mutationKey: ["deleteClassGroup", classGroupId, raidGroupId], mutationKey: ["deleteClassGroup", classGroupId, raidGroupId],
mutationFn: async () => { mutationFn: async () => {
try{ await api.delete(`/raidGroup/${raidGroupId}/classGroup/${classGroupId}`);
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;
}
}
}, },
onSuccess: () => { 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 { GameClass } from "@/interface/GameClass";
import { api } from "@/util/AxiosUtil"; import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetGameClass(gameClassId: string){ export function useGetGameClass(gameClassId: string){
return useQuery({ return useQuery({
queryKey: ["gameClasses", gameClassId], queryKey: ["gameClasses", gameClassId],
queryFn: async () => { queryFn: async () => {
try{ const response = await api.get(`/gameClass/${gameClassId}`);
const response = await api.get(`/gameClass/${gameClassId}`);
if(response.data.errors){ return response.data as GameClass;
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;
}
}
}, },
enabled: !!gameClassId enabled: !!gameClassId
}) })
@@ -41,23 +27,9 @@ export function useGetGameClasses(gameId: string, page: number, pageSize: number
params.append("searchTerm", searchTerm); 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){ return response.data as GameClass[];
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;
}
}
} }
}); });
} }
@@ -66,23 +38,9 @@ export function useGetGameClassesByClassGroup(classGroupId?: string){
return useQuery({ return useQuery({
queryKey: ["gameClasses", "classGroups", classGroupId], queryKey: ["gameClasses", "classGroups", classGroupId],
queryFn: async () => { queryFn: async () => {
try{ const response = await api.get(`/gameClass/classGroup/${classGroupId}`);
const response = await api.get(`/gameClass/classGroup/${classGroupId}`);
if(response.data.errors){ return response.data as GameClass[];
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;
}
}
}, },
enabled: !!classGroupId enabled: !!classGroupId
}); });
@@ -99,23 +57,9 @@ export function useGetGameClassesCount(gameId: string, searchTerm?: string){
return useQuery({ return useQuery({
queryKey: ["gameClasses", gameId, "count", searchTerm], queryKey: ["gameClasses", gameId, "count", searchTerm],
queryFn: async () => { 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){ return (response.data as Counter).count;
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;
}
}
} }
}); });
} }
@@ -135,27 +79,13 @@ export function useCreateGameClass(){
formData.append("gameClassName", gameClassName); formData.append("gameClassName", gameClassName);
formData.append("gameId", gameId); formData.append("gameId", gameId);
try{ await api.post(
const response = await api.post( `/gameClass/game/${gameId}`,
`/gameClass/game/${gameId}`, formData
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["gameClasses"] }); void queryClient.invalidateQueries({ queryKey: ["gameClasses"] });
} }
}); });
} }
@@ -177,24 +107,10 @@ export function useUpdateGameClass(){
formData.append("gameClassIcon", gameClass.gameClassIcon); formData.append("gameClassIcon", gameClass.gameClassIcon);
} }
try{ await api.put(`/gameClass/${gameClass.gameClassId}/game/${gameClass.gameId}`, formData);
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["gameClasses"] }); void queryClient.invalidateQueries({ queryKey: ["gameClasses"] });
} }
}); });
} }
@@ -206,24 +122,10 @@ export function useDeleteGameClass(){
return useMutation({ return useMutation({
mutationKey: ["deleteGameClass"], mutationKey: ["deleteGameClass"],
mutationFn: async (gameClass: GameClass) => { mutationFn: async (gameClass: GameClass) => {
try{ await api.delete(`/gameClass/${gameClass.gameClassId}/game/${gameClass.gameId}`);
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;
}
}
}, },
onSuccess: () => { 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 { Game } from "@/interface/Game";
import { api } from "@/util/AxiosUtil"; import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetGame(gameId: string, disabled: boolean){ export function useGetGame(gameId: string, disabled: boolean){
return useQuery({ return useQuery({
queryKey: ["games", gameId], queryKey: ["games", gameId],
queryFn: async () => { queryFn: async () => {
try{ const response = await api.get(`/game/${gameId}`);
const response = await api.get(`/game/${gameId}`);
if(response.data.errors){ return (response.data as Game)?.gameId ? response.data as Game : undefined;
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;
}
}
}, },
enabled: !disabled enabled: !disabled
}); });
@@ -41,19 +27,9 @@ export function useGetGames(page: number, pageSize: number, searchTerm?: string)
params.append("searchTerm", searchTerm); params.append("searchTerm", searchTerm);
} }
try{ const response = await api.get(`/game?${params}`);
const response = await api.get(`/game?${params}`);
return response.data as Game[]; 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;
}
}
} }
}); });
} }
@@ -68,23 +44,9 @@ export function useGetGamesCount(searchTerm?: string){
return useQuery({ return useQuery({
queryKey: ["games", "count", searchTerm], queryKey: ["games", "count", searchTerm],
queryFn: async () => { queryFn: async () => {
try{ const response = await api.get(`/game/count?${searchParams}`);
const response = await api.get(`/game/count?${searchParams}`);
if(response.data.errors){ return (response.data as Counter).count;
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;
}
}
} }
}); });
} }
@@ -102,27 +64,13 @@ export function useCreateGame(){
} }
formData.append("gameName", gameName); formData.append("gameName", gameName);
try{ await api.post(
const response = await api.post( "/game",
"/game", formData
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["games"] }); void queryClient.invalidateQueries({ queryKey: ["games"] });
} }
}); });
} }
@@ -143,24 +91,10 @@ export function useUpdateGame(){
formData.append("gameIcon", game.gameIcon); formData.append("gameIcon", game.gameIcon);
} }
try{ await api.put(`/game/${game.gameId}`, formData);
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["games"] }); void queryClient.invalidateQueries({ queryKey: ["games"] });
} }
}); });
} }
@@ -172,24 +106,10 @@ export function useDeleteGame(){
return useMutation({ return useMutation({
mutationKey: ["deleteGame"], mutationKey: ["deleteGame"],
mutationFn: async (gameId: string) => { mutationFn: async (gameId: string) => {
try{ await api.delete(`/game/${gameId}`);
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;
}
}
}, },
onSuccess: () => { 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 { PersonCharacter } from "@/interface/PersonCharacter";
import { api } from "@/util/AxiosUtil"; import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetPersonCharactersByPersonId(personId: string, raidGroupId: string){ export function useGetPersonCharactersByPersonId(personId: string, raidGroupId: string){
return useQuery({ return useQuery({
queryKey: ["personCharacters", personId], queryKey: ["personCharacters", personId],
queryFn: async () => { 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){ return response.data as PersonCharacter[];
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;
}
}
} }
}); });
} }
@@ -41,23 +27,9 @@ export function useGetPersonCharactersByPersonIdSearch(personId: string, raidGro
return useQuery({ return useQuery({
queryKey: ["personCharacters", personId, { page, pageSize, searchTerm }], queryKey: ["personCharacters", personId, { page, pageSize, searchTerm }],
queryFn: async () => { 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){ return response.data as PersonCharacter[];
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;
}
}
} }
}); });
} }
@@ -71,23 +43,9 @@ export function useGetPersonCharactersCountByPersonIdSearch(personId: string, ra
return useQuery({ return useQuery({
queryKey: ["personCharactersCount", personId, { searchTerm }], queryKey: ["personCharactersCount", personId, { searchTerm }],
queryFn: async () => { 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){ return (response.data as Counter).count;
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;
}
}
} }
}); });
} }
@@ -96,23 +54,9 @@ export function useGetPersonCharactersByRaidGroup(raidGroupId: string){
return useQuery({ return useQuery({
queryKey: ["personCharacters", raidGroupId], queryKey: ["personCharacters", raidGroupId],
queryFn: async () => { 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){ return response.data as PersonCharacter[];
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;
}
}
}, },
enabled: !!raidGroupId enabled: !!raidGroupId
}); });
@@ -125,24 +69,10 @@ export function useCreatePersonCharacter(raidGroupId: string, personId: string){
return useMutation({ return useMutation({
mutationKey: ["createPersonCharacter"], mutationKey: ["createPersonCharacter"],
mutationFn: async (personCharacter: PersonCharacter) => { mutationFn: async (personCharacter: PersonCharacter) => {
try{ await api.post(`/raidGroup/${raidGroupId}/person/${personId}/character`, personCharacter);
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["personCharacters"] }); void queryClient.invalidateQueries({ queryKey: ["personCharacters"] });
} }
}); });
} }
@@ -154,24 +84,10 @@ export function useUpdatePersonCharacter(raidGroupId: string, personId: string){
return useMutation({ return useMutation({
mutationKey: ["updatePersonCharacter"], mutationKey: ["updatePersonCharacter"],
mutationFn: async (personCharacter: PersonCharacter) => { mutationFn: async (personCharacter: PersonCharacter) => {
try{ await api.put(`/raidGroup/${raidGroupId}/person/${personId}/character/${personCharacter.personCharacterId}`, personCharacter);
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["personCharacters"] }); void queryClient.invalidateQueries({ queryKey: ["personCharacters"] });
} }
}); });
} }
@@ -183,24 +99,10 @@ export function useDeletePersonCharacter(raidGroupId: string, personId: string){
return useMutation({ return useMutation({
mutationKey: ["deletePersonCharacter"], mutationKey: ["deletePersonCharacter"],
mutationFn: async (personCharacterId: string) => { mutationFn: async (personCharacterId: string) => {
try{ await api.delete(`/raidGroup/${raidGroupId}/person/${personId}/character/${personCharacterId}`);
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;
}
}
}, },
onSuccess: () => { 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 { Person } from "@/interface/Person";
import { api } from "@/util/AxiosUtil"; import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetPerson(raidGroupId: string, personId: string, disabled: boolean){ export function useGetPerson(raidGroupId: string, personId: string, disabled: boolean){
return useQuery({ return useQuery({
queryKey: ["people", raidGroupId, personId], queryKey: ["people", raidGroupId, personId],
queryFn: async () => { 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){ return response.data as Person;
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;
}
}
}, },
enabled: !disabled enabled: !disabled
}); });
@@ -41,23 +27,9 @@ export function useGetPeopleByRaidGroup(raidGroupId: string, page: number, pageS
searchParams.append("searchTerm", searchTerm); 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){ return response.data as Person[];
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;
}
}
} }
}); });
} }
@@ -72,23 +44,9 @@ export function useGetPeopleByRaidGroupCount(raidGroupId: string, searchTerm?: s
return useQuery({ return useQuery({
queryKey: ["people", raidGroupId, "count", searchTerm], queryKey: ["people", raidGroupId, "count", searchTerm],
queryFn: async () => { 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){ return (response.data as Counter).count;
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;
}
}
} }
}); });
} }
@@ -100,24 +58,10 @@ export function useCreatePerson(){
return useMutation({ return useMutation({
mutationKey: ["createPerson"], mutationKey: ["createPerson"],
mutationFn: async ({raidGroupId, personName, discordId}:{raidGroupId: string; personName: string; discordId?: string;}) => { mutationFn: async ({raidGroupId, personName, discordId}:{raidGroupId: string; personName: string; discordId?: string;}) => {
try{ await api.post(`/raidGroup/${raidGroupId}/person`, {raidGroupId, personName, discordId});
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["people"] }); void queryClient.invalidateQueries({ queryKey: ["people"] });
} }
}); });
} }
@@ -129,24 +73,10 @@ export function useUpdatePerson(){
return useMutation({ return useMutation({
mutationKey: ["updatePerson"], mutationKey: ["updatePerson"],
mutationFn: async (person: Person) => { mutationFn: async (person: Person) => {
try{ await api.put(`/raidGroup/${person.raidGroupId}/person/${person.personId}`, person);
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["people"] }); void queryClient.invalidateQueries({ queryKey: ["people"] });
} }
}); });
} }
@@ -158,24 +88,10 @@ export function useDeletePerson(){
return useMutation({ return useMutation({
mutationKey: ["deletePerson"], mutationKey: ["deletePerson"],
mutationFn: async ({raidGroupId, personId}:{raidGroupId: string; personId: string;}) => { mutationFn: async ({raidGroupId, personId}:{raidGroupId: string; personId: string;}) => {
try{ await api.delete(`/raidGroup/${raidGroupId}/person/${personId}`);
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;
}
}
}, },
onSuccess: () => { 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 { RaidGroup } from "@/interface/RaidGroup";
import { api } from "@/util/AxiosUtil"; import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetRaidGroup(raidGroupId: string, disabled: boolean){ export function useGetRaidGroup(raidGroupId: string, disabled: boolean){
return useQuery({ return useQuery({
queryKey: ["raidGroups", raidGroupId], queryKey: ["raidGroups", raidGroupId],
queryFn: async () => { queryFn: async () => {
try{ const response = await api.get(`/raidGroup/${raidGroupId}`);
const response = await api.get(`/raidGroup/${raidGroupId}`);
if(response.data.errors){ return (response.data as RaidGroup)?.raidGroupId ? response.data as RaidGroup : undefined;
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;
}
}
}, },
enabled: !disabled enabled: !disabled
}); });
@@ -41,23 +27,9 @@ export function useGetRaidGroups(page: number, pageSize: number, searchTerm?: st
params.append("searchTerm", searchTerm); params.append("searchTerm", searchTerm);
} }
try{ const response = await api.get(`/raidGroup?${params}`);
const response = await api.get(`/raidGroup?${params}`);
if(response.data.errors){ return response.data as RaidGroup[];
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;
}
}
} }
}); });
} }
@@ -72,23 +44,9 @@ export function useGetRaidGroupsCount(searchTerm?: string){
return useQuery({ return useQuery({
queryKey: ["raidGroups", "count", searchTerm], queryKey: ["raidGroups", "count", searchTerm],
queryFn: async () => { queryFn: async () => {
try{ const response = await api.get(`/raidGroup/count?${searchParams}`);
const response = await api.get(`/raidGroup/count?${searchParams}`);
if(response.data.errors){ return (response.data as Counter).count;
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;
}
}
} }
}); });
} }
@@ -104,23 +62,9 @@ export function useGetRaidGroupsByGame(gameId: string, page: number, pageSize: n
params.append("searchTerm", searchTerm); 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){ return response.data as RaidGroup[];
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;
}
}
} }
}); });
} }
@@ -135,23 +79,9 @@ export function useGetRaidGroupsByGameCount(gameId: string, searchTerm?: string)
return useQuery({ return useQuery({
queryKey: ["raidGroups", gameId, "count", searchTerm], queryKey: ["raidGroups", gameId, "count", searchTerm],
queryFn: async () => { 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){ return (response.data as Counter).count;
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;
}
}
} }
}); });
} }
@@ -167,23 +97,9 @@ export function useGetRaidGroupsByAccount(accountId: string, page: number, pageS
params.append("searchTerm", searchTerm); 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){ return response.data as RaidGroup[];
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;
}
}
} }
}); });
} }
@@ -198,23 +114,9 @@ export function useGetRaidGroupsCountByAccount(accountId: string, searchTerm?: s
return useQuery({ return useQuery({
queryKey: ["raidGroups", accountId, "count", searchTerm], queryKey: ["raidGroups", accountId, "count", searchTerm],
queryFn: async () => { 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){ return (response.data as Counter).count;
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;
}
}
} }
}); });
@@ -235,27 +137,13 @@ export function useCreateRaidGroup(){
formData.append("raidGroupName", raidGroupName); formData.append("raidGroupName", raidGroupName);
formData.append("gameId", gameId); formData.append("gameId", gameId);
try{ await api.post(
const response = await api.post( "/raidGroup",
"/raidGroup", formData
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidGroups"] }); void queryClient.invalidateQueries({ queryKey: ["raidGroups"] });
} }
}); });
} }
@@ -277,24 +165,10 @@ export function useUpdateRaidGroup(){
formData.append("raidGroupIcon", raidGroup.raidGroupIcon); formData.append("raidGroupIcon", raidGroup.raidGroupIcon);
} }
try{ await api.put(`/raidGroup/${raidGroup.raidGroupId}`, formData);
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidGroups"] }); void queryClient.invalidateQueries({ queryKey: ["raidGroups"] });
} }
}); });
} }
@@ -306,24 +180,10 @@ export function useDeleteRaidGroup(){
return useMutation({ return useMutation({
mutationKey: ["deleteRaidGroup"], mutationKey: ["deleteRaidGroup"],
mutationFn: async (raidGroupId: string) => { mutationFn: async (raidGroupId: string) => {
try{ await api.delete(`/raidGroup/${raidGroupId}`);
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;
}
}
}, },
onSuccess: () => { 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 { RaidGroupPermissionType } from "@/interface/RaidGroup";
import { RaidGroupRequest } from "@/interface/RaidGroupRequest"; import { RaidGroupRequest } from "@/interface/RaidGroupRequest";
import { api } from "@/util/AxiosUtil"; import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetRaidGroupRequests(raidGroupId: string, page: number, pageSize: number, searchTerm?: string){ 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({ return useQuery({
queryKey: ["raidGroupRequest", raidGroupId, {page, pageSize, searchTerm}], queryKey: ["raidGroupRequest", raidGroupId, {page, pageSize, searchTerm}],
queryFn: async () => { 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){ return response.data as RaidGroupRequest[];
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;
}
}
}, },
enabled: !!raidGroupId && raidGroupId !== "" enabled: !!raidGroupId && raidGroupId !== ""
}); });
@@ -47,23 +33,9 @@ export function useGetRaidGroupRequestCount(raidGroupId?: string, searchTerm?: s
return useQuery({ return useQuery({
queryKey: ["raidGroupRequest", raidGroupId, "count", searchTerm], queryKey: ["raidGroupRequest", raidGroupId, "count", searchTerm],
queryFn: async () => { 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){ return (response.data as Counter).count;
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;
}
}
}, },
enabled: !!raidGroupId && raidGroupId !== "" enabled: !!raidGroupId && raidGroupId !== ""
}); });
@@ -76,24 +48,10 @@ export function useCreateRaidGroupRequest(raidGroupId: string){
return useMutation({ return useMutation({
mutationKey: ["raidGroupRequest", raidGroupId], mutationKey: ["raidGroupRequest", raidGroupId],
mutationFn: async (requestMessage: string) => { mutationFn: async (requestMessage: string) => {
try{ await api.post(`/raidGroup/${raidGroupId}/raidGroupRequest`, {requestMessage});
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] }); void queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] });
} }
}); });
} }
@@ -104,24 +62,10 @@ export function useResolveRaidGroupRequest(raidGroupId: string, raidGroupRequest
return useMutation({ return useMutation({
mutationKey: ["raidGroupRequest", raidGroupId, raidGroupRequestId], mutationKey: ["raidGroupRequest", raidGroupId, raidGroupRequestId],
mutationFn: async (permission: RaidGroupPermissionType) => { mutationFn: async (permission: RaidGroupPermissionType) => {
try{ await api.put(`/raidGroup/${raidGroupId}/raidGroupRequest/${raidGroupRequestId}/resolve`, {resolution: permission});
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] }); void queryClient.invalidateQueries({ queryKey: ["raidGroupRequest", raidGroupId] });
} }
}); });
@@ -133,24 +77,10 @@ export function useDeleteRaidGroupRequest(raidGroupId: string, raidGroupRequestI
return useMutation({ return useMutation({
mutationKey: ["raidGroupRequest", raidGroupId, raidGroupRequestId], mutationKey: ["raidGroupRequest", raidGroupId, raidGroupRequestId],
mutationFn: async () => { mutationFn: async () => {
try{ await api.delete(`/raidGroup/${raidGroupId}/raidGroupRequest/${raidGroupRequestId}`);
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;
}
}
}, },
onSuccess: () => { 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 { RaidInstance } from "@/interface/RaidInstance";
import { RaidInstancePersonCharacterXref } from "@/interface/RaidInstancePersonCharacterXref"; import { RaidInstancePersonCharacterXref } from "@/interface/RaidInstancePersonCharacterXref";
import { api } from "@/util/AxiosUtil"; import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetRaidInstance(raidInstanceId: string, raidGroupId: string){ export function useGetRaidInstance(raidInstanceId: string, raidGroupId: string){
return useQuery({ return useQuery({
queryKey: ["raidInstances", raidInstanceId, raidGroupId], queryKey: ["raidInstances", raidInstanceId, raidGroupId],
queryFn: async () => { 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){ return response.data as RaidInstance;
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;
}
}
}, },
enabled: !!raidInstanceId && !!raidGroupId enabled: !!raidInstanceId && !!raidGroupId
}); });
@@ -42,23 +28,9 @@ export function useGetRaidInstancesByRaidGroup(raidGroupId: string, page: number
params.append("searchTerm", searchTerm); 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){ return response.data as RaidInstance[];
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;
}
}
} }
}); });
} }
@@ -73,23 +45,9 @@ export function useGetRaidInstancesByRaidGroupCount(raidGroupId: string, searchT
params.append("searchTerm", searchTerm); 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){ return (response.data as Counter).count;
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;
}
}
} }
}); });
} }
@@ -102,26 +60,12 @@ export function useCreateRaidInstance(raidGroupId: string){
return useMutation({ return useMutation({
mutationKey: ["createRaidInstance", raidGroupId], mutationKey: ["createRaidInstance", raidGroupId],
mutationFn: async (raidInstance: RaidInstance) => { mutationFn: async (raidInstance: RaidInstance) => {
try{
const response = await api.post(`/raidGroup/${raidGroupId}/raidInstance`, raidInstance); const response = await api.post(`/raidGroup/${raidGroupId}/raidInstance`, raidInstance);
if(response.data.errors){ return (response.data as RaidInstance).raidInstanceId;
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidInstances"] }); void queryClient.invalidateQueries({ queryKey: ["raidInstances"] });
} }
}); });
} }
@@ -133,24 +77,10 @@ export function useUpdateRaidInstance(raidGroupId: string){
return useMutation({ return useMutation({
mutationKey: ["updateRaidInstance", raidGroupId], mutationKey: ["updateRaidInstance", raidGroupId],
mutationFn: async (raidInstance: RaidInstance) => { mutationFn: async (raidInstance: RaidInstance) => {
try{ await api.put(`/raidGroup/${raidGroupId}/raidInstance/${raidInstance.raidInstanceId}`, raidInstance);
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidInstances"] }); void queryClient.invalidateQueries({ queryKey: ["raidInstances"] });
} }
}); });
} }
@@ -159,21 +89,7 @@ export function useUpdateRaidInstanceNoInvalidation(raidGroupId: string){
return useMutation({ return useMutation({
mutationKey: ["updateRaidInstance", raidGroupId], mutationKey: ["updateRaidInstance", raidGroupId],
mutationFn: async (raidInstance: RaidInstance) => { mutationFn: async (raidInstance: RaidInstance) => {
try{ await api.put(`/raidGroup/${raidGroupId}/raidInstance/${raidInstance.raidInstanceId}`, raidInstance);
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;
}
}
} }
}); });
} }
@@ -185,24 +101,10 @@ export function useDeleteRaidInstance(raidGroupId: string, raidInstanceId: strin
return useMutation({ return useMutation({
mutationKey: ["deleteRaidInstance", raidGroupId, raidInstanceId], mutationKey: ["deleteRaidInstance", raidGroupId, raidInstanceId],
mutationFn: async () => { mutationFn: async () => {
try{ await api.delete(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}`);
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidInstances"] }); void queryClient.invalidateQueries({ queryKey: ["raidInstances"] });
} }
}); });
} }
@@ -212,23 +114,9 @@ export function useGetRaidInstancePersonCharacterXrefs(raidGroupId?: string, rai
return useQuery({ return useQuery({
queryKey: ["raidInstancePersonCharacterXrefs", raidGroupId, raidInstanceId], queryKey: ["raidInstancePersonCharacterXrefs", raidGroupId, raidInstanceId],
queryFn: async () => { 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){ return response.data as RaidInstancePersonCharacterXref[];
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;
}
}
}, },
enabled: !!raidGroupId && !!raidInstanceId enabled: !!raidGroupId && !!raidInstanceId
}); });
@@ -241,24 +129,10 @@ export function useUpdateRaidInstancePersonCharacterXrefs(raidGroupId?: string,
return useMutation({ return useMutation({
mutationKey: ["updateRaidInstancePersonCharacterXrefs", raidGroupId, raidInstanceId], mutationKey: ["updateRaidInstancePersonCharacterXrefs", raidGroupId, raidInstanceId],
mutationFn: async (raidInstancePersonCharacterXrefs: RaidInstancePersonCharacterXref[]) => { mutationFn: async (raidInstancePersonCharacterXrefs: RaidInstancePersonCharacterXref[]) => {
try{ await api.post(`/raidGroup/${raidGroupId}/raidInstance/${raidInstanceId}/personCharacterXref`, raidInstancePersonCharacterXrefs);
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;
}
}
}, },
onSuccess: () => { 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 { RaidLayout, RaidLayoutClassGroupXref } from "@/interface/RaidLayout";
import { api } from "@/util/AxiosUtil"; import api from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetRaidLayout(raidGroupId?: string, raidLayoutId?: string){ export function useGetRaidLayout(raidGroupId?: string, raidLayoutId?: string){
return useQuery({ return useQuery({
queryKey: ["raidLayout", raidGroupId, raidLayoutId], queryKey: ["raidLayout", raidGroupId, raidLayoutId],
queryFn: async () => { 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){ return response.data as RaidLayout;
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;
}
}
}, },
enabled: !!raidGroupId && !!raidLayoutId enabled: !!raidGroupId && !!raidLayoutId
}); });
@@ -41,23 +27,9 @@ export function useGetRaidLayoutsByRaidGroup(raidGroupId: string, page: number,
params.append("searchTerm", searchTerm); 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){ return response.data as RaidLayout[];
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;
}
}
} }
}); });
} }
@@ -71,23 +43,9 @@ export function useGetRaidLayoutsByRaidGroupCount(raidGroupId: string, searchTer
params.append("searchTerm", searchTerm); 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){ return (response.data as Counter).count;
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;
}
}
} }
}); });
} }
@@ -99,29 +57,15 @@ export function useCreateRaidLayout(raidGroupId: string){
return useMutation({ return useMutation({
mutationKey: ["createRaidLayout", raidGroupId], mutationKey: ["createRaidLayout", raidGroupId],
mutationFn: async ({raidLayout, raidLayoutClassGroupXrefs}:{raidLayout: RaidLayout; raidLayoutClassGroupXrefs: RaidLayoutClassGroupXref[];}) => { mutationFn: async ({raidLayout, raidLayoutClassGroupXrefs}:{raidLayout: RaidLayout; raidLayoutClassGroupXrefs: RaidLayoutClassGroupXref[];}) => {
try{ await api.post(`/raidGroup/${raidGroupId}/raidLayout`,
const response = await api.post(`/raidGroup/${raidGroupId}/raidLayout`, {
{ raidLayout,
raidLayout, raidLayoutClassGroupXrefs
raidLayoutClassGroupXrefs
}
);
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] }); void queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] });
} }
}); });
} }
@@ -133,30 +77,16 @@ export function useUpdateRaidLayout(raidGroupId: string){
return useMutation({ return useMutation({
mutationKey: ["updateRaidLayout", raidGroupId], mutationKey: ["updateRaidLayout", raidGroupId],
mutationFn: async ({raidLayout, raidLayoutClassGroupXrefs}:{raidLayout: RaidLayout; raidLayoutClassGroupXrefs: RaidLayoutClassGroupXref[];}) => { mutationFn: async ({raidLayout, raidLayoutClassGroupXrefs}:{raidLayout: RaidLayout; raidLayoutClassGroupXrefs: RaidLayoutClassGroupXref[];}) => {
try{ await api.put(`/raidGroup/${raidGroupId}/raidLayout/${raidLayout.raidLayoutId}`,
const response = await api.put(`/raidGroup/${raidGroupId}/raidLayout/${raidLayout.raidLayoutId}`, {
{ raidLayout,
raidLayout, raidLayoutClassGroupXrefs
raidLayoutClassGroupXrefs
}
);
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] }); void queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] });
queryClient.invalidateQueries({ queryKey: ["classGroups", "raidLayout"] }); void queryClient.invalidateQueries({ queryKey: ["classGroups", "raidLayout"] });
} }
}); });
} }
@@ -168,24 +98,10 @@ export function useDeleteRaidLayout(raidGroupId: string, raidLayoutId: string){
return useMutation({ return useMutation({
mutationKey: ["deleteRaidLayout", raidGroupId, raidLayoutId], mutationKey: ["deleteRaidLayout", raidGroupId, raidLayoutId],
mutationFn: async () => { mutationFn: async () => {
try{ await api.delete(`/raidGroup/${raidGroupId}/raidLayout/${raidLayoutId}`)
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;
}
}
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] }); void queryClient.invalidateQueries({ queryKey: ["raidLayouts", raidGroupId] });
} }
}); });
} }

View File

@@ -22,4 +22,5 @@ export interface Account {
refreshToken?: string; refreshToken?: string;
refreshTokenExpiration?: Date; refreshTokenExpiration?: Date;
accountStatus: AccountStatus; 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 { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { StrictMode } from 'react' import { StrictMode } from "react";
import { createRoot } from 'react-dom/client' import { createRoot } from "react-dom/client";
import App from './App.tsx' import App from "./App.tsx";
import './index.css' import "./index.css";
import { AuthProvider } from './providers/AuthProvider.tsx' import { AuthProvider } from "./providers/components/AuthProviderComponent.tsx";
import { ThemeProvider } from './providers/ThemeProvider.tsx' import { ThemeProvider } from "./providers/components/ThemeProviderComponent.tsx";
import { TimedModalProvider } from "./providers/TimedModalProvider.tsx" import { TimedModalProvider } from "./providers/components/TimedModalProviderComponent.tsx";
const queryClient = new QueryClient(); const queryClient = new QueryClient();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,8 @@
import PrimaryButton from "@/components/button/PrimaryButton"; import PrimaryButton from "@/components/button/PrimaryButton";
import PasswordInput from "@/components/input/PasswordInput"; import PasswordInput from "@/components/input/PasswordInput";
import TextInput from "@/components/input/TextInput"; import TextInput from "@/components/input/TextInput";
import { Account } from "@/interface/Account";
import { ResponseError } from "@/interface/Errors";
import { useAuth } from "@/providers/AuthProvider"; import { useAuth } from "@/providers/AuthProvider";
import { useTimedModal } from "@/providers/TimedModalProvider"; import { useTimedModal } from "@/providers/TimedModalProvider";
import { Link, Navigate, useNavigate } from "react-router"; import { Link, Navigate, useNavigate } from "react-router";
@@ -27,12 +29,12 @@ export default function LoginPage(){
.then(async (response) => { .then(async (response) => {
if(response.status === 200){ if(response.status === 200){
addSuccessMessage("Logged in successfully"); addSuccessMessage("Logged in successfully");
const json = await response.json(); const json = await response.json() as Account;
setTokenData(json); setTokenData(json);
navigate("/raidGroup"); void navigate("/raidGroup");
} }
else{ 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 => { .catch(error => {

View File

@@ -48,7 +48,7 @@ export default function SignupPage(){
if(signupQuery.status === "success"){ if(signupQuery.status === "success"){
addSuccessMessage("Signed up successfully"); addSuccessMessage("Signed up successfully");
navigate("/login"); void navigate("/login");
} }
else if(signupQuery.status === "error"){ else if(signupQuery.status === "error"){
addErrorMessage("Failed to signup: " + signupQuery.error.message); 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 { AccountPermission } from "@/interface/AccountPermission";
import { AccountTutorialStatus } from "@/interface/AccountTutorialStatus"; import { AccountTutorialStatus } from "@/interface/AccountTutorialStatus";
import { GamePermission } from "@/interface/GamePermission"; import { GamePermission } from "@/interface/GamePermission";
import { RaidGroupPermission } from "@/interface/RaidGroupPermission"; import { RaidGroupPermission } from "@/interface/RaidGroupPermission";
import { RaidGroupRequest } from "@/interface/RaidGroupRequest"; import { RaidGroupRequest } from "@/interface/RaidGroupRequest";
import { api } from "@/util/AxiosUtil"; import { createContext, useContext } from "react";
import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useState } from "react";
import { Navigate, Outlet } from "react-router";
type AuthProviderProps = { export type AuthProviderProps = {
children: React.ReactNode; children: React.ReactNode;
jwtStorageKey?: string; jwtStorageKey?: string;
refreshTokenStorageKey?: string; refreshTokenStorageKey?: string;
} }
type AuthProviderState = { export type AuthProviderState = {
jwt: string | null; jwt: string | null | undefined;
setJwt: (token: string | null) => void; setJwt: (token: string | null | undefined) => void;
expiration: Date | null; expiration: Date | null;
setExpiration: (expiration: Date | null) => void; setExpiration: (expiration: Date | null) => void;
accountId: string | null; accountId: string | null;
@@ -28,9 +26,7 @@ type AuthProviderState = {
tutorialsStatus: AccountTutorialStatus; tutorialsStatus: AccountTutorialStatus;
setTutorialsStatus: (tutorialsStatus: AccountTutorialStatus) => void; setTutorialsStatus: (tutorialsStatus: AccountTutorialStatus) => void;
reset: () => void; reset: () => void;
/* eslint-disable @typescript-eslint/no-explicit-any */ setTokenData: (data: Account) => void;
setTokenData: (data: any) => void;
/* eslint-enable @typescript-eslint/no-explicit-any */
} }
const initialState: AuthProviderState = { const initialState: AuthProviderState = {
@@ -49,159 +45,7 @@ const initialState: AuthProviderState = {
setTokenData: () => null setTokenData: () => null
} }
const AuthContext = createContext<AuthProviderState>(initialState); export 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 useAuth = () => { 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 { RaidInstance } from "@/interface/RaidInstance";
import { RaidInstancePersonCharacterXref } from "@/interface/RaidInstancePersonCharacterXref"; import { RaidInstancePersonCharacterXref } from "@/interface/RaidInstancePersonCharacterXref";
import { RaidLayout } from "@/interface/RaidLayout"; import { RaidLayout } from "@/interface/RaidLayout";
import { createContext, useContext, useEffect, useMemo, useState } from "react"; import { useEffect, useMemo, useState } from "react";
import { RaidInstanceContext, RaidInstanceContextState } from "../RaidInstanceLayoutProvider";
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: () => {}
});
export default function RaidInstanceLayoutProvider({ export default function RaidInstanceLayoutProvider({
@@ -181,14 +143,3 @@ export default function RaidInstanceLayoutProvider({
</RaidInstanceContext.Provider> </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"; import { useEffect, useMemo, useState } from "react";
import { Theme, ThemeProviderContext, ThemeProviderProps } from "../ThemeProvider";
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);
export function ThemeProvider({ export function ThemeProvider({
@@ -59,13 +39,3 @@ export function ThemeProvider({
</ThemeProviderContext.Provider> </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 SuccessMessage from "@/components/message/SuccessMessage";
import Modal from "@/components/modal/Modal"; import Modal from "@/components/modal/Modal";
import ModalBody from "@/components/modal/ModalBody"; import ModalBody from "@/components/modal/ModalBody";
import { createContext, useContext, useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { TimedModalProviderContext } from "../TimedModalProvider";
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);
export function TimedModalProvider({ export function TimedModalProvider({
@@ -92,13 +77,3 @@ export function TimedModalProvider({
</TimedModalProviderContext.Provider> </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[] = [ const headElements: React.ReactNode[] = [
<div> <div key="username">
Username Username
</div>, </div>,
isSiteAdmin(accountPermissions) && isSiteAdmin(accountPermissions) &&
<div> <div key="email">
Email Email
</div>, </div>,
<div> <div key="loginDate">
Login Date Login Date
</div>, </div>,
raidGroup && isRaidGroupAdmin(raidGroup?.raidGroupId ?? "", raidGroupPermissions ?? [], accountPermissions) && raidGroup && isRaidGroupAdmin(raidGroup?.raidGroupId ?? "", raidGroupPermissions ?? [], accountPermissions) &&
<div> <div key="raidGroupPermission">
Raid Group Permission Raid Group Permission
</div>, </div>,
<div> <div key="status">
Status Status
</div>, </div>,
<div <div
key="actions"
className="pl-16" className="pl-16"
> >
Actions Actions
@@ -69,27 +70,30 @@ export default function AccountsList({
const bodyElements: React.ReactNode[][] = accounts.map((account) => [ const bodyElements: React.ReactNode[][] = accounts.map((account) => [
<div <div
key={`username-${account.accountId}`}
className="text-nowrap pl-2 text-start" className="text-nowrap pl-2 text-start"
> >
{account.username} {account.username}
</div>, </div>,
isSiteAdmin(accountPermissions) && isSiteAdmin(accountPermissions) &&
<div> <div key={`email-${account.accountId}`}>
{account.email} {account.email}
</div>, </div>,
<div <div
key={`loginDate-${account.accountId}`}
className="text-nowrap" className="text-nowrap"
> >
{account.loginDate ? moment(account.loginDate).format("MM-DD-YYYY hh:mm a") : <>&nbsp;</>} {account.loginDate ? moment(account.loginDate).format("MM-DD-YYYY hh:mm a") : <>&nbsp;</>}
</div>, </div>,
raidGroup && isRaidGroupAdmin(raidGroup?.raidGroupId ?? "", raidGroupPermissions ?? [], accountPermissions) && raidGroup && isRaidGroupAdmin(raidGroup?.raidGroupId ?? "", raidGroupPermissions ?? [], accountPermissions) &&
<div> <div key={`raidGroupPermission-${account.accountId}`}>
{raidGroupPermissions.find((perm) => (perm.raidGroupId === raidGroup?.raidGroupId))?.permission} {raidGroupPermissions.find((perm) => (perm.raidGroupId === raidGroup?.raidGroupId))?.permission}
</div>, </div>,
<div> <div key={`status-${account.accountId}`}>
{account.accountStatus} {account.accountStatus}
</div>, </div>,
<div <div
key={`actions-${account.accountId}`}
className="flex flex-row items-center justify-center gap-2 pl-16" className="flex flex-row items-center justify-center gap-2 pl-16"
> >
<div <div

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,16 +7,17 @@ import PersonAdminButtons from "./PersonAdminButtons";
export default function PersonListSkeleton(){ export default function PersonListSkeleton(){
const headElements: React.ReactNode[] = [ const headElements: React.ReactNode[] = [
<div> <div key="name">
Person Name Person Name
</div>, </div>,
<div> <div key="discordId">
Discord ID Discord ID
</div>, </div>,
<div> <div key="characters">
Characters Characters
</div>, </div>,
<div <div
key="actions"
className="pl-16" className="pl-16"
> >
Actions Actions
@@ -59,15 +60,19 @@ export function PersonSkeleton(): React.ReactNode[]{
} }
const elements: React.ReactNode[] = [ const elements: React.ReactNode[] = [
<div <div
key="name"
className={`h-6 w-64 mr-1 ${elementBg}`} className={`h-6 w-64 mr-1 ${elementBg}`}
/>, />,
<div <div
key="discordId"
className={`h-6 w-48 ml-2 ${elementBg}`} className={`h-6 w-48 ml-2 ${elementBg}`}
/>, />,
<div <div
key="characters"
className={`h-6 w-[48rem] ${elementBg}`} className={`h-6 w-[48rem] ${elementBg}`}
/>, />,
<div <div
key="actions"
className={`flex flex-row items-center justify-center gap-2 pl-16`} className={`flex flex-row items-center justify-center gap-2 pl-16`}
> >
<div className="py-4 border-l border-neutral-500">&nbsp;</div> <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[] = [ const headElements: React.ReactNode[] = [
<div <div
key="name"
className="text-nowrap" className="text-nowrap"
> >
Character Name Character Name
</div>, </div>,
<div> <div key="class">
Class Class
</div>, </div>,
<div> <div key="rating">
Rating Rating
</div>, </div>,
<div> <div key="comments">
Comments Comments
</div>, </div>,
<div <div
key="actions"
className="pl-16" className="pl-16"
> >
Actions Actions
@@ -55,30 +57,33 @@ export default function PersonCharacterList({
const bodyElements: React.ReactNode[][] = personCharacters.map((personCharacter) => [ const bodyElements: React.ReactNode[][] = personCharacters.map((personCharacter) => [
<div <div
key="name"
className="text-nowrap" className="text-nowrap"
> >
{personCharacter.characterName} {personCharacter.characterName}
</div>, </div>,
<div <div
key="class"
className="flex flex-row items-center justify-center h-full" className="flex flex-row items-center justify-center h-full"
> >
<GameClassCellDisplay <GameClassCellDisplay
gameClassId={personCharacter.gameClassId} gameClassId={personCharacter.gameClassId}
/> />
</div>, </div>,
<div> <div key="rating">
{ {
personCharacter.characterRating && personCharacter.characterRating > 0 ? personCharacter.characterRating && personCharacter.characterRating > 0 ?
personCharacter.characterRating : personCharacter.characterRating :
<>&nbsp;</> <>&nbsp;</>
} }
</div>, </div>,
<div> <div key="comments">
{ {
personCharacter.characterComments || <>&nbsp;</> personCharacter.characterComments || <>&nbsp;</>
} }
</div>, </div>,
<div <div
key="actions"
className="flex flex-row flex-nowrap items-center justify-center gap-2 pl-16" className="flex flex-row flex-nowrap items-center justify-center gap-2 pl-16"
> >
<div <div

View File

@@ -6,19 +6,20 @@ import PersonCharacterAdminButtons from "./PersonCharacterAdminButtons";
export default function PersonCharacterListSkeleton(){ export default function PersonCharacterListSkeleton(){
const headElements: React.ReactNode[] = [ const headElements: React.ReactNode[] = [
<div> <div key="name">
Character Name Character Name
</div>, </div>,
<div> <div key="class">
Class Class
</div>, </div>,
<div> <div key="rating">
Rating Rating
</div>, </div>,
<div> <div key="comments">
Comments Comments
</div>, </div>,
<div <div
key="actions"
className="pl-16" className="pl-16"
> >
Actions Actions
@@ -61,18 +62,23 @@ function PersonCharacterSkeleton(): React.ReactNode[]{
const elements: React.ReactNode[] = [ const elements: React.ReactNode[] = [
<div <div
key="name"
className={`h-6 w-96 mr-1 ${elementBg}`} className={`h-6 w-96 mr-1 ${elementBg}`}
/>, />,
<div <div
key="class"
className={`h-6 w-72 ml-2 ${elementBg}`} className={`h-6 w-72 ml-2 ${elementBg}`}
/>, />,
<div <div
key="rating"
className={`h-6 w-32 ${elementBg}`} className={`h-6 w-32 ${elementBg}`}
/>, />,
<div <div
key="comments"
className={`h-6 w-[32rem] ${elementBg}`} className={`h-6 w-[32rem] ${elementBg}`}
/>, />,
<div <div
key="actions"
className={`flex flex-row items-center justify-center gap-2 pl-16`} className={`flex flex-row items-center justify-center gap-2 pl-16`}
> >
<div className="py-4 border-l border-neutral-500">&nbsp;</div> <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[] = [ const headElements: React.ReactNode[] = [
<div> <div key="icon">
Icon Icon
</div>, </div>,
<div> <div key="name">
Name Name
</div>, </div>,
<div <div
key="actions"
className="pl-16" className="pl-16"
> >
Actions Actions
@@ -45,7 +46,7 @@ export default function RaidGroupsList({
]; ];
const bodyElements: React.ReactNode[][] = raidGroups.map((raidGroup) => [ const bodyElements: React.ReactNode[][] = raidGroups.map((raidGroup) => [
<div> <div key="icon">
{ {
raidGroup.raidGroupIcon && raidGroup.raidGroupIcon &&
<div <div
@@ -60,11 +61,13 @@ export default function RaidGroupsList({
&nbsp; &nbsp;
</div>, </div>,
<Link <Link
key="name"
to={`/raidGroup/${raidGroup.raidGroupId}`} to={`/raidGroup/${raidGroup.raidGroupId}`}
> >
{raidGroup.raidGroupName} {raidGroup.raidGroupName}
</Link>, </Link>,
<div <div
key="actions"
className="flex flex-row items-center justify-center gap-2 pl-16" className="flex flex-row items-center justify-center gap-2 pl-16"
> >
<div <div

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,21 +8,25 @@ import RaidLayoutAdminButtons from "./RaidLayoutAdminButtons";
export default function RaidLayoutListSkeleton(){ export default function RaidLayoutListSkeleton(){
const headElements: React.ReactNode[] = [ const headElements: React.ReactNode[] = [
<div <div
key="name"
className="text-nowrap" className="text-nowrap"
> >
Raid Layout Name Raid Layout Name
</div>, </div>,
<div <div
key="size"
className="text-nowrap" className="text-nowrap"
> >
Raid Size Raid Size
</div>, </div>,
<div <div
key="classGroups"
className="text-nowrap" className="text-nowrap"
> >
Class Groups Class Groups
</div>, </div>,
<div <div
key="actions"
className="text-nowrap" className="text-nowrap"
> >
Actions Actions
@@ -67,15 +71,19 @@ function RaidLayoutSkeleton(){
const elements: React.ReactNode[] = [ const elements: React.ReactNode[] = [
<div <div
key="name"
className={`h-6 w-64 mr-1 ${elementBg}`} className={`h-6 w-64 mr-1 ${elementBg}`}
/>, />,
<div <div
key="size"
className={`h-6 w-24 ml-2 ${elementBg}`} className={`h-6 w-24 ml-2 ${elementBg}`}
/>, />,
<div <div
key="classGroups"
className={`h-6 w-[56rem] ml-2 ${elementBg}`} className={`h-6 w-[56rem] ml-2 ${elementBg}`}
/>, />,
<div <div
key="actions"
className="flex flex-row items-center justify-center gap-2 pl-16" className="flex flex-row items-center justify-center gap-2 pl-16"
> >
<div className="py-4 border-l border-neutral-500">&nbsp;</div> <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){ else if(newLayoutSize > classGroups.length){
setClassGroups([ setClassGroups([
...classGroups, ...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}`, baseURL: `${import.meta.env.VITE_API_URL}`,
timeout: 10000, timeout: 10000,
withCredentials: true 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 tailwindcss from "@tailwindcss/vite";
import react from '@vitejs/plugin-react'; import react from "@vitejs/plugin-react";
import { resolve } from 'path'; import { resolve } from "path";
import { defineConfig } from 'vite'; import { defineConfig } from "vite";
// https://vite.dev/config/ // https://vite.dev/config/
@@ -15,5 +15,8 @@ export default defineConfig({
"@": resolve(__dirname, "./src"), "@": resolve(__dirname, "./src"),
"#root": resolve(__dirname) "#root": resolve(__dirname)
} }
},
build: {
chunkSizeWarningLimit: 1024
} }
}); });