ProfileBankDataDialog.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <template>
  2. <q-dialog ref="dialogRef" persistent maximized transition-show="slide-left" transition-hide="slide-right">
  3. <div class="bg-page full-height no-shadow">
  4. <div class="row items-center q-px-md q-pt-md q-pb-sm bg-white shadow-profile bg-surface">
  5. <q-btn v-close-popup icon="mdi-chevron-left" flat round dense color="primary" />
  6. <q-space />
  7. <span class="gradient-diarista font16 fontbold">{{ $t('profile.bank_data.title') }}</span>
  8. <q-space />
  9. <div style="width: 32px"></div>
  10. </div>
  11. <q-card-section class="col">
  12. <div class="text-text">
  13. <div class="gradient-diarista font14 fontbold">{{ $t('profile.bank_data.my_bank_data_title') }}</div>
  14. <div class="text-grey-7 q-mb-md font12 fontregular">{{ $t('profile.bank_data.subtitle') }}</div>
  15. <div class="pix-warning q-pa-md q-mb-md row items-start q-col-gutter-sm">
  16. <q-icon name="mdi-alert-outline" color="warning" size="20px" class="q-mt-xs" />
  17. <div class="col font12">
  18. <span class="fontbold">{{ $t('profile.bank_data.warning_title') }}</span>
  19. {{ $t('profile.bank_data.warning_message') }}
  20. </div>
  21. </div>
  22. <q-card class="q-pa-md bg-white shadow-card q-mb-md" style="border-radius: 20px;" :flat="false">
  23. <div class="text-center text-text q-mb-sm font14 fontbold">
  24. <div>
  25. {{ $t('profile.bank_data.pix_title') }}
  26. </div>
  27. </div>
  28. <q-input
  29. v-model="pixForm.pix_key"
  30. outlined
  31. dense
  32. input-class="text-text"
  33. :placeholder="$t('profile.bank_data.pix_key_placeholder')"
  34. class="q-mb-sm"
  35. />
  36. <q-btn
  37. unelevated
  38. rounded
  39. no-caps
  40. color="primary"
  41. class="full-width"
  42. padding="4px 12px"
  43. :label="pixAlreadyRegistered ? $t('profile.bank_data.att_pix') : $t('profile.bank_data.save_pix')"
  44. :loading="savingPix"
  45. :disable="!hasPixUpdatedFields"
  46. @click="savePix"
  47. />
  48. </q-card>
  49. <q-card class="q-pa-md bg-white row shadow-card q-mb-md" style="border-radius: 20px;" :flat="false">
  50. <div class="text-center text-text q-mb-sm col-12 font14 fontbold">
  51. {{ $t('profile.bank_data.bank_account_title') }}
  52. </div>
  53. <div class="row q-mb-sm q-my-auto col-12 row items-center">
  54. <q-radio
  55. v-model="bankForm.bank_account_type"
  56. val="checking"
  57. :label="$t('profile.bank_data.checking')"
  58. color="primary"
  59. keep-color
  60. class="q-mr-lg text-text"
  61. />
  62. <q-radio
  63. v-model="bankForm.bank_account_type"
  64. val="savings"
  65. :label="$t('profile.bank_data.savings')"
  66. color="primary"
  67. keep-color
  68. class="text-text"
  69. />
  70. </div>
  71. <q-input
  72. v-model="bankForm.agency"
  73. outlined
  74. dense
  75. input-class="text-text"
  76. :placeholder="$t('profile.bank_data.agency')"
  77. class="q-mb-sm col-12"
  78. />
  79. <q-input
  80. v-model="bankForm.account"
  81. outlined
  82. dense
  83. input-class="text-text"
  84. :placeholder="$t('profile.bank_data.account')"
  85. class="q-mb-sm col-12"
  86. />
  87. <q-input
  88. v-model="bankForm.digit"
  89. outlined
  90. dense
  91. input-class="text-text"
  92. :placeholder="$t('profile.bank_data.digit')"
  93. class="q-mb-sm col-3"
  94. />
  95. <q-btn
  96. unelevated
  97. rounded
  98. no-caps
  99. color="primary"
  100. padding="8px 16px"
  101. class="full-width"
  102. :label="bankAlreadyRegistered ? $t('profile.bank_data.att_bank') : $t('profile.bank_data.save_account')"
  103. :loading="savingBank"
  104. :disable="!hasBankUpdatedFields"
  105. @click="saveBank"
  106. />
  107. </q-card>
  108. </div>
  109. <div class="q-pb-xl"></div>
  110. </q-card-section>
  111. </div>
  112. </q-dialog>
  113. </template>
  114. <script setup>
  115. import { ref, onMounted } from 'vue';
  116. import { useDialogPluginComponent, useQuasar } from 'quasar';
  117. import {
  118. getProviderPaymentMethods,
  119. createProviderPaymentMethod,
  120. updateProviderPaymentMethod,
  121. } from 'src/api/providerPaymentMethod';
  122. import { userStore } from 'src/stores/user';
  123. import { useFormUpdateTracker } from 'src/composables/useFormUpdateTracker';
  124. import { useI18n } from 'vue-i18n';
  125. defineEmits([...useDialogPluginComponent.emits]);
  126. const { dialogRef } = useDialogPluginComponent();
  127. const $q = useQuasar();
  128. const { t } = useI18n();
  129. const user = userStore();
  130. const pixId = ref(null);
  131. const bankId = ref(null);
  132. const savingPix = ref(false);
  133. const savingBank = ref(false);
  134. const pixAlreadyRegistered = ref(false);
  135. const bankAlreadyRegistered = ref(false);
  136. const {
  137. form: pixForm,
  138. hasUpdatedFields: hasPixUpdatedFields,
  139. getUpdatedFields: getPixUpdatedFields,
  140. setUpdateFormAsOriginal: setPixOriginal,
  141. } = useFormUpdateTracker({
  142. pix_key: '',
  143. });
  144. const {
  145. form: bankForm,
  146. hasUpdatedFields: hasBankUpdatedFields,
  147. getUpdatedFields: getBankUpdatedFields,
  148. setUpdateFormAsOriginal: setBankOriginal,
  149. } = useFormUpdateTracker({
  150. bank_account_type: 'checking',
  151. agency: '',
  152. account: '',
  153. digit: '',
  154. });
  155. const savePix = async () => {
  156. if (!pixForm.pix_key) {
  157. $q.notify({ type: 'negative', message: t('profile.bank_data.pix_key_required') });
  158. return;
  159. }
  160. savingPix.value = true;
  161. try {
  162. const payload = {
  163. provider_id: user.user.provider.id,
  164. account_type: 'pix',
  165. pix_key: pixForm.pix_key,
  166. };
  167. if (pixId.value) {
  168. await updateProviderPaymentMethod(pixId.value, getPixUpdatedFields.value);
  169. } else {
  170. const created = await createProviderPaymentMethod(payload);
  171. pixId.value = created.id;
  172. }
  173. setPixOriginal();
  174. $q.notify({ type: 'positive', message: t('profile.bank_data.pix_saved') });
  175. } catch (error) {
  176. $q.notify({ type: 'negative', message: t('profile.bank_data.save_error') });
  177. console.log(error);
  178. } finally {
  179. savingPix.value = false;
  180. }
  181. };
  182. const saveBank = async () => {
  183. if (!bankForm.agency || !bankForm.account) {
  184. $q.notify({ type: 'negative', message: t('profile.bank_data.bank_fields_required') });
  185. return;
  186. }
  187. savingBank.value = true;
  188. try {
  189. const payload = {
  190. provider_id: user.user.provider.id,
  191. account_type: 'bank_account',
  192. bank_account_type: bankForm.bank_account_type,
  193. agency: bankForm.agency,
  194. account: bankForm.account,
  195. digit: bankForm.digit,
  196. };
  197. if (bankId.value) {
  198. await updateProviderPaymentMethod(bankId.value, getBankUpdatedFields.value);
  199. } else {
  200. const created = await createProviderPaymentMethod(payload);
  201. bankId.value = created.id;
  202. }
  203. setBankOriginal();
  204. $q.notify({ type: 'positive', message: t('profile.bank_data.account_saved') });
  205. } catch (error) {
  206. $q.notify({ type: 'negative', message: t('profile.bank_data.save_error') });
  207. console.log(error);
  208. } finally {
  209. savingBank.value = false;
  210. }
  211. };
  212. onMounted(async () => {
  213. try {
  214. const methods = await getProviderPaymentMethods(user.user.provider.id);
  215. if (!methods) return;
  216. const pix = methods.find((m) => m.account_type === 'pix');
  217. if (pix) {
  218. pixId.value = pix.id;
  219. pixForm.pix_key = pix.pix_key || '';
  220. setPixOriginal();
  221. pixAlreadyRegistered.value = true;
  222. }
  223. const bank = methods.find((m) => m.account_type === 'bank_account');
  224. if (bank) {
  225. bankId.value = bank.id;
  226. bankForm.bank_account_type = bank.bank_account_type || 'checking';
  227. bankForm.agency = bank.agency || '';
  228. bankForm.account = bank.account || '';
  229. bankForm.digit = bank.digit || '';
  230. setBankOriginal();
  231. bankAlreadyRegistered.value = true;
  232. }
  233. } catch (error) {
  234. console.error('Erro ao carregar dados bancários:', error);
  235. }
  236. });
  237. </script>
  238. <style scoped>
  239. .pix-warning {
  240. background-color: #EEF0FF;
  241. border-radius: 12px;
  242. }
  243. </style>