| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- <template>
- <q-page class="address-completion-page bg-surface">
- <div class="address-completion-inner">
- <q-btn
- flat
- dense
- round
- color="primary"
- icon="mdi-arrow-left"
- class="address-completion-back"
- @click="router.back()"
- />
- <div class="address-completion-content">
- <div class="text-text">
- <span class="text-weight-medium">{{ $t('common.terms.address') }}</span>
- </div>
- <q-input
- :model-value="flowStore.confirmedAddress"
- outlined
- rounded
- readonly
- class="bg-surface q-mt-sm q-mb-md"
- input-class="text-text"
- />
- <div class="row q-col-gutter-sm">
- <div class="col-4">
- <div class="text-text">
- <span class="text-weight-medium">{{ $t('common.terms.address_number') }}</span>
- </div>
- <q-input
- v-model="form.number"
- outlined
- rounded
- class="bg-surface q-mt-sm q-mb-md"
- placeholder="0000"
- input-class="text-text"
- />
- </div>
- <div class="col-8">
- <div class="text-text">
- <span class="text-weight-medium">{{ $t('common.terms.district') }}</span>
- </div>
- <q-input
- :model-value="flowStore.confirmedDistrict"
- outlined
- rounded
- readonly
- class="bg-surface q-mt-sm q-mb-md"
- input-class="text-text"
- />
- </div>
- </div>
- <div class="row q-col-gutter-sm">
- <div class="col-8">
- <div class="text-text">
- <span class="text-weight-medium">{{ $t('common.terms.city') }}</span>
- </div>
- <q-input
- :model-value="flowStore.confirmedCity"
- outlined
- rounded
- readonly
- class="bg-surface q-mt-sm q-mb-md"
- input-class="text-text"
- />
- </div>
- <div class="col-4">
- <div class="text-text">
- <span class="text-weight-medium">{{ $t('common.terms.state') }}</span>
- </div>
- <q-input
- :model-value="flowStore.confirmedState"
- outlined
- rounded
- readonly
- class="bg-surface q-mt-sm q-mb-md"
- input-class="text-text"
- />
- </div>
- </div>
- <q-checkbox
- v-model="form.no_complement"
- :label="$t('auth.no_complement')"
- color="primary"
- keep-color
- class="q-mb-md text-text"
- />
- <template v-if="!form.no_complement">
- <div class="text-text">
- <span class="text-weight-medium">{{ $t('auth.complement') }}</span>
- </div>
- <q-input
- v-model="form.complement"
- outlined
- rounded
- class="bg-surface q-mt-sm q-mb-md"
- :placeholder="$t('auth.complement_placeholder')"
- input-class="text-text"
- />
- </template>
- <div class="text-text">
- <span class="text-weight-medium">{{ $t('auth.address_nickname') }}</span>
- </div>
- <q-input
- v-model="form.nickname"
- outlined
- rounded
- class="bg-surface q-mt-sm q-mb-md"
- :placeholder="$t('auth.address_nickname_placeholder')"
- input-class="text-text"
- />
- <div class="text-text">
- <span class="text-weight-medium">{{ $t('auth.address_instructions') }}</span>
- </div>
- <q-input
- v-model="form.instructions"
- outlined
- rounded
- class="bg-surface q-mt-sm q-mb-md"
- type="textarea"
- rows="3"
- autogrow
- input-class="text-text"
- />
- <div class="row q-gutter-sm q-mt-xs q-mb-xl">
- <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"
- >
- {{ type.label }}
- </q-chip>
- </div>
- </div>
- <div class="address-completion-footer">
- <q-btn
- color="primary-button"
- :label="$t('auth.confirm_address')"
- rounded
- padding="14px 16px"
- class="full-width"
- :loading="submitting"
- @click="handleConfirm"
- />
- </div>
- </div>
- </q-page>
- </template>
- <script setup>
- import { ref, computed, onMounted } from 'vue';
- import { useRouter } from 'vue-router';
- import { useQuasar } from 'quasar';
- import { useI18n } from 'vue-i18n';
- import { useRegistrationFlowStore } from 'src/stores/registrationFlow';
- import { useAuth } from 'src/composables/useAuth';
- import { createUserAndClient } from 'src/api/user';
- const router = useRouter();
- const $q = useQuasar();
- const { t } = useI18n();
- const flowStore = useRegistrationFlowStore();
- const { setAuthDataFromPayload } = useAuth();
- const submitting = ref(false);
- const form = ref({
- number: '',
- no_complement: false,
- complement: '',
- nickname: '',
- instructions: '',
- address_type: 'home',
- });
- const addressTypes = computed(() => [
- { value: 'home', label: t('auth.address_type_home'), icon: 'mdi-home-outline' },
- { value: 'commercial', label: t('auth.address_type_commercial'), icon: 'mdi-office-building-outline' },
- { value: 'other', label: t('auth.address_type_other'), icon: 'mdi-map-marker-outline' },
- ]);
- const handleConfirm = async () => {
- if (!form.value.no_complement && !form.value.complement?.trim()) {
- $q.notify({ type: 'warning', message: t('auth.complement_required') });
- return;
- }
- submitting.value = true;
- try {
- const payload = {
- email: flowStore.email || undefined,
- phone: flowStore.phone || undefined,
- code: flowStore.code,
- zip_code: flowStore.confirmedZipCode || undefined,
- address: flowStore.confirmedAddress || undefined,
- number: form.value.number || undefined,
- district: flowStore.confirmedDistrict || undefined,
- city: flowStore.confirmedCity || undefined,
- state: flowStore.confirmedState || undefined,
- latitude: flowStore.confirmedLat,
- longitude: flowStore.confirmedLng,
- has_complement: !form.value.no_complement,
- complement: form.value.no_complement ? null : (form.value.complement || null),
- nickname: form.value.nickname || null,
- instructions: form.value.instructions || null,
- address_type: form.value.address_type,
- };
- const response = await createUserAndClient(payload);
- if (response.status >= 200 && response.status < 300) {
- await setAuthDataFromPayload(response.data.payload);
- flowStore.clear();
- router.push({ name: 'DashboardPage' });
- }
- } catch {
- $q.notify({ type: 'negative', message: t('auth.register_error') });
- } finally {
- submitting.value = false;
- }
- };
- onMounted(() => {
- if (!flowStore.hasConfirmedLocation() || !flowStore.hasCredentials()) {
- router.replace({ name: 'LoginPage' });
- return;
- }
- form.value.number = flowStore.confirmedNumber || '';
- });
- </script>
- <style lang="scss" scoped>
- .address-completion-page {
- min-height: 100dvh;
- display: flex;
- justify-content: center;
- }
- .address-completion-inner {
- width: 100%;
- max-width: 500px;
- min-height: 100dvh;
- display: flex;
- flex-direction: column;
- padding: 16px 20px;
- }
- .address-completion-back {
- align-self: flex-start;
- margin-bottom: 12px;
- margin-top: env(safe-area-inset-top);
- }
- .address-completion-content {
- flex: 1;
- }
- .address-type-row {
- display: flex;
- gap: 10px;
- flex-wrap: wrap;
- }
- .address-completion-footer {
- padding: 16px 0 calc(12px + env(safe-area-inset-bottom));
- }
- </style>
|