Introduced address management functionality, including address creation, deletion, and display with full localization support. Integrated GraphQL queries, mutations, and reusable composables for backend communication. - Added `addresses.vue` to profile for managing user addresses. - Implemented `useAddressCreate`, `useAddressDelete`, and `useAddressAutocomplete` composables. - Created reusable components: `forms/address.vue` and `cards/address.vue`. - Updated `navigation.vue` to include addresses in profile navigation. - Enhanced localization files for address-related translations. This improves user experience by enabling comprehensive address management in the profile section. No breaking changes.
113 lines
No EOL
2.7 KiB
Vue
113 lines
No EOL
2.7 KiB
Vue
<template>
|
|
<div class="card">
|
|
<p class="card__title">{{ name }}</p>
|
|
<div class="card__list">
|
|
<ui-input
|
|
v-model="address.country"
|
|
:isDisabled="true"
|
|
:label="t('fields.country')"
|
|
/>
|
|
<ui-input
|
|
v-model="address.city"
|
|
:isDisabled="true"
|
|
:label="t('fields.city')"
|
|
/>
|
|
<ui-input
|
|
v-if="address.region"
|
|
v-model="address.region"
|
|
:isDisabled="true"
|
|
:label="t('fields.region')"
|
|
/>
|
|
<ui-input
|
|
v-else-if="address.district"
|
|
v-model="address.district"
|
|
:isDisabled="true"
|
|
:label="t('fields.district')"
|
|
/>
|
|
<ui-input
|
|
v-model="address.postalCode"
|
|
:isDisabled="true"
|
|
:label="t('fields.postalCode')"
|
|
/>
|
|
<ui-input
|
|
v-model="address.street"
|
|
:isDisabled="true"
|
|
:label="t('fields.street')"
|
|
/>
|
|
<ui-input
|
|
v-model="entrance"
|
|
:isDisabled="true"
|
|
:label="t('fields.entrance')"
|
|
/>
|
|
<ui-input
|
|
v-model="floor"
|
|
:isDisabled="true"
|
|
:label="t('fields.floor')"
|
|
/>
|
|
<ui-input
|
|
v-model="apartmentNumber"
|
|
:isDisabled="true"
|
|
:label="t('fields.apartNumber')"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type {IAddress} from "@types";
|
|
|
|
const props = defineProps<{
|
|
address: IAddress;
|
|
}>();
|
|
|
|
const {t} = useI18n();
|
|
|
|
const isHouse = computed<boolean>(() => {
|
|
return props.address.addressLine.split(' ').find(el => el.includes('is_house'))?.split('=')[1] === 'true';
|
|
});
|
|
|
|
const name = computed<string | undefined>(() => {
|
|
return props.address.addressLine.split(' ').find(el => el.includes('name'))?.split('=')[1]?.split('_').join(' ');
|
|
});
|
|
|
|
const apartmentNumber = computed<string | undefined>(() => {
|
|
return props.address.addressLine.split(' ').find(el => el.includes('apartment_number'))?.split('=')[1];
|
|
});
|
|
|
|
const floor = computed<string | undefined>(() => {
|
|
return props.address.addressLine.split(' ').find(el => el.includes('floor'))?.split('=')[1];
|
|
});
|
|
|
|
const entrance = computed<string | undefined>(() => {
|
|
return props.address.addressLine.split(' ').find(el => el.includes('entrance'))?.split('=')[1];
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.card {
|
|
width: 100%;
|
|
border: 1px solid $border;
|
|
border-radius: $default_border_radius;
|
|
padding: 15px 30px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 25px;
|
|
|
|
&__title {
|
|
font-weight: 600;
|
|
font-size: 20px;
|
|
font-family: "Playfair Display", sans-serif;
|
|
}
|
|
|
|
&__list {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 15px;
|
|
}
|
|
}
|
|
|
|
:deep(.block__input) {
|
|
padding: 10px 12px;
|
|
font-size: 14px;
|
|
}
|
|
</style> |