|
@@ -187,6 +187,31 @@
|
|
|
subtitle="0 pagamentos pendentes"
|
|
subtitle="0 pagamentos pendentes"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="charts-row">
|
|
|
|
|
+ <DashboardChartCard title="Faturamento Serviço / Materiais">
|
|
|
|
|
+ <GroupedBarChart
|
|
|
|
|
+ :labels="faturamentoChart.labels"
|
|
|
|
|
+ :datasets="faturamentoChart.datasets"
|
|
|
|
|
+ label-y="R$"
|
|
|
|
|
+ :tick-formatter="formatCurrencyTick"
|
|
|
|
|
+ :tooltip-formatter="formatCurrencyTooltip"
|
|
|
|
|
+ class="full-width full-height"
|
|
|
|
|
+ />
|
|
|
|
|
+ </DashboardChartCard>
|
|
|
|
|
+
|
|
|
|
|
+ <DashboardChartCard title="Matrículas por Período">
|
|
|
|
|
+ <GroupedBarChart
|
|
|
|
|
+ :labels="matriculasChart.labels"
|
|
|
|
|
+ :datasets="matriculasChart.datasets"
|
|
|
|
|
+ :bar-radius="50"
|
|
|
|
|
+ :show-datalabels="true"
|
|
|
|
|
+ class="full-width full-height"
|
|
|
|
|
+ />
|
|
|
|
|
+ </DashboardChartCard>
|
|
|
|
|
+
|
|
|
|
|
+ <AniversariantesCard :people="aniversariantes" />
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div v-else class="flex flex-center full-width q-pa-xl">
|
|
<div v-else class="flex flex-center full-width q-pa-xl">
|
|
@@ -200,6 +225,9 @@ import { onMounted, ref, watch } from "vue";
|
|
|
import { useI18n } from "vue-i18n";
|
|
import { useI18n } from "vue-i18n";
|
|
|
import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
|
|
import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
|
|
|
import DashboardStatCard from "src/components/charts/DashboardStatCard.vue";
|
|
import DashboardStatCard from "src/components/charts/DashboardStatCard.vue";
|
|
|
|
|
+import DashboardChartCard from "src/components/charts/DashboardChartCard.vue";
|
|
|
|
|
+import GroupedBarChart from "src/components/charts/normal/GroupedBarChart.vue";
|
|
|
|
|
+import AniversariantesCard from "src/components/charts/AniversariantesCard.vue";
|
|
|
|
|
|
|
|
const { t } = useI18n();
|
|
const { t } = useI18n();
|
|
|
|
|
|
|
@@ -220,6 +248,56 @@ const periodOptions = [
|
|
|
{ label: "Personalizado", value: "custom" },
|
|
{ label: "Personalizado", value: "custom" },
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
|
|
+// --- Aniversariantes do Mês (hardcoded) ---
|
|
|
|
|
+const aniversariantes = [
|
|
|
|
|
+ { day: 10, name: "Heloisa Faria" },
|
|
|
|
|
+ { day: 7, name: "Juliana Costa" },
|
|
|
|
|
+ { day: 24, name: "Fernando Almeida" },
|
|
|
|
|
+ { day: 28, name: "Patrícia Lima" },
|
|
|
|
|
+];
|
|
|
|
|
+// -------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+// --- Matrículas por Período (hardcoded) ---
|
|
|
|
|
+const matriculasChart = {
|
|
|
|
|
+ labels: ["JAN", "FEV", "MAR", "ABR", "MAI", "JUN"],
|
|
|
|
|
+ datasets: [
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "Matrículas",
|
|
|
|
|
+ data: [120, 200, 150, 80, 70, 110],
|
|
|
|
|
+ color: ["#3B82F6", "#EF4444", "#A855F7", "#374151", "#EAB308", "#06B6D4"],
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+};
|
|
|
|
|
+// ---------------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+// --- Faturamento Serviço / Materiais (hardcoded) ---
|
|
|
|
|
+const faturamentoChart = {
|
|
|
|
|
+ labels: ["17/02", "20/02", "23/02", "26/02"],
|
|
|
|
|
+ datasets: [
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "Serviço",
|
|
|
|
|
+ data: [18500, 22300, 15800, 27600],
|
|
|
|
|
+ color: "#7C3AED",
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "Materiais",
|
|
|
|
|
+ data: [9200, 11400, 8700, 13100],
|
|
|
|
|
+ color: "#EC4899",
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const formatCurrencyTick = (value) => {
|
|
|
|
|
+ if (value >= 1000) return `R$ ${(value / 1000).toFixed(0)}k`;
|
|
|
|
|
+ return `R$ ${value}`;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const formatCurrencyTooltip = (context) => {
|
|
|
|
|
+ const value = context.parsed.y;
|
|
|
|
|
+ return ` ${context.dataset.label}: R$ ${value.toLocaleString("pt-BR", { minimumFractionDigits: 2 })}`;
|
|
|
|
|
+};
|
|
|
|
|
+// ---------------------------------------------------
|
|
|
|
|
+
|
|
|
const ordersChart = ref({});
|
|
const ordersChart = ref({});
|
|
|
const participantsChart = ref({});
|
|
const participantsChart = ref({});
|
|
|
const paymentsChart = ref({});
|
|
const paymentsChart = ref({});
|
|
@@ -410,6 +488,28 @@ onMounted(async () => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.charts-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 16px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.charts-row > * {
|
|
|
|
|
+ flex: 1 1 350px;
|
|
|
|
|
+ min-width: 280px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.charts-row > *:last-child {
|
|
|
|
|
+ flex: 0 1 240px;
|
|
|
|
|
+ min-width: 200px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@media (max-width: 599px) {
|
|
|
|
|
+ .charts-row > * {
|
|
|
|
|
+ flex: 1 1 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.filter-row {
|
|
.filter-row {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
flex-wrap: wrap;
|