feat: add UserAvatar component to display employee profile pictures in various HR pages, enhancing visual representation of employee data

This commit is contained in:
2025-12-01 22:13:01 -03:00
parent c19c8c859e
commit 95c3b48ae6
6 changed files with 178 additions and 34 deletions

View File

@@ -11,6 +11,7 @@
import ErrorModal from '$lib/components/ErrorModal.svelte';
import CalendarioAfastamentos from '$lib/components/CalendarioAfastamentos.svelte';
import AreaChart from '$lib/components/ti/charts/AreaChart.svelte';
import UserAvatar from '$lib/components/chat/UserAvatar.svelte';
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
import jsPDF from 'jspdf';
import autoTable from 'jspdf-autotable';
@@ -1578,7 +1579,16 @@
<tbody>
{#each registrosFiltrados.atestados as atestado}
<tr>
<td>{atestado.funcionario?.nome || '-'}</td>
<td>
<div class="flex items-center gap-3">
<UserAvatar
fotoPerfilUrl={atestado.fotoPerfilUrl}
nome={atestado.funcionario?.nome || 'Funcionário'}
size="sm"
/>
<span>{atestado.funcionario?.nome || '-'}</span>
</div>
</td>
<td>
<span
class="badge {atestado.tipo === 'atestado_medico'
@@ -1651,7 +1661,16 @@
{/each}
{#each registrosFiltrados.licencas as licenca}
<tr>
<td>{licenca.funcionario?.nome || '-'}</td>
<td>
<div class="flex items-center gap-3">
<UserAvatar
fotoPerfilUrl={licenca.fotoPerfilUrl}
nome={licenca.funcionario?.nome || 'Funcionário'}
size="sm"
/>
<span>{licenca.funcionario?.nome || '-'}</span>
</div>
</td>
<td>
<span
class="badge {licenca.tipo === 'maternidade'

View File

@@ -4,6 +4,7 @@
import { Clock, Plus, X, Trash2, AlertTriangle } from 'lucide-svelte';
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
import { toast } from 'svelte-sonner';
import UserAvatar from '$lib/components/chat/UserAvatar.svelte';
const client = useConvexClient();
@@ -43,7 +44,7 @@
// Lista de funcionários do time
const funcionarios = $derived.by(() => {
const funcs: Array<{ _id: Id<'funcionarios'>; nome: string; matricula?: string }> = [];
const funcs: Array<{ _id: Id<'funcionarios'>; nome: string; matricula?: string; fotoPerfilUrl?: string | null }> = [];
for (const time of subordinados) {
for (const membro of time.membros) {
if (membro.funcionario && !funcs.find((f) => f._id === membro.funcionario._id)) {
@@ -51,6 +52,7 @@
_id: membro.funcionario._id,
nome: membro.funcionario.nome,
matricula: membro.funcionario.matricula,
fotoPerfilUrl: membro.funcionario.fotoPerfilUrl,
});
}
}
@@ -199,12 +201,19 @@
<div class="max-h-60 overflow-y-auto border border-base-300 rounded-lg p-4 space-y-2">
{#each funcionarios as funcionario}
<label class="flex items-center justify-between p-3 rounded-lg hover:bg-base-200 transition-colors cursor-pointer">
<span class="label-text font-medium">
{funcionario.nome}
{#if funcionario.matricula}
<span class="text-base-content/60 ml-2">({funcionario.matricula})</span>
{/if}
</span>
<div class="flex items-center gap-3">
<UserAvatar
fotoPerfilUrl={funcionario.fotoPerfilUrl}
nome={funcionario.nome}
size="sm"
/>
<span class="label-text font-medium">
{funcionario.nome}
{#if funcionario.matricula}
<span class="text-base-content/60 ml-2">({funcionario.matricula})</span>
{/if}
</span>
</div>
<input
type="checkbox"
class="checkbox checkbox-primary"
@@ -319,13 +328,21 @@
{#each dispensas as dispensa}
<tr>
<td>
{dispensa.funcionario?.nome || '-'}
{#if dispensa.funcionario?.matricula}
<br />
<span class="text-sm text-base-content/70">
Mat: {dispensa.funcionario.matricula}
</span>
{/if}
<div class="flex items-center gap-3">
<UserAvatar
fotoPerfilUrl={dispensa.fotoPerfilUrl}
nome={dispensa.funcionario?.nome || 'Funcionário'}
size="sm"
/>
<div>
<div class="font-medium">{dispensa.funcionario?.nome || '-'}</div>
{#if dispensa.funcionario?.matricula}
<span class="text-sm text-base-content/70">
Mat: {dispensa.funcionario.matricula}
</span>
{/if}
</div>
</div>
</td>
<td>
<div class="text-sm">

View File

@@ -6,6 +6,7 @@
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
import { formatarHoraPonto, getTipoRegistroLabel } from '$lib/utils/ponto';
import { toast } from 'svelte-sonner';
import UserAvatar from '$lib/components/chat/UserAvatar.svelte';
const client = useConvexClient();
@@ -156,7 +157,7 @@
// Lista de funcionários do time
const funcionarios = $derived.by(() => {
const funcs: Array<{ _id: Id<'funcionarios'>; nome: string; matricula?: string }> = [];
const funcs: Array<{ _id: Id<'funcionarios'>; nome: string; matricula?: string; fotoPerfilUrl?: string | null }> = [];
for (const time of subordinados) {
for (const membro of time.membros) {
if (membro.funcionario && !funcs.find((f) => f._id === membro.funcionario._id)) {
@@ -164,6 +165,7 @@
_id: membro.funcionario._id,
nome: membro.funcionario.nome,
matricula: membro.funcionario.matricula,
fotoPerfilUrl: membro.funcionario.fotoPerfilUrl,
});
}
}
@@ -873,13 +875,21 @@
</td>
{#if !funcionarioSelecionado}
<td>
{homologacao.funcionario?.nome || '-'}
{#if homologacao.funcionario?.matricula}
<br />
<span class="text-xs text-base-content/70">
Mat: {homologacao.funcionario.matricula}
</span>
{/if}
<div class="flex items-center gap-3">
<UserAvatar
fotoPerfilUrl={homologacao.fotoPerfilUrl}
nome={homologacao.funcionario?.nome || 'Funcionário'}
size="sm"
/>
<div>
<div class="font-medium">{homologacao.funcionario?.nome || '-'}</div>
{#if homologacao.funcionario?.matricula}
<span class="text-xs text-base-content/70">
Mat: {homologacao.funcionario.matricula}
</span>
{/if}
</div>
</div>
</td>
{/if}
<td>
@@ -980,14 +990,22 @@
})}
</div>
<div>
<span class="font-medium">Funcionário:</span>{' '}
{homologacaoSelecionada.funcionario?.nome || '-'}
{#if homologacaoSelecionada.funcionario?.matricula}
<br />
<span class="text-xs text-base-content/70">
Mat: {homologacaoSelecionada.funcionario.matricula}
</span>
{/if}
<span class="font-medium">Funcionário:</span>
<div class="flex items-center gap-3 mt-2">
<UserAvatar
fotoPerfilUrl={homologacaoSelecionada.fotoPerfilUrl}
nome={homologacaoSelecionada.funcionario?.nome || 'Funcionário'}
size="sm"
/>
<div>
<div class="font-medium">{homologacaoSelecionada.funcionario?.nome || '-'}</div>
{#if homologacaoSelecionada.funcionario?.matricula}
<span class="text-xs text-base-content/70">
Mat: {homologacaoSelecionada.funcionario.matricula}
</span>
{/if}
</div>
</div>
</div>
<div>
<span class="font-medium">Gestor:</span>{' '}