feat(auth): add user invitation flow with account setup
- add `createAccountSetup`, `verifyAccountSetupToken`, `deleteAccountSetupToken` to verifications core - add `completeAccountSetup` function to auth core for password creation on invite - add `InvitationEmail` template for sending invite links - add `SetupAccountPage` client page for invited users to set their password - add `UserCreateModal` admin component to invite new users - wire invitation action and API endpoint in auth feature - update admin `UsersPage` to include user creation modal - update auth and admin README docs
This commit is contained in:
@@ -7,8 +7,9 @@ import { PencilEdit01Icon } from '@zen/core/shared/icons';
|
||||
import { useToast } from '@zen/core/toast';
|
||||
import AdminHeader from '../components/AdminHeader.js';
|
||||
import UserEditModal from '../components/UserEditModal.client.js';
|
||||
import UserCreateModal from '../components/UserCreateModal.client.js';
|
||||
|
||||
const UsersPageClient = ({ currentUserId }) => {
|
||||
const UsersPageClient = ({ currentUserId, refreshKey }) => {
|
||||
const toast = useToast();
|
||||
const [users, setUsers] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -126,7 +127,7 @@ const UsersPageClient = ({ currentUserId }) => {
|
||||
|
||||
useEffect(() => {
|
||||
fetchUsers();
|
||||
}, [sortBy, sortOrder, pagination.page, pagination.limit]);
|
||||
}, [sortBy, sortOrder, pagination.page, pagination.limit, refreshKey]);
|
||||
|
||||
const handlePageChange = (newPage) => setPagination(prev => ({ ...prev, page: newPage }));
|
||||
const handleLimitChange = (newLimit) => setPagination(prev => ({ ...prev, limit: newLimit, page: 1 }));
|
||||
@@ -168,12 +169,30 @@ const UsersPageClient = ({ currentUserId }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const UsersPage = ({ user }) => (
|
||||
<div className="flex flex-col gap-4 sm:gap-6 lg:gap-8">
|
||||
<AdminHeader title="Utilisateurs" description="Gérez les comptes utilisateurs" />
|
||||
<UsersPageClient currentUserId={user?.id} />
|
||||
</div>
|
||||
);
|
||||
const UsersPage = ({ user }) => {
|
||||
const [createModalOpen, setCreateModalOpen] = useState(false);
|
||||
const [refreshKey, setRefreshKey] = useState(0);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-4 sm:gap-6 lg:gap-8">
|
||||
<AdminHeader
|
||||
title="Utilisateurs"
|
||||
description="Gérez les comptes utilisateurs"
|
||||
action={
|
||||
<Button variant="primary" onClick={() => setCreateModalOpen(true)}>
|
||||
Nouvel utilisateur
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<UsersPageClient currentUserId={user?.id} refreshKey={refreshKey} />
|
||||
<UserCreateModal
|
||||
isOpen={createModalOpen}
|
||||
onClose={() => setCreateModalOpen(false)}
|
||||
onSaved={() => setRefreshKey(k => k + 1)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default UsersPage;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user