arcadiasuite/plus/resources/views/teste.blade.php

370 lines
13 KiB
PHP

<!doctype html>
<html lang="pt-br">
<head>
<meta charset="utf-8">
<title>Dashboard</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap 5 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Bootstrap Icons -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet">
<!-- Chart.js 4 -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.4/dist/chart.umd.min.js"></script>
<style>
:root{
--bg: #f4f5f7;
--text-muted: #6b7280;
--ink: #111827;
--card: #ffffff;
--shadow: 0 8px 24px rgba(0,0,0,.06);
--violet-50: #ede9fe;
--violet-400: #8b5cf6;
--indigo-600: #4f46e5;
--slate-700: #334155;
--success: #16a34a;
--warning: #f59e0b;
--teal: #10b981;
--teal-200: rgba(16,185,129,.18);
--blue: #3b82f6;
--blue-200: rgba(59,130,246,.18);
--rose: #ef4444;
--rose-200: rgba(239,68,68,.16);
--radius: 16px;
}
body{ background:var(--bg); }
.container-xl{ max-width: 1280px; }
/* Header topo direito (breadcrumb) */
.crumb-top{ color:#606774; font-weight:600; }
/* Cards base */
.card{
border:0; border-radius: var(--radius); box-shadow: var(--shadow);
background: var(--card);
}
.mini-card .icon{
width:44px;height:44px;border-radius:12px;display:grid;place-items:center;font-size:1.2rem;
background:#eef2ff;color:#4338ca;
}
.mini-card .value{ font-size:1.6rem; font-weight:800; }
/* Welcome card */
.welcome-top{
background: #cdd0ff; /* lilás suave como no print */
background: linear-gradient(135deg,#cfd2ff 0%, #dcd6ff 100%);
border-radius: 14px;
padding:16px 16px 6px 16px;
color:#1f2544;
font-weight: 700;
}
.welcome-top small{ font-weight:600; opacity:.9 }
.welcome-body .avatar{
width:72px; height:72px; border-radius:50%; object-fit:cover; box-shadow:0 4px 10px rgba(0,0,0,.15);
}
.btn-deep{ background:#2c3557; color:#fff; border:0; }
.btn-deep:hover{ background:#242c4a; color:#fff; }
/* Chart containers fixos (não descem a tela) */
.chart-box{ position:relative; height: 360px; }
@media (max-width: 768px){ .chart-box{ height: 260px; } }
/* Donut */
.ring { position:relative; height: 180px; }
@media (max-width: 768px){ .ring{ height: 160px; } }
.hint{ color:var(--text-muted); font-size:.95rem; }
/* Legenda custom (cores iguais às do Chart.js) */
.legend-dot{
display:inline-block;width:10px;height:10px;border-radius:50%;margin-right:.4rem;
}
.header-card {
background-color: #7963f2;
background-image: url('https://cdn-icons-png.flaticon.com/512/4149/4149676.png');
background-repeat: no-repeat;
background-position: right 15px bottom 5px;
background-size: 70px;
height: 80px;
position: relative;
}
.avatar-wrapper {
position: absolute;
top: 45px;
left: 0;
right: 0;
}
.avatar-img {
background-color: #fff;
}
.card {
transition: all 0.3s ease;
}
.card:hover {
transform: translateY(-3px);
box-shadow: 0 6px 16px rgba(0,0,0,0.1);
}
/* Títulos */
h5.card-title{ font-weight:700; }
</style>
</head>
<body>
<div class="container-xl py-4">
<div class="d-flex justify-content-end">
<div class="crumb-top">Dashboard / Dashboard</div>
</div>
<!-- Linha 1: Welcome + 3 KPIs -->
<div class="row g-3 align-items-stretch mt-2">
<!-- Welcome -->
<div class="col-12 col-lg-5">
<!-- Card Boas-vindas -->
<div class="card border-0 shadow-sm rounded-4 overflow-hidden" style="max-width: 380px; position: relative;">
<!-- Cabeçalho -->
<div class="p-3 text-white header-card text-start">
<h6 class="fw-bold mb-0">Seja Bem Vindo!</h6>
<small class="opacity-75">Área Administrativa</small>
</div>
<!-- Avatar -->
<div class="avatar-wrapper text-center">
<img src="https://i.pravatar.cc/100" class="avatar-img rounded-circle border border-3 border-white shadow" width="80" height="80" alt="Foto de perfil">
</div>
<!-- Corpo -->
<div class="card-body text-center pt-4">
<h6 class="fw-semibold mb-0 text-truncate">Cesar Henrique de...</h6>
<small class="text-muted d-block mb-2">Desenvolvimento de sistemas</small>
<div class="d-flex justify-content-center align-items-center mt-3">
<div class="me-4 text-muted small">
<span class="d-block fw-bold fs-6 text-dark">6</span>
Produtos
</div>
<div class="border-start ps-4 text-muted small">
<span class="d-block fw-bold fs-6 text-success">R$ 7.203,43</span>
Vendas Total
</div>
</div>
</div>
<!-- Rodapé -->
<div class="card-footer bg-white border-0 text-center pb-4">
<button class="btn btn-primary px-4 rounded-3">Abrir</button>
</div>
</div>
</div>
<!-- KPI 1 -->
<div class="col-12 col-lg-7">
<div class="row g-3">
<div class="col-12 col-md-4">
<div class="card mini-card h-100">
<div class="card-body d-flex align-items-start justify-content-between">
<div>
<div class="text-muted small fw-semibold">Receita Líquida</div>
<div class="value mt-1" id="kpi-rec-liq">R$ 4.179,16</div>
<a class="small" href="#">Estimativa sobre as<br> vendas</a>
</div>
<div class="icon"><i class="bi bi-coin"></i></div>
</div>
</div>
</div>
<div class="col-12 col-md-4">
<div class="card mini-card h-100">
<div class="card-body d-flex align-items-start justify-content-between">
<div>
<div class="text-muted small fw-semibold">Custo Produto</div>
<div class="value mt-1" id="kpi-custo">R$ 3.024,27</div>
<a class="small" href="#">Custo sobre os<br> produtos</a>
</div>
<div class="icon"><i class="bi bi-coin"></i></div>
</div>
</div>
</div>
<div class="col-12 col-md-4">
<div class="card mini-card h-100">
<div class="card-body d-flex align-items-start justify-content-between">
<div>
<div class="text-muted small fw-semibold">Em Estoque</div>
<div class="value mt-1" id="kpi-estoque">R$ 00</div>
<a class="small" href="#">Valor parado sobre<br> produtos</a>
</div>
<div class="icon"><i class="bi bi-exclamation-circle"></i></div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Linha 2: Venda Mensal + Gráfico principal -->
<div class="row g-3 mt-1">
<!-- Venda Mensal -->
<div class="col-12 col-xl-5">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">Venda Mensal</h5>
<div class="text-primary fw-semibold">Este Mês</div>
<div class="row g-3 align-items-center mt-2">
<div class="col-6">
<div class="fs-2 fw-bold" id="venda-mensal">R$ 0,00</div>
<div class="text-success fw-semibold">0,00%</div>
<button class="btn btn-outline-primary btn-sm mt-3">Ver Detalhado</button>
<p class="hint mt-3 mb-0">Projeção calculada com base nas transações recentes.</p>
</div>
<div class="col-6">
<div class="ring">
<canvas id="donutUso"></canvas>
</div>
<div class="text-center hint">Uso Plano NF</div>
</div>
</div>
</div>
</div>
</div>
<!-- Gráfico principal -->
<div class="col-12 col-xl-7">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">Receita Bruta vs Custo por produto - Mês</h5>
<div class="text-center hint mb-2">Desempenho Mensal</div>
<div class="chart-box">
<canvas id="chartArea"></canvas>
</div>
<!-- legenda estilo do print -->
<div class="d-flex justify-content-center gap-4 mt-3">
<span><i class="legend-dot" style="background: rgba(16,185,129,.8)"></i>Receitas</span>
<span><i class="legend-dot" style="background: rgba(239,68,68,.8)"></i>Custos</span>
<span><i class="legend-dot" style="background: rgba(59,130,246,.8)"></i>Lucro Bruto</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
// ===== Helpers =====
const brl = v => v.toLocaleString('pt-BR',{style:'currency',currency:'BRL'});
// ===== Donut (Uso Plano NF) =====
const ctxDonut = document.getElementById('donutUso');
const donut = new Chart(ctxDonut, {
type: 'doughnut',
data: {
labels: ['Usado', 'Livre'],
datasets: [{
data: [0, 100],
backgroundColor: ['#3b82f6', '#e5e7eb'],
borderWidth: 0,
hoverOffset: 3
}]
},
options: {
responsive:true,
maintainAspectRatio:false,
cutout: '70%',
plugins: { legend: { display:false }, tooltip:{ enabled:false } }
}
});
function updateDonut(perc){
const p = Math.max(0, Math.min(100, perc|0));
donut.data.datasets[0].data = [p, 100 - p];
donut.update();
}
// ===== Área: Receita x Custo x Lucro =====
const ctxArea = document.getElementById('chartArea');
const area = new Chart(ctxArea, {
data: {
labels: [],
datasets: [
// Receitas (verde) - área
{ type:'line', label:'Receitas', data:[], tension:.35, pointRadius:3,
fill:true, backgroundColor:'rgba(16,185,129,.18)', borderColor:'rgba(16,185,129,1)', borderWidth:2 },
// Custos (vermelho) - área
{ type:'line', label:'Custos', data:[], tension:.35, pointRadius:3,
fill:true, backgroundColor:'rgba(239,68,68,.16)', borderColor:'rgba(239,68,68,1)', borderWidth:2 },
// Lucro (azul) - linha
{ type:'line', label:'Lucro Bruto', data:[], tension:.35, pointRadius:3,
fill:false, borderColor:'rgba(59,130,246,1)', borderWidth:2 }
]
},
options:{
responsive:true,
maintainAspectRatio:false,
scales:{
x:{ grid:{ display:false } },
y:{ ticks:{ callback:v=> 'R$ ' + v.toLocaleString('pt-BR') } }
},
plugins:{
legend: { display:false },
tooltip: {
callbacks:{
label: ctx => `${ctx.dataset.label}: ${brl(ctx.parsed.y)}`
}
}
}
}
});
/**
* Atualiza o gráfico principal com arrays (formato A):
* updateChartData(
* [500, 800, ...], // receitas
* [300, 500, ...], // custos
* [200, 300, ...], // lucro
* ['mar. de 25', ...]// labels
* )
*/
function updateChartData(receitas=[], custos=[], lucro=[], labels=[]){
area.data.labels = labels;
area.data.datasets[0].data = receitas;
area.data.datasets[1].data = custos;
area.data.datasets[2].data = lucro;
area.update();
// KPIs e "Venda Mensal" com base nos arrays
const receitaTotal = receitas.reduce((a,b)=>a+b,0);
const custoTotal = custos.reduce((a,b)=>a+b,0);
const lucroTotal = lucro.reduce((a,b)=>a+b,0);
document.getElementById('kpi-rec-liq').textContent = brl(receitaTotal - custoTotal * 0.03); // exemplificando taxa/ajuste
document.getElementById('kpi-custo').textContent = brl(custoTotal);
document.getElementById('venda-mensal').textContent= brl(receitaTotal);
// Donut fictício: % de uso proporcional ao número de pontos válidos
const percUso = Math.round((receitas.filter(v=>v>0).length / (labels.length||1)) * 100);
updateDonut(percUso);
}
// ===== DEMO inicial (iguais ao aspecto do print) =====
const labelsDemo = ['mar. de 25','abr. de 25','mai. de 25','jun. de 25','jul. de 25','ago. de 25'];
const receitasDemo = [100, 800, 1600, 4800, 0, 20];
const custosDemo = [80, 500, 1100, 2100, 0, 10];
const lucroDemo = receitasDemo.map((r,i)=> Math.max(0, r - custosDemo[i])); // simples
updateChartData(receitasDemo, custosDemo, lucroDemo, labelsDemo);
updateDonut(0); // começa zerado
</script>
</body>
</html>