Skip to content

Commit

Permalink
fix: modal & handle 409
Browse files Browse the repository at this point in the history
  • Loading branch information
ClementNumericite committed Jan 29, 2024
1 parent e68611b commit d6182f1
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 92 deletions.
35 changes: 9 additions & 26 deletions components/administration/UserCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,10 @@ import { Dispatch, SetStateAction } from 'react';

type Props = {
user: User;
modalProps: { onClick: () => void };
setCurrentUser: Dispatch<
SetStateAction<
(Prisma.UserUpdateInput & { id: string }) | Prisma.UserCreateInput
>
>;
onButtonClick: ({ type, user }: OnButtonClickUserParams) => void;
};

const UserCard = ({
user,
onButtonClick,
modalProps,
setCurrentUser
}: Props) => {
const UserCard = ({ user, onButtonClick }: Props) => {
const { data: session } = useSession({ required: true });
const { cx, classes } = useStyles();

Expand Down Expand Up @@ -66,21 +55,15 @@ const UserCard = ({
>
Supprimer
</Button>
<div
onClick={() => {
setCurrentUser(user);
}}
<Button
priority="secondary"
size="small"
iconId="fr-icon-edit-line"
iconPosition="right"
onClick={() => onButtonClick({ type: 'update', user })}
>
<Button
priority="secondary"
size="small"
iconId="fr-icon-edit-line"
iconPosition="right"
{...modalProps}
>
Modifier
</Button>
</div>
Modifier
</Button>
</div>
</div>
</div>
Expand Down
136 changes: 71 additions & 65 deletions pages/administration/bo/users/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import UserCard from '@/components/administration/UserCard';
import { Loader } from '@/components/generic/Loader';
import { Modal } from '@/components/generic/Modal';
import { Pagination } from '@/components/generic/Pagination';
import { useUsers } from '@/utils/api';
import { getNbPages } from '@/utils/tools';
Expand All @@ -12,7 +13,7 @@ import { Prisma, User } from '@prisma/client';
import { useEffect, useRef, useState } from 'react';

export type OnButtonClickUserParams =
| { type: 'create'; user?: User }
| { type: 'update'; user: User }
| { type: 'delete'; user: User };

type Props = {
Expand All @@ -36,8 +37,10 @@ export default function Editions(props: Props) {
const [currentPage, setCurrentPage] = useState(1);
const [numberPerPage, _] = useState(10);

const [isModalOpen, setIsModalOpen] = useState(false);
const [currentUser, setCurrentUser] =
useState<UpsertUser>(defaultUserCreation);
const [alreadyExists, setAlreadyExists] = useState(false);

const usernameInputRef = useRef<HTMLInputElement>(null);
const emailInputRef = useRef<HTMLInputElement>(null);
Expand Down Expand Up @@ -79,19 +82,6 @@ export default function Editions(props: Props) {

if (!users) return <div>Aucun utilisateur</div>;

const { UserModal, userModalButtonProps } = createModal({
name: 'user',
isOpenedByDefault: false
});

// WORKAROUND BESCAUSE THIS IS NOT POSSIBLE ON REACT-DSFR V1
const closeModal = () => {
const button = document.getElementsByClassName(
'fr-link--close'
)[0] as HTMLButtonElement;
if (button) button.click();
};

const handlePageChange = (pageNumber: number) => {
setCurrentPage(pageNumber);
};
Expand All @@ -116,8 +106,9 @@ export default function Editions(props: Props) {
return;
}

let response;
if (currentUser.id) {
await fetch('/api/users', {
response = await fetch('/api/users', {
method: 'PUT',
body: JSON.stringify({
id: currentUser.id,
Expand All @@ -130,7 +121,7 @@ export default function Editions(props: Props) {
passwordInputRef?.current?.focus();
return;
}
await fetch('/api/users', {
response = await fetch('/api/users', {
method: 'POST',
body: JSON.stringify({
username: usernameInputRef?.current?.value,
Expand All @@ -140,8 +131,12 @@ export default function Editions(props: Props) {
});
}

closeModal();
refetchUsers();
if (response.status === 409) {
setAlreadyExists(true);
} else if ([201, 200].includes(response.status)) {
setIsModalOpen(false);
refetchUsers();
}
};

const nbPages = getNbPages(usersCount, numberPerPage);
Expand All @@ -162,7 +157,9 @@ export default function Editions(props: Props) {
<Button
iconId="fr-icon-add-circle-line"
type="button"
{...userModalButtonProps}
onClick={() => {
setIsModalOpen(true);
}}
className={fr.cx('fr-btn--secondary')}
>
Ajouter un utilisateur
Expand Down Expand Up @@ -220,10 +217,12 @@ export default function Editions(props: Props) {
<UserCard
user={user}
key={index}
setCurrentUser={setCurrentUser}
modalProps={userModalButtonProps}
onButtonClick={({ type, user }) => {
if (type === 'delete') deleteUser(user);
if (type === 'update') {
setCurrentUser(user);
setIsModalOpen(true);
}
}}
/>
))}
Expand Down Expand Up @@ -269,57 +268,64 @@ export default function Editions(props: Props) {
</div>
)}
</div>
<UserModal
title={
currentUser.id
? "Modification d'un utilisateur"
: "Création d'un utilisateur"
}
buttons={[
{
onClick: upsertUser,
children: currentUser.id
? "Modifier l'utilisateur"
: "Créer l'utilisateur",
doClosesModal: false
{isModalOpen && (
<Modal
onClose={() => {}}
title={
currentUser.id
? "Modification d'un utilisateur"
: "Création d'un utilisateur"
}
]}
>
<form
onSubmit={e => {
e.preventDefault();
upsertUser();
}}
buttons={[
{
onClick: upsertUser,
children: currentUser.id
? "Modifier l'utilisateur"
: "Créer l'utilisateur"
}
]}
>
<Input
label="Nom complet"
nativeInputProps={{
name: 'username',
ref: usernameInputRef
<form
onSubmit={e => {
e.preventDefault();
upsertUser();
}}
/>
<Input
label="Email"
disabled={!!currentUser.id}
nativeInputProps={{
name: 'email',
type: 'email',
ref: emailInputRef
}}
/>
{!currentUser.id && (
>
<Input
label="Nom complet"
nativeInputProps={{
name: 'username',
ref: usernameInputRef
}}
/>
<Input
label="Mot de passe"
label="Email"
disabled={!!currentUser.id}
state={alreadyExists ? 'error' : 'default'}
stateRelatedMessage="Un utilisateur avec cette adresse email existe déjà"
nativeInputProps={{
name: 'password',
type: 'password',
ref: passwordInputRef
name: 'email',
type: 'email',
ref: emailInputRef,
onChange: () => {
setAlreadyExists(false);
}
}}
/>
)}
<button type="submit" style={{ display: 'none' }}></button>
</form>
</UserModal>
{!currentUser.id && (
<Input
label="Mot de passe"
nativeInputProps={{
name: 'password',
type: 'password',
ref: passwordInputRef
}}
/>
)}
<button type="submit" style={{ display: 'none' }}></button>
</form>
</Modal>
)}
</div>
);
}
Expand Down
12 changes: 11 additions & 1 deletion pages/api/users/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ export async function getUserById(id: string) {
}

export async function createUser(data: Omit<User, 'id'>) {
const alreadyExists = await prisma.user.findUnique({
where: {
email: data.email
}
});

if (!!alreadyExists) return 409;

const user = await prisma.user.create({
data: {
...data,
Expand Down Expand Up @@ -91,7 +99,9 @@ export default async function handler(
} else if (req.method === 'POST') {
const data = JSON.parse(req.body);
const user = await createUser(data);
res.status(201).json(user);

if (user === 409) res.status(409).json({ message: 'user already exists' });
else res.status(201).json(user);
} else if (req.method === 'PUT') {
const { id, ...data } = JSON.parse(req.body);
const user = await updateUser(id as string, data);
Expand Down

0 comments on commit d6182f1

Please sign in to comment.