refactor(admin): replace inline email form with modal dialog
- import Modal component from shared components - rename emailFormOpen state to emailModalOpen for clarity - convert handleEmailSubmit from form event handler to plain async function - move email change form into a Modal instead of inline collapsible form - pass pendingEmailMessage as Input description prop instead of separate paragraph - simplify toggle button to only show when no pending message
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { registerPage } from '../registry.js';
|
import { registerPage } from '../registry.js';
|
||||||
import { useState, useEffect, useRef } from 'react';
|
import { useState, useEffect, useRef } from 'react';
|
||||||
import { Card, Input, Button, TabNav, UserAvatar } from '@zen/core/shared/components';
|
import { Card, Input, Button, TabNav, UserAvatar, Modal } from '@zen/core/shared/components';
|
||||||
import { useToast } from '@zen/core/toast';
|
import { useToast } from '@zen/core/toast';
|
||||||
import AdminHeader from '../components/AdminHeader.js';
|
import AdminHeader from '../components/AdminHeader.js';
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ const ProfilePage = ({ user: initialUser }) => {
|
|||||||
const [uploadingImage, setUploadingImage] = useState(false);
|
const [uploadingImage, setUploadingImage] = useState(false);
|
||||||
const [formData, setFormData] = useState({ name: initialUser?.name || '' });
|
const [formData, setFormData] = useState({ name: initialUser?.name || '' });
|
||||||
|
|
||||||
const [emailFormOpen, setEmailFormOpen] = useState(false);
|
const [emailModalOpen, setEmailModalOpen] = useState(false);
|
||||||
const [emailFormData, setEmailFormData] = useState({ newEmail: '', password: '' });
|
const [emailFormData, setEmailFormData] = useState({ newEmail: '', password: '' });
|
||||||
const [emailLoading, setEmailLoading] = useState(false);
|
const [emailLoading, setEmailLoading] = useState(false);
|
||||||
const [pendingEmailMessage, setPendingEmailMessage] = useState('');
|
const [pendingEmailMessage, setPendingEmailMessage] = useState('');
|
||||||
@@ -31,8 +31,7 @@ const ProfilePage = ({ user: initialUser }) => {
|
|||||||
|
|
||||||
const hasChanges = formData.name !== user?.name;
|
const hasChanges = formData.name !== user?.name;
|
||||||
|
|
||||||
const handleEmailSubmit = async (e) => {
|
const handleEmailSubmit = async () => {
|
||||||
e.preventDefault();
|
|
||||||
if (!emailFormData.newEmail.trim()) {
|
if (!emailFormData.newEmail.trim()) {
|
||||||
toast.error('Le nouveau courriel est requis');
|
toast.error('Le nouveau courriel est requis');
|
||||||
return;
|
return;
|
||||||
@@ -53,7 +52,7 @@ const ProfilePage = ({ user: initialUser }) => {
|
|||||||
if (!response.ok || !data.success) throw new Error(data.error || data.message || 'Échec de la demande de changement de courriel');
|
if (!response.ok || !data.success) throw new Error(data.error || data.message || 'Échec de la demande de changement de courriel');
|
||||||
toast.success(data.message);
|
toast.success(data.message);
|
||||||
setPendingEmailMessage(data.message);
|
setPendingEmailMessage(data.message);
|
||||||
setEmailFormOpen(false);
|
setEmailModalOpen(false);
|
||||||
setEmailFormData({ newEmail: '', password: '' });
|
setEmailFormData({ newEmail: '', password: '' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(error.message || 'Échec de la demande de changement de courriel');
|
toast.error(error.message || 'Échec de la demande de changement de courriel');
|
||||||
@@ -188,48 +187,17 @@ const ProfilePage = ({ user: initialUser }) => {
|
|||||||
value={user?.email || ''}
|
value={user?.email || ''}
|
||||||
disabled
|
disabled
|
||||||
readOnly
|
readOnly
|
||||||
|
description={pendingEmailMessage || undefined}
|
||||||
/>
|
/>
|
||||||
{pendingEmailMessage ? (
|
{!pendingEmailMessage && (
|
||||||
<p className="text-xs text-blue-600 dark:text-blue-400">{pendingEmailMessage}</p>
|
|
||||||
) : (
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => { setEmailFormOpen(prev => !prev); setPendingEmailMessage(''); setEmailFormData({ newEmail: '', password: '' }); }}
|
onClick={() => setEmailModalOpen(true)}
|
||||||
className="text-xs text-neutral-500 hover:text-neutral-800 dark:hover:text-neutral-200 underline self-start transition-colors"
|
className="text-xs text-neutral-500 hover:text-neutral-800 dark:hover:text-neutral-200 underline self-start transition-colors"
|
||||||
>
|
>
|
||||||
{emailFormOpen ? 'Annuler' : 'Modifier le courriel'}
|
Modifier le courriel
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{emailFormOpen && (
|
|
||||||
<form onSubmit={handleEmailSubmit} className="flex flex-col gap-3 mt-2 p-3 rounded-lg border border-neutral-200 dark:border-neutral-700 bg-neutral-50 dark:bg-neutral-800/50">
|
|
||||||
<Input
|
|
||||||
label="Nouveau courriel"
|
|
||||||
type="email"
|
|
||||||
value={emailFormData.newEmail}
|
|
||||||
onChange={(value) => setEmailFormData(prev => ({ ...prev, newEmail: value }))}
|
|
||||||
placeholder="nouvelle@adresse.com"
|
|
||||||
required
|
|
||||||
disabled={emailLoading}
|
|
||||||
/>
|
|
||||||
<Input
|
|
||||||
label="Mot de passe actuel"
|
|
||||||
type="password"
|
|
||||||
value={emailFormData.password}
|
|
||||||
onChange={(value) => setEmailFormData(prev => ({ ...prev, password: value }))}
|
|
||||||
placeholder="Votre mot de passe"
|
|
||||||
required
|
|
||||||
disabled={emailLoading}
|
|
||||||
/>
|
|
||||||
<div className="flex gap-2 justify-end">
|
|
||||||
<Button type="button" variant="secondary" onClick={() => { setEmailFormOpen(false); setEmailFormData({ newEmail: '', password: '' }); }} disabled={emailLoading}>
|
|
||||||
Annuler
|
|
||||||
</Button>
|
|
||||||
<Button type="submit" variant="primary" loading={emailLoading} disabled={emailLoading}>
|
|
||||||
Envoyer la confirmation
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<Input
|
<Input
|
||||||
label="Compte créé"
|
label="Compte créé"
|
||||||
@@ -292,6 +260,37 @@ const ProfilePage = ({ user: initialUser }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
isOpen={emailModalOpen}
|
||||||
|
onClose={() => { setEmailModalOpen(false); setEmailFormData({ newEmail: '', password: '' }); }}
|
||||||
|
title="Modifier le courriel"
|
||||||
|
onSubmit={handleEmailSubmit}
|
||||||
|
submitLabel="Envoyer la confirmation"
|
||||||
|
loading={emailLoading}
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<Input
|
||||||
|
label="Nouveau courriel"
|
||||||
|
type="email"
|
||||||
|
value={emailFormData.newEmail}
|
||||||
|
onChange={(value) => setEmailFormData(prev => ({ ...prev, newEmail: value }))}
|
||||||
|
placeholder="nouvelle@adresse.com"
|
||||||
|
required
|
||||||
|
disabled={emailLoading}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
label="Mot de passe actuel"
|
||||||
|
type="password"
|
||||||
|
value={emailFormData.password}
|
||||||
|
onChange={(value) => setEmailFormData(prev => ({ ...prev, password: value }))}
|
||||||
|
placeholder="Votre mot de passe"
|
||||||
|
required
|
||||||
|
disabled={emailLoading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user