diff --git a/client/src/pages/organizations.tsx b/client/src/pages/organizations.tsx index 4b09509..fae0a7d 100644 --- a/client/src/pages/organizations.tsx +++ b/client/src/pages/organizations.tsx @@ -14,6 +14,7 @@ import { useAuth } from '@/hooks/use-auth'; import { Users, Plus, Edit, Trash2, Building, Calendar, Clock, Info, AlertCircle } from 'lucide-react'; import { apiRequest, queryClient } from '@/lib/queryClient'; import { cn } from '@/lib/utils'; +import { Badge } from '@/components/ui/badge'; import { AlertDialog, AlertDialogAction, @@ -27,7 +28,15 @@ import { export default function OrganizationsPage() { const { user } = useAuth(); - const { organizations, currentOrganization, setCurrentOrganization, createOrganizationMutation } = useOrganization(); + const { + organizations, + currentOrganization, + setCurrentOrganization, + createOrganizationMutation, + updateOrganizationMutation, + deleteOrganizationMutation, + domainsByOrganization + } = useOrganization(); const { toast } = useToast(); const [newOrgName, setNewOrgName] = useState(''); const [newOrgActive, setNewOrgActive] = useState(true); @@ -175,7 +184,8 @@ export default function OrganizationsPage() { className="text-muted-foreground" onClick={(e) => { e.stopPropagation(); - // View organization details + setSelectedOrg(org); + setIsViewDialogOpen(true); }} > View Details @@ -189,7 +199,10 @@ export default function OrganizationsPage() { className="h-8 w-8 text-muted-foreground hover:text-foreground" onClick={(e) => { e.stopPropagation(); - // Edit organization + setSelectedOrg(org); + setEditOrgName(org.name); + setEditOrgActive(org.isActive); + setIsEditDialogOpen(true); }} > @@ -200,7 +213,8 @@ export default function OrganizationsPage() { className="h-8 w-8 text-muted-foreground hover:text-destructive" onClick={(e) => { e.stopPropagation(); - // Delete organization + setSelectedOrg(org); + setIsDeleteDialogOpen(true); }} > @@ -231,6 +245,159 @@ export default function OrganizationsPage() { )} + + {/* View Organization Dialog */} + + + + Organization Details + + View details for this organization. + + +
+ {selectedOrg && ( + <> +
+
+

Name

+

{selectedOrg.name}

+
+
+

Status

+

+ {selectedOrg.isActive ? ( + + Active + + ) : ( + + Inactive + + )} +

+
+
+ +
+

Created

+

{new Date(selectedOrg.createdAt).toLocaleDateString()}

+
+ +
+

Domains

+ {/* Check if domain data is available for this org */} + {selectedOrg.id in (domainsByOrganization || {}) && domainsByOrganization[selectedOrg.id]?.length > 0 ? ( +
    + {domainsByOrganization[selectedOrg.id]?.map(domain => ( +
  • {domain.name}
  • + ))} +
+ ) : ( +

No domains associated with this organization.

+ )} +
+ + )} +
+ + Close + +
+
+ + {/* Edit Organization Dialog */} + + + + Edit Organization + + Make changes to the organization details. + + +
{ + e.preventDefault(); + if (!editOrgName.trim()) { + toast({ + title: 'Error', + description: 'Organization name cannot be empty', + variant: 'destructive', + }); + return; + } + + if (selectedOrg) { + // Use the updateOrganizationMutation from context + updateOrganizationMutation.mutate({ + id: selectedOrg.id, + data: { + name: editOrgName, + isActive: editOrgActive, + } + }); + + setIsEditDialogOpen(false); + } + }}> +
+
+ + setEditOrgName(e.target.value)} + placeholder="Enter organization name" + required + /> +
+
+ setEditOrgActive(checked as boolean)} + /> + +
+
+ + + +
+
+
+ + {/* Delete Organization Dialog */} + + + + Are you sure? + + This action cannot be undone. This will permanently delete the organization + {selectedOrg && "{selectedOrg.name}"} and all associated data. + + + + Cancel + { + if (selectedOrg) { + deleteOrganizationMutation.mutate(selectedOrg.id); + setIsDeleteDialogOpen(false); + } + }} + > + {deleteOrganizationMutation.isPending ? 'Deleting...' : 'Delete'} + + + + ); } \ No newline at end of file