Explorar o código

feat(dashboard): color code active students card based on unit ranges

alvesantos hai 1 semana
pai
achega
c8416bab02

+ 2 - 1
src/components/charts/DashboardStatCard.vue

@@ -6,7 +6,7 @@
     </div>
 
     <div class="value-area">
-      <span class="text-h5 text-primary value-text">{{ value }}</span>
+      <span class="text-h5 value-text" :class="valueColor ? `text-${valueColor}` : 'text-primary'">{{ value }}</span>
 
       <q-badge
         v-if="badge"
@@ -30,6 +30,7 @@ defineProps({
   subtitle: { type: String, default: "" },
   badge: { type: String, default: "" },
   badgeColor: { type: String, default: "accent-1" },
+  valueColor: { type: String, default: "" },
   customStyle: { type: String, default: "padding: 4px" },
 });
 </script>

+ 21 - 1
src/pages/dashboard/DashboardPage.vue

@@ -7,6 +7,7 @@
         <DashboardStatCard
           :badge="`${totalAlunos} ativos`"
           :value="String(totalAlunos)"
+          :value-color="activeStudentsColor"
           icon="mdi-account-multiple-outline"
           title="Total alunos (contratos ativos)"
         />
@@ -299,6 +300,21 @@ const aniversariantes = ref([]);
 const feriadosLoading = ref(false);
 const students = ref([]);
 const totalAlunos = ref(0);
+const unitConfig = ref({
+  active_students_min: 30,
+  active_students_medium: 50,
+  active_students_max: 80,
+});
+
+const activeStudentsColor = computed(() => {
+  const count = totalAlunos.value;
+  const min = unitConfig.value.active_students_min;
+  const med = unitConfig.value.active_students_medium;
+
+  if (count < min) return "negative"; // Vermelho
+  if (count >= min && count < med) return "warning"; // Amarelo
+  return "positive"; // Verde (>= med)
+});
 
 const gaugeData = ref({
   datasets: [
@@ -541,6 +557,10 @@ const fetchSummary = async () => {
     students.value = summary.enrollments;
     totalAlunos.value = summary.students_count;
 
+    if (summary.unit_config) {
+      unitConfig.value = summary.unit_config;
+    }
+
     gaugeData.value.datasets[0].needleValue = Math.min(
       activeContracts.value,
       10,
@@ -668,4 +688,4 @@ onMounted(() => {
     flex: 1 1 calc(50% - 8px);
   }
 }
-</style>
+</style>

+ 43 - 0
src/pages/unit/tabs/UnitDataTab.vue

@@ -189,6 +189,42 @@
               outlined
             />
 
+            <div class="col-12 q-mt-md">
+              <div class="text-subtitle2 text-grey-7 q-mb-sm">
+                Configurações de Dashboard (Metas de Alunos)
+              </div>
+            </div>
+
+            <DefaultInput
+              v-model="form.active_students_min"
+              type="number"
+              :error="!!validationErrors.active_students_min"
+              :error-message="validationErrors.active_students_min"
+              class="col-4"
+              label="Mínimo de Alunos (🔴 Abaixo deste valor)"
+              outlined
+            />
+
+            <DefaultInput
+              v-model="form.active_students_medium"
+              type="number"
+              :error="!!validationErrors.active_students_medium"
+              :error-message="validationErrors.active_students_medium"
+              class="col-4"
+              label="Meta Média (🟡 Entre mín e médio)"
+              outlined
+            />
+
+            <DefaultInput
+              v-model="form.active_students_max"
+              type="number"
+              :error="!!validationErrors.active_students_max"
+              :error-message="validationErrors.active_students_max"
+              class="col-4"
+              label="Meta Máxima (🟢 Acima da média)"
+              outlined
+            />
+
             <div class="col-12 q-mt-sm">
               <div class="text-subtitle2 text-grey-7 q-mb-sm">
                 Alterar Senha
@@ -322,6 +358,9 @@ const {
   state_id: null,
   state_registration: null,
   street: null,
+  active_students_min: null,
+  active_students_medium: null,
+  active_students_max: null,
 });
 
 const hasChanges = computed(
@@ -418,6 +457,10 @@ onMounted(async () => {
 
     form.street = unit.street;
 
+    form.active_students_min = unit.active_students_min ?? 30;
+    form.active_students_medium = unit.active_students_medium ?? 50;
+    form.active_students_max = unit.active_students_max ?? 80;
+
     cityName.value = unit.city?.name ?? "";
     stateName.value = unit.state?.name ?? "";