refactor: update user role management and enhance UI components
- Updated the user role management logic to improve type safety and error handling, including better handling of role permissions and user associations. - Refactored the UI components for user management, enhancing the layout and styling for better user experience. - Removed outdated code related to menu permissions and streamlined the database schema for roles and profiles. - Improved the overall structure and readability of the codebase, ensuring consistency across components.
This commit is contained in:
@@ -1,337 +1,384 @@
|
||||
<script lang="ts">
|
||||
import { goto } from "$app/navigation";
|
||||
type HighlightVariant = "solid" | "outline";
|
||||
type FeatureIcon =
|
||||
| "control"
|
||||
| "support"
|
||||
| "shieldCheck"
|
||||
| "envelope"
|
||||
| "users"
|
||||
| "bell"
|
||||
| "monitor"
|
||||
| "document"
|
||||
| "teams";
|
||||
type PaletteKey = "primary" | "success" | "secondary" | "accent" | "info" | "error";
|
||||
|
||||
type FeatureCard = {
|
||||
title: string;
|
||||
description: string;
|
||||
ctaLabel: string;
|
||||
href?: string;
|
||||
disabled?: boolean;
|
||||
palette: PaletteKey;
|
||||
icon: FeatureIcon;
|
||||
highlightBadges?: Array<{ label: string; variant: HighlightVariant }>;
|
||||
};
|
||||
|
||||
type IconPath = {
|
||||
d: string;
|
||||
strokeLinecap?: "butt" | "round" | "square";
|
||||
strokeLinejoin?: "miter" | "round" | "bevel";
|
||||
strokeWidth?: number;
|
||||
};
|
||||
|
||||
const paletteStyles: Record<
|
||||
PaletteKey,
|
||||
{
|
||||
cardBorder: string;
|
||||
iconBg: string;
|
||||
iconRing: string;
|
||||
iconColor: string;
|
||||
button: string;
|
||||
badgeSolid: string;
|
||||
badgeOutline: string;
|
||||
}
|
||||
> = {
|
||||
primary: {
|
||||
cardBorder: "border-primary/25",
|
||||
iconBg: "bg-primary/15",
|
||||
iconRing: "ring-1 ring-primary/30",
|
||||
iconColor: "text-primary",
|
||||
button: "btn-primary",
|
||||
badgeSolid: "badge-primary text-primary-content",
|
||||
badgeOutline: "badge-outline border-primary/30",
|
||||
},
|
||||
success: {
|
||||
cardBorder: "border-success/25",
|
||||
iconBg: "bg-success/15",
|
||||
iconRing: "ring-1 ring-success/25",
|
||||
iconColor: "text-success",
|
||||
button: "btn-success",
|
||||
badgeSolid: "badge-success text-success-content",
|
||||
badgeOutline: "badge-outline border-success/30",
|
||||
},
|
||||
secondary: {
|
||||
cardBorder: "border-secondary/25",
|
||||
iconBg: "bg-secondary/15",
|
||||
iconRing: "ring-1 ring-secondary/25",
|
||||
iconColor: "text-secondary",
|
||||
button: "btn-secondary",
|
||||
badgeSolid: "badge-secondary text-secondary-content",
|
||||
badgeOutline: "badge-outline border-secondary/30",
|
||||
},
|
||||
accent: {
|
||||
cardBorder: "border-accent/25",
|
||||
iconBg: "bg-accent/15",
|
||||
iconRing: "ring-1 ring-accent/20",
|
||||
iconColor: "text-accent",
|
||||
button: "btn-accent",
|
||||
badgeSolid: "badge-accent text-accent-content",
|
||||
badgeOutline: "badge-outline border-accent/30",
|
||||
},
|
||||
info: {
|
||||
cardBorder: "border-info/25",
|
||||
iconBg: "bg-info/15",
|
||||
iconRing: "ring-1 ring-info/25",
|
||||
iconColor: "text-info",
|
||||
button: "btn-info",
|
||||
badgeSolid: "badge-info text-info-content",
|
||||
badgeOutline: "badge-outline border-info/30",
|
||||
},
|
||||
error: {
|
||||
cardBorder: "border-error/20",
|
||||
iconBg: "bg-error/15",
|
||||
iconRing: "ring-1 ring-error/25",
|
||||
iconColor: "text-error",
|
||||
button: "btn-error",
|
||||
badgeSolid: "badge-error text-error-content",
|
||||
badgeOutline: "badge-outline border-error/30",
|
||||
},
|
||||
};
|
||||
|
||||
const iconPaths = {
|
||||
control: [
|
||||
{
|
||||
d: "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4",
|
||||
strokeLinecap: "round",
|
||||
strokeLinejoin: "round",
|
||||
},
|
||||
],
|
||||
support: [
|
||||
{
|
||||
d: "M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192l-3.536 3.536M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-5 0a4 4 0 11-8 0 4 4 0 018 0z",
|
||||
strokeLinecap: "round",
|
||||
strokeLinejoin: "round",
|
||||
},
|
||||
],
|
||||
shieldCheck: [
|
||||
{
|
||||
d: "M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z",
|
||||
strokeLinecap: "round",
|
||||
strokeLinejoin: "round",
|
||||
},
|
||||
],
|
||||
envelope: [
|
||||
{
|
||||
d: "M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z",
|
||||
strokeLinecap: "round",
|
||||
strokeLinejoin: "round",
|
||||
},
|
||||
],
|
||||
users: [
|
||||
{
|
||||
d: "M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z",
|
||||
strokeLinecap: "round",
|
||||
strokeLinejoin: "round",
|
||||
},
|
||||
],
|
||||
bell: [
|
||||
{
|
||||
d: "M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9",
|
||||
strokeLinecap: "round",
|
||||
strokeLinejoin: "round",
|
||||
},
|
||||
],
|
||||
monitor: [
|
||||
{
|
||||
d: "M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z",
|
||||
strokeLinecap: "round",
|
||||
strokeLinejoin: "round",
|
||||
},
|
||||
],
|
||||
document: [
|
||||
{
|
||||
d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z",
|
||||
strokeLinecap: "round",
|
||||
strokeLinejoin: "round",
|
||||
},
|
||||
],
|
||||
teams: [
|
||||
{
|
||||
d: "M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z",
|
||||
strokeLinecap: "round",
|
||||
strokeLinejoin: "round",
|
||||
},
|
||||
],
|
||||
} satisfies Record<FeatureIcon, IconPath[]>;
|
||||
|
||||
const featureCards: Array<FeatureCard> = [
|
||||
{
|
||||
title: "Painel Administrativo",
|
||||
description:
|
||||
"Acesso restrito para gerenciamento de solicitações de acesso ao sistema e outras configurações administrativas.",
|
||||
ctaLabel: "Acessar Painel",
|
||||
href: "/ti/painel-administrativo",
|
||||
palette: "primary",
|
||||
icon: "control",
|
||||
},
|
||||
{
|
||||
title: "Suporte Técnico",
|
||||
description:
|
||||
"Central de atendimento para resolução de problemas técnicos e dúvidas sobre o sistema.",
|
||||
ctaLabel: "Em breve",
|
||||
palette: "info",
|
||||
icon: "support",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
title: "Gerenciar Permissões",
|
||||
description:
|
||||
"Configure as permissões de acesso aos menus do sistema por função. Controle quem pode acessar, consultar e gravar dados.",
|
||||
ctaLabel: "Configurar Permissões",
|
||||
href: "/ti/painel-permissoes",
|
||||
palette: "success",
|
||||
icon: "shieldCheck",
|
||||
},
|
||||
{
|
||||
title: "Configuração de Email",
|
||||
description:
|
||||
"Configure o servidor SMTP para envio automático de notificações e emails do sistema.",
|
||||
ctaLabel: "Configurar SMTP",
|
||||
href: "/ti/configuracoes-email",
|
||||
palette: "secondary",
|
||||
icon: "envelope",
|
||||
},
|
||||
{
|
||||
title: "Gerenciar Usuários",
|
||||
description:
|
||||
"Criar, editar, bloquear e gerenciar usuários do sistema. Controle total sobre contas de acesso.",
|
||||
ctaLabel: "Gerenciar Usuários",
|
||||
href: "/ti/usuarios",
|
||||
palette: "accent",
|
||||
icon: "users",
|
||||
},
|
||||
{
|
||||
title: "Gestão de Times",
|
||||
description:
|
||||
"Organize funcionários em equipes e defina gestores. Gerencie membros e estrutura organizacional do sistema.",
|
||||
ctaLabel: "Gerenciar Times",
|
||||
href: "/ti/times",
|
||||
palette: "success",
|
||||
icon: "teams",
|
||||
},
|
||||
{
|
||||
title: "Notificações e Mensagens",
|
||||
description:
|
||||
"Envie notificações para usuários do sistema via chat ou email. Configure templates de mensagens reutilizáveis.",
|
||||
ctaLabel: "Acessar Painel",
|
||||
href: "/ti/notificacoes",
|
||||
palette: "info",
|
||||
icon: "bell",
|
||||
},
|
||||
{
|
||||
title: "Monitorar SGSE",
|
||||
description:
|
||||
"Monitore em tempo real as métricas técnicas do sistema e configure alertas inteligentes para a equipe de TI.",
|
||||
ctaLabel: "Monitorar Sistema",
|
||||
href: "/ti/monitoramento",
|
||||
palette: "error",
|
||||
icon: "monitor",
|
||||
highlightBadges: [
|
||||
{ label: "Tempo Real", variant: "solid" },
|
||||
{ label: "Alertas", variant: "outline" },
|
||||
{ label: "Relatórios", variant: "outline" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Documentação",
|
||||
description:
|
||||
"Manuais, guias e documentação técnica do sistema para usuários e administradores.",
|
||||
ctaLabel: "Em breve",
|
||||
palette: "primary",
|
||||
icon: "document",
|
||||
disabled: true,
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<main class="container mx-auto px-4 py-4">
|
||||
<h1 class="text-3xl font-bold text-primary mb-6">Tecnologia da Informação</h1>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<!-- Card Painel Administrativo -->
|
||||
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-shadow">
|
||||
<div class="card-body">
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<div class="p-3 bg-primary/20 rounded-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8 text-primary"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="card-title text-xl">Painel Administrativo</h2>
|
||||
</div>
|
||||
<p class="text-base-content/70 mb-4">
|
||||
Acesso restrito para gerenciamento de solicitações de acesso ao sistema e outras configurações administrativas.
|
||||
<main class="mx-auto w-full max-w-7xl space-y-12 px-4 py-10">
|
||||
<section class="relative overflow-hidden rounded-3xl border border-primary/25 bg-gradient-to-br from-primary/10 via-base-100 to-secondary/20 p-8 shadow-2xl">
|
||||
<div class="absolute -left-10 top-10 h-40 w-40 rounded-full bg-primary/20 blur-3xl"></div>
|
||||
<div class="absolute -bottom-16 right-0 h-56 w-56 rounded-full bg-secondary/20 blur-3xl"></div>
|
||||
<div class="relative z-10 flex flex-col gap-6 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div class="max-w-3xl space-y-4">
|
||||
<span class="inline-flex w-fit items-center gap-2 rounded-full border border-primary/40 bg-primary/10 px-4 py-1 text-xs font-semibold uppercase tracking-[0.28em] text-primary">
|
||||
Tecnologia da Informação
|
||||
</span>
|
||||
<h1 class="text-4xl font-black leading-tight text-base-content sm:text-5xl">
|
||||
Sistemas de Informação
|
||||
</h1>
|
||||
<p class="text-base leading-relaxed text-base-content/70 sm:text-lg">
|
||||
Acesso restrito para gerenciamento de solicitações de acesso ao sistema, configuração de permissões e monitoramento técnico das operações do SGSE.
|
||||
</p>
|
||||
<div class="card-actions justify-end">
|
||||
<a href="/ti/painel-administrativo" class="btn btn-primary">
|
||||
Acessar Painel
|
||||
</a>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4 rounded-2xl border border-base-200/60 bg-base-100/70 p-6 shadow-lg backdrop-blur sm:max-w-sm">
|
||||
<div>
|
||||
<p class="text-sm font-semibold text-base-content/60">Status</p>
|
||||
<p class="mt-2 text-2xl font-bold text-base-content">Operacional</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p class="text-sm font-semibold text-base-content/60">Última atualização</p>
|
||||
<p class="mt-2 text-xl font-bold text-base-content">Agora mesmo</p>
|
||||
</div>
|
||||
<div class="col-span-2 h-px bg-gradient-to-r from-transparent via-base-300 to-transparent"></div>
|
||||
<div class="col-span-2 flex items-center justify-between text-sm text-base-content/70">
|
||||
<span>Monitoramento em tempo real.</span>
|
||||
<span class="badge badge-primary badge-sm">SGSE</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Card Suporte Técnico -->
|
||||
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-shadow">
|
||||
<div class="card-body">
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<div class="p-3 bg-primary/20 rounded-lg">
|
||||
<section class="grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3">
|
||||
{#each featureCards as card (card.title)}
|
||||
<article
|
||||
class={`card-hover group relative overflow-hidden rounded-2xl border ${paletteStyles[card.palette].cardBorder} bg-base-100/90 p-6 shadow-lg transition-all duration-300`}
|
||||
>
|
||||
<div class="absolute inset-x-6 top-0 h-24 rounded-b-full bg-gradient-to-b from-base-200/40 to-transparent opacity-0 transition-opacity duration-300 group-hover:opacity-100"></div>
|
||||
<div class="relative flex items-start gap-4">
|
||||
<div
|
||||
class={`flex h-14 w-14 items-center justify-center rounded-2xl ${paletteStyles[card.palette].iconBg} ${paletteStyles[card.palette].iconRing}`}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8 text-primary"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
class={`h-7 w-7 ${paletteStyles[card.palette].iconColor}`}
|
||||
>
|
||||
{#each iconPaths[card.icon] as path (path.d)}
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192l-3.536 3.536M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-5 0a4 4 0 11-8 0 4 4 0 018 0z"
|
||||
/>
|
||||
d={path.d}
|
||||
stroke-linecap={path.strokeLinecap ?? "round"}
|
||||
stroke-linejoin={path.strokeLinejoin ?? "round"}
|
||||
stroke-width={path.strokeWidth ?? 2}
|
||||
/>
|
||||
{/each}
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="card-title text-xl">Suporte Técnico</h2>
|
||||
</div>
|
||||
<p class="text-base-content/70 mb-4">
|
||||
Central de atendimento para resolução de problemas técnicos e dúvidas sobre o sistema.
|
||||
</p>
|
||||
<div class="card-actions justify-end">
|
||||
<button class="btn btn-primary" disabled>
|
||||
Em breve
|
||||
<div class="relative flex-1">
|
||||
<h2 class="text-xl font-semibold text-base-content">{card.title}</h2>
|
||||
<p class="mt-2 text-sm leading-relaxed text-base-content/70">{card.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if card.highlightBadges}
|
||||
<div class="mt-4 flex flex-wrap gap-2">
|
||||
{#each card.highlightBadges as badge (badge.label)}
|
||||
{#if badge.variant === "solid"}
|
||||
<span class={`badge ${paletteStyles[card.palette].badgeSolid}`}>{badge.label}</span>
|
||||
{:else}
|
||||
<span
|
||||
class={`badge ${paletteStyles[card.palette].badgeOutline} ${paletteStyles[card.palette].iconColor}`}
|
||||
>
|
||||
{badge.label}
|
||||
</span>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="mt-6 flex justify-end">
|
||||
{#if card.href && !card.disabled}
|
||||
<a
|
||||
class={`btn ${paletteStyles[card.palette].button} btn-sm sm:btn-md shadow-md transition-all duration-200 hover:shadow-lg`}
|
||||
href={card.href}
|
||||
>
|
||||
{card.ctaLabel}
|
||||
</a>
|
||||
{:else}
|
||||
<button
|
||||
type="button"
|
||||
class={`btn ${paletteStyles[card.palette].button} btn-sm sm:btn-md shadow-md`}
|
||||
disabled
|
||||
>
|
||||
{card.ctaLabel}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
{/each}
|
||||
</section>
|
||||
|
||||
<!-- Card Gerenciar Permissões -->
|
||||
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-shadow">
|
||||
<div class="card-body">
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<div class="p-3 bg-success/20 rounded-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8 text-success"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="card-title text-xl">Gerenciar Permissões</h2>
|
||||
</div>
|
||||
<p class="text-base-content/70 mb-4">
|
||||
Configure as permissões de acesso aos menus do sistema por função. Controle quem pode acessar, consultar e gravar dados.
|
||||
</p>
|
||||
<div class="card-actions justify-end">
|
||||
<a href="/ti/painel-permissoes" class="btn btn-success">
|
||||
Configurar Permissões
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card Configuração de Email -->
|
||||
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-shadow">
|
||||
<div class="card-body">
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<div class="p-3 bg-secondary/20 rounded-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8 text-secondary"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="card-title text-xl">Configuração de Email</h2>
|
||||
</div>
|
||||
<p class="text-base-content/70 mb-4">
|
||||
Configure o servidor SMTP para envio automático de notificações e emails do sistema.
|
||||
</p>
|
||||
<div class="card-actions justify-end">
|
||||
<a href="/ti/configuracoes-email" class="btn btn-secondary">
|
||||
Configurar SMTP
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card Gerenciar Usuários -->
|
||||
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-shadow">
|
||||
<div class="card-body">
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<div class="p-3 bg-accent/20 rounded-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8 text-accent"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="card-title text-xl">Gerenciar Usuários</h2>
|
||||
</div>
|
||||
<p class="text-base-content/70 mb-4">
|
||||
Criar, editar, bloquear e gerenciar usuários do sistema. Controle total sobre contas de acesso.
|
||||
</p>
|
||||
<div class="card-actions justify-end">
|
||||
<a href="/ti/usuarios" class="btn btn-accent">
|
||||
Gerenciar Usuários
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card Gerenciar Perfis -->
|
||||
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-shadow">
|
||||
<div class="card-body">
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<div class="p-3 bg-warning/20 rounded-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8 text-warning"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="card-title text-xl">Gerenciar Perfis</h2>
|
||||
</div>
|
||||
<p class="text-base-content/70 mb-4">
|
||||
Crie e gerencie perfis de acesso personalizados com permissões específicas para grupos de usuários.
|
||||
</p>
|
||||
<div class="card-actions justify-end">
|
||||
<a href="/ti/perfis" class="btn btn-warning">
|
||||
Gerenciar Perfis
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card Notificações e Mensagens -->
|
||||
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-shadow">
|
||||
<div class="card-body">
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<div class="p-3 bg-info/20 rounded-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8 text-info"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="card-title text-xl">Notificações e Mensagens</h2>
|
||||
</div>
|
||||
<p class="text-base-content/70 mb-4">
|
||||
Envie notificações para usuários do sistema via chat ou email. Configure templates de mensagens reutilizáveis.
|
||||
</p>
|
||||
<div class="card-actions justify-end">
|
||||
<a href="/ti/notificacoes" class="btn btn-info">
|
||||
Acessar Painel
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card Monitorar SGSE -->
|
||||
<div class="card bg-gradient-to-br from-error/10 to-error/5 shadow-xl hover:shadow-2xl transition-all duration-300 hover:scale-105 border-2 border-error/20">
|
||||
<div class="card-body">
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<div class="p-3 bg-gradient-to-br from-error/30 to-error/20 rounded-2xl shadow-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-10 w-10 text-error"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="card-title text-xl text-error">Monitorar SGSE</h2>
|
||||
</div>
|
||||
<p class="text-base-content/70 mb-4">
|
||||
Monitore em tempo real as métricas técnicas do sistema: CPU, memória, rede, usuários online e muito mais. Configure alertas personalizados.
|
||||
</p>
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<div class="badge badge-error badge-sm">Tempo Real</div>
|
||||
<div class="badge badge-outline badge-sm">Alertas</div>
|
||||
<div class="badge badge-outline badge-sm">Relatórios</div>
|
||||
</div>
|
||||
<div class="card-actions justify-end">
|
||||
<a href="/ti/monitoramento" class="btn btn-error shadow-lg hover:shadow-error/30">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
|
||||
</svg>
|
||||
Monitorar Sistema
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card Documentação -->
|
||||
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-shadow">
|
||||
<div class="card-body">
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<div class="p-3 bg-primary/20 rounded-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8 text-primary"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="card-title text-xl">Documentação</h2>
|
||||
</div>
|
||||
<p class="text-base-content/70 mb-4">
|
||||
Manuais, guias e documentação técnica do sistema para usuários e administradores.
|
||||
</p>
|
||||
<div class="card-actions justify-end">
|
||||
<button type="button" class="btn btn-primary" disabled>
|
||||
Em breve
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info mt-8">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
class="stroke-current shrink-0 w-6 h-6"
|
||||
>
|
||||
<section class="relative overflow-hidden rounded-2xl border border-warning/30 bg-gradient-to-br from-warning/15 via-warning/10 to-warning/5 p-6 shadow-lg">
|
||||
<div class="absolute -top-10 right-0 h-32 w-32 rounded-full bg-warning/30 blur-3xl"></div>
|
||||
<div class="relative z-10 flex items-start gap-4">
|
||||
<div class="flex h-12 w-12 items-center justify-center rounded-full bg-warning/25 text-warning">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="h-6 w-6 stroke-current">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
></path>
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-bold">Área Restrita</h3>
|
||||
<div class="text-sm">
|
||||
Esta é uma área de acesso restrito. Apenas usuários autorizados pela equipe de TI podem acessar o Painel Administrativo.
|
||||
<h3 class="text-lg font-bold text-base-content">Área Restrita</h3>
|
||||
<p class="mt-2 text-sm leading-relaxed text-base-content/70">
|
||||
Esta área é exclusiva da equipe de Tecnologia da Informação. Garanta que apenas usuários autorizados acessem o Painel Administrativo e mantenha suas credenciais em segurança.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
|
||||
@@ -4,18 +4,35 @@
|
||||
import StatsCard from "$lib/components/ti/StatsCard.svelte";
|
||||
|
||||
const client = useConvexClient();
|
||||
const usuarios = useQuery(api.usuarios.listar, {});
|
||||
const usuariosQuery = useQuery(api.usuarios.listar, {});
|
||||
|
||||
// Verificar se está carregando
|
||||
const carregando = $derived(usuariosQuery === undefined);
|
||||
|
||||
// Extrair dados dos usuários
|
||||
const usuarios = $derived(usuariosQuery?.data ?? []);
|
||||
|
||||
// Estatísticas derivadas
|
||||
const stats = $derived.by(() => {
|
||||
if (!usuarios?.data || !Array.isArray(usuarios.data)) return null;
|
||||
// Se ainda está carregando, retorna null para mostrar loading
|
||||
if (carregando) return null;
|
||||
|
||||
const ativos = usuarios.data.filter(u => u.ativo && !u.bloqueado).length;
|
||||
const bloqueados = usuarios.data.filter(u => u.bloqueado).length;
|
||||
const inativos = usuarios.data.filter(u => !u.ativo).length;
|
||||
// Se não há usuários, retorna stats zeradas (mas não null para não mostrar loading)
|
||||
if (!Array.isArray(usuarios) || usuarios.length === 0) {
|
||||
return {
|
||||
total: 0,
|
||||
ativos: 0,
|
||||
bloqueados: 0,
|
||||
inativos: 0
|
||||
};
|
||||
}
|
||||
|
||||
const ativos = usuarios.filter(u => u.ativo && !u.bloqueado).length;
|
||||
const bloqueados = usuarios.filter(u => u.bloqueado === true).length;
|
||||
const inativos = usuarios.filter(u => !u.ativo).length;
|
||||
|
||||
return {
|
||||
total: usuarios.data.length,
|
||||
total: usuarios.length,
|
||||
ativos,
|
||||
bloqueados,
|
||||
inativos
|
||||
@@ -52,7 +69,7 @@
|
||||
<StatsCard
|
||||
title="Usuários Ativos"
|
||||
value={stats.ativos}
|
||||
description="{((stats.ativos / stats.total) * 100).toFixed(1)}% do total"
|
||||
description="{stats.total > 0 ? ((stats.ativos / stats.total) * 100).toFixed(1) + '% do total' : '0% do total'}"
|
||||
icon='<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />'
|
||||
color="success"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user