schon/storefront/app/components/cards/address.vue
Alexandr SaVBaD Waltz 132ed8a89e feat(addresses): add delete button to address card
Enhanced address management UI by introducing a delete button to the address card component. Moved address deletion logic from the profile page to the card for better modularity.

- Added a delete icon to `address.vue` with hover effect and error color styling.
- Integrated `useAddressDelete` composable into the card for deletion handling.
- Updated SCSS to style the delete button with proper alignment and spacing.

Improves usability and keeps the address management interface consistent and intuitive. No breaking changes.
2026-03-10 13:38:01 +03:00

138 lines
No EOL
3.2 KiB
Vue

<template>
<div class="card">
<div class="card__top">
<h6 class="card__title">{{ name }}</h6>
<icon
class="card__delete"
name="material-symbols:delete-outline"
size="20"
@click="deleteAddress(address.uuid)"
/>
</div>
<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";
import {useAddressDelete} from "@composables/adresses";
const props = defineProps<{
address: IAddress;
}>();
const {t} = useI18n();
const { deleteAddress, deleteLoading } = useAddressDelete();
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;
&__top {
display: flex;
justify-content: space-between;
align-items: center;
}
&__title {
font-weight: 600;
font-size: 20px;
font-family: "Playfair Display", sans-serif;
}
&__delete {
cursor: pointer;
@include hover {
color: $error;
}
}
&__list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px;
}
}
:deep(.block__input) {
padding: 10px 12px;
font-size: 14px;
}
</style>