Procházet zdrojové kódy

feat(treasury): render dynamic bank cards with add button

Replaces hardcoded banks with treasury_accounts loaded from the API;
keeps a fixed Saldo Total card and adds a + card opening the create dialog.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ebagabee před 1 dnem
rodič
revize
b82b28fd73
1 změnil soubory, kde provedl 76 přidání a 12 odebrání
  1. 76 12
      src/pages/financial/TreasuryPage.vue

+ 76 - 12
src/pages/financial/TreasuryPage.vue

@@ -3,9 +3,9 @@
     <DefaultHeaderPage title="Tesouraria" :show-filter-icon="false" />
 
     <div class="q-px-md"><DevBanner /></div>
-    <div class="row q-pa-md q-gutter-md">
+    <div class="row q-pa-md q-gutter-md items-stretch">
       <FinancialCard
-        v-for="bank in banks"
+        v-for="bank in cards"
         :key="bank.key"
         :title="bank.label"
         :icon="bank.icon"
@@ -15,6 +15,15 @@
         :selected="selectedBank.key === bank.key"
         @click="selectedBank = bank"
       />
+
+      <q-card
+        v-if="!loading"
+        class="treasury-add-card"
+        @click="openCreateDialog"
+      >
+        <q-icon name="mdi-plus" size="28px" color="primary" />
+        <span class="text-subtitle2 text-primary">Adicionar banco</span>
+      </q-card>
     </div>
 
     <div class="q-px-md">
@@ -33,22 +42,33 @@
 </template>
 
 <script setup>
-import { ref } from "vue";
+import { ref, computed, onMounted } from "vue";
+import { useQuasar } from "quasar";
 import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
 import DevBanner from "src/components/shared/DevBanner.vue";
 import DefaultTable from "src/components/defaults/DefaultTable.vue";
 import FinancialCard from "src/components/financial/FinancialCard.vue";
+import AddEditTreasuryAccountDialog from "src/components/financial/AddEditTreasuryAccountDialog.vue";
+import { getTreasuryAccounts } from "src/api/treasury_account";
 
-const banks = [
-  { key: "total", label: "Saldo Total", icon: "mdi-bank" },
-  { key: "bb", label: "Banco do Brasil", icon: "mdi-bank-outline" },
-  { key: "itau", label: "Itaú Unibanco", icon: "mdi-bank-outline" },
-  { key: "bradesco", label: "Bradesco", icon: "mdi-bank-outline" },
-  { key: "santander", label: "Santander", icon: "mdi-bank-outline" },
-  { key: "carteira", label: "Carteira", icon: "mdi-wallet-outline" },
-];
+const $q = useQuasar();
+
+const totalCard = { key: "total", label: "Saldo Total", icon: "mdi-bank" };
+
+const accounts = ref([]);
+const loading = ref(false);
+const selectedBank = ref(totalCard);
+
+const cards = computed(() => [
+  totalCard,
+  ...accounts.value.map((account) => ({
+    key: `account-${account.id}`,
+    label: account.name,
+    icon: "mdi-bank-outline",
+    account,
+  })),
+]);
 
-const selectedBank = ref(banks[0]);
 const rows = ref([]);
 
 const columns = [
@@ -57,5 +77,49 @@ const columns = [
   { name: "updated_at", label: "Atualização", field: "updated_at", align: "left" },
 ];
 
+const fetchAccounts = async () => {
+  loading.value = true;
+  try {
+    accounts.value = await getTreasuryAccounts();
+  } catch {
+    $q.notify({ type: "negative", message: "Erro ao carregar os bancos." });
+  } finally {
+    loading.value = false;
+  }
+};
+
+const openCreateDialog = () => {
+  $q.dialog({ component: AddEditTreasuryAccountDialog }).onOk(() => {
+    $q.notify({ type: "positive", message: "Banco cadastrado com sucesso." });
+    fetchAccounts();
+  });
+};
+
 const handleAddItem = () => {};
+
+onMounted(fetchAccounts);
 </script>
+
+<style scoped lang="scss">
+@import "src/css/quasar.variables.scss";
+
+.treasury-add-card {
+  flex: 1 1 0;
+  min-width: 220px;
+  border-radius: 12px;
+  border: 1.5px dashed #c0c0c0;
+  box-shadow: none !important;
+  padding: 16px 20px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  gap: 8px;
+  cursor: pointer;
+  transition: border-color 0.15s ease;
+
+  &:hover {
+    border-color: $primary;
+  }
+}
+</style>