| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- <template>
- <q-card-section class="no-padding">
- <div>
- <div class="text-text">
- <span class="font14 fontbold">{{ $t('auth.full_name') }}</span>
- </div>
- <q-input
- v-model="form.name"
- no-error-icon
- outlined
- rounded
- bg-color="surface"
- class="q-mt-sm q-mb-md"
- input-class="text-text"
- :placeholder="$t('auth.full_name')"
- hide-bottom-space
- :rules="[inputRules.required]"
- lazy-rules
- />
- </div>
- <div>
- <div class="text-text">
- <span class="font14 fontbold">{{ $t('common.terms.cpf') }}</span>
- </div>
- <q-input
- v-model="form.document"
- no-error-icon
- outlined
- rounded
- bg-color="surface"
- class="q-mt-sm q-mb-md"
- input-class="text-text"
- placeholder="000.000.000-00"
- hide-bottom-space
- :rules="[inputRules.required, inputRules.cpf]"
- lazy-rules
- mask="###.###.###-##"
- />
- </div>
- <div>
- <div class="text-text">
- <span class="font14 fontbold">{{ $t('common.terms.cep') }}</span>
- </div>
- <q-input
- v-model="form.zip_code"
- no-error-icon
- outlined
- rounded
- bg-color="surface"
- class="q-mt-sm q-mb-md"
- input-class="text-text"
- placeholder="00000-000"
- hide-bottom-space
- :rules="[inputRules.required, inputRules.cep]"
- lazy-rules
- mask="#####-###"
- :loading="loadingCep"
- @update:model-value="onCepChange"
- />
- </div>
- <div>
- <div class="text-text">
- <span class="font14 fontbold">{{ $t('common.terms.address') }}</span>
- </div>
- <q-input
- v-model="form.address"
- no-error-icon
- outlined
- rounded
- bg-color="surface"
- class="q-mt-sm q-mb-md"
- input-class="text-text"
- :placeholder="`${$t('common.terms.address')}...`"
- hide-bottom-space
- :rules="[inputRules.required]"
- lazy-rules
- readonly
- />
- </div>
- <div class="row q-col-gutter-sm">
- <div class="col-4">
- <div class="text-text">
- <span class="font14 fontbold">{{ $t('common.terms.address_number') }}</span>
- </div>
- <q-input
- v-model="form.number"
- no-error-icon
- outlined
- rounded
- bg-color="surface"
- class="q-mt-sm q-mb-md"
- input-class="text-text"
- placeholder="0000"
- hide-bottom-space
- :rules="[inputRules.required]"
- lazy-rules
- />
- </div>
- <div class="col-8">
- <div class="text-text">
- <span class="font14 fontbold">{{ $t('common.terms.district') }}</span>
- </div>
- <q-input
- v-model="form.district"
- no-error-icon
- outlined
- rounded
- bg-color="surface"
- class="q-mt-sm q-mb-md"
- input-class="text-text"
- :placeholder="`${$t('common.terms.district')}...`"
- hide-bottom-space
- readonly
- />
- </div>
- </div>
- <div class="row q-col-gutter-sm">
- <div class="col-8">
- <div class="text-text">
- <span class="font14 fontbold">{{ $t('common.terms.city') }}</span>
- </div>
- <q-input
- v-model="form.city"
- no-error-icon
- outlined
- rounded
- bg-color="surface"
- class="q-mt-sm q-mb-md"
- input-class="text-text"
- readonly
- />
- </div>
- <div class="col-4">
- <div class="text-text">
- <span class="font14 fontbold">{{ $t('common.terms.state') }}</span>
- </div>
- <q-input
- v-model="form.state"
- no-error-icon
- outlined
- rounded
- bg-color="surface"
- class="q-mt-sm q-mb-md"
- input-class="text-text"
- hide-bottom-space
- readonly
- />
- </div>
- </div>
- <div>
- <q-checkbox
- v-model="form.no_complement"
- :label="$t('auth.no_complement')"
- color="primary"
- keep-color
- class="q-mb-md text-text font14 fontbold"
- />
- </div>
- <div>
- <template v-if="!form.no_complement">
- <div class="text-text">
- <span class="font14 fontbold">{{ $t('common.terms.complement') }}</span>
- </div>
- <q-input
- v-model="form.complement"
- no-error-icon
- outlined
- rounded
- bg-color="surface"
- class="q-mt-sm q-mb-md"
- input-class="text-text"
- :placeholder="`${$t('common.ui.misc.example')}: Apartamento, Conjunto, Casa`"
- hide-bottom-space
- :rules="!form.no_complement ? [inputRules.required] : []"
- lazy-rules
- />
- </template>
- </div>
- <div>
- <div class="text-text">
- <span class="font14 fontbold">{{ $t('auth.address_nickname') }}</span>
- </div>
- <q-input
- v-model="form.nickname"
- no-error-icon
- outlined
- rounded
- bg-color="surface"
- class="q-mt-sm q-mb-md"
- input-class="text-text"
- :placeholder="`${$t('common.ui.misc.example')}: Casa`"
- hide-bottom-space
- lazy-rules
- />
- </div>
- <div>
- <div class="text-text">
- <span class="font14 fontbold">{{ $t('auth.address_instructions') }}</span>
- </div>
- <q-input
- v-model="form.instructions"
- no-error-icon
- outlined
- rounded
- bg-color="surface"
- class="q-mt-sm q-mb-md"
- input-class="text-text"
- type="textarea"
- rows="3"
- autogrow
- hide-bottom-space
- lazy-rules
- />
- </div>
- <div>
- <div class="row q-gutter-sm q-mt-xs">
- <q-chip
- v-for="type in addressTypes"
- :key="type.value"
- :selected="form.address_type === type.value"
- clickable
- color="primary"
- :outline="form.address_type !== type.value"
- text-color="surface"
- :icon="type.icon"
- :icon-selected="type.icon"
- @click="form.address_type = type.value"
- >
- {{ $t(type.label) }}
- </q-chip>
- </div>
- </div>
- </q-card-section>
- </template>
- <script setup>
- import { ref } from 'vue';
- import { useInputRules } from 'src/composables/useInputRules';
- import axios from 'axios';
- const form = defineModel({ type: Object, required: true });
- const { inputRules } = useInputRules();
- const loadingCep = ref(false);
- const addressTypes = [
- { value: 'home', label: 'auth.address_type_home', icon: 'mdi-home-outline' },
- { value: 'commercial', label: 'auth.address_type_commercial', icon: 'mdi-briefcase-variant-outline' },
- { value: 'other', label: 'auth.address_type_other', icon: 'mdi-map-marker-outline' },
- ];
- const fetchCep = async (rawCep) => {
- const cleaned = rawCep.replace(/\D/g, '');
- if (cleaned.length !== 8) return;
- loadingCep.value = true;
- try {
- const { data } = await axios.get(`https://viacep.com.br/ws/${cleaned}/json/`);
- if (!data.erro) {
- form.value.address = data.logradouro ?? '';
- form.value.district = data.bairro ?? '';
- form.value.city = data.localidade ?? '';
- form.value.state = data.uf ?? '';
- } else {
- form.value.address = '';
- form.value.district = '';
- form.value.city = '';
- form.value.state = '';
- }
- } catch {
- form.value.address = '';
- form.value.district = '';
- form.value.city = '';
- form.value.state = '';
- } finally {
- loadingCep.value = false;
- }
- };
- const onCepChange = (val) => {
- const cleaned = val?.replace(/\D/g, '') ?? '';
- if (cleaned.length === 8) {
- fetchCep(val);
- } else {
- form.value.address = '';
- form.value.district = '';
- form.value.city = '';
- form.value.state = '';
- }
- };
- </script>
|