ultima versao
This commit is contained in:
parent
326276d4a4
commit
9c4c66a4f6
@ -1,19 +1,32 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-navigation-drawer class="body" v-model="drawer" app temporary>
|
<v-navigation-drawer
|
||||||
<v-list>
|
v-model="drawer"
|
||||||
<v-list-item
|
permanent
|
||||||
v-for="(item, index) in menuItems"
|
class="custom-drawer"
|
||||||
:key="index"
|
>
|
||||||
:to="{ path: item.path }"
|
<v-list nav dense>
|
||||||
|
<v-list-item-title class="app-title">Admin</v-list-item-title>
|
||||||
|
<v-list-subheader class="app-sub">Sistema de Ponto</v-list-subheader>
|
||||||
|
|
||||||
|
<v-divider class="my-2" />
|
||||||
|
|
||||||
|
<v-list-item
|
||||||
|
v-for="(item, index) in menuItems"
|
||||||
|
:key="index"
|
||||||
|
:to="item.path"
|
||||||
exact
|
exact
|
||||||
|
active-class="active-item"
|
||||||
>
|
>
|
||||||
<v-icon>{{ item.icon }}</v-icon>
|
<template #prepend>
|
||||||
<v-list-item-content>{{ item.title }}</v-list-item-content>
|
<v-icon class="mr-3" size="20">{{ item.icon }}</v-icon>
|
||||||
|
</template>
|
||||||
|
<v-list-item-title class="menu-text">{{ item.title }}</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-navigation-drawer>
|
</v-navigation-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
@ -31,13 +44,13 @@ console.log("Permissões do usuário:", dashboardPermissions)
|
|||||||
const menuItems = [
|
const menuItems = [
|
||||||
//{ title: 'Home', path: '/dashboard/home', icon: 'mdi mdi-home-circle', requiredPermission: 'read' },
|
//{ title: 'Home', path: '/dashboard/home', icon: 'mdi mdi-home-circle', requiredPermission: 'read' },
|
||||||
{ title: 'Dashboard', path: '/dashboard', icon: 'mdi mdi-view-dashboard', requiredPermission: 'read' },
|
{ title: 'Dashboard', path: '/dashboard', icon: 'mdi mdi-view-dashboard', requiredPermission: 'read' },
|
||||||
{ title: 'Admin', path: '/dashboard/profile', icon: 'mdi-account', requiredPermission: 'read' },
|
//{ title: 'Admin', path: '/dashboard/profile', icon: 'mdi-account', requiredPermission: 'read' },
|
||||||
{ title: 'Colaboradores', path: '/dashboard/colaboradores', icon: 'mdi-account-multiple-outline', requiredPermission: 'write' },
|
{ title: 'Colaboradores', path: '/dashboard/colaboradores', icon: 'mdi-account-multiple-outline', requiredPermission: 'write' },
|
||||||
{ title: 'Câmera', path: '/dashboard/agentlist', icon: 'mdi mdi-cctv', requiredPermission: 'write' },
|
//{ title: 'Câmera', path: '/dashboard/agentlist', icon: 'mdi mdi-cctv', requiredPermission: 'write' },
|
||||||
//{ title: 'Train', path: '/dashboard/train', icon: 'mdi mdi-thought-bubble', requiredPermission: 'write' },
|
//{ title: 'Train', path: '/dashboard/train', icon: 'mdi mdi-thought-bubble', requiredPermission: 'write' },
|
||||||
{ title: 'Escalas', path: '/dashboard/shifts', icon: 'mdi mdi-sitemap', requiredPermission: 'write' },
|
{ title: 'Escalas', path: '/dashboard/shifts', icon: 'mdi mdi-sitemap', requiredPermission: 'write' },
|
||||||
{ title: 'Feriados', path: '/dashboard/feriados', icon: 'mdi mdi-calendar-blank', requiredPermission: 'write' },
|
{ title: 'Feriados', path: '/dashboard/feriados', icon: 'mdi mdi-calendar-blank', requiredPermission: 'write' },
|
||||||
{ title: 'Empresas', path: '/dashboard/empresas', icon: 'mdi mdi-domain', requiredPermission: 'write' },
|
//{ title: 'Empresas', path: '/dashboard/empresas', icon: 'mdi mdi-domain', requiredPermission: 'write' },
|
||||||
{ title: 'Configurações', path: '/dashboard/settings', icon: 'mdi-cog', requiredPermission: 'write' }
|
{ title: 'Configurações', path: '/dashboard/settings', icon: 'mdi-cog', requiredPermission: 'write' }
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -48,44 +61,48 @@ const toggleDrawer = () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.body {
|
.custom-drawer {
|
||||||
background-color: #fafafab9;
|
background-color: #fff;
|
||||||
|
border-right: 1px solid #eaecef;
|
||||||
|
padding-top: 24px;
|
||||||
|
width: 240px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-navigation-drawer {
|
.app-title {
|
||||||
border-style: none;
|
font-weight: 700;
|
||||||
|
font-size: 18px;
|
||||||
|
padding-left: 10px;
|
||||||
|
color: #1e293b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-sub {
|
||||||
|
font-size: 13px;
|
||||||
|
padding-left: 10px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #1e293b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-list-item {
|
.v-list-item {
|
||||||
color: rgba(60, 135, 245, 1);
|
border-radius: 8px;
|
||||||
transition: all 0.3s ease;
|
margin: 4px 12px;
|
||||||
border-style: solid;
|
padding-left: 8px;
|
||||||
border-radius: 15px;
|
transition: 0.2s;
|
||||||
margin: 8px 0;
|
|
||||||
padding: 10px 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-list-item:hover {
|
.v-list-item:hover {
|
||||||
background-color: #f5f5f5;
|
background-color: #f3f4f6;
|
||||||
color: rgba(76,201,240);
|
|
||||||
border-radius: 15px !important;
|
|
||||||
margin-left: 25px;
|
|
||||||
border-radius: 50px;
|
|
||||||
background: linear-gradient(145deg, #eeeded, #ffffff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-list-item--active {
|
.active-item {
|
||||||
background-color: #4cc9f0 !important;
|
background-color: #e0f2fe !important;
|
||||||
color: white !important;
|
color: #1e3a8a !important;
|
||||||
border-radius: 15px !important;
|
font-weight: 600;
|
||||||
margin-left: 25px;
|
|
||||||
margin-right: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v-list-item-content {
|
|
||||||
margin-left: 16px;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import api from '../services/api';
|
import api from '../services/api';
|
||||||
import router from '../routes/router';
|
import router from '../routes/router';
|
||||||
import { useAuthStore } from './auth';
|
|
||||||
import { ca } from 'date-fns/locale';
|
|
||||||
|
|
||||||
export const useServiceInstanceStore = defineStore('servic_instance', {
|
export const useServiceInstanceStore = defineStore('servic_instance', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
service_instance: [],
|
service_instance: [],
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import api from '../services/api'; // A instância personalizada do Axios
|
import api from '../services/api'; // A instância personalizada do Axios
|
||||||
import router from '../routes/router';
|
import router from '../routes/router';
|
||||||
import { useAuthStore } from './auth'; // Importa o AuthStore
|
import { useAuthStore } from './auth';
|
||||||
import { ca } from 'date-fns/locale';
|
|
||||||
|
|
||||||
export const useSpaceStore = defineStore('spaces', {
|
export const useSpaceStore = defineStore('spaces', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
|
|||||||
@ -1,289 +1,268 @@
|
|||||||
<template class="body">
|
<template>
|
||||||
<v-container fluid>
|
<v-container fluid>
|
||||||
<!-- Cabeçalho da página -->
|
<!-- Título -->
|
||||||
<v-row>
|
<!-- Header da página -->
|
||||||
<v-col cols="12" class="d-flex align-center">
|
<div class="header-container">
|
||||||
<v-img
|
<div class="header-left">
|
||||||
src="/logo3.png"
|
<div class="icon-wrapper">
|
||||||
max-width="40"
|
<v-icon color="primary" size="32">mdi-clock-outline</v-icon>
|
||||||
class="mr-3"
|
</div>
|
||||||
:elevation="0"
|
<div class="header-title">
|
||||||
:class="'clean-image'"
|
<h1>Sistema de Ponto | Admin</h1>
|
||||||
></v-img>
|
</div>
|
||||||
<div class="text">
|
</div>
|
||||||
<h3>Dashboard Olha ai</h3>
|
<div class="header-right">
|
||||||
<p>Bem-vindo ao painel de controle</p>
|
|
||||||
|
|
||||||
|
<v-badge dot color="error" class="notification-badge">
|
||||||
|
<v-icon>mdi-bell</v-icon>
|
||||||
|
</v-badge>
|
||||||
|
<div class="admin-profile">
|
||||||
|
<v-avatar class="mr-2" color="primary" size="40">
|
||||||
|
<v-img src="/api/placeholder/40/40" alt="Administrador"></v-img>
|
||||||
|
</v-avatar>
|
||||||
|
<div class="admin-info">
|
||||||
|
<span class="admin-name">Administrador</span>
|
||||||
|
<span class="admin-role">Gestor</span>
|
||||||
|
</div>
|
||||||
|
<v-icon>mdi-chevron-down</v-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Título e descrição da seção -->
|
||||||
|
<div class="section-header">
|
||||||
|
<h2>Dashboard</h2>
|
||||||
</div>
|
</div>
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
|
|
||||||
|
<!-- Cards de Resumo -->
|
||||||
<!-- Cards de informações -->
|
<v-row class="mb-4">
|
||||||
<v-row>
|
<v-col cols="12" md="3" v-for="card in cards" :key="card.label">
|
||||||
<!-- Total de Usuários -->
|
<v-card class="summary-card">
|
||||||
<v-col cols="12" md="3">
|
|
||||||
<v-card class="cards">
|
|
||||||
<v-card-title>
|
|
||||||
<v-icon class="icon" left>mdi-account-group</v-icon>
|
|
||||||
Colaboradores
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-row align="center">
|
<div class="summary-label">{{ card.label }}</div>
|
||||||
<v-col class="sub">
|
<div class="summary-value">{{ card.value }}</div>
|
||||||
<h2>{{ totalColaboradores }}</h2>
|
<div class="summary-sub">{{ card.sub }}</div>
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<!-- Trabalhando -->
|
|
||||||
<v-col cols="12" md="3">
|
|
||||||
<v-card class="cards">
|
|
||||||
<v-card-title>
|
|
||||||
<v-icon class="icon" left>mdi mdi-account-hard-hat</v-icon>
|
|
||||||
Trabalhando
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row align="center">
|
|
||||||
<v-col class="sub">
|
|
||||||
<h2>{{ totalAgentes }}</h2>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
|
|
||||||
<!-- atrasados -->
|
|
||||||
<v-col cols="12" md="3">
|
|
||||||
<v-card class="cards">
|
|
||||||
<v-card-title class="card-text justify-center mx-auto">
|
|
||||||
<v-icon class="icon" left>mdi mdi-clock</v-icon>
|
|
||||||
Atrasados
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row align="center">
|
|
||||||
<v-col class="sub">
|
|
||||||
<h2>{{ temperaturaAgente }}</h2>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
|
|
||||||
<!-- Total de Faltas -->
|
|
||||||
<v-col cols="12" md="3">
|
|
||||||
<v-card class="cards">
|
|
||||||
<v-card-title>
|
|
||||||
<v-icon class="icon" left>mdi mdi-account-multiple-remove-outline</v-icon>
|
|
||||||
Faltas e Ausências
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-text>
|
|
||||||
<v-row align="center">
|
|
||||||
<v-col class="sub">
|
|
||||||
<h2>{{ totalFalhas }}</h2>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
<v-btn block class="button">Ver Logs...</v-btn>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
<!-- Gráfico de Colaboradores por categoria -->
|
<!-- Filtros Visão Geral / Solicitações -->
|
||||||
|
<v-row class="mb-4">
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-btn-toggle v-model="visaoSelecionada" divided>
|
||||||
|
<v-btn value="geral" prepend-icon="mdi-chart-line">Visão Geral</v-btn>
|
||||||
|
<v-btn value="pendentes" prepend-icon="mdi-information">Solicitações Pendentes</v-btn>
|
||||||
|
</v-btn-toggle>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<!-- Gráficos + Feriados -->
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="12" md="6">
|
<v-col cols="12" md="4">
|
||||||
<v-card class="cards">
|
<v-card>
|
||||||
<v-card-title>
|
<v-card-title class="text-subtitle-1 font-weight-bold">Distribuição de Horas</v-card-title>
|
||||||
<v-icon class="icon" left>mdi-chart-bar</v-icon>
|
<v-card-text class="text-center">Gráfico de distribuição de horas</v-card-text>
|
||||||
Gráfico de Colaboradores por categoria
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-subtitle>
|
|
||||||
Trabalhando, Atrasados, Ausentes
|
|
||||||
</v-card-subtitle>
|
|
||||||
<v-card-text>
|
|
||||||
<div>
|
|
||||||
<apexchart type="bar" height="350" :options="chartOptions" :series="series" />
|
|
||||||
</div>
|
|
||||||
</v-card-text>
|
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<!-- Horas extras do mês -->
|
<v-col cols="12" md="4">
|
||||||
<v-col cols="12" md="6">
|
<v-card>
|
||||||
<v-card class="cards">
|
<v-card-title class="text-subtitle-1 font-weight-bold">Marcações por Dia</v-card-title>
|
||||||
<v-card-title>
|
<v-card-text class="text-center">Gráfico de marcações diárias</v-card-text>
|
||||||
<v-icon class="icon" left>mdi-chart-bar</v-icon>
|
</v-card>
|
||||||
Horas extras do mês
|
</v-col>
|
||||||
|
|
||||||
|
<v-col cols="12" md="4">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title class="text-subtitle-1 font-weight-bold">
|
||||||
|
<v-icon size="18" class="mr-1">mdi-calendar</v-icon>
|
||||||
|
Próximos Feriados
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<v-card-subtitle>
|
|
||||||
Colaboradores - Terceiros, Freelancer
|
|
||||||
</v-card-subtitle>
|
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<div :style="chartContainerStyle">
|
<div class="holiday-entry" v-for="feriado in proximosFeriados" :key="feriado.nome">
|
||||||
<apexchart type="line" height="350" :options="chartOptions" :series="series" />
|
<div>{{ feriado.nome }}</div>
|
||||||
|
<div>{{ feriado.data }}</div>
|
||||||
</div>
|
</div>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
|
||||||
<!-- Card de logs
|
|
||||||
|
|
||||||
<v-col cols="12" md="12">
|
|
||||||
<v-card class="cards">
|
|
||||||
<v-card-item class="text">
|
|
||||||
<v-card-title>
|
|
||||||
<v-icon class="icon" left>mdi mdi-math-log</v-icon>
|
|
||||||
Log dos Agentes
|
|
||||||
</v-card-title>
|
|
||||||
</v-card-item>
|
|
||||||
|
|
||||||
<v-btn block class="button">Ver Logs...</v-btn>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
|
|
||||||
-->
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
|
import api from '../services/api';
|
||||||
|
import { useHolidayStore } from '../stores/holiday';
|
||||||
import { useUserStore } from '../stores/users';
|
import { useUserStore } from '../stores/users';
|
||||||
import { useAgentStore } from '../stores/agentStore';
|
|
||||||
import VueApexCharts from 'vue3-apexcharts';
|
|
||||||
|
|
||||||
// Referências reativas para os valores
|
const holidayStore = useHolidayStore();
|
||||||
const totalColaboradores = ref(0);
|
|
||||||
const totalAgentes = ref(0);
|
|
||||||
const totalFalhas = ref(0);
|
|
||||||
const temperaturaAgente = ref(0);
|
|
||||||
|
|
||||||
// Dados de vendas por categoria de produto
|
|
||||||
const series = ref([]);
|
|
||||||
|
|
||||||
// Configurações do gráfico
|
|
||||||
const chartOptions = ref({
|
|
||||||
chart: {
|
|
||||||
type: 'bar',
|
|
||||||
},
|
|
||||||
plotOptions: {
|
|
||||||
bar: {
|
|
||||||
horizontal: false,
|
|
||||||
columnWidth: '50%',
|
|
||||||
endingShape: 'rounded',
|
|
||||||
borderRadius: 20,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
dataLabels: {
|
|
||||||
enabled: false,
|
|
||||||
},
|
|
||||||
xaxis: {
|
|
||||||
categories: [], // Categorias de produtos
|
|
||||||
},
|
|
||||||
yaxis: {
|
|
||||||
title: {
|
|
||||||
text: 'Número de Colaboradores',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
fill: {
|
|
||||||
type: 'gradient',
|
|
||||||
gradient: {
|
|
||||||
shade: 'dark',
|
|
||||||
type: 'vertical',
|
|
||||||
gradientToColors: ['#00eeef'],
|
|
||||||
stops: [0, 50, 100],
|
|
||||||
},
|
|
||||||
opacity: 1,
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
y: {
|
|
||||||
formatter: function (val) {
|
|
||||||
return `${val} `;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Stores
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const agentStore = useAgentStore();
|
|
||||||
|
|
||||||
// Função para carregar os dados
|
const cards = ref([
|
||||||
const loadData = async () => {
|
{
|
||||||
try {
|
label: 'Total de Colaboradores',
|
||||||
// Atualizar total de usuários
|
value: 0,
|
||||||
const users = await userStore.catchUsers();
|
sub: 'Colaboradores cadastrados no sistema'
|
||||||
totalColaboradores.value = users.length;
|
|
||||||
|
|
||||||
|
|
||||||
// Atualizar total de agentes
|
|
||||||
const agents = agentStore.agents.filter(agent => !agent.isDeleted);
|
|
||||||
totalAgentes.value = agents.length;
|
|
||||||
|
|
||||||
// Atualizar temperatura dos agentes (exemplo: média de temperaturas)
|
|
||||||
temperaturaAgente.value = agents.reduce((sum, agent) => sum + (agent.temperature || 0), 0) / agents.length;
|
|
||||||
|
|
||||||
// Atualizar total de falhas (exemplo: agentes com status de falha)
|
|
||||||
totalFalhas.value = agents.filter(agent => agent.status === 'falha').length;
|
|
||||||
|
|
||||||
// Atualizar dados do gráfico
|
|
||||||
series.value = [
|
|
||||||
{
|
|
||||||
name: 'Colaboradores',
|
|
||||||
data: [15, 10, 20], // Substituir pelos dados reais
|
|
||||||
},
|
|
||||||
];
|
|
||||||
chartOptions.value.xaxis.categories = ['Trabalhando', 'Atrasados', 'Ausentes']; // Substituir pelas categorias reais
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Erro ao carregar os dados:', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Carregar os dados ao montar o componente
|
|
||||||
onMounted(loadData);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
apexchart: VueApexCharts,
|
|
||||||
},
|
},
|
||||||
}
|
{
|
||||||
|
label: 'Marcações Hoje',
|
||||||
|
value: '-',
|
||||||
|
sub: 'Registros de ponto realizados hoje'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Ajustes Pendentes',
|
||||||
|
value: '-',
|
||||||
|
sub: 'Solicitações aguardando aprovação'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Horas Extras',
|
||||||
|
value: '-',
|
||||||
|
sub: 'Total de horas extras no mês'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visaoSelecionada = ref('geral');
|
||||||
|
|
||||||
|
const proximosFeriados = ref([]);
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
// Busca o total de colaboradores
|
||||||
|
try {
|
||||||
|
const response = await userStore.catchUsers(); // Retorna diretamente um array
|
||||||
|
cards.value[0].value = response.length; // Calcula quantidade de usuários
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erro ao buscar colaboradores:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Busca feriados
|
||||||
|
try {
|
||||||
|
const response = await holidayStore.getHolidays(); // Aguarda a Promise e recebe um array
|
||||||
|
console.log('Feriados:', response);
|
||||||
|
const feriados = response
|
||||||
|
.filter(f => new Date(f.date) > new Date())
|
||||||
|
.sort((a, b) => new Date(a.date) - new Date(b.date))
|
||||||
|
.slice(0, 3)
|
||||||
|
.map(f => ({
|
||||||
|
nome: f.name,
|
||||||
|
data: new Date(f.date).toLocaleDateString('pt-BR')
|
||||||
|
}));
|
||||||
|
proximosFeriados.value = feriados;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erro ao buscar feriados:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.dashboard-title {
|
||||||
.fill-height {
|
|
||||||
min-height: 95vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cards {
|
|
||||||
text-align: center;
|
|
||||||
color: rgba(0,0,0);
|
|
||||||
border-radius: 50px;
|
|
||||||
background: linear-gradient(145deg, #eeeded, #ffffff);
|
|
||||||
box-shadow: 20px 20px 60px #d9d9d9,
|
|
||||||
-20px -20px 60px #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
background-color: rgba(76, 202, 240, 0.336);
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
font-size: 18px;
|
|
||||||
color: rgba(0,0,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
color: rgba(0,0,0);
|
|
||||||
font-size: 55px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub {
|
|
||||||
color: #23408e;
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1e293b;
|
||||||
}
|
}
|
||||||
|
.dashboard-subtitle {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
.summary-card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
.summary-label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
.summary-value {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #1e293b;
|
||||||
|
}
|
||||||
|
.summary-sub {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #94a3b8;
|
||||||
|
}
|
||||||
|
.holiday-entry {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 8px 0;
|
||||||
|
border-bottom: 1px solid #f1f1f1;
|
||||||
|
}
|
||||||
|
.holiday-entry:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
/* Estilo do cabeçalho */
|
||||||
|
.header-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding: 0 0 20px 0;
|
||||||
|
border-bottom: 1px solid #eaecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-wrapper {
|
||||||
|
background-color: #e3f2fd;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title h1 {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 0;
|
||||||
|
color: #1e293b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-button {
|
||||||
|
color: #1976d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-holiday-btn {
|
||||||
|
background-color: #1976d2;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-profile {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-name {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1e293b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-role {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-badge {
|
||||||
|
margin: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import vue from '@vitejs/plugin-vue';
|
import vue from '@vitejs/plugin-vue';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [vue()],
|
plugins: [vue()],
|
||||||
@ -15,6 +16,12 @@ export default defineConfig({
|
|||||||
target: 'http://127.0.0.1:5001',
|
target: 'http://127.0.0.1:5001',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path) => path.replace(/^\/new-api/, '')
|
rewrite: (path) => path.replace(/^\/new-api/, '')
|
||||||
|
},
|
||||||
|
fs: {
|
||||||
|
allow: [
|
||||||
|
// Caminho absoluto para o node_modules no seu caso
|
||||||
|
path.resolve(__dirname, 'node_modules')
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user