"use client"; import React, { useState, useEffect } from "react"; import { useRouter, useParams } from "next/navigation"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { ChevronLeftIcon, SaveIcon, SettingsIcon, UsersIcon, WorkflowIcon, } from "@/components/icons"; import { Tenant, TenantUpdateRequest, getTenantById, updateTenant, } from "@/service/tenant"; import { getTenantList } from "@/service/tenant"; import SiteBreadcrumb from "@/components/site-breadcrumb"; import Swal from "sweetalert2"; import { FormField } from "@/components/form/common/FormField"; import { getCookiesDecrypt } from "@/lib/utils"; import { ApprovalWorkflowForm } from "@/components/form/ApprovalWorkflowForm"; import { UserLevelsForm } from "@/components/form/UserLevelsForm"; import { CreateApprovalWorkflowWithClientSettingsRequest, UserLevelsCreateRequest, UserLevel, getUserLevels, getApprovalWorkflowComprehensiveDetails, ComprehensiveWorkflowResponse, createUserLevel, } from "@/service/approval-workflows"; import TenantCompanyUpdateForm from "@/components/form/tenant/tenant-detail-update-form"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { flexRender, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, PaginationState, useReactTable, } from "@tanstack/react-table"; import TablePagination from "@/components/table/table-pagination"; import useTableColumns from "@/app/[locale]/(admin)/admin/settings/tenant/component/columns"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { PlusIcon, EditIcon, DeleteIcon } from "@/components/icons"; import { errorAutoClose, successAutoClose } from "@/lib/swal"; import { close, loading } from "@/config/swal"; export default function EditTenantPage() { const router = useRouter(); const params = useParams(); const tenantId = params?.id as string; const [totalData, setTotalData] = useState(0); const [totalPage, setTotalPage] = useState(1); const [tenant, setTenant] = useState(null); const [parentTenants, setParentTenants] = useState([]); const [isLoading, setIsLoading] = useState(true); const [isSaving, setIsSaving] = useState(false); const [activeTab, setActiveTab] = useState("profile"); // Workflow state const [workflow, setWorkflow] = useState(null); const [isEditingWorkflow, setIsEditingWorkflow] = useState(false); // User Levels state const [userLevels, setUserLevels] = useState([]); const [isUserLevelDialogOpen, setIsUserLevelDialogOpen] = useState(false); const [editingUserLevel, setEditingUserLevel] = useState( null, ); // Tenant form data const [formData, setFormData] = useState({ name: "", description: "", clientType: "standalone", parentClientId: undefined, maxUsers: undefined, maxStorage: undefined, address: "", phoneNumber: "", website: "", isActive: true, }); useEffect(() => { // Check if user has roleId = 1 const roleId = getCookiesDecrypt("urie"); if (Number(roleId) !== 1) { Swal.fire({ title: "Access Denied", text: "You don't have permission to access this page", icon: "error", confirmButtonText: "OK", customClass: { popup: "swal-z-index-9999", }, }).then(() => { router.push("/admin/dashboard"); }); return; } if (tenantId) { loadData(); } }, [tenantId, router]); // Load workflow and user levels when switching to those tabs useEffect(() => { if (tenant && (activeTab === "workflows" || activeTab === "user-levels")) { loadWorkflowAndUserLevels(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [activeTab]); const loadData = async () => { setIsLoading(true); try { const [tenantRes, parentRes] = await Promise.all([ getTenantById(tenantId), getTenantList({ clientType: "parent_client", limit: 100 }), ]); if (tenantRes?.error || !tenantRes?.data?.data) { Swal.fire({ title: "Error", text: tenantRes?.message || "Failed to load tenant data", icon: "error", confirmButtonText: "OK", customClass: { popup: "swal-z-index-9999", }, }).then(() => { router.push("/admin/tenants"); }); return; } const tenantData = tenantRes.data.data; setTenant(tenantData); // Set form data with all available fields setFormData({ name: tenantData.name || "", description: tenantData.description || "", clientType: tenantData.clientType || "standalone", parentClientId: tenantData.parentClientId || undefined, maxUsers: tenantData.maxUsers || undefined, maxStorage: tenantData.maxStorage || undefined, address: tenantData.address || "", phoneNumber: tenantData.phoneNumber || "", website: tenantData.website || "", isActive: tenantData.isActive !== undefined ? tenantData.isActive : true, logoUrl: tenantData.logoUrl || undefined, logoImagePath: tenantData.logoImagePath || undefined, }); if (!parentRes?.error) { setParentTenants(parentRes?.data?.data || []); } // Load workflow and user levels if on those tabs // Note: This will be loaded when tab changes via useEffect } catch (error) { console.error("Error loading tenant:", error); Swal.fire({ title: "Error", text: "An unexpected error occurred while loading tenant data", icon: "error", confirmButtonText: "OK", customClass: { popup: "swal-z-index-9999", }, }).then(() => { router.push("/admin/tenants"); }); } finally { setIsLoading(false); } }; const loadWorkflowAndUserLevels = async () => { try { const [comprehensiveWorkflowRes, userLevelsRes] = await Promise.all([ getApprovalWorkflowComprehensiveDetails(), getUserLevels(), ]); if (!comprehensiveWorkflowRes?.error) { setWorkflow(comprehensiveWorkflowRes?.data?.data || null); } else { setWorkflow(null); } if (!userLevelsRes?.error) { const data = userLevelsRes?.data?.data || []; setUserLevels(data); setTotalData(data.length); const pageSize = pagination.pageSize; setTotalPage(Math.max(1, Math.ceil(data.length / pageSize))); } if (!userLevelsRes?.error) { setUserLevels(userLevelsRes?.data?.data || []); } } catch (error) { console.error("Error loading workflow and user levels:", error); } }; const handleSaveTenantInfo = async () => { if (!tenantId) return; setIsSaving(true); try { const updateData: TenantUpdateRequest = { name: formData.name, description: formData.description || undefined, clientType: formData.clientType, parentClientId: formData.parentClientId || undefined, maxUsers: formData.maxUsers, maxStorage: formData.maxStorage, address: formData.address || undefined, phoneNumber: formData.phoneNumber || undefined, website: formData.website || undefined, isActive: formData.isActive, }; const res = await updateTenant(tenantId, updateData); if (res?.error) { Swal.fire({ title: "Error", text: res?.message || "Failed to update tenant", icon: "error", confirmButtonText: "OK", customClass: { popup: "swal-z-index-9999", }, }); } else { Swal.fire({ title: "Success", text: "Tenant updated successfully", icon: "success", confirmButtonText: "OK", customClass: { popup: "swal-z-index-9999", }, }); await loadData(); } } catch (error) { console.error("Error saving tenant:", error); Swal.fire({ title: "Error", text: "An unexpected error occurred", icon: "error", confirmButtonText: "OK", customClass: { popup: "swal-z-index-9999", }, }); } finally { setIsSaving(false); } }; const handleWorkflowSave = async ( data: CreateApprovalWorkflowWithClientSettingsRequest, ) => { setIsEditingWorkflow(false); await loadWorkflowAndUserLevels(); }; const handleUserLevelSave = async (data: UserLevelsCreateRequest) => { try { loading(); const response = await createUserLevel(data); close(); if (response?.error) { errorAutoClose(response.message || "Failed to create user level."); return; } successAutoClose("User level created successfully."); setIsUserLevelDialogOpen(false); setEditingUserLevel(null); setTimeout(async () => { await loadWorkflowAndUserLevels(); }, 1000); } catch (error) { close(); errorAutoClose("An error occurred while creating user level."); console.error("Error creating user level:", error); } }; const handleEditUserLevel = (userLevel: UserLevel) => { setEditingUserLevel(userLevel); setIsUserLevelDialogOpen(true); }; const handleDeleteUserLevel = async (userLevel: UserLevel) => { const result = await Swal.fire({ title: "Delete User Level?", text: `Are you sure you want to delete "${userLevel.name}"? This action cannot be undone.`, icon: "warning", showCancelButton: true, confirmButtonText: "Yes, delete it", cancelButtonText: "Cancel", customClass: { popup: "swal-z-index-9999", }, }); if (result.isConfirmed) { try { // TODO: Implement delete API call console.log("Delete user level:", userLevel.id); await loadWorkflowAndUserLevels(); } catch (error) { console.error("Error deleting user level:", error); } } }; const columns = React.useMemo( () => useTableColumns((data) => handleEditUserLevel(data)), [], ); const [pagination, setPagination] = React.useState({ pageIndex: 0, pageSize: 10, }); const table = useReactTable({ data: userLevels, columns, getCoreRowModel: getCoreRowModel(), getPaginationRowModel: getPaginationRowModel(), getSortedRowModel: getSortedRowModel(), getFilteredRowModel: getFilteredRowModel(), onPaginationChange: setPagination, state: { pagination, }, }); const roleId = getCookiesDecrypt("urie"); if (Number(roleId) !== 1) { return null; } if (isLoading) { return ( <>

Loading tenant data...

); } if (!tenant) { return null; } return ( <>

Edit Tenant: {tenant.name}

Manage tenant information, workflows, and user levels

Tenant Information Approval Workflows User Levels {/* Tenant Information Tab */} Tenant Information setFormData({ ...formData, name: value }) } required /> setFormData({ ...formData, description: value || undefined, }) } /> setFormData({ ...formData, clientType: value as any }) } options={[ { value: "standalone", label: "Standalone" }, { value: "parent_client", label: "Parent Client" }, { value: "sub_client", label: "Sub Client" }, ]} required /> {formData.clientType === "sub_client" && ( setFormData({ ...formData, parentClientId: value === "none" ? undefined : value, }) } options={[ { value: "none", label: "No Parent Tenant" }, ...parentTenants .filter((t) => t.id !== tenantId) .map((t) => ({ value: t.id, label: t.name, })), ]} required /> )}
setFormData({ ...formData, maxUsers: value ? Number(value) : undefined, }) } helpText="Maximum number of users allowed" /> setFormData({ ...formData, maxStorage: value ? Number(value) : undefined, }) } helpText="Maximum storage in MB" />
setFormData({ ...formData, address: value || undefined }) } />
setFormData({ ...formData, phoneNumber: value || undefined, }) } /> setFormData({ ...formData, website: value || undefined }) } />
setFormData({ ...formData, isActive: value === "active" }) } options={[ { value: "active", label: "Active" }, { value: "inactive", label: "Inactive" }, ]} required />
{/* Approval Workflows Tab */}

Approval Workflow Setup

{workflow && !isEditingWorkflow && ( )}
{isEditingWorkflow ? ( Setup Approval Workflow ({ stepOrder: step.stepOrder, stepName: step.stepName, requiredUserLevelId: step.requiredUserLevelId, canSkip: step.canSkip, autoApproveAfterHours: step.autoApproveAfterHours, isActive: step.isActive, conditionType: step.conditionType, conditionValue: step.conditionValue, })) || [], clientApprovalSettings: { approvalExemptCategories: workflow.clientSettings .exemptCategoriesDetails || [], approvalExemptRoles: workflow.clientSettings.exemptRolesDetails || [], approvalExemptUsers: workflow.clientSettings.exemptUsersDetails || [], autoPublishArticles: workflow.clientSettings.autoPublishArticles, isActive: workflow.clientSettings.isActive, requireApprovalFor: workflow.clientSettings.requireApprovalFor || [], requiresApproval: workflow.clientSettings.requiresApproval, skipApprovalFor: workflow.clientSettings.skipApprovalFor || [], }, } : undefined } workflowId={workflow?.workflow.id} onSave={handleWorkflowSave} onCancel={() => setIsEditingWorkflow(false)} /> ) : workflow ? ( {workflow.workflow.name}
{workflow.workflow.isDefault && ( Default )} {workflow.workflow.isActive ? ( Active ) : ( Inactive )}

{workflow.workflow.description}

{workflow.workflow.totalSteps}
Total Steps
{workflow.workflow.activeSteps}
Active Steps
{workflow.workflow.requiresApproval ? "Yes" : "No"}
Requires Approval
{workflow.workflow.autoPublish ? "Yes" : "No"}
Auto Publish
{workflow.steps && workflow.steps.length > 0 && (

Workflow Steps

{workflow.steps.map((step: any, index: number) => (
{step.stepOrder}
{step.stepName}
Required Level: {step.requiredUserLevelName}
{step.isActive ? ( Active ) : ( Inactive )}
))}
)}
) : (

No Workflow Found

No approval workflow has been set up for this tenant yet.

)}
{/* User Levels Tab */}

User Levels Management

{editingUserLevel ? `Edit User Level: ${editingUserLevel.name}` : "Create New User Level"} { setIsUserLevelDialogOpen(false); setEditingUserLevel(null); }} />
{userLevels.length > 0 ? ( {table .getHeaderGroups() .map((headerGroup) => headerGroup.headers.map((header) => ( {header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext(), )} )), )} Actions {table.getRowModel().rows?.length ? ( table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ))}
)) ) : ( No results. )}
) : (

No User Levels Found

Create your first user level to define user hierarchy

)}
); }