diff --git a/apps/console/src/pages/organizations/vendors/VendorView.tsx b/apps/console/src/pages/organizations/vendors/VendorView.tsx index a09196187..4692b6866 100644 --- a/apps/console/src/pages/organizations/vendors/VendorView.tsx +++ b/apps/console/src/pages/organizations/vendors/VendorView.tsx @@ -402,57 +402,6 @@ function ComplianceReportsTable({ ); } -function TagList({ - tags, - onAdd, - onRemove, -}: { - tags: readonly string[]; - onAdd: (tag: string) => void; - onRemove: (tag: string) => void; -}) { - const [newTag, setNewTag] = useState(""); - - const handleAddTag = (e: React.KeyboardEvent) => { - if (e.key === "Enter" && newTag.trim()) { - e.preventDefault(); - onAdd(newTag.trim()); - setNewTag(""); - } - }; - - return ( -
-
- {tags.map((tag) => ( -
- {tag} - -
- ))} -
-
- setNewTag(e.target.value)} - onKeyDown={handleAddTag} - placeholder="Type and press Enter to add a certification" - className="border-0 bg-transparent p-1 shadow-none focus-visible:ring-0" - /> -
-
- ); -} - function CertificationsView({ certifications, onAdd, @@ -466,7 +415,7 @@ function CertificationsView({ const securityStandards = ["SOC 2", "ISO 27001", "HITRUST", "NIST"]; // Regulatory and legal certifications - const regulatoryLegal = ["HIPAA", "FERPA", "FISMA", "PIPEDA"]; + const regulatoryLegal = ["HIPAA", "FERPA", "FISMA", "PIPEDA", "GDPR", "CCPA"]; // Industry-specific certifications const industrySpecific = ["FinTech", "MPAA", "GSMA"]; @@ -474,17 +423,34 @@ function CertificationsView({ // International & government certifications const internationalGov = ["FedRAMP", "ENS High", "IRAP", "CJIS"]; - // Check if certification is in vendor's list - const isCertificationActive = (cert: string) => { - return certifications.includes(cert); + // State for new certification input + const [showAddModal, setShowAddModal] = useState(false); + const [newCertification, setNewCertification] = useState(""); + + // Handle adding a new custom certification + const handleAddCertification = () => { + if (newCertification.trim()) { + onAdd(newCertification.trim()); + setNewCertification(""); + setShowAddModal(false); + } }; + // Get certifications by category + const securityCerts = certifications.filter(cert => securityStandards.includes(cert)); + const regulatoryCerts = certifications.filter(cert => regulatoryLegal.includes(cert)); + const industryCerts = certifications.filter(cert => industrySpecific.includes(cert)); + const internationalCerts = certifications.filter(cert => internationalGov.includes(cert)); + const customCerts = certifications.filter(cert => + ![...securityStandards, ...regulatoryLegal, ...industrySpecific, ...internationalGov].includes(cert) + ); + return (

Certifications

- ))} + {securityCerts.length > 0 && ( +
+

Security Standards

+
+ {securityCerts.map(cert => ( +
+ {cert} + +
+ ))} +
-
+ )} {/* Regulatory & Legal */} -
-

Regulatory & Legal

-
- {regulatoryLegal.map(cert => ( - - ))} + {regulatoryCerts.length > 0 && ( +
+

Regulatory & Legal

+
+ {regulatoryCerts.map(cert => ( +
+ {cert} + +
+ ))} +
-
+ )} {/* Industry-Specific */} -
-

Industry-Specific

-
- {industrySpecific.map(cert => ( - - ))} + {industryCerts.length > 0 && ( +
+

Industry-Specific

+
+ {industryCerts.map(cert => ( +
+ {cert} + +
+ ))} +
-
+ )} {/* International & Government */} -
-

International & Government

-
- {internationalGov.map(cert => ( - - ))} + {internationalCerts.length > 0 && ( +
+

International & Government

+
+ {internationalCerts.map(cert => ( +
+ {cert} + +
+ ))} +
-
+ )} {/* Custom certifications */} - {certifications.length > 0 && ( + {customCerts.length > 0 && (

Custom Certifications

- {certifications - .filter(cert => - ![...securityStandards, ...regulatoryLegal, ...industrySpecific, ...internationalGov].includes(cert) - ) - .map(cert => ( -
( +
+ {cert} + -
- ))} + + + + + +
+ ))}
)}
+ + {/* Add Certification Modal */} + {showAddModal && ( +
+
+

Add Custom Certification

+
+
+ + setNewCertification(e.target.value)} + placeholder="Enter certification name" + className="mt-1" + /> +
+
+ + +
+
+
+
+ )}
); } @@ -935,6 +926,42 @@ function VendorViewContent({ setEditedFields((prev) => new Set(prev).add(field)); }; + // Auto-save handler specifically for certifications + const handleCertificationChange = useCallback((newCertifications: string[]) => { + // Update local state + setFormData(prev => ({ + ...prev, + certifications: newCertifications, + })); + + // Auto-save the changes immediately + const formattedData = { + id: data.node.id!, + certifications: newCertifications, + }; + + updateVendor({ + variables: { + input: formattedData, + }, + onCompleted: () => { + toast({ + title: "Success", + description: "Certifications updated", + variant: "default", + }); + loadQuery({ vendorId: data.node.id!, organizationId: organizationId! }); + }, + onError: (error) => { + toast({ + title: "Error", + description: error.message || "Failed to update certifications", + variant: "destructive", + }); + }, + }); + }, [updateVendor, data.node.id, loadQuery, toast, organizationId]); + const handleCancel = () => { setFormData({ name: data.node.name || "", @@ -1378,14 +1405,13 @@ function VendorViewContent({ - handleFieldChange("certifications", [ + handleCertificationChange([ ...formData.certifications.filter(c => c !== cert), cert, ]) } onRemove={(cert) => - handleFieldChange( - "certifications", + handleCertificationChange( formData.certifications.filter((c) => c !== cert) ) }