DashboardStatCard.vue 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. <template>
  2. <q-card class="stat-card">
  3. <div class="flex justify-between items-start no-wrap">
  4. <span class="text-subtitle2 text-dark">{{ title }}</span>
  5. <q-icon :name="icon" size="22px" color="dark" />
  6. </div>
  7. <div class="value-area">
  8. <span class="text-h5 text-primary value-text">{{ value }}</span>
  9. <q-badge
  10. v-if="badge"
  11. :color="badgeColor"
  12. :label="badge"
  13. :style="customStyle"
  14. class="stat-badge"
  15. />
  16. <span v-else-if="subtitle" class="text-caption text-foreground">{{
  17. subtitle
  18. }}</span>
  19. </div>
  20. </q-card>
  21. </template>
  22. <script setup>
  23. defineProps({
  24. title: { type: String, required: true },
  25. icon: { type: String, default: "mdi-information-outline" },
  26. value: { type: [String, Number], required: true },
  27. subtitle: { type: String, default: "" },
  28. badge: { type: String, default: "" },
  29. badgeColor: { type: String, default: "accent-1" },
  30. customStyle: { type: String, default: "padding: 4px" },
  31. });
  32. </script>
  33. <style scoped lang="scss">
  34. .stat-card {
  35. flex: 1 1 0;
  36. min-width: 0;
  37. height: 140px;
  38. border-radius: 12px;
  39. box-shadow: 0 0 0 1px #c0c0c0c0 !important;
  40. padding: 16px 20px;
  41. display: flex;
  42. flex-direction: column;
  43. justify-content: space-between;
  44. }
  45. .value-area {
  46. display: flex;
  47. flex-direction: column;
  48. gap: 4px;
  49. }
  50. .value-text {
  51. font-weight: 600;
  52. line-height: 1.2;
  53. }
  54. .stat-badge {
  55. font-size: 12px;
  56. border-radius: 8px;
  57. width: fit-content;
  58. color: $primary;
  59. }
  60. </style>