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}
|
||||
/>
|
||||
}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user