style: padroniza layout do formulário de criação de empresas com o de vagas

This commit is contained in:
GoHorse Deploy 2026-03-07 17:44:17 -03:00
parent a754b4eba8
commit 007a708ffe

View file

@ -6,11 +6,11 @@ import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input" import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea" import { Textarea } from "@/components/ui/textarea"
import { Label } from "@/components/ui/label" import { Label } from "@/components/ui/label"
import { Loader2, Eye, EyeOff, ArrowLeft } from "lucide-react" import { Loader2, Eye, EyeOff, ArrowLeft, Building2 } from "lucide-react"
import { adminCompaniesApi } from "@/lib/api" import { adminCompaniesApi } from "@/lib/api"
import { toast } from "sonner" import { toast } from "sonner"
import { useTranslation } from "@/lib/i18n" import { useTranslation } from "@/lib/i18n"
import { Card, CardContent } from "@/components/ui/card" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import Link from "next/link" import Link from "next/link"
const formatCNPJ = (value: string) => { const formatCNPJ = (value: string) => {
@ -85,185 +85,240 @@ export default function NewCompanyPage() {
} }
return ( return (
<div className="space-y-8 max-w-3xl mx-auto"> <div className="container max-w-4xl py-10">
<div className="flex items-center gap-4"> <div className="mb-8">
<Button variant="ghost" size="icon" asChild> <Button variant="ghost" size="sm" asChild className="mb-4">
<Link href="/dashboard/companies"> <Link href="/dashboard/companies" className="flex items-center gap-2">
<ArrowLeft className="h-5 w-5" /> <ArrowLeft className="h-4 w-4" />
{t('admin.companies.create.backToList', { defaultValue: 'Voltar para lista' })}
</Link> </Link>
</Button> </Button>
<div>
<h1 className="text-3xl font-bold text-foreground">{t('admin.companies.create.title')}</h1>
<p className="text-muted-foreground mt-1">{t('admin.companies.create.subtitle')}</p>
</div>
</div> </div>
<Card> <Card className="border-0 shadow-lg">
<CardContent className="pt-6"> <CardHeader className="bg-muted/50 pb-8 pt-8">
<div className="grid gap-6"> <div className="flex items-center gap-4">
<div className="grid gap-2"> <div className="bg-primary/10 p-3 rounded-xl">
<Label htmlFor="name">{t('admin.companies.create.name')}</Label> <Building2 className="h-8 w-8 text-primary" />
<Input
id="name"
value={formData.name}
onChange={(e) =>
setFormData({
...formData,
name: e.target.value,
slug: generateSlug(e.target.value),
})
}
placeholder={t('admin.companies.create.namePlaceholder')}
/>
</div> </div>
<div className="grid gap-2"> <div>
<Label htmlFor="slug">{t('admin.companies.create.slug')}</Label> <CardTitle className="text-2xl font-bold">{t('admin.companies.create.title')}</CardTitle>
<Input <CardDescription className="text-base mt-1">
id="slug" {t('admin.companies.create.subtitle')}
value={formData.slug} </CardDescription>
onChange={(e) => setFormData({ ...formData, slug: e.target.value })}
placeholder={t('admin.companies.create.slugPlaceholder')}
/>
</div> </div>
<div className="grid gap-2"> </div>
<Label htmlFor="document">{t('admin.companies.fields.document')}</Label> </CardHeader>
<Input <CardContent className="pt-8">
id="document" <div className="grid gap-8">
maxLength={18} {/* Seção: Informações Básicas */}
value={formData.document} <div className="grid gap-4">
onChange={(e) => setFormData({ ...formData, document: formatCNPJ(e.target.value) })} <h3 className="text-lg font-semibold border-b pb-2 flex items-center gap-2">
placeholder="CNPJ / Document" <span className="bg-primary w-1 h-5 rounded-full"></span>
/> {t('admin.companies.sections.basicInfo', { defaultValue: 'Informações Básicas' })}
</div> </h3>
<div className="grid gap-2"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<Label htmlFor="email">{t('admin.companies.create.email')}</Label> <div className="grid gap-2">
<Input <Label htmlFor="name">{t('admin.companies.create.name')}</Label>
id="email"
type="email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
placeholder={t('admin.companies.create.emailPlaceholder')}
/>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="grid gap-2">
<Label htmlFor="password">{t('admin.companies.fields.password')}</Label>
<div className="relative">
<Input <Input
id="password" id="name"
type={showPassword ? "text" : "password"} value={formData.name}
value={formData.password} onChange={(e) =>
onChange={(e) => setFormData({ ...formData, password: e.target.value })} setFormData({
placeholder="******" ...formData,
name: e.target.value,
slug: generateSlug(e.target.value),
})
}
placeholder={t('admin.companies.create.namePlaceholder')}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="slug">{t('admin.companies.create.slug')}</Label>
<Input
id="slug"
value={formData.slug}
onChange={(e) => setFormData({ ...formData, slug: e.target.value })}
placeholder={t('admin.companies.create.slugPlaceholder')}
/>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="grid gap-2">
<Label htmlFor="document">{t('admin.companies.fields.document')}</Label>
<Input
id="document"
maxLength={18}
value={formData.document}
onChange={(e) => setFormData({ ...formData, document: formatCNPJ(e.target.value) })}
placeholder="CNPJ / Document"
/>
</div>
<div className="grid gap-2">
<Label htmlFor="email">{t('admin.companies.create.email')}</Label>
<Input
id="email"
type="email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
placeholder={t('admin.companies.create.emailPlaceholder')}
/>
</div>
</div>
</div>
{/* Seção: Segurança */}
<div className="grid gap-4">
<h3 className="text-lg font-semibold border-b pb-2 flex items-center gap-2">
<span className="bg-primary w-1 h-5 rounded-full"></span>
{t('admin.companies.sections.security', { defaultValue: 'Segurança' })}
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="grid gap-2">
<Label htmlFor="password">{t('admin.companies.fields.password')}</Label>
<div className="relative">
<Input
id="password"
type={showPassword ? "text" : "password"}
value={formData.password}
onChange={(e) => setFormData({ ...formData, password: e.target.value })}
placeholder="******"
/>
<Button
type="button"
variant="ghost"
size="sm"
className="absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent"
onClick={() => setShowPassword(!showPassword)}
>
{showPassword ? (
<EyeOff className="h-4 w-4 text-muted-foreground" />
) : (
<Eye className="h-4 w-4 text-muted-foreground" />
)}
</Button>
</div>
</div>
<div className="grid gap-2">
<Label htmlFor="confirmPassword">{t('admin.companies.fields.confirmPassword')}</Label>
<div className="relative">
<Input
id="confirmPassword"
type={showConfirmPassword ? "text" : "password"}
value={formData.confirmPassword}
onChange={(e) => setFormData({ ...formData, confirmPassword: e.target.value })}
placeholder="******"
/>
<Button
type="button"
variant="ghost"
size="sm"
className="absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent"
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
>
{showConfirmPassword ? (
<EyeOff className="h-4 w-4 text-muted-foreground" />
) : (
<Eye className="h-4 w-4 text-muted-foreground" />
)}
</Button>
</div>
{formData.password !== formData.confirmPassword && formData.confirmPassword && (
<p className="text-xs text-red-500">{t('admin.companies.fields.passwordsDoNotMatch')}</p>
)}
</div>
</div>
</div>
{/* Seção: Contato e Localização */}
<div className="grid gap-4">
<h3 className="text-lg font-semibold border-b pb-2 flex items-center gap-2">
<span className="bg-primary w-1 h-5 rounded-full"></span>
{t('admin.companies.sections.contact', { defaultValue: 'Contato e Localização' })}
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="grid gap-2">
<Label htmlFor="phone">{t('admin.companies.fields.phone')}</Label>
<Input
id="phone"
maxLength={15}
value={formData.phone}
onChange={(e) => setFormData({ ...formData, phone: formatPhone(e.target.value) })}
placeholder="(99) 99999-9999"
/>
</div>
<div className="grid gap-2">
<Label htmlFor="website">{t('admin.companies.fields.website')}</Label>
<Input
id="website"
value={formData.website}
onChange={(e) => setFormData({ ...formData, website: e.target.value })}
placeholder="https://example.com"
/> />
<Button
type="button"
variant="ghost"
size="sm"
className="absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent"
onClick={() => setShowPassword(!showPassword)}
>
{showPassword ? (
<EyeOff className="h-4 w-4 text-muted-foreground" />
) : (
<Eye className="h-4 w-4 text-muted-foreground" />
)}
</Button>
</div> </div>
</div> </div>
<div className="grid gap-2"> <div className="grid gap-2">
<Label htmlFor="confirmPassword">{t('admin.companies.fields.confirmPassword')}</Label> <Label htmlFor="address">{t('admin.companies.fields.address')}</Label>
<div className="relative"> <Input
<Input id="address"
id="confirmPassword" value={formData.address}
type={showConfirmPassword ? "text" : "password"} onChange={(e) => setFormData({ ...formData, address: e.target.value })}
value={formData.confirmPassword} placeholder="Endereço completo"
onChange={(e) => setFormData({ ...formData, confirmPassword: e.target.value })} />
placeholder="******"
/>
<Button
type="button"
variant="ghost"
size="sm"
className="absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent"
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
>
{showConfirmPassword ? (
<EyeOff className="h-4 w-4 text-muted-foreground" />
) : (
<Eye className="h-4 w-4 text-muted-foreground" />
)}
</Button>
</div>
{formData.password !== formData.confirmPassword && formData.confirmPassword && (
<p className="text-xs text-red-500">{t('admin.companies.fields.passwordsDoNotMatch')}</p>
)}
</div> </div>
</div> </div>
<div className="grid gap-2">
<Label htmlFor="phone">{t('admin.companies.fields.phone')}</Label> {/* Seção: Detalhes da Empresa */}
<Input <div className="grid gap-4">
id="phone" <h3 className="text-lg font-semibold border-b pb-2 flex items-center gap-2">
maxLength={15} <span className="bg-primary w-1 h-5 rounded-full"></span>
value={formData.phone} {t('admin.companies.sections.details', { defaultValue: 'Detalhes Adicionais' })}
onChange={(e) => setFormData({ ...formData, phone: formatPhone(e.target.value) })} </h3>
placeholder="+55 11 99999-9999" <div className="grid gap-2">
/> <Label htmlFor="description">{t('admin.companies.fields.description')}</Label>
<Textarea
id="description"
value={formData.description}
onChange={(e) => setFormData({ ...formData, description: e.target.value })}
placeholder="Conte um pouco sobre a empresa..."
className="min-h-[120px] resize-none"
/>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="grid gap-2">
<Label htmlFor="logoUrl">Logo URL</Label>
<Input
id="logoUrl"
value={formData.logoUrl}
onChange={(e) => setFormData({ ...formData, logoUrl: e.target.value })}
placeholder="https://example.com/logo.png"
/>
</div>
<div className="grid gap-2">
<Label htmlFor="yearsInMarket">Anos no mercado</Label>
<Input
id="yearsInMarket"
type="number"
value={formData.yearsInMarket}
onChange={(e) => setFormData({ ...formData, yearsInMarket: e.target.value })}
placeholder="Ex: 10"
/>
</div>
</div>
</div> </div>
<div className="grid gap-2">
<Label htmlFor="website">{t('admin.companies.fields.website')}</Label> <div className="flex justify-end gap-4 pt-6 mt-4 border-t">
<Input
id="website"
value={formData.website}
onChange={(e) => setFormData({ ...formData, website: e.target.value })}
placeholder="https://..."
/>
</div>
<div className="grid gap-2">
<Label htmlFor="address">{t('admin.companies.fields.address')}</Label>
<Input
id="address"
value={formData.address}
onChange={(e) => setFormData({ ...formData, address: e.target.value })}
placeholder="Address..."
/>
</div>
<div className="grid gap-2">
<Label htmlFor="description">{t('admin.companies.fields.description')}</Label>
<Textarea
id="description"
value={formData.description}
onChange={(e) => setFormData({ ...formData, description: e.target.value })}
placeholder="Company description..."
className="min-h-[120px]"
/>
</div>
<div className="grid gap-2">
<Label htmlFor="logoUrl">Logo URL</Label>
<Input
id="logoUrl"
value={formData.logoUrl}
onChange={(e) => setFormData({ ...formData, logoUrl: e.target.value })}
placeholder="https://example.com/logo.png"
/>
</div>
<div className="grid gap-2">
<Label htmlFor="yearsInMarket">Anos no mercado</Label>
<Input
id="yearsInMarket"
value={formData.yearsInMarket}
onChange={(e) => setFormData({ ...formData, yearsInMarket: e.target.value })}
placeholder="Ex: 10"
/>
</div>
<div className="flex justify-end gap-4 pt-4 border-t">
<Button variant="outline" asChild> <Button variant="outline" asChild>
<Link href="/dashboard/companies"> <Link href="/dashboard/companies">
{t('admin.companies.create.cancel')} {t('admin.companies.create.cancel')}
</Link> </Link>
</Button> </Button>
<Button onClick={handleCreate} disabled={creating}> <Button onClick={handleCreate} disabled={creating} className="min-w-[140px]">
{creating && <Loader2 className="h-4 w-4 mr-2 animate-spin" />} {creating ? (
<Loader2 className="h-4 w-4 mr-2 animate-spin" />
) : (
<Building2 className="h-4 w-4 mr-2" />
)}
{t('admin.companies.create.submit')} {t('admin.companies.create.submit')}
</Button> </Button>
</div> </div>