| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- <template>
- <div class="column col-12">
- <q-card class="step4-card col-12">
- <div class="bg-surface q-pa-lg">
- <div class="text-center q-mb-md">
- <div class="text-primary font14 fontbold">
- {{ $t("auth.step4_title") }}
- </div>
- </div>
- <q-input
- v-model="cep"
- class="bg-surface q-mb-md"
- hide-bottom-space
- input-class="text-text"
- lazy-rules
- mask="#####-###"
- no-error-icon
- outlined
- rounded
- :bottom-slots="false"
- :loading="loadingCep"
- :placeholder="$t('common.terms.cep')"
- @update:model-value="onCepChange"
- >
- <template #prepend>
- <q-icon color="grey-5" name="mdi-map-marker-outline" />
- </template>
- </q-input>
- <q-btn
- class="full-width"
- color="primary-button"
- padding="8px 12px"
- rounded
- :label="$t('auth.use_location')"
- :loading="loadingLocation"
- @click="useLocation"
- />
- </div>
- </q-card>
- <div class="text-center q-pt-sm">
- <q-btn
- color="surface"
- flat
- icon="mdi-chevron-left-circle-outline"
- rounded
- :label="$t('auth.back_to_register')"
- @click="emit('back')"
- />
- </div>
- </div>
- </template>
- <script setup>
- import { ref } from "vue";
- import { useQuasar } from "quasar";
- import { useI18n } from "vue-i18n";
- import { useGeocodingApi } from "src/composables/useGeocodingApi";
- import { useGeolocation } from "src/composables/useGeolocation";
- const emit = defineEmits(["back", "cep-resolved", "device-location"]);
- const $q = useQuasar();
- const { t } = useI18n();
- const { geocodeCep } = useGeocodingApi();
- const { requestPermission, getCurrentPosition } = useGeolocation();
- const cep = ref("");
- const loadingCep = ref(false);
- const loadingLocation = ref(false);
- const onCepChange = async (val) => {
- const cleaned = val?.replace(/\D/g, "") ?? "";
- if (cleaned.length !== 8) {
- return;
- }
- loadingCep.value = true;
- try {
- const result = await geocodeCep(cleaned);
- if (!result) {
- $q.notify({
- message: t("auth.cep_not_found"),
- type: "negative",
- });
- return;
- }
- emit("cep-resolved", result);
- } catch {
- $q.notify({
- message: t("auth.cep_not_found"),
- type: "negative",
- });
- } finally {
- loadingCep.value = false;
- }
- };
- const useLocation = async () => {
- loadingLocation.value = true;
- try {
- const granted = await requestPermission();
- if (!granted) {
- $q.notify({
- message: t("auth.location_permission_denied"),
- type: "warning",
- });
- return;
- }
- const position = await getCurrentPosition();
- emit("device-location", position);
- } catch (err) {
- const isPermissionError =
- err?.code === 1 || err?.message?.toLowerCase().includes("denied");
- $q.notify({
- message: isPermissionError
- ? t("auth.location_permission_denied")
- : t("auth.location_error"),
- type: "warning",
- });
- } finally {
- loadingLocation.value = false;
- }
- };
- </script>
- <style lang="scss" scoped>
- .step4-card {
- border-radius: 30px;
- max-width: 340px;
- position: relative;
- width: 100%;
- z-index: 1;
- :deep(.q-field__marginal) {
- height: 44px;
- }
- }
- </style>
|