From 644d8610de67d821b0598a53c0f087147d3a416f Mon Sep 17 00:00:00 2001 From: yassinedorbozgithub Date: Sun, 29 Sep 2024 10:07:04 +0100 Subject: [PATCH 1/5] feat: add creation user required step --- src/app/components/RequiredSteps.tsx | 48 ++++++++ src/app/components/dialogs/AddUserDialog.tsx | 120 +++++++++++++++++++ src/app/layout.tsx | 10 +- src/app/services/api.types.ts | 10 ++ src/app/services/endpoints/user.class.ts | 34 ++++++ 5 files changed, 215 insertions(+), 7 deletions(-) create mode 100644 src/app/components/RequiredSteps.tsx create mode 100644 src/app/components/dialogs/AddUserDialog.tsx create mode 100644 src/app/services/endpoints/user.class.ts diff --git a/src/app/components/RequiredSteps.tsx b/src/app/components/RequiredSteps.tsx new file mode 100644 index 0000000..856de20 --- /dev/null +++ b/src/app/components/RequiredSteps.tsx @@ -0,0 +1,48 @@ +'use client'; +import { Grid } from '@mui/material'; +import React from 'react'; + +import { AddUserDialog } from './dialogs/AddUserDialog'; +import { useAuth } from '../context/AuthProvider'; +import { apiUser } from '../services/endpoints/user.class'; + +export const RequiredSteps = ({ children }: { children: React.ReactNode }) => { + const { user } = useAuth(); + + const [isCreateUserDialogOpened, setIsCreateUserDialogOpened] = + React.useState(false); + const [hasUser, setHasUser] = React.useState(false); + React.useEffect(() => { + const fetchUser = async () => { + await apiUser + .getUser(user.id) + .then(({ data }) => { + setHasUser(true); + return data; + }) + .catch((e) => { + setHasUser(false); + setIsCreateUserDialogOpened(true); + }); + }; + fetchUser(); + }, []); + + return ( + + {hasUser ? ( + children + ) : ( + { + setIsCreateUserDialogOpened(false); + }} + callback={() => { + setHasUser(true); + }} + /> + )} + + ); +}; diff --git a/src/app/components/dialogs/AddUserDialog.tsx b/src/app/components/dialogs/AddUserDialog.tsx new file mode 100644 index 0000000..8474a59 --- /dev/null +++ b/src/app/components/dialogs/AddUserDialog.tsx @@ -0,0 +1,120 @@ +'use client'; + +import { KeyboardBackspace, Send } from '@mui/icons-material'; +import { + Dialog, + DialogContent, + Grid, + Alert, + TextField, + Button, +} from '@mui/material'; +import { FC, useEffect, useState } from 'react'; +import { useForm } from 'react-hook-form'; + +import { useAuth } from '@/app/context/AuthProvider'; +import { apiUser } from '@/app/services/endpoints/user.class'; +import { CreateUserDto } from '@/domain/dtos/user'; + +import { StyledButton } from '../StyledButton'; +import { StyledDialogActions } from '../StyledDialogActions'; +import { StyledDialogContent } from '../StyledDialogContent'; +import { StyledDialogTitle } from '../StyledDialogTitle'; + +interface AddUserDialogProps { + open?: boolean; + onClose?: () => void; + callback?: () => void; +} + +export const AddUserDialog: FC = ({ + open, + onClose, + callback, +}) => { + const { session } = useAuth(); + const [hasError, setHasError] = useState(false); + const [disableButton, setDisableButton] = useState(false); + + const { + reset, + register, + formState: { errors }, + resetField, + handleSubmit, + } = useForm(); + + const onSubmitForm = async (data: CreateUserDto) => { + setDisableButton(true); + try { + await apiUser + .createUser(data) + .then(() => { + onClose?.(); + callback?.(); + }) + .catch(() => { + setHasError(true); + setDisableButton(false); + }); + } catch (error) { + console.error('Failed to create user:', error); + } + }; + + useEffect(() => { + if (open) { + reset(); + setHasError(false); + setDisableButton(false); + } + }, [open]); + + useEffect(() => { + if (session?.token?.sub) + resetField('userId', { defaultValue: session.token.sub }); + }, [session?.token?.sub]); + + return ( + +
+ Create a user + + + {hasError && ( + + The creation of a user is failed + + )} + + value || undefined, + })} + /> + + + + + + Create + + +
+
+ ); +}; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 46e6549..43d6fe5 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,12 +1,13 @@ -import { Grid } from '@mui/material'; import { ThemeProvider } from '@mui/material/styles'; import { AppRouterCacheProvider } from '@mui/material-nextjs/v14-appRouter'; import type { Metadata } from 'next'; import { getServerSession } from 'next-auth'; +import React from 'react'; import { authOptions } from './api/auth/authOptions'; import Footer from './components/Footer'; import Header from './components/Header'; +import { RequiredSteps } from './components/RequiredSteps'; import AuthProvider from './context/AuthProvider'; import theme from './theme'; @@ -32,12 +33,7 @@ export default async function RootLayout({
- - {children} - + {children}