DashboardStatCard.vue 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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 value-text" :class="valueColor ? `text-${valueColor}` : 'text-primary'">{{ 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. valueColor: { type: String, default: "" },
  31. customStyle: { type: String, default: "padding: 4px" },
  32. });
  33. </script>
  34. <style scoped lang="scss">
  35. .stat-card {
  36. flex: 1 1 0;
  37. min-width: 0;
  38. height: 140px;
  39. border-radius: 12px;
  40. box-shadow: 0 0 0 1px #c0c0c0c0 !important;
  41. padding: 16px 20px;
  42. display: flex;
  43. flex-direction: column;
  44. justify-content: space-between;
  45. }
  46. .value-area {
  47. display: flex;
  48. flex-direction: column;
  49. gap: 4px;
  50. }
  51. .value-text {
  52. font-weight: 600;
  53. line-height: 1.2;
  54. }
  55. .stat-badge {
  56. font-size: 12px;
  57. border-radius: 8px;
  58. width: fit-content;
  59. color: $primary;
  60. }
  61. </style>