refactor: move company creation to separate page and improve users table
This commit is contained in:
parent
e157910dd4
commit
2d10101394
3 changed files with 286 additions and 238 deletions
275
frontend/src/app/dashboard/companies/new/page.tsx
Normal file
275
frontend/src/app/dashboard/companies/new/page.tsx
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Textarea } from "@/components/ui/textarea"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import { Loader2, Eye, EyeOff, ArrowLeft } from "lucide-react"
|
||||
import { adminCompaniesApi } from "@/lib/api"
|
||||
import { toast } from "sonner"
|
||||
import { useTranslation } from "@/lib/i18n"
|
||||
import { Card, CardContent } from "@/components/ui/card"
|
||||
import Link from "next/link"
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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 NewCompanyPage() {
|
||||
const { t } = useTranslation()
|
||||
const router = useRouter()
|
||||
const [creating, setCreating] = useState(false)
|
||||
const [showPassword, setShowPassword] = useState(false)
|
||||
const [showConfirmPassword, setShowConfirmPassword] = useState(false)
|
||||
const [formData, setFormData] = useState({
|
||||
name: "",
|
||||
slug: "",
|
||||
email: "",
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
document: "",
|
||||
phone: "",
|
||||
website: "",
|
||||
address: "",
|
||||
description: "",
|
||||
logoUrl: "",
|
||||
yearsInMarket: "",
|
||||
})
|
||||
|
||||
const generateSlug = (name: string) => {
|
||||
return name
|
||||
.toLowerCase()
|
||||
.normalize("NFD")
|
||||
.replace(/[\u0300-\u036f]/g, "")
|
||||
.replace(/[^a-z0-9]+/g, "-")
|
||||
.replace(/(^-|-$)/g, "")
|
||||
}
|
||||
|
||||
const handleCreate = async () => {
|
||||
try {
|
||||
setCreating(true)
|
||||
const payload = {
|
||||
...formData,
|
||||
document: formData.document.replace(/\D/g, ''),
|
||||
phone: formData.phone.replace(/\D/g, ''),
|
||||
}
|
||||
await adminCompaniesApi.create(payload)
|
||||
toast.success(t('admin.companies.success.created'))
|
||||
router.push("/dashboard/companies")
|
||||
} catch (error: any) {
|
||||
console.error("Error creating company:", error)
|
||||
if (error.message?.includes("already exists")) {
|
||||
toast.error(t('admin.companies.error.emailExists', { defaultValue: "User with this email already exists" }))
|
||||
} else {
|
||||
toast.error("Failed to create company")
|
||||
}
|
||||
} finally {
|
||||
setCreating(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-8 max-w-3xl mx-auto">
|
||||
<div className="flex items-center gap-4">
|
||||
<Button variant="ghost" size="icon" asChild>
|
||||
<Link href="/dashboard/companies">
|
||||
<ArrowLeft className="h-5 w-5" />
|
||||
</Link>
|
||||
</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>
|
||||
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<div className="grid gap-6">
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="name">{t('admin.companies.create.name')}</Label>
|
||||
<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 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 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 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 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="+55 11 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://..."
|
||||
/>
|
||||
</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>
|
||||
<Link href="/dashboard/companies">
|
||||
{t('admin.companies.create.cancel')}
|
||||
</Link>
|
||||
</Button>
|
||||
<Button onClick={handleCreate} disabled={creating}>
|
||||
{creating && <Loader2 className="h-4 w-4 mr-2 animate-spin" />}
|
||||
{t('admin.companies.create.submit')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import { useEffect, useState } from "react"
|
||||
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"
|
||||
|
|
@ -87,29 +88,11 @@ export default function AdminCompaniesPage() {
|
|||
const [searchTerm, setSearchTerm] = useState("")
|
||||
const [page, setPage] = useState(1)
|
||||
const [totalCompanies, setTotalCompanies] = useState(0)
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false)
|
||||
const [isViewDialogOpen, setIsViewDialogOpen] = useState(false)
|
||||
const [selectedCompany, setSelectedCompany] = useState<AdminCompany | null>(null)
|
||||
const [companyToDelete, setCompanyToDelete] = useState<AdminCompany | null>(null)
|
||||
const [creating, setCreating] = useState(false)
|
||||
const [updating, setUpdating] = useState(false)
|
||||
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false)
|
||||
const [showPassword, setShowPassword] = useState(false)
|
||||
const [showConfirmPassword, setShowConfirmPassword] = useState(false)
|
||||
const [formData, setFormData] = useState({
|
||||
name: "",
|
||||
slug: "",
|
||||
email: "",
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
document: "",
|
||||
phone: "",
|
||||
website: "",
|
||||
address: "",
|
||||
description: "",
|
||||
logoUrl: "",
|
||||
yearsInMarket: "",
|
||||
})
|
||||
const [editFormData, setEditFormData] = useState({
|
||||
name: "",
|
||||
slug: "",
|
||||
|
|
@ -156,45 +139,6 @@ export default function AdminCompaniesPage() {
|
|||
}
|
||||
}
|
||||
|
||||
const handleCreate = async () => {
|
||||
try {
|
||||
setCreating(true)
|
||||
// Strip non-digits for payload
|
||||
const payload = {
|
||||
...formData,
|
||||
document: formData.document.replace(/\D/g, ''),
|
||||
phone: formData.phone.replace(/\D/g, ''),
|
||||
}
|
||||
await adminCompaniesApi.create(payload)
|
||||
toast.success(t('admin.companies.success.created'))
|
||||
setIsDialogOpen(false)
|
||||
setFormData({
|
||||
name: "",
|
||||
slug: "",
|
||||
email: "",
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
document: "",
|
||||
phone: "",
|
||||
website: "",
|
||||
address: "",
|
||||
description: "",
|
||||
logoUrl: "",
|
||||
yearsInMarket: "",
|
||||
})
|
||||
loadCompanies(1) // Reload first page
|
||||
} catch (error: any) {
|
||||
console.error("Error creating company:", error)
|
||||
if (error.message?.includes("already exists")) {
|
||||
toast.error(t('admin.companies.error.emailExists', { defaultValue: "User with this email already exists" }))
|
||||
} else {
|
||||
toast.error("Failed to create company")
|
||||
}
|
||||
} finally {
|
||||
setCreating(false)
|
||||
}
|
||||
}
|
||||
|
||||
const handleView = (company: AdminCompany) => {
|
||||
setSelectedCompany(company)
|
||||
setIsViewDialogOpen(true)
|
||||
|
|
@ -321,181 +265,12 @@ export default function AdminCompaniesPage() {
|
|||
<RefreshCw className={`h-4 w-4 mr-2 ${loading ? "animate-spin" : ""}`} />
|
||||
{t('admin.companies.refresh')}
|
||||
</Button>
|
||||
<Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
|
||||
<DialogTrigger asChild>
|
||||
<Button className="gap-2">
|
||||
<Button className="gap-2" asChild>
|
||||
<Link href="/dashboard/companies/new">
|
||||
<Plus className="h-4 w-4" />
|
||||
{t('admin.companies.newCompany')}
|
||||
</Link>
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('admin.companies.create.title')}</DialogTitle>
|
||||
<DialogDescription>{t('admin.companies.create.subtitle')}</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="grid gap-4 py-4">
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="name">{t('admin.companies.create.name')}</Label>
|
||||
<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 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 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 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 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="+55 11 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://..."
|
||||
/>
|
||||
</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..."
|
||||
/>
|
||||
</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>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => setIsDialogOpen(false)}>{t('admin.companies.create.cancel')}</Button>
|
||||
<Button onClick={handleCreate} disabled={creating}>
|
||||
{creating && <Loader2 className="h-4 w-4 mr-2 animate-spin" />}
|
||||
{t('admin.companies.create.submit')}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -564,17 +564,16 @@ export default function AdminUsersPage() {
|
|||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>{t('admin.users.table.name')}</TableHead>
|
||||
<TableHead className="hidden sm:table-cell">{t('admin.users.table.email')}</TableHead>
|
||||
<TableHead>{t('admin.users.table.role')}</TableHead>
|
||||
<TableHead className="hidden md:table-cell">{t('admin.users.table.status')}</TableHead>
|
||||
<TableHead className="hidden lg:table-cell">{t('admin.users.table.created')}</TableHead>
|
||||
<TableHead className="hidden sm:table-cell">{t('admin.users.table.created')}</TableHead>
|
||||
<TableHead className="text-right">{t('admin.users.table.actions')}</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{filteredUsers.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={6} className="text-center text-muted-foreground py-8">
|
||||
<TableCell colSpan={5} className="text-center text-muted-foreground py-8">
|
||||
{t('admin.users.table.no_users')}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
|
@ -582,7 +581,6 @@ export default function AdminUsersPage() {
|
|||
filteredUsers.map((user) => (
|
||||
<TableRow key={user.id}>
|
||||
<TableCell className="font-medium">{user.name}</TableCell>
|
||||
<TableCell className="hidden sm:table-cell">{user.email}</TableCell>
|
||||
<TableCell>{getRoleBadge(user.role)}</TableCell>
|
||||
<TableCell className="hidden md:table-cell">
|
||||
<Badge
|
||||
|
|
@ -596,8 +594,8 @@ export default function AdminUsersPage() {
|
|||
{user.status ? user.status.toUpperCase() : "UNKNOWN"}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell className="hidden lg:table-cell">
|
||||
{user.created_at ? userDateFormatter.format(new Date(user.created_at)) : "-"}
|
||||
<TableCell className="hidden sm:table-cell">
|
||||
{user.created_at || (user as any).createdAt ? userDateFormatter.format(new Date(user.created_at || (user as any).createdAt)) : "-"}
|
||||
</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<div className="flex justify-end gap-2">
|
||||
|
|
|
|||
Loading…
Reference in a new issue