✨ Support delete own account and other tweaks (#614)
Co-authored-by: Esteban Maya Cadavid <emaya@trueblue.com>
This commit is contained in:
@@ -2,7 +2,6 @@ import React from 'react';
|
||||
|
||||
import { Box, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerOverlay, Flex, IconButton, Image, Text, useColorModeValue, useDisclosure } from '@chakra-ui/react';
|
||||
import { FiLogOut, FiMenu } from 'react-icons/fi';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import Logo from '../../assets/images/fastapi-logo.svg';
|
||||
import useAuth from '../../hooks/useAuth';
|
||||
@@ -16,11 +15,9 @@ const Sidebar: React.FC = () => {
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const { user } = useUserStore();
|
||||
const { logout } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleLogout = async () => {
|
||||
logout()
|
||||
navigate('/login');
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -3,17 +3,15 @@ import React from 'react';
|
||||
import { Box, IconButton, Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/react';
|
||||
import { FaUserAstronaut } from 'react-icons/fa';
|
||||
import { FiLogOut, FiUser } from 'react-icons/fi';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import useAuth from '../../hooks/useAuth';
|
||||
|
||||
const UserMenu: React.FC = () => {
|
||||
const navigate = useNavigate();
|
||||
const { logout } = useAuth();
|
||||
|
||||
const handleLogout = async () => {
|
||||
logout()
|
||||
navigate('/login');
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -2,7 +2,10 @@ import React, { useState } from 'react';
|
||||
|
||||
import { AlertDialog, AlertDialogBody, AlertDialogContent, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, Button } from '@chakra-ui/react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { ApiError } from '../../client';
|
||||
import useAuth from '../../hooks/useAuth';
|
||||
import useCustomToast from '../../hooks/useCustomToast';
|
||||
import { useUserStore } from '../../store/user-store';
|
||||
|
||||
interface DeleteProps {
|
||||
isOpen: boolean;
|
||||
@@ -12,18 +15,19 @@ interface DeleteProps {
|
||||
const DeleteConfirmation: React.FC<DeleteProps> = ({ isOpen, onClose }) => {
|
||||
const showToast = useCustomToast();
|
||||
const cancelRef = React.useRef<HTMLButtonElement | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const { handleSubmit } = useForm();
|
||||
const { handleSubmit, formState: { isSubmitting } } = useForm();
|
||||
const { user, deleteUser } = useUserStore();
|
||||
const { logout } = useAuth();
|
||||
|
||||
const onSubmit = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
// TODO: Delete user account when API is ready
|
||||
await deleteUser(user!.id);
|
||||
logout();
|
||||
onClose();
|
||||
showToast('Success', 'Your account has been successfully deleted.', 'success');
|
||||
} catch (err) {
|
||||
showToast('An error occurred', 'An error occurred while deleting your account.', 'error');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
const errDetail = (err as ApiError).body.detail;
|
||||
showToast('Something went wrong.', `${errDetail}`, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +51,7 @@ const DeleteConfirmation: React.FC<DeleteProps> = ({ isOpen, onClose }) => {
|
||||
</AlertDialogBody>
|
||||
|
||||
<AlertDialogFooter gap={3}>
|
||||
<Button bg='ui.danger' color='white' _hover={{ opacity: 0.8 }} type='submit' isLoading={isLoading}>
|
||||
<Button bg='ui.danger' color='white' _hover={{ opacity: 0.8 }} type='submit' isLoading={isSubmitting}>
|
||||
Confirm
|
||||
</Button>
|
||||
<Button ref={cancelRef} onClick={onClose} isDisabled={isLoading}>
|
||||
|
||||
@@ -2,11 +2,14 @@ import { useUserStore } from '../store/user-store';
|
||||
import { Body_login_login_access_token as AccessToken, LoginService } from '../client';
|
||||
import { useUsersStore } from '../store/users-store';
|
||||
import { useItemsStore } from '../store/items-store';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
const useAuth = () => {
|
||||
const { user, getUser, resetUser } = useUserStore();
|
||||
const { resetUsers } = useUsersStore();
|
||||
const { resetItems } = useItemsStore();
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
||||
const login = async (data: AccessToken) => {
|
||||
const response = await LoginService.loginAccessToken({
|
||||
@@ -21,6 +24,7 @@ const useAuth = () => {
|
||||
resetUser();
|
||||
resetUsers();
|
||||
resetItems();
|
||||
navigate('/login');
|
||||
};
|
||||
|
||||
const isLoggedIn = () => {
|
||||
|
||||
@@ -14,7 +14,7 @@ export const useItemsStore = create<ItemsStore>((set) => ({
|
||||
items: [],
|
||||
getItems: async () => {
|
||||
const itemsResponse = await ItemsService.readItems({ skip: 0, limit: 10 });
|
||||
set({ items: itemsResponse });
|
||||
set({ items: itemsResponse.data });
|
||||
},
|
||||
addItem: async (item: ItemCreate) => {
|
||||
const itemResponse = await ItemsService.createItem({ requestBody: item });
|
||||
|
||||
@@ -14,7 +14,7 @@ export const useUsersStore = create<UsersStore>((set) => ({
|
||||
users: [],
|
||||
getUsers: async () => {
|
||||
const usersResponse = await UsersService.readUsers({ skip: 0, limit: 10 });
|
||||
set({ users: usersResponse });
|
||||
set({ users: usersResponse.data });
|
||||
},
|
||||
addUser: async (user: UserCreate) => {
|
||||
const userResponse = await UsersService.createUser({ requestBody: user });
|
||||
|
||||
Reference in New Issue
Block a user