Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 248x 248x 248x 248x 248x 8x 8x 8x 8x 8x 4x 4x 4x 4x 3x 3x 7x 248x 5x 5x 5x 248x 248x 101x 58x | import { useState } from "react";
import { useNavigate } from "@tanstack/react-router";
import { X } from "lucide-react";
import { Button } from "../../ui/button";
import { Input } from "../../ui/input";
import { adminApi } from "../../../lib/api";
import { useDialogAccessibility } from "../../../hooks";
interface CreateProModalProps {
isOpen: boolean;
onClose: () => void;
}
export function CreateProModal({ isOpen, onClose }: CreateProModalProps) {
const navigate = useNavigate();
const [businessName, setBusinessName] = useState("");
const [isCreating, setIsCreating] = useState(false);
const [error, setError] = useState<string | null>(null);
const handleCreatePro = async () => {
Iif (!businessName.trim()) return;
setIsCreating(true);
setError(null);
try {
const result = await adminApi.createPro({
businessName,
status: "draft",
});
Eif (result.data) {
onClose();
setBusinessName("");
navigate({ to: `/admin/pros/${result.data.id}` });
}
} catch (err) {
console.error("Failed to create pro:", err);
setError("Failed to create pro");
} finally {
setIsCreating(false);
}
};
const handleClose = () => {
onClose();
setError(null);
setBusinessName("");
};
const { dialogRef, handleFocusTrap } = useDialogAccessibility(handleClose);
if (!isOpen) return null;
return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50" tabIndex={-1}>
<div
ref={dialogRef}
role="dialog"
aria-modal="true"
aria-labelledby="create-pro-dialog-title"
onKeyDown={handleFocusTrap}
className="bg-background-elevated rounded-lg shadow-xl w-full max-w-md mx-4"
>
<div className="flex items-center justify-between p-4 border-b">
<h3 id="create-pro-dialog-title" className="text-lg font-semibold">Create New Pro</h3>
<button
type="button"
onClick={handleClose}
aria-label="Close"
className="p-1 hover:bg-background-subtle rounded"
>
<X className="h-5 w-5" />
</button>
</div>
<div className="p-4 space-y-4">
{error && (
<div className="bg-notification-error-bg text-notification-error-text px-3 py-2 rounded text-sm">
{error}
</div>
)}
<div>
<label
htmlFor="new-pro-business-name"
className="block text-sm font-medium text-foreground-default mb-1"
>
Business Name *
</label>
<Input
id="new-pro-business-name"
value={businessName}
onChange={(e) => setBusinessName(e.target.value)}
placeholder="Enter business name"
/>
</div>
</div>
<div className="flex justify-end gap-2 p-4 border-t">
<Button variant="outline" onClick={handleClose}>
Cancel
</Button>
<Button
onClick={handleCreatePro}
isLoading={isCreating}
disabled={!businessName.trim()}
>
Create Pro
</Button>
</div>
</div>
</div>
);
}
|