diff --git a/src/app/components/RequiredSteps.tsx b/src/app/components/RequiredSteps.tsx new file mode 100644 index 0000000..342171f --- /dev/null +++ b/src/app/components/RequiredSteps.tsx @@ -0,0 +1,52 @@ +'use client'; +import { Grid } from '@mui/material'; +import { usePathname } from 'next/navigation'; +import React, { useEffect } 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, isAuthenticated } = useAuth(); + const pathname = usePathname(); + + const [isCreateUserDialogOpened, setIsCreateUserDialogOpened] = + React.useState(false); + const [hasUser, setHasUser] = React.useState(false); + const isAnonymous = !isAuthenticated && pathname === '/viewer'; + + useEffect(() => { + const fetchUser = async (id: string) => + apiUser + .getUser(id) + .then(({ data }) => { + setHasUser(true); + return data; + }) + .catch(() => { + setHasUser(false); + setIsCreateUserDialogOpened(true); + }); + + if (user?.id) fetchUser(user.id); + }, []); + + return ( + + {isAnonymous || 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..0f5d2ba --- /dev/null +++ b/src/app/components/dialogs/AddUserDialog.tsx @@ -0,0 +1,113 @@ +'use client'; + +import { Send } from '@mui/icons-material'; +import { Dialog, DialogContent, Grid, Alert, TextField } 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 ( + +
+ Verify user details + + + {hasError && ( + + The creation of a user is failed + + )} + + value || undefined, + })} + /> + + + + + + Create + + +
+
+ ); +}; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index f615d33..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,7 +33,7 @@ export default async function RootLayout({
- {children} + {children}