Add AccountList skeleton
This commit is contained in:
@@ -20,6 +20,7 @@ export default function Modal(props: ModalProps){
|
||||
delete divProps["backgroundClassName"];
|
||||
delete divProps["close"];
|
||||
delete divProps["className"];
|
||||
delete divProps["top"];
|
||||
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
import DangerMessage from "@/components/message/DangerMessage";
|
||||
import SuccessMessage from "@/components/message/SuccessMessage";
|
||||
import Modal from "@/components/modal/Modal";
|
||||
import ModalBody from "@/components/modal/ModalBody";
|
||||
import { createContext, useContext, useEffect, useRef, useState } from "react";
|
||||
|
||||
|
||||
type TimedModalProviderState = {
|
||||
addMessage: (timeout: number, message: React.ReactNode) => void;
|
||||
addMessage: (message: React.ReactNode, timeout: number) => void;
|
||||
addSuccessMessage: (message: string) => void;
|
||||
addErrorMessage: (message: string) => void;
|
||||
}
|
||||
|
||||
|
||||
const initialState: TimedModalProviderState = {
|
||||
addMessage: () => null
|
||||
addMessage: () => null,
|
||||
addSuccessMessage: () => null,
|
||||
addErrorMessage: () => null
|
||||
}
|
||||
|
||||
const TimedModalProviderContext = createContext<TimedModalProviderState>(initialState);
|
||||
@@ -27,8 +33,6 @@ export function TimedModalProvider({
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
console.log("effect");
|
||||
console.log(messages);
|
||||
if(messages.length > 0){
|
||||
setDisplay(true);
|
||||
}
|
||||
@@ -38,16 +42,30 @@ export function TimedModalProvider({
|
||||
}, [ messages ]);
|
||||
|
||||
|
||||
const addMessage = (timeout: number, message: React.ReactNode) => {
|
||||
const addMessage = (message: React.ReactNode, timeout: number) => {
|
||||
setMessages([...messages, message]);
|
||||
setTimeout(() => {
|
||||
setMessages(messagesRef.current.filter((m) => m !== message));
|
||||
}, timeout);
|
||||
}
|
||||
|
||||
const addSuccessMessage = (message: string) => {
|
||||
addMessage(<SuccessMessage>{message}</SuccessMessage>, 5000);
|
||||
}
|
||||
|
||||
const addErrorMessage = (message: string) => {
|
||||
addMessage(<DangerMessage>{message}</DangerMessage>, 5000);
|
||||
}
|
||||
|
||||
const currentContext = {
|
||||
addMessage,
|
||||
addSuccessMessage,
|
||||
addErrorMessage
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<TimedModalProviderContext.Provider value={{addMessage}}>
|
||||
<TimedModalProviderContext.Provider value={currentContext}>
|
||||
<Modal
|
||||
display={display}
|
||||
backgroundType="none"
|
||||
|
||||
@@ -1,7 +1,91 @@
|
||||
import { ButtonShape, ButtonSizeType, ButtonVariant } from "@/components/button/Button";
|
||||
import Table from "@/components/table/Table";
|
||||
import { elementBg } from "@/util/SkeletonUtil";
|
||||
import AccountAdminButtons from "./AccountAdminButtons";
|
||||
|
||||
|
||||
export default function AccountsListSkeleton(){
|
||||
return (
|
||||
const headElements: React.ReactNode[] = [
|
||||
<div>
|
||||
Accounts List Skeleton
|
||||
ID
|
||||
</div>,
|
||||
<div>
|
||||
Username
|
||||
</div>,
|
||||
<div>
|
||||
Email
|
||||
</div>,
|
||||
<div>
|
||||
Login Date
|
||||
</div>,
|
||||
<div>
|
||||
Status
|
||||
</div>,
|
||||
<div
|
||||
className="pl-16"
|
||||
>
|
||||
Actions
|
||||
</div>
|
||||
];
|
||||
const bodyElements: React.ReactNode[][] = [
|
||||
AccountSkeleton(),
|
||||
AccountSkeleton(),
|
||||
AccountSkeleton(),
|
||||
AccountSkeleton(),
|
||||
AccountSkeleton(),
|
||||
AccountSkeleton(),
|
||||
AccountSkeleton(),
|
||||
AccountSkeleton(),
|
||||
AccountSkeleton(),
|
||||
AccountSkeleton()
|
||||
];
|
||||
|
||||
|
||||
return (
|
||||
<Table
|
||||
tableHeadElements={headElements}
|
||||
tableBodyElements={bodyElements}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function AccountSkeleton(): React.ReactNode[]{
|
||||
const buttonsProps = {
|
||||
buttonProps: {
|
||||
variant: "ghost" as ButtonVariant,
|
||||
size: "md" as ButtonSizeType,
|
||||
shape: "square" as ButtonShape,
|
||||
disabled: true
|
||||
},
|
||||
showForcePasswordResetModal: () => {},
|
||||
showAccountPasswordSetModal: () => {},
|
||||
showRevokeRefreshTokenModal: () => {},
|
||||
showUpdateAccountModal: () => {},
|
||||
showDeleteAccountModal: () => {}
|
||||
}
|
||||
const elements: React.ReactNode[] = [
|
||||
<div
|
||||
className={`h-6 w-72 mr-1 ${elementBg}`}
|
||||
/>,
|
||||
<div
|
||||
className={`h-6 w-48 ${elementBg}`}
|
||||
/>,
|
||||
<div
|
||||
className={`h-6 w-80 ${elementBg}`}
|
||||
/>,
|
||||
<div
|
||||
className={`h-6 w-64 ${elementBg}`}
|
||||
/>,
|
||||
<div
|
||||
className={`h-6 w-28 ${elementBg}`}
|
||||
/>,
|
||||
<div
|
||||
className={`flex flex-row items-center justify-center gap-2 pl-16`}
|
||||
>
|
||||
<div className="py-4 border-l border-neutral-500"> </div>
|
||||
<AccountAdminButtons {...buttonsProps}/>
|
||||
</div>
|
||||
];
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import PrimaryButton from "@/components/button/PrimaryButton";
|
||||
import DangerMessage from "@/components/message/DangerMessage";
|
||||
import { useGetAccounts } from "@/hooks/AccountHooks";
|
||||
import { useState } from "react";
|
||||
import AccountsList from "./AccountsList";
|
||||
@@ -16,13 +17,12 @@ export default function AccountsLoader(){
|
||||
return <AccountsListSkeleton/>
|
||||
}
|
||||
else if(accountsQuery.isError){
|
||||
//TODO:
|
||||
return <div>Error: {accountsQuery.error.message}</div>
|
||||
return <DangerMessage>Error: {accountsQuery.error.message}</DangerMessage>
|
||||
}
|
||||
else{
|
||||
return (
|
||||
<>
|
||||
{/* TODO: Add Account Button */}
|
||||
{/* Add Account Button */}
|
||||
<PrimaryButton
|
||||
className="mb-8"
|
||||
onClick={() => setDisplayCreateAccountModal(true)}
|
||||
|
||||
@@ -6,6 +6,7 @@ import TextInput from "@/components/input/TextInput";
|
||||
import RaidBuilderModal from "@/components/modal/RaidBuilderModal";
|
||||
import { useCreateAccount, useUpdateAccount } from "@/hooks/AccountHooks";
|
||||
import { Account, AccountStatus } from "@/interface/Account";
|
||||
import { useTimedModal } from "@/providers/TimedModalProvider";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
|
||||
@@ -35,17 +36,31 @@ export default function AccountModal({
|
||||
|
||||
const updateAccountMutate = useUpdateAccount();
|
||||
const createAccountMutate = useCreateAccount();
|
||||
const { addSuccessMessage, addErrorMessage } = useTimedModal();
|
||||
|
||||
if((updateAccountMutate.isSuccess) || (createAccountMutate.isSuccess)){
|
||||
updateAccountMutate.reset();
|
||||
|
||||
useEffect(() => {
|
||||
if(createAccountMutate.isSuccess){
|
||||
createAccountMutate.reset();
|
||||
addSuccessMessage(`Account ${username} created successfully`);
|
||||
close();
|
||||
}
|
||||
else if((updateAccountMutate.isError) || (updateAccountMutate.isError)){
|
||||
//TODO: Add message modal here
|
||||
console.log(updateAccountMutate.error);
|
||||
else if(updateAccountMutate.isSuccess){
|
||||
updateAccountMutate.reset();
|
||||
addSuccessMessage(`Account ${username} updated successfully`);
|
||||
close();
|
||||
}
|
||||
else if(createAccountMutate.isError){
|
||||
createAccountMutate.reset();
|
||||
addErrorMessage(`Error creating account ${username}: ${createAccountMutate.error.message}`);
|
||||
console.log(createAccountMutate.error);
|
||||
}
|
||||
else if(updateAccountMutate.isError){
|
||||
updateAccountMutate.reset();
|
||||
addErrorMessage(`Error updating account ${username}: ${updateAccountMutate.error.message}`);
|
||||
console.log(updateAccountMutate.error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const updateAccount = () => {
|
||||
|
||||
@@ -4,7 +4,8 @@ import PasswordInput from "@/components/input/PasswordInput";
|
||||
import RaidBuilderModal from "@/components/modal/RaidBuilderModal";
|
||||
import { useResetPassword } from "@/hooks/AccountHooks";
|
||||
import { Account } from "@/interface/Account";
|
||||
import { useState } from "react";
|
||||
import { useTimedModal } from "@/providers/TimedModalProvider";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
|
||||
export default function AccountPasswordRestModal({
|
||||
@@ -17,6 +18,7 @@ export default function AccountPasswordRestModal({
|
||||
account: Account | undefined;
|
||||
}){
|
||||
const [ newPassword, setNewPassword ] = useState<string>("");
|
||||
const { addSuccessMessage, addErrorMessage } = useTimedModal();
|
||||
|
||||
|
||||
const passwordResetMutate = useResetPassword(account?.accountId ?? "");
|
||||
@@ -27,14 +29,18 @@ export default function AccountPasswordRestModal({
|
||||
passwordResetMutate.mutate(newPassword);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if(passwordResetMutate.isSuccess){
|
||||
passwordResetMutate.reset();
|
||||
addSuccessMessage(`Successfully reset password for ${account?.username}`);
|
||||
close();
|
||||
}
|
||||
else if(passwordResetMutate.isError){
|
||||
//TODO: Add message modal here
|
||||
passwordResetMutate.reset();
|
||||
addErrorMessage(`Failed to reset password for ${account?.username}: ${passwordResetMutate.error.message}`);
|
||||
console.log(passwordResetMutate.error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return (
|
||||
|
||||
@@ -3,6 +3,8 @@ import SecondaryButton from "@/components/button/SecondaryButton";
|
||||
import RaidBuilderModal from "@/components/modal/RaidBuilderModal";
|
||||
import { useDeleteAccount } from "@/hooks/AccountHooks";
|
||||
import { Account } from "@/interface/Account";
|
||||
import { useTimedModal } from "@/providers/TimedModalProvider";
|
||||
import { useEffect } from "react";
|
||||
|
||||
|
||||
export default function DeleteAccountModal({
|
||||
@@ -15,20 +17,26 @@ export default function DeleteAccountModal({
|
||||
account: Account | undefined;
|
||||
}){
|
||||
const deleteAccountMutate = useDeleteAccount(account?.accountId ?? "");
|
||||
const { addSuccessMessage, addErrorMessage } = useTimedModal();
|
||||
|
||||
|
||||
const deleteAccount = () => {
|
||||
deleteAccountMutate.mutate();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if(deleteAccountMutate.isSuccess){
|
||||
deleteAccountMutate.reset();
|
||||
addSuccessMessage(`Successfully deleted ${account?.username}`);
|
||||
close();
|
||||
}
|
||||
else if(deleteAccountMutate.isError){
|
||||
//TODO: Add message modal here
|
||||
deleteAccountMutate.reset();
|
||||
addErrorMessage(`Error deleting ${account?.username}: ${deleteAccountMutate.error.message}`);
|
||||
console.log(deleteAccountMutate.error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return (
|
||||
<RaidBuilderModal
|
||||
|
||||
@@ -3,6 +3,8 @@ import SecondaryButton from "@/components/button/SecondaryButton";
|
||||
import RaidBuilderModal from "@/components/modal/RaidBuilderModal";
|
||||
import { useForcePasswordReset } from "@/hooks/AccountHooks";
|
||||
import { Account } from "@/interface/Account";
|
||||
import { useTimedModal } from "@/providers/TimedModalProvider";
|
||||
import { useEffect } from "react";
|
||||
|
||||
|
||||
export default function ForcePasswordResetModal({
|
||||
@@ -14,21 +16,26 @@ export default function ForcePasswordResetModal({
|
||||
close: () => void;
|
||||
account: Account | undefined;
|
||||
}){
|
||||
const accountMutate = useForcePasswordReset(account?.accountId ?? "");
|
||||
const forcePasswordResetMutate = useForcePasswordReset(account?.accountId ?? "");
|
||||
const { addSuccessMessage, addErrorMessage } = useTimedModal();
|
||||
|
||||
|
||||
const forcePasswordReset = () => {
|
||||
accountMutate.mutate();
|
||||
forcePasswordResetMutate.mutate();
|
||||
}
|
||||
|
||||
if(accountMutate.isSuccess){
|
||||
accountMutate.reset();
|
||||
useEffect(() => {
|
||||
if(forcePasswordResetMutate.isSuccess){
|
||||
forcePasswordResetMutate.reset();
|
||||
addSuccessMessage(`Successfully forced password reset for ${account?.username}`);
|
||||
close();
|
||||
}
|
||||
else if(accountMutate.isError){
|
||||
//TODO: Add message modal here
|
||||
console.log(accountMutate.error);
|
||||
else if(forcePasswordResetMutate.isError){
|
||||
forcePasswordResetMutate.reset();
|
||||
addErrorMessage(`Error forcing password reset for ${account?.username}: ${forcePasswordResetMutate.error.message}`);
|
||||
console.log(forcePasswordResetMutate.error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return (
|
||||
|
||||
@@ -3,6 +3,8 @@ import SecondaryButton from "@/components/button/SecondaryButton";
|
||||
import RaidBuilderModal from "@/components/modal/RaidBuilderModal";
|
||||
import { useRevokeRefreshToken } from "@/hooks/AccountHooks";
|
||||
import { Account } from "@/interface/Account";
|
||||
import { useTimedModal } from "@/providers/TimedModalProvider";
|
||||
import { useEffect } from "react";
|
||||
|
||||
|
||||
export default function RevokeRefreshTokenModal({
|
||||
@@ -15,20 +17,25 @@ export default function RevokeRefreshTokenModal({
|
||||
account: Account | undefined;
|
||||
}){
|
||||
const revokeRefreshTokenMutate = useRevokeRefreshToken(account?.accountId ?? "");
|
||||
const { addSuccessMessage, addErrorMessage } = useTimedModal();
|
||||
|
||||
|
||||
const revokeRefreshToken = () => {
|
||||
revokeRefreshTokenMutate.mutate();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if(revokeRefreshTokenMutate.isSuccess){
|
||||
revokeRefreshTokenMutate.reset();
|
||||
addSuccessMessage(`Refresh token for ${account?.username} was successfully revoked`);
|
||||
close();
|
||||
}
|
||||
else if(revokeRefreshTokenMutate.isError){
|
||||
//TODO: Add message modal here
|
||||
revokeRefreshTokenMutate.reset();
|
||||
addErrorMessage(`Error revoking refresh token for ${account?.username}: ${revokeRefreshTokenMutate.error.message}`);
|
||||
console.log(revokeRefreshTokenMutate.error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return (
|
||||
|
||||
1
src/util/SkeletonUtil.ts
Normal file
1
src/util/SkeletonUtil.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const elementBg = "rounded-lg bg-neutral-700 dark:bg-neutral-200 animate-pulse";
|
||||
Reference in New Issue
Block a user