Improve the frontend
This commit is contained in:
@@ -283,7 +283,7 @@ const TeamPage: React.FC = () => {
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="p-6 space-y-6">
|
||||
<div className="space-y-6">
|
||||
<PageHeader
|
||||
title="Gestión de Equipo"
|
||||
description="Administra los miembros del equipo, roles y permisos"
|
||||
@@ -300,7 +300,7 @@ const TeamPage: React.FC = () => {
|
||||
|
||||
|
||||
return (
|
||||
<div className="p-6 space-y-6">
|
||||
<div className="space-y-6">
|
||||
<PageHeader
|
||||
title={t('settings:team.title', 'Gestión de Equipo')}
|
||||
description={t('settings:team.description', 'Administra los miembros del equipo, roles y permisos')}
|
||||
@@ -368,48 +368,46 @@ const TeamPage: React.FC = () => {
|
||||
] as FilterConfig[]}
|
||||
/>
|
||||
|
||||
{/* Add Member Button */}
|
||||
{canManageTeam && filteredMembers.length > 0 && (
|
||||
<div className="flex justify-end">
|
||||
<Button
|
||||
onClick={() => setShowAddForm(true)}
|
||||
variant="primary"
|
||||
size="md"
|
||||
className="font-medium px-4 py-2 shadow-sm hover:shadow-md transition-all duration-200"
|
||||
>
|
||||
<Plus className="w-4 h-4 mr-2 flex-shrink-0" />
|
||||
<span>Agregar Miembro</span>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Team Members List - Responsive grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-4 lg:gap-6">
|
||||
{filteredMembers.map((member) => (
|
||||
<StatusCard
|
||||
key={member.id}
|
||||
id={`team-member-${member.id}`}
|
||||
statusIndicator={getMemberStatusConfig(member)}
|
||||
title={member.user?.full_name || member.user_full_name}
|
||||
subtitle={member.user?.email || member.user_email}
|
||||
primaryValue={Math.floor((Date.now() - new Date(member.joined_at).getTime()) / (1000 * 60 * 60 * 24))}
|
||||
primaryValueLabel="días"
|
||||
secondaryInfo={{
|
||||
label: 'Estado',
|
||||
value: member.is_active ? 'Activo' : 'Inactivo'
|
||||
}}
|
||||
metadata={[
|
||||
`Email: ${member.user?.email || member.user_email}`,
|
||||
`Teléfono: ${member.user?.phone || 'No disponible'}`,
|
||||
...(member.role === TENANT_ROLES.OWNER ? ['🏢 Propietario de la organización'] : [])
|
||||
]}
|
||||
actions={getMemberActions(member)}
|
||||
className={`
|
||||
${!member.is_active ? 'opacity-75' : ''}
|
||||
transition-all duration-200 hover:scale-[1.02]
|
||||
`}
|
||||
/>
|
||||
))}
|
||||
{filteredMembers.map((member: any) => {
|
||||
const user = member.user;
|
||||
const daysInTeam = Math.floor((Date.now() - new Date(member.joined_at).getTime()) / (1000 * 60 * 60 * 24));
|
||||
const lastLogin = user?.last_login ? new Date(user.last_login).toLocaleDateString('es-ES', {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
}) : 'Nunca';
|
||||
|
||||
return (
|
||||
<StatusCard
|
||||
key={member.id}
|
||||
id={`team-member-${member.id}`}
|
||||
statusIndicator={getMemberStatusConfig(member)}
|
||||
title={user?.full_name || member.user_full_name || 'Usuario'}
|
||||
subtitle={user?.email || member.user_email || ''}
|
||||
primaryValue={daysInTeam}
|
||||
primaryValueLabel="días en el equipo"
|
||||
secondaryInfo={{
|
||||
label: 'Último acceso',
|
||||
value: lastLogin
|
||||
}}
|
||||
metadata={[
|
||||
`Email: ${user?.email || member.user_email || 'No disponible'}`,
|
||||
`Teléfono: ${user?.phone || 'No disponible'}`,
|
||||
`Idioma: ${user?.language?.toUpperCase() || 'No especificado'}`,
|
||||
`Unido: ${new Date(member.joined_at).toLocaleDateString('es-ES', { year: 'numeric', month: 'short', day: 'numeric' })}`,
|
||||
...(member.role === TENANT_ROLES.OWNER ? ['🏢 Propietario de la organización'] : []),
|
||||
...(user?.timezone ? [`Zona horaria: ${user.timezone}`] : [])
|
||||
]}
|
||||
actions={getMemberActions(member)}
|
||||
className={`
|
||||
${!member.is_active ? 'opacity-75' : ''}
|
||||
transition-all duration-200 hover:scale-[1.02]
|
||||
`}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{filteredMembers.length === 0 && (
|
||||
|
||||
Reference in New Issue
Block a user