|
|
@@ -0,0 +1,158 @@
|
|
|
+<template>
|
|
|
+ <div class="parceiros-page">
|
|
|
+ <DefaultHeaderPage class="q-mx-md"/>
|
|
|
+
|
|
|
+ <div class="q-pb-sm q-ma-md">
|
|
|
+ <q-input
|
|
|
+ v-model="searchQuery"
|
|
|
+ outlined
|
|
|
+ dense
|
|
|
+ bg-color="white"
|
|
|
+ :placeholder="$t('parceiro.search_placeholder')"
|
|
|
+ clearable
|
|
|
+ class="parceiros-page__search-input"
|
|
|
+ >
|
|
|
+ <template #prepend>
|
|
|
+ <q-icon name="mdi-magnify" />
|
|
|
+ </template>
|
|
|
+ </q-input>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="chips-scroll q-ma-md">
|
|
|
+ <div
|
|
|
+ :class="['cat-chip', activeCategory === 'all' ? 'cat-chip--selected' : 'cat-chip--default']"
|
|
|
+ @click="activeCategory = 'all'"
|
|
|
+ >
|
|
|
+ {{ $t('common.terms.all') }}
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-for="cat in categories"
|
|
|
+ :key="cat.id"
|
|
|
+ :class="['cat-chip', activeCategory === String(cat.id) ? 'cat-chip--selected' : 'cat-chip--default']"
|
|
|
+ @click="activeCategory = String(cat.id)"
|
|
|
+ >
|
|
|
+ {{ cat.name }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-if="loading" class="flex flex-center q-pa-xl q-ma-md">
|
|
|
+ <q-spinner color="violet-normal" size="50px" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-else-if="filteredPartners.length === 0" class="flex flex-center q-pa-xl text-grey-6 q-ma-md">
|
|
|
+ {{ $t("http.errors.no_records_found") }}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-else class="cards-column q-ma-md">
|
|
|
+ <PartnerAgreementCard
|
|
|
+ v-for="partner in filteredPartners"
|
|
|
+ :key="partner.id"
|
|
|
+ :partner="partner"
|
|
|
+ :editable="false"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, computed, onMounted } from "vue";
|
|
|
+import { getPartnerAgreements } from "src/api/partnerAgreement";
|
|
|
+import { getCategories } from "src/api/category";
|
|
|
+import { normalizeString } from "src/helpers/utils";
|
|
|
+import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
|
|
|
+import PartnerAgreementCard from "./components/PartnerAgreementCard.vue";
|
|
|
+
|
|
|
+const loading = ref(true);
|
|
|
+const allPartners = ref([]);
|
|
|
+const categories = ref([]);
|
|
|
+const activeCategory = ref("all");
|
|
|
+const searchQuery = ref("");
|
|
|
+
|
|
|
+const filteredPartners = computed(() => {
|
|
|
+ let list = allPartners.value;
|
|
|
+
|
|
|
+ if (activeCategory.value !== "all") {
|
|
|
+ list = list.filter((p) => String(p.category_id) === activeCategory.value);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (searchQuery.value) {
|
|
|
+ const needle = normalizeString(searchQuery.value);
|
|
|
+ list = list.filter((p) => {
|
|
|
+ const fields = [p.company_name, p.cnpj, p.responsible, p.email, p.phone, p.category?.name, p.address, p.city?.name];
|
|
|
+ return fields.some((f) => f && normalizeString(String(f)).includes(needle));
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ return list;
|
|
|
+});
|
|
|
+
|
|
|
+onMounted(async () => {
|
|
|
+ try {
|
|
|
+ const [partners, cats] = await Promise.all([
|
|
|
+ getPartnerAgreements({ type: "partner" }),
|
|
|
+ getCategories("partner"),
|
|
|
+ ]);
|
|
|
+ allPartners.value = partners;
|
|
|
+ categories.value = cats;
|
|
|
+ } finally {
|
|
|
+ loading.value = false;
|
|
|
+ }
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+@use "src/css/quasar.variables.scss" as vars;
|
|
|
+
|
|
|
+.parceiros-page {
|
|
|
+ background: vars.$violet-light;
|
|
|
+ min-height: calc(100dvh - 68px);
|
|
|
+ box-sizing: border-box;
|
|
|
+ overflow-x: hidden;
|
|
|
+ max-width: 100vw;
|
|
|
+ width: 100%;
|
|
|
+ padding-bottom: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.parceiros-page__search-input {
|
|
|
+ max-width: 700px;
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.chips-scroll {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.cat-chip {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ height: 28px;
|
|
|
+ padding: 0 12px;
|
|
|
+ border-radius: 5px;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 500;
|
|
|
+ cursor: pointer;
|
|
|
+ user-select: none;
|
|
|
+ white-space: nowrap;
|
|
|
+ transition: background 0.15s, color 0.15s;
|
|
|
+}
|
|
|
+
|
|
|
+.cat-chip--default {
|
|
|
+ background: #c9a3dc;
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.cat-chip--selected {
|
|
|
+ background: #4d1658;
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.cards-column {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 16px;
|
|
|
+}
|
|
|
+</style>
|