feat: implement user role status toggle and reset password functionality
- Added toggle functionality for user roles (activate/deactivate) in roles and users pages. - Introduced a reset password page that validates and updates user passwords via a reset link. - Enhanced user detail page with edit functionality for user information (display name, email, mobile number). - Implemented sending reset link feature for users, with appropriate error handling and success notifications. - Updated API endpoints for user management to support new functionalities. - Improved UI components for better user experience during status updates and password changes.
This commit is contained in:
@@ -28,6 +28,10 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@
|
||||
import { toast } from "@/components/ui/toast"
|
||||
|
||||
const PAGE_SIZE_OPTIONS = [5, 10, 20, 25]
|
||||
// Mirrors Branch.DefaultCode (backend) — the deployment's seeded branch, which
|
||||
// BranchService blocks deactivating or deleting (every branch-scoped entity needs
|
||||
// at least one branch to exist).
|
||||
const DEFAULT_BRANCH_CODE = "BR-000"
|
||||
// Mobile has no page-size selector — tapping "Show more" just grows the page size and
|
||||
// re-fetches from page 1, so previously loaded cards stay put and more append below.
|
||||
const MOBILE_PAGE_SIZE_STEP = 10
|
||||
@@ -329,12 +333,16 @@ export function BranchMasterPage() {
|
||||
size="icon-sm"
|
||||
className={cn(
|
||||
item.status === "Active"
|
||||
? "text-destructive hover:bg-destructive/10"
|
||||
? "text-destructive hover:bg-destructive/10 disabled:pointer-events-auto disabled:cursor-not-allowed"
|
||||
: "text-success hover:bg-success/10"
|
||||
)}
|
||||
aria-label={item.status === "Active" ? `Deactivate ${item.name}` : `Activate ${item.name}`}
|
||||
title={item.status === "Active" ? `Deactivate ${item.name}` : `Activate ${item.name}`}
|
||||
disabled={actionPendingId === item.branchId}
|
||||
title={
|
||||
item.status === "Active" && item.code === DEFAULT_BRANCH_CODE
|
||||
? "The default branch cannot be deactivated"
|
||||
: item.status === "Active" ? `Deactivate ${item.name}` : `Activate ${item.name}`
|
||||
}
|
||||
disabled={actionPendingId === item.branchId || (item.status === "Active" && item.code === DEFAULT_BRANCH_CODE)}
|
||||
onClick={() => toggleStatus(item)}
|
||||
>
|
||||
{item.status === "Active" ? <XCircle className="size-4" /> : <CheckCircle2 className="size-4" />}
|
||||
@@ -345,10 +353,10 @@ export function BranchMasterPage() {
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className="text-destructive hover:bg-destructive/10"
|
||||
className="text-destructive hover:bg-destructive/10 disabled:pointer-events-auto disabled:cursor-not-allowed"
|
||||
aria-label={`Delete ${item.name}`}
|
||||
title={`Delete ${item.name}`}
|
||||
disabled={deletingId === item.branchId}
|
||||
title={item.code === DEFAULT_BRANCH_CODE ? "The default branch cannot be deleted" : `Delete ${item.name}`}
|
||||
disabled={deletingId === item.branchId || item.code === DEFAULT_BRANCH_CODE}
|
||||
/>
|
||||
}
|
||||
>
|
||||
@@ -433,12 +441,16 @@ export function BranchMasterPage() {
|
||||
size="icon-sm"
|
||||
className={cn(
|
||||
item.status === "Active"
|
||||
? "text-destructive hover:bg-destructive/10"
|
||||
? "text-destructive hover:bg-destructive/10 disabled:pointer-events-auto disabled:cursor-not-allowed"
|
||||
: "text-success hover:bg-success/10"
|
||||
)}
|
||||
aria-label={item.status === "Active" ? `Deactivate ${item.name}` : `Activate ${item.name}`}
|
||||
title={item.status === "Active" ? `Deactivate ${item.name}` : `Activate ${item.name}`}
|
||||
disabled={actionPendingId === item.branchId}
|
||||
title={
|
||||
item.status === "Active" && item.code === DEFAULT_BRANCH_CODE
|
||||
? "The default branch cannot be deactivated"
|
||||
: item.status === "Active" ? `Deactivate ${item.name}` : `Activate ${item.name}`
|
||||
}
|
||||
disabled={actionPendingId === item.branchId || (item.status === "Active" && item.code === DEFAULT_BRANCH_CODE)}
|
||||
onClick={() => toggleStatus(item)}
|
||||
>
|
||||
{item.status === "Active" ? <XCircle className="size-4" /> : <CheckCircle2 className="size-4" />}
|
||||
@@ -449,10 +461,10 @@ export function BranchMasterPage() {
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className="text-destructive hover:bg-destructive/10"
|
||||
className="text-destructive hover:bg-destructive/10 disabled:pointer-events-auto disabled:cursor-not-allowed"
|
||||
aria-label={`Delete ${item.name}`}
|
||||
title={`Delete ${item.name}`}
|
||||
disabled={deletingId === item.branchId}
|
||||
title={item.code === DEFAULT_BRANCH_CODE ? "The default branch cannot be deleted" : `Delete ${item.name}`}
|
||||
disabled={deletingId === item.branchId || item.code === DEFAULT_BRANCH_CODE}
|
||||
/>
|
||||
}
|
||||
>
|
||||
|
||||
@@ -88,9 +88,10 @@ function AlertDialogContent({
|
||||
|
||||
return (
|
||||
<AlertDialogPortal>
|
||||
<AlertDialogOverlay />
|
||||
<AlertDialogOverlay data-no-row-nav />
|
||||
<AlertDialogPrimitive.Popup
|
||||
data-slot="alert-dialog-content"
|
||||
data-no-row-nav
|
||||
className={cn(
|
||||
"fixed top-1/2 left-1/2 z-50 w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 rounded-2xl bg-popover p-6 shadow-xl ring-1 duration-150 outline-none sm:max-w-sm",
|
||||
"data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
||||
|
||||
@@ -49,9 +49,10 @@ function DialogContent({
|
||||
}) {
|
||||
return (
|
||||
<DialogPortal>
|
||||
<DialogOverlay />
|
||||
<DialogOverlay data-no-row-nav />
|
||||
<DialogPrimitive.Popup
|
||||
data-slot="dialog-content"
|
||||
data-no-row-nav
|
||||
className={cn(
|
||||
"fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
||||
className
|
||||
|
||||
Reference in New Issue
Block a user