Files
auto_rfp/components/organizations/CreateOrganizationDialog.tsx
T
2025-05-16 13:56:36 -07:00

156 lines
4.3 KiB
TypeScript

'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { useToast } from '@/components/ui/use-toast';
interface CreateOrganizationDialogProps {
isOpen: boolean;
onOpenChange: (open: boolean) => void;
onSuccess?: (orgId: string, orgSlug: string) => void;
}
export function CreateOrganizationDialog({
isOpen,
onOpenChange,
onSuccess
}: CreateOrganizationDialogProps) {
const [name, setName] = useState('');
const [description, setDescription] = useState('');
const [isSubmitting, setIsSubmitting] = useState(false);
const { toast } = useToast();
const router = useRouter();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!name.trim()) {
toast({
title: 'Error',
description: 'Organization name is required',
variant: 'destructive',
});
return;
}
try {
setIsSubmitting(true);
const response = await fetch('/api/organizations', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name,
description: description.trim() || null,
}),
});
if (response.ok) {
const organization = await response.json();
toast({
title: 'Success',
description: `${organization.name} has been created`,
});
// Reset form
setName('');
setDescription('');
// Close dialog
onOpenChange(false);
// Call success callback or redirect
if (onSuccess) {
onSuccess(organization.id, organization.slug);
} else {
router.push(`/organizations/${organization.slug}`);
}
} else {
const error = await response.json();
throw new Error(error.error || 'Failed to create organization');
}
} catch (error) {
toast({
title: 'Error',
description: error instanceof Error ? error.message : 'Failed to create organization',
variant: 'destructive',
});
} finally {
setIsSubmitting(false);
}
};
return (
<Dialog open={isOpen} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[425px]">
<form onSubmit={handleSubmit}>
<DialogHeader>
<DialogTitle>Create organization</DialogTitle>
<DialogDescription>
Create a new organization to manage projects and team members.
</DialogDescription>
</DialogHeader>
<div className="grid gap-4 py-4">
<div className="grid gap-2">
<Label htmlFor="name">Name</Label>
<Input
id="name"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Acme Inc."
className="col-span-3"
required
/>
</div>
<div className="grid gap-2">
<Label htmlFor="description">Description (optional)</Label>
<Textarea
id="description"
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder="Brief description of your organization"
className="col-span-3"
rows={3}
/>
</div>
</div>
<DialogFooter>
<Button
type="button"
variant="outline"
onClick={() => onOpenChange(false)}
disabled={isSubmitting}
>
Cancel
</Button>
<Button
type="submit"
disabled={isSubmitting || !name.trim()}
>
{isSubmitting ? 'Creating...' : 'Create'}
</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
);
}