Files
cameleer-saas/ui/src/pages/vendor/CreateTenantPage.tsx
2026-04-09 22:39:23 +02:00

110 lines
3.4 KiB
TypeScript

import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router';
import { Button, Card, FormField, Input, useToast } from '@cameleer/design-system';
import { useCreateTenant } from '../../api/vendor-hooks';
import { toSlug } from '../../utils/slug';
const TIERS = ['LOW', 'MID', 'HIGH', 'BUSINESS'];
export function CreateTenantPage() {
const navigate = useNavigate();
const { toast } = useToast();
const createTenant = useCreateTenant();
const [name, setName] = useState('');
const [slug, setSlug] = useState('');
const [slugTouched, setSlugTouched] = useState(false);
const [tier, setTier] = useState('LOW');
useEffect(() => {
if (!slugTouched) {
setSlug(toSlug(name));
}
}, [name, slugTouched]);
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
try {
const result = await createTenant.mutateAsync({ name, slug, tier });
toast({ title: 'Tenant created', variant: 'success' });
navigate(`/vendor/tenants/${result.id}`);
} catch (err) {
toast({ title: 'Failed to create tenant', description: String(err), variant: 'error' });
}
}
return (
<div style={{ padding: '24px', maxWidth: 560 }}>
<div style={{ marginBottom: 20 }}>
<h1 style={{ margin: 0, fontSize: '1.25rem', fontWeight: 600 }}>Create Tenant</h1>
</div>
<Card title="Tenant details">
<form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: 16, padding: '8px 0' }}>
<FormField label="Name" htmlFor="tenant-name" required>
<Input
id="tenant-name"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Acme Corp"
required
/>
</FormField>
<FormField label="Slug" htmlFor="tenant-slug" required hint="URL-safe identifier, auto-generated from name">
<Input
id="tenant-slug"
value={slug}
onChange={(e) => {
setSlug(e.target.value);
setSlugTouched(true);
}}
placeholder="acme-corp"
required
/>
</FormField>
<FormField label="Tier" htmlFor="tenant-tier" required>
<select
id="tenant-tier"
value={tier}
onChange={(e) => setTier(e.target.value)}
style={{
width: '100%',
padding: '8px 12px',
border: '1px solid var(--border)',
borderRadius: 6,
background: 'var(--bg-surface)',
color: 'var(--text-primary)',
fontSize: '0.875rem',
}}
>
{TIERS.map((t) => (
<option key={t} value={t}>{t}</option>
))}
</select>
</FormField>
<div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', paddingTop: 8 }}>
<Button
type="button"
variant="ghost"
onClick={() => navigate('/vendor/tenants')}
>
Cancel
</Button>
<Button
type="submit"
variant="primary"
loading={createTenant.isPending}
disabled={!name || !slug}
>
Create Tenant
</Button>
</div>
</form>
</Card>
</div>
);
}