| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- <template>
- <q-dialog ref="dialogRef" persistent maximized transition-show="slide-left" transition-hide="slide-right">
- <div class="bg-page full-height column no-shadow">
- <div class="row items-center q-px-md q-pt-md q-pb-sm bg-white shadow-profile bg-surface">
- <q-btn v-close-popup icon="mdi-chevron-left" flat round dense color="primary" />
- <q-space />
- <span class="text-subtitle1 text-primary font16 fontbold gradient-diarista">{{ $t('profile.payments.subtitle') }}</span>
- <q-space />
- </div>
- <div v-if="loading" class="col flex flex-center">
- <q-spinner color="primary" size="3em" />
- </div>
- <div v-else class="col column q-px-md q-pt-lg overflow-auto">
- <span class="text-primary q-mb-lg ml-xs font16 fontbold gradient-diarista">{{ $t('profile.payments.description')
- }}</span>
- <div class="payment-card-container q-pa-lg font12 fontregular">
- <div>
- <div v-if="paymentMethods.length === 0" class="column items-center justify-center q-py-xl">
- <q-icon name="mdi-credit-card-off-outline" size="64px" color="grey-4" class="q-mb-md" />
- <p class="text-text text-center q-mb-xs">
- {{ $t('profile.payments.no_cards') }}
- </p>
- <p class="text-grey-6 text-center q-mb-xl">
- {{ $t('profile.payments.add_first_card') }}
- </p>
- </div>
- <div v-else class="column q-gutter-y-md">
- <div v-for="item in paymentMethods" :key="item.id" class="card-item-box row items-center no-wrap q-pa-md">
- <div class="brand-logo-wrapper q-mr-md">
- <BrandDetectorPanel :brand="item.brand" />
- </div>
- <div class="col column">
- <span class="card-type text-dark">{{ $t('profile.payments.credit') }}</span>
- <div class="row items-center no-wrap">
- <span class="card-bank-new">{{ cardLabel(item) }}</span>
- </div>
- <span class="card-number-new">{{ '**** ' + item.last_four_digits }}</span>
- </div>
- <div class="row items-end">
- <q-btn flat round icon="mdi-pencil-outline" color="grey-8" size="15px" @click="openEditDialog(item)" />
- <q-btn flat round icon="mdi-trash-can-outline" color="grey-8" size="15px" @click="confirmRemove(item)" />
- </div>
- </div>
- </div>
- </div>
- <div class="q-mt-xl">
- <q-btn unelevated rounded no-caps color="primary" class="full-width" padding="8px 16px" :label="$t('profile.payments.add_card')" @click="openAddDialog" />
- </div>
- </div>
- </div>
- </div>
- </q-dialog>
- </template>
- <script setup>
- import { ref, onMounted } from 'vue';
- import { useDialogPluginComponent, useQuasar } from 'quasar';
- import { userStore } from 'src/stores/user';
- import { getClientPaymentMethods, deleteClientPaymentMethod } from 'src/api/clientPaymentMethod';
- import ProfilePaymentAddDialog from './ProfilePaymentAddDialog.vue';
- import ProfilePaymentRemoveDialog from './ProfilePaymentRemoveDialog.vue';
- import BrandDetectorPanel from '../brandDetector/BrandDetectorPanel.vue';
- defineEmits([...useDialogPluginComponent.emits]);
- const { dialogRef } = useDialogPluginComponent();
- const $q = useQuasar();
- const store = userStore();
- const paymentMethods = ref([]);
- const loading = ref(false);
- const cardLabel = (item) => {
- const parts = [];
- if (item.card_name) parts.push(item.card_name);
- if (item.brand) parts.push(item.brand.charAt(0).toUpperCase() + item.brand.slice(1));
- return parts.join(' - ') || '—';
- };
- const openAddDialog = () => {
- $q.dialog({
- component: ProfilePaymentAddDialog,
- componentProps: {
- clientId: store.user?.client_id,
- },
- }).onOk(() => {
- loadPaymentMethods();
- });
- };
- const openEditDialog = (item) => {
- $q.dialog({
- component: ProfilePaymentAddDialog,
- componentProps: {
- clientId: store.user?.client_id,
- paymentMethod: item,
- },
- }).onOk(() => {
- loadPaymentMethods();
- });
- };
- const confirmRemove = (item) => {
- $q.dialog({
- component: ProfilePaymentRemoveDialog,
- }).onOk(async () => {
- try {
- await deleteClientPaymentMethod(item.id);
- paymentMethods.value = paymentMethods.value.filter(p => p.id !== item.id);
- } catch (error) {
- console.error('Erro ao remover cartão:', error);
- }
- });
- };
- const loadPaymentMethods = async () => {
- loading.value = true;
- try {
- const clientId = store.user?.client_id;
- if (clientId) {
- paymentMethods.value = await getClientPaymentMethods(clientId);
- }
- } catch (error) {
- console.error('Erro ao carregar métodos de pagamento:', error);
- } finally {
- loading.value = false;
- }
- };
- onMounted(loadPaymentMethods);
- </script>
- <style scoped lang="scss">
- .payment-card-container {
- background: white;
- border-radius: 30px;
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
- margin-bottom: 40px;
- }
- .card-item-box {
- border: 1px solid #b5b5b5;
- border-radius: 4px;
- background: white;
- }
- .brand-logo-wrapper {
- width: 50px;
- height: 32px;
- display: flex;
- align-items: center;
- justify-content: center;
- flex-shrink: 0;
- }
- .card-type {
- line-height: 1.2;
- }
- .card-bank-new {
- color: #666;
- line-height: 1.4;
- }
- .card-number-new {
- color: #333;
- letter-spacing: 0.5px;
- line-height: 1.2;
- }
- .ml-xs {
- margin-left: 4px;
- }
- </style>
|