feat(platform): add Provisioning Success Modal with 1-click Copy Credentials button for tenant onboarding
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Plus, Building2, Search, Play, StopCircle, CheckCircle, XCircle } from "lucide-react";
|
||||
import { Plus, Building2, Search, Play, StopCircle, CheckCircle, XCircle, Copy, Check } from "lucide-react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { PageWrapper } from "../../../components/layouts/PageWrapper";
|
||||
import { Breadcrumb } from "../../../components/layouts/Breadcrumb";
|
||||
@@ -37,6 +37,9 @@ export default function PlatformTenantsPage() {
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
const [provisionedSuccessData, setProvisionedSuccessData] = useState<any | null>(null);
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
tenant_name: "",
|
||||
@@ -54,9 +57,14 @@ export default function PlatformTenantsPage() {
|
||||
}),
|
||||
onSubmit: async (values, { setSubmitting, resetForm }) => {
|
||||
try {
|
||||
await provisionTenant(values);
|
||||
const result = await provisionTenant(values);
|
||||
resetForm();
|
||||
setIsProvisionModalOpen(false);
|
||||
setProvisionedSuccessData({
|
||||
tenant: result.tenant || result.data?.tenant,
|
||||
admin: result.admin || result.data?.admin,
|
||||
rawPassword: values.admin_password
|
||||
});
|
||||
fetchPlatformTenants();
|
||||
} catch (err) {
|
||||
// Error handled in hook
|
||||
@@ -308,6 +316,62 @@ export default function PlatformTenantsPage() {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Provisioning Success Modal with Copy Credentials */}
|
||||
{provisionedSuccessData && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm p-4 animate-in fade-in duration-200">
|
||||
<div className="w-full max-w-md bg-surface border border-primary/20 rounded-2xl p-6 shadow-2xl space-y-5">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-12 h-12 rounded-xl bg-success/10 text-success flex items-center justify-center">
|
||||
<CheckCircle className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-bold text-foreground">Tenant Provisioned!</h3>
|
||||
<p className="text-xs text-muted-foreground">Share these setup credentials with your client</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-primary/5 border border-primary/10 rounded-xl p-4 space-y-3 font-mono text-xs text-foreground">
|
||||
<div className="flex justify-between border-b border-primary/10 pb-2">
|
||||
<span className="text-muted-foreground font-sans">Organization:</span>
|
||||
<span className="font-semibold text-primary">{provisionedSuccessData.tenant?.tenant_name}</span>
|
||||
</div>
|
||||
<div className="flex justify-between border-b border-primary/10 pb-2">
|
||||
<span className="text-muted-foreground font-sans">Tenant Code:</span>
|
||||
<span className="font-semibold">{provisionedSuccessData.tenant?.tenant_code}</span>
|
||||
</div>
|
||||
<div className="flex justify-between border-b border-primary/10 pb-2">
|
||||
<span className="text-muted-foreground font-sans">Admin Email:</span>
|
||||
<span className="font-semibold">{provisionedSuccessData.admin?.email || provisionedSuccessData.tenant?.contact_email}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-muted-foreground font-sans">Admin Password:</span>
|
||||
<span className="font-semibold text-danger">{provisionedSuccessData.rawPassword || '••••••••'}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-3 pt-2">
|
||||
<Button
|
||||
variant="primary"
|
||||
className="w-full flex items-center justify-center gap-2"
|
||||
onClick={() => {
|
||||
const textToCopy = `Organization: ${provisionedSuccessData.tenant?.tenant_name}\nTenant Code: ${provisionedSuccessData.tenant?.tenant_code}\nAdmin Email: ${provisionedSuccessData.admin?.email || provisionedSuccessData.tenant?.contact_email}\nPassword: ${provisionedSuccessData.rawPassword || 'Admin@123'}\nLogin URL: http://localhost:5173/login`;
|
||||
navigator.clipboard.writeText(textToCopy);
|
||||
setCopied(true);
|
||||
notify.success("Provisioning credentials copied to clipboard!");
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
}}
|
||||
>
|
||||
{copied ? <Check className="w-4 h-4" /> : <Copy className="w-4 h-4" />}
|
||||
{copied ? "Copied to Clipboard!" : "Copy Client Credentials"}
|
||||
</Button>
|
||||
<Button variant="outline" onClick={() => setProvisionedSuccessData(null)}>
|
||||
Done
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</PageWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user