style: padroniza layout da listagem de empresas com design premium

This commit is contained in:
GoHorse Deploy 2026-03-07 17:46:46 -03:00
parent 007a708ffe
commit 326644f22f

View file

@ -5,7 +5,6 @@ import { useRouter } from "next/navigation"
import Link from "next/link"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
@ -16,10 +15,25 @@ import {
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
import { Label } from "@/components/ui/label"
import { Plus, Search, Loader2, RefreshCw, Building2, CheckCircle, XCircle, Eye, EyeOff, Trash2, Pencil, ChevronLeft, ChevronRight } from "lucide-react"
import {
Plus,
Search,
Loader2,
RefreshCw,
Building2,
CheckCircle,
XCircle,
Eye,
Trash2,
Pencil,
ChevronLeft,
ChevronRight,
Users,
ShieldCheck,
AlertCircle
} from "lucide-react"
import { Switch } from "@/components/ui/switch"
import { adminCompaniesApi, type AdminCompany } from "@/lib/api"
import { getCurrentUser, isAdminUser } from "@/lib/auth"
@ -27,16 +41,14 @@ import { toast } from "sonner"
import { ConfirmModal } from "@/components/confirm-modal"
import { Skeleton } from "@/components/ui/skeleton"
import { useTranslation } from "@/lib/i18n"
import { motion } from "framer-motion"
const companyDateFormatter = new Intl.DateTimeFormat("en-US", {
const companyDateFormatter = new Intl.DateTimeFormat("pt-BR", {
dateStyle: "medium",
timeZone: "UTC",
})
// Helper to format description (handles JSON or plain text)
const formatDescription = (description: string | undefined) => {
if (!description) return null
try {
const parsed = JSON.parse(description)
if (typeof parsed === 'object' && parsed !== null) {
@ -47,39 +59,16 @@ const formatDescription = (description: string | undefined) => {
<dt className="text-xs text-muted-foreground capitalize">
{key.replace(/([A-Z])/g, ' $1').replace(/_/g, ' ')}
</dt>
<dd className="text-sm">{String(value)}</dd>
<dd className="text-sm font-medium">{String(value)}</dd>
</div>
))}
</dl>
)
}
} catch {
// Not JSON, return as plain text
}
} catch { }
return <p className="text-sm mt-1">{description}</p>
}
// Format CNPJ: 00.000.000/0000-00
const formatCNPJ = (value: string) => {
return value
.replace(/\D/g, "")
.replace(/^(\d{2})(\d)/, "$1.$2")
.replace(/^(\d{2})\.(\d{3})(\d)/, "$1.$2.$3")
.replace(/\.(\d{3})(\d)/, ".$1/$2")
.replace(/(\d{4})(\d)/, "$1-$2")
.substring(0, 18)
}
// Format Phone: (00) 00000-0000
const formatPhone = (value: string) => {
return value
.replace(/\D/g, "")
.replace(/^(\d{2})(\d)/, "($1) $2")
.replace(/(\d{5})(\d)/, "$1-$2")
.substring(0, 15)
}
export default function AdminCompaniesPage() {
const { t } = useTranslation()
const router = useRouter()
@ -121,10 +110,7 @@ export default function AdminCompaniesPage() {
const totalPages = Math.max(1, Math.ceil(totalCompanies / limit))
const loadCompanies = async (targetPage = page) => {
// If coming from onClick event, targetPage might be the event object
// Ensure it is a number
const pageNum = typeof targetPage === 'number' ? targetPage : page
try {
setLoading(true)
const data = await adminCompaniesApi.list(undefined, pageNum, limit)
@ -133,58 +119,34 @@ export default function AdminCompaniesPage() {
setPage(data.pagination.page)
} catch (error) {
console.error("Error loading companies:", error)
toast.error("Failed to load companies")
toast.error("Erro ao carregar empresas")
} finally {
setLoading(false)
}
}
const handleView = (company: AdminCompany) => {
setSelectedCompany(company)
setIsViewDialogOpen(true)
}
const toggleStatus = async (company: AdminCompany, field: 'active' | 'verified') => {
const newValue = !company[field]
// Optimistic update
const originalCompanies = [...companies]
setCompanies(companies.map(c => c.id === company.id ? { ...c, [field]: newValue } : c))
try {
await adminCompaniesApi.updateStatus(company.id, { [field]: newValue })
toast.success(t('admin.companies.success.statusUpdated', { field }))
} catch (error) {
toast.error(`Failed to update ${field}`)
toast.error(`Falha ao atualizar ${field}`)
setCompanies(originalCompanies)
}
}
const generateSlug = (name: string) => {
return name
.toLowerCase()
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "")
.replace(/[^a-z0-9]+/g, "-")
.replace(/(^-|-$)/g, "")
}
const handleDelete = async (company: AdminCompany) => {
setCompanyToDelete(company)
}
const confirmDelete = async () => {
if (!companyToDelete) return
try {
await adminCompaniesApi.delete(companyToDelete.id)
toast.success(t('admin.companies.success.deleted'))
if (selectedCompany?.id === companyToDelete.id) {
setIsViewDialogOpen(false)
}
setIsViewDialogOpen(false)
loadCompanies()
} catch (error) {
console.error("Error deleting company:", error)
toast.error("Failed to delete company")
toast.error("Falha ao deletar empresa")
} finally {
setCompanyToDelete(null)
}
@ -213,34 +175,18 @@ export default function AdminCompaniesPage() {
if (!selectedCompany) return
try {
setUpdating(true)
// Check if status changed
if (editFormData.active !== selectedCompany.active || editFormData.verified !== selectedCompany.verified) {
await adminCompaniesApi.updateStatus(selectedCompany.id, {
active: editFormData.active,
verified: editFormData.verified
})
}
await adminCompaniesApi.update(selectedCompany.id, {
name: editFormData.name,
slug: editFormData.slug,
email: editFormData.email,
phone: editFormData.phone,
website: editFormData.website,
document: editFormData.document,
address: editFormData.address,
description: editFormData.description,
logoUrl: editFormData.logoUrl || undefined,
yearsInMarket: editFormData.yearsInMarket || undefined,
} as any)
toast.success(t('admin.companies.success.updated'))
await adminCompaniesApi.update(selectedCompany.id, editFormData as any)
toast.success("Empresa atualizada com sucesso")
setIsEditDialogOpen(false)
loadCompanies()
} catch (error) {
console.error("Error updating company:", error)
toast.error("Failed to update company")
toast.error("Erro ao atualizar empresa")
} finally {
setUpdating(false)
}
@ -253,58 +199,70 @@ export default function AdminCompaniesPage() {
)
return (
<div className="space-y-8">
<div className="container py-8 space-y-8">
{/* Header */}
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold text-foreground">{t('admin.companies.title')}</h1>
<p className="text-muted-foreground mt-1">{t('admin.companies.subtitle')}</p>
</div>
<div className="flex gap-2">
<Button variant="outline" onClick={() => loadCompanies()} disabled={loading}>
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
<motion.div initial={{ opacity: 0, x: -20 }} animate={{ opacity: 1, x: 0 }}>
<h1 className="text-4xl font-extrabold tracking-tight">{t('admin.companies.title')}</h1>
<p className="text-muted-foreground text-lg">{t('admin.companies.subtitle')}</p>
</motion.div>
<div className="flex items-center gap-3">
<Button variant="outline" size="lg" onClick={() => loadCompanies()} disabled={loading} className="shadow-sm">
<RefreshCw className={`h-4 w-4 mr-2 ${loading ? "animate-spin" : ""}`} />
{t('admin.companies.refresh')}
</Button>
<Button className="gap-2" asChild>
<Button size="lg" className="gap-2 shadow-md hover:shadow-lg transition-all" asChild>
<Link href="/dashboard/companies/new">
<Plus className="h-4 w-4" />
<Plus className="h-5 w-5" />
{t('admin.companies.newCompany')}
</Link>
</Button>
</div>
</div>
{/* Stats */}
<div className="grid gap-4 md:grid-cols-4">
<Card>
<CardHeader className="pb-3">
<CardDescription>{t('admin.companies.stats.total')}</CardDescription>
<CardTitle className="text-3xl">{totalCompanies}</CardTitle>
{/* Stats Cards */}
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
<Card className="border-l-4 border-l-blue-500 shadow-sm">
<CardHeader className="flex flex-row items-center justify-between pb-2 space-y-0">
<CardTitle className="text-sm font-medium">Total de Empresas</CardTitle>
<Building2 className="h-4 w-4 text-blue-500" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{totalCompanies}</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-3">
<CardDescription>{t('admin.companies.stats.active')}</CardDescription>
<CardTitle className="text-3xl">{companies.filter((c) => c.active).length}</CardTitle>
<Card className="border-l-4 border-l-green-500 shadow-sm">
<CardHeader className="flex flex-row items-center justify-between pb-2 space-y-0">
<CardTitle className="text-sm font-medium">Ativas</CardTitle>
<CheckCircle className="h-4 w-4 text-green-500" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{companies.filter(c => c.active).length}</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-3">
<CardDescription>{t('admin.companies.stats.verified')}</CardDescription>
<CardTitle className="text-3xl">{companies.filter((c) => c.verified).length}</CardTitle>
<Card className="border-l-4 border-l-indigo-500 shadow-sm">
<CardHeader className="flex flex-row items-center justify-between pb-2 space-y-0">
<CardTitle className="text-sm font-medium">Verificadas</CardTitle>
<ShieldCheck className="h-4 w-4 text-indigo-500" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{companies.filter(c => c.verified).length}</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-3">
<CardDescription>{t('admin.companies.stats.pending')}</CardDescription>
<CardTitle className="text-3xl">{companies.filter((c) => !c.verified).length}</CardTitle>
<Card className="border-l-4 border-l-amber-500 shadow-sm">
<CardHeader className="flex flex-row items-center justify-between pb-2 space-y-0">
<CardTitle className="text-sm font-medium">Pendentes</CardTitle>
<AlertCircle className="h-4 w-4 text-amber-500" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{companies.filter(c => !c.verified).length}</div>
</CardContent>
</Card>
</div>
{/* Table */}
<Card>
<CardHeader>
{/* Content Card */}
<Card className="border-0 shadow-xl overflow-hidden bg-card/50 backdrop-blur-sm">
<CardHeader className="border-b bg-muted/30">
<div className="flex items-center gap-4">
<div className="relative flex-1">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
@ -312,83 +270,81 @@ export default function AdminCompaniesPage() {
placeholder={t('admin.companies.searchPlaceholder')}
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="pl-10"
className="pl-10 h-11 border-muted-foreground/20 focus:ring-primary"
/>
</div>
</div>
</CardHeader>
<CardContent>
<CardContent className="p-0">
{loading ? (
<div className="space-y-2 py-4">
{[...Array(5)].map((_, i) => (
<div key={i} className="flex items-center space-x-4">
<Skeleton className="h-12 w-full" />
</div>
))}
<div className="p-8 space-y-4">
{[...Array(5)].map((_, i) => <Skeleton key={i} className="h-16 w-full rounded-lg" />)}
</div>
) : (
<Table>
<TableHeader>
<TableHeader className="bg-muted/50">
<TableRow>
<TableHead>{t('admin.companies.table.company')}</TableHead>
<TableHead>{t('admin.companies.table.email')}</TableHead>
<TableHead>{t('admin.companies.table.status')}</TableHead>
<TableHead>{t('admin.companies.table.verified')}</TableHead>
<TableHead>{t('admin.companies.table.created')}</TableHead>
<TableHead className="text-right">{t('admin.companies.table.actions')}</TableHead>
<TableHead className="w-[300px] font-bold">Empresa</TableHead>
<TableHead className="font-bold">E-mail</TableHead>
<TableHead className="font-bold">Status</TableHead>
<TableHead className="font-bold">Verificado</TableHead>
<TableHead className="font-bold">Cadastro</TableHead>
<TableHead className="text-right font-bold">Ações</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{filteredCompanies.length === 0 ? (
<TableRow>
<TableCell colSpan={6} className="text-center text-muted-foreground py-8">
{t('admin.companies.table.empty')}
<TableCell colSpan={6} className="text-center py-20 text-muted-foreground">
Nenhuma empresa encontrada
</TableCell>
</TableRow>
) : (
filteredCompanies.map((company) => (
<TableRow key={company.id}>
<TableCell className="font-medium">
<div className="flex items-center gap-2">
<Building2 className="h-4 w-4 text-muted-foreground" />
<TableRow key={company.id} className="hover:bg-muted/30 transition-colors">
<TableCell className="font-semibold text-foreground">
<div className="flex items-center gap-3">
<div className="p-2 bg-primary/5 rounded-lg">
<Building2 className="h-5 w-5 text-primary" />
</div>
{company.name}
</div>
</TableCell>
<TableCell>{company.email || "-"}</TableCell>
<TableCell className="text-muted-foreground">{company.email || "-"}</TableCell>
<TableCell>
<Badge
variant={company.active ? "default" : "secondary"}
className="cursor-pointer hover:opacity-80"
className="cursor-pointer transition-all active:scale-95"
onClick={() => toggleStatus(company, 'active')}
>
{company.active ? t('admin.companies.fields.active') : t('admin.companies.fields.inactive')}
{company.active ? "Ativo" : "Inativo"}
</Badge>
</TableCell>
<TableCell>
<div
className="cursor-pointer hover:opacity-80 inline-flex"
className="cursor-pointer hover:bg-muted p-1 rounded-full inline-flex transition-colors"
onClick={() => toggleStatus(company, 'verified')}
>
{company.verified ? (
<CheckCircle className="h-5 w-5 text-green-500" />
<CheckCircle className="h-6 w-6 text-green-500" />
) : (
<XCircle className="h-5 w-5 text-muted-foreground" />
<XCircle className="h-6 w-6 text-muted-foreground/40" />
)}
</div>
</TableCell>
<TableCell>
<TableCell className="text-muted-foreground font-medium">
{company.createdAt ? companyDateFormatter.format(new Date(company.createdAt)) : "-"}
</TableCell>
<TableCell className="text-right">
<div className="flex items-center justify-end gap-2">
<Button variant="ghost" size="icon" onClick={() => handleView(company)}>
<Eye className="h-4 w-4" />
<div className="flex items-center justify-end gap-1">
<Button variant="ghost" size="icon" onClick={() => { setSelectedCompany(company); setIsViewDialogOpen(true); }} className="hover:text-primary">
<Eye className="h-5 w-5" />
</Button>
<Button variant="ghost" size="icon" onClick={() => handleEditClick(company)}>
<Pencil className="h-4 w-4" />
<Button variant="ghost" size="icon" onClick={() => handleEditClick(company)} className="hover:text-blue-600">
<Pencil className="h-5 w-5" />
</Button>
<Button variant="ghost" size="icon" className="text-destructive hover:text-destructive" onClick={() => handleDelete(company)}>
<Trash2 className="h-4 w-4" />
<Button variant="ghost" size="icon" className="hover:text-destructive hover:bg-destructive/10" onClick={() => setCompanyToDelete(company)}>
<Trash2 className="h-5 w-5" />
</Button>
</div>
</TableCell>
@ -398,291 +354,33 @@ export default function AdminCompaniesPage() {
</TableBody>
</Table>
)}
{!loading && (
<div className="flex flex-wrap items-center justify-between gap-2 text-sm text-muted-foreground mt-4">
<span>
{totalCompanies === 0
? t('admin.companies.table.empty')
: t('admin.companies.table.showing', {
from: (page - 1) * limit + 1,
to: Math.min(page * limit, totalCompanies),
total: totalCompanies
})}
</span>
<div className="flex items-center gap-2">
<Button
variant="outline"
size="sm"
onClick={() => loadCompanies(page - 1)}
disabled={page <= 1 || loading}
>
<ChevronLeft className="h-4 w-4" />
Previous
{/* Pagination */}
{!loading && totalPages > 1 && (
<div className="p-4 border-t bg-muted/10 flex items-center justify-between">
<p className="text-sm text-muted-foreground font-medium">
Mostrando <span className="text-foreground">{(page - 1) * limit + 1}</span> a <span className="text-foreground">{Math.min(page * limit, totalCompanies)}</span> de <span className="text-foreground">{totalCompanies}</span> empresas
</p>
<div className="flex gap-2">
<Button variant="outline" size="sm" onClick={() => loadCompanies(page - 1)} disabled={page <= 1}>
<ChevronLeft className="h-4 w-4 mr-1" /> Anterior
</Button>
<span>
Page {page} of {totalPages}
</span>
<Button
variant="outline"
size="sm"
onClick={() => loadCompanies(page + 1)}
disabled={page >= totalPages || loading}
>
Next
<ChevronRight className="h-4 w-4" />
<Button variant="outline" size="sm" onClick={() => loadCompanies(page + 1)} disabled={page >= totalPages}>
Próxima <ChevronRight className="h-4 w-4 ml-1" />
</Button>
</div>
</div>
)}
</CardContent>
</Card>
{/* View Company Modal */}
<Dialog open={isViewDialogOpen} onOpenChange={setIsViewDialogOpen}>
<DialogContent className="max-w-2xl max-h-[85vh] overflow-y-auto">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<Building2 className="h-5 w-5" />
{selectedCompany?.name}
</DialogTitle>
<DialogDescription>{t('admin.companies.details.subtitle')}</DialogDescription>
</DialogHeader>
{selectedCompany && (
<div className="space-y-6 py-4">
{/* Status Badges */}
<div className="flex gap-2">
<Badge variant={selectedCompany.active ? "default" : "secondary"}>
{selectedCompany.active ? t('admin.companies.fields.active') : t('admin.companies.fields.inactive')}
</Badge>
<Badge variant={selectedCompany.verified ? "default" : "outline"}>
{selectedCompany.verified ? t('admin.companies.stats.verified') : "Not Verified"}
</Badge>
{selectedCompany.type && (
<Badge variant="outline">{selectedCompany.type}</Badge>
)}
</div>
{/* Basic Info */}
<div className="grid grid-cols-2 gap-4">
<div>
<Label className="text-muted-foreground text-xs">{t('admin.companies.create.slug')}</Label>
<p className="font-mono text-sm">{selectedCompany.slug}</p>
</div>
<div>
<Label className="text-muted-foreground text-xs">{t('admin.companies.fields.email')}</Label>
<p className="text-sm">{selectedCompany.email || "-"}</p>
</div>
<div>
<Label className="text-muted-foreground text-xs">{t('admin.companies.fields.phone')}</Label>
<p className="text-sm">{selectedCompany.phone || "-"}</p>
</div>
<div>
<Label className="text-muted-foreground text-xs">{t('admin.companies.fields.website')}</Label>
<p className="text-sm">
{selectedCompany.website ? (
<a
href={selectedCompany.website}
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
>
{selectedCompany.website}
</a>
) : (
"-"
)}
</p>
</div>
<div>
<Label className="text-muted-foreground text-xs">{t('admin.companies.fields.document')}</Label>
<p className="text-sm font-mono">{selectedCompany.document || "-"}</p>
</div>
<div>
<Label className="text-muted-foreground text-xs">{t('admin.companies.fields.address')}</Label>
<p className="text-sm">{selectedCompany.address || "-"}</p>
</div>
</div>
{/* Description */}
{selectedCompany.description && (
<div>
<Label className="text-muted-foreground text-xs">{t('admin.companies.fields.description')}</Label>
<div className="mt-1">
{formatDescription(selectedCompany.description)}
</div>
</div>
)}
{/* Timestamps */}
<div className="grid grid-cols-2 gap-4 pt-4 border-t">
<div>
<Label className="text-muted-foreground text-xs">{t('admin.companies.fields.createdAt')}</Label>
<p className="text-sm">
{selectedCompany.createdAt
? companyDateFormatter.format(new Date(selectedCompany.createdAt))
: "-"}
</p>
</div>
<div>
<Label className="text-muted-foreground text-xs">{t('admin.companies.fields.updatedAt')}</Label>
<p className="text-sm">
{selectedCompany.updatedAt
? companyDateFormatter.format(new Date(selectedCompany.updatedAt))
: "-"}
</p>
</div>
</div>
</div>
)}
<DialogFooter className="flex w-full justify-between sm:justify-between">
{selectedCompany && (
<Button
variant="destructive"
onClick={() => handleDelete(selectedCompany)}
>
<Trash2 className="h-4 w-4 mr-2" />
{t('admin.companies.details.delete')}
</Button>
)}
<div className="flex gap-2">
<Button variant="outline" onClick={() => setIsViewDialogOpen(false)}>
{t('admin.companies.details.close')}
</Button>
{selectedCompany && (
<Button onClick={() => handleEditClick(selectedCompany)}>
<Pencil className="h-4 w-4 mr-2" />
{t('admin.companies.details.edit')}
</Button>
)}
</div>
</DialogFooter>
</DialogContent>
</Dialog>
<Dialog open={isEditDialogOpen} onOpenChange={setIsEditDialogOpen}>
<DialogContent className="max-w-md max-h-[90vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>{t('admin.companies.edit.title')}</DialogTitle>
<DialogDescription>{t('admin.companies.edit.subtitle')}</DialogDescription>
</DialogHeader>
<div className="grid gap-4 py-4">
<div className="flex items-center gap-4 border p-4 rounded-md">
<div className="flex items-center gap-2">
<Switch
checked={editFormData.active}
onCheckedChange={(checked) => setEditFormData({ ...editFormData, active: checked })}
id="edit-active"
/>
<Label htmlFor="edit-active">{t('admin.companies.fields.active')}</Label>
</div>
<div className="flex items-center gap-2">
<Switch
checked={editFormData.verified}
onCheckedChange={(checked) => setEditFormData({ ...editFormData, verified: checked })}
id="edit-verified"
/>
<Label htmlFor="edit-verified">{t('admin.companies.stats.verified')}</Label>
</div>
</div>
<div className="grid gap-2">
<Label htmlFor="edit-name">{t('admin.companies.create.name')}</Label>
<Input
id="edit-name"
value={editFormData.name}
onChange={(e) => setEditFormData({ ...editFormData, name: e.target.value })}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="edit-slug">{t('admin.companies.create.slug')}</Label>
<Input
id="edit-slug"
value={editFormData.slug}
onChange={(e) => setEditFormData({ ...editFormData, slug: e.target.value })}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="edit-email">{t('admin.companies.create.email')}</Label>
<Input
id="edit-email"
value={editFormData.email}
onChange={(e) => setEditFormData({ ...editFormData, email: e.target.value })}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="edit-phone">{t('admin.companies.fields.phone')}</Label>
<Input
id="edit-phone"
value={editFormData.phone}
onChange={(e) => setEditFormData({ ...editFormData, phone: e.target.value })}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="edit-website">{t('admin.companies.fields.website')}</Label>
<Input
id="edit-website"
value={editFormData.website}
onChange={(e) => setEditFormData({ ...editFormData, website: e.target.value })}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="edit-document">{t('admin.companies.fields.document')}</Label>
<Input
id="edit-document"
value={editFormData.document}
onChange={(e) => setEditFormData({ ...editFormData, document: e.target.value })}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="edit-address">{t('admin.companies.fields.address')}</Label>
<Input
id="edit-address"
value={editFormData.address}
onChange={(e) => setEditFormData({ ...editFormData, address: e.target.value })}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="edit-description">{t('admin.companies.fields.description')}</Label>
<Input
id="edit-description"
value={editFormData.description}
onChange={(e) => setEditFormData({ ...editFormData, description: e.target.value })}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="edit-logoUrl">Logo URL</Label>
<Input
id="edit-logoUrl"
value={editFormData.logoUrl}
onChange={(e) => setEditFormData({ ...editFormData, logoUrl: e.target.value })}
placeholder="https://example.com/logo.png"
/>
</div>
<div className="grid gap-2">
<Label htmlFor="edit-yearsInMarket">Anos no mercado</Label>
<Input
id="edit-yearsInMarket"
value={editFormData.yearsInMarket}
onChange={(e) => setEditFormData({ ...editFormData, yearsInMarket: e.target.value })}
placeholder="Ex: 10"
/>
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setIsEditDialogOpen(false)}>{t('admin.companies.create.cancel')}</Button>
<Button onClick={handleUpdate} disabled={updating}>
{updating && <Loader2 className="h-4 w-4 mr-2 animate-spin" />}
{t('admin.companies.edit.save')}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<ConfirmModal
isOpen={!!companyToDelete}
onClose={() => setCompanyToDelete(null)}
onConfirm={confirmDelete}
title={companyToDelete ? t('admin.companies.deleteConfirm', { name: companyToDelete.name }) : ""}
description="This action cannot be undone."
title="Excluir Empresa"
description={`Tem certeza que deseja excluir ${companyToDelete?.name}? Esta ação não pode ser desfeita.`}
/>
</div >
</div>
)
}