diff --git a/src/app/styles/variables.scss b/src/app/styles/variables.scss index 6fc08288..34a70466 100644 --- a/src/app/styles/variables.scss +++ b/src/app/styles/variables.scss @@ -46,9 +46,9 @@ // 1440px body.light { // colors + --black: #000; --white: #fff; --white-tr: #ffffffa9; - --black: #000; --noble-white-100: #f5f5f5; --noble-white-200: #f0f0f0; --noble-gray-200: #eaeaea; @@ -86,6 +86,8 @@ --noble-gray-600: #cdcdcd; --noble-gray-700: #b0b0b0; --noble-gray-800: #c4c4c4; + --noble-gray-tr-800: #acacacbd; + --noble-gray-900: #1d1d1d; --noble-gray-1000: #1a1a1ab5; --red-power-600: #d0302f; --steam-green-300: #46a35880; @@ -94,6 +96,7 @@ --steam-green-500: #b6f09c; --steam-green-700: #70d27a; --steam-green-800: #46a358; + --steam-green-900: #46a3581a; --steam-green-gr-800: #c5e1cb2b; } } diff --git a/src/entities/Address/model/AddressModel.ts b/src/entities/Address/model/AddressModel.ts index b105c11c..4e161abc 100644 --- a/src/entities/Address/model/AddressModel.ts +++ b/src/entities/Address/model/AddressModel.ts @@ -13,7 +13,7 @@ class AddressModel { private view: AddressView; - constructor(addressType: AddressType, options: AddressOptions) { + constructor(options: AddressOptions, addressType: AddressType = ADDRESS_TYPE.GENERAL) { this.addressType = addressType; this.view = new AddressView(addressType, options); this.init(); @@ -26,9 +26,22 @@ class AddressModel { public getAddressData(personalData: PersonalData): Address { const store = getStore().getState(); + let country: string; + + switch (this.addressType) { + case ADDRESS_TYPE.BILLING: + country = store.billingCountry; + break; + case ADDRESS_TYPE.SHIPPING: + country = store.shippingCountry; + break; + default: + country = store.defaultCountry; + break; + } const addressData: Address = { city: formattedText(this.view.getCityField().getView().getValue()), - country: this.addressType === ADDRESS_TYPE.BILLING ? store.billingCountry : store.shippingCountry, + country, email: personalData.email, firstName: personalData.firstName, id: '', @@ -38,6 +51,7 @@ class AddressModel { streetName: formattedText(this.view.getStreetField().getView().getValue()), streetNumber: '', }; + return addressData; } diff --git a/src/entities/Address/view/AddressView.ts b/src/entities/Address/view/AddressView.ts index 939fdb71..596c9af3 100644 --- a/src/entities/Address/view/AddressView.ts +++ b/src/entities/Address/view/AddressView.ts @@ -212,19 +212,29 @@ class AddressView { } private createTitle(): HTMLHeadingElement { + let titleText: string; + let key: string; + switch (this.addressType) { + case ADDRESS_TYPE.BILLING: + titleText = TITLE_TEXT[getStore().getState().currentLanguage].BILLING_ADDRESS; + key = TITLE_TEXT_KEYS.BILLING_ADDRESS; + break; + case ADDRESS_TYPE.SHIPPING: + titleText = TITLE_TEXT[getStore().getState().currentLanguage].SHIPPING_ADDRESS; + key = TITLE_TEXT_KEYS.SHIPPING_ADDRESS; + break; + default: + titleText = TITLE_TEXT[getStore().getState().currentLanguage].ADDRESS; + key = TITLE_TEXT_KEYS.ADDRESS; + break; + } + const title = createBaseElement({ cssClasses: [styles.title], - innerContent: - this.addressType === ADDRESS_TYPE.SHIPPING - ? TITLE_TEXT[getStore().getState().currentLanguage].SHIPPING_ADDRESS - : TITLE_TEXT[getStore().getState().currentLanguage].BILLING_ADDRESS, + innerContent: titleText, tag: 'h3', }); - observeCurrentLanguage( - title, - TITLE_TEXT, - this.addressType === ADDRESS_TYPE.SHIPPING ? TITLE_TEXT_KEYS.SHIPPING_ADDRESS : TITLE_TEXT_KEYS.BILLING_ADDRESS, - ); + observeCurrentLanguage(title, TITLE_TEXT, key); return title; } diff --git a/src/entities/Address/view/addressView.module.scss b/src/entities/Address/view/addressView.module.scss index 23290767..61196719 100644 --- a/src/entities/Address/view/addressView.module.scss +++ b/src/entities/Address/view/addressView.module.scss @@ -40,6 +40,7 @@ .shippingAddressWrapper { grid-row: 3; + animation: show 0.5s ease-in forwards; } .billingAddressWrapper { diff --git a/src/entities/UserAddress/model/UserAddressModel.ts b/src/entities/UserAddress/model/UserAddressModel.ts index f93b2982..d5eba45f 100644 --- a/src/entities/UserAddress/model/UserAddressModel.ts +++ b/src/entities/UserAddress/model/UserAddressModel.ts @@ -1,15 +1,14 @@ -/* eslint-disable max-lines-per-function */ import type { Address, User } from '@/shared/types/user.ts'; +import AddressEditModel from '@/features/AddressEdit/model/AddressEditModel.ts'; import getCustomerModel, { CustomerModel } from '@/shared/API/customer/model/CustomerModel.ts'; +import ConfirmModel from '@/shared/Confirm/model/ConfirmModel.ts'; import EventMediatorModel from '@/shared/EventMediator/model/EventMediatorModel.ts'; -import LoaderModel from '@/shared/Loader/model/LoaderModel.ts'; import modal from '@/shared/Modal/model/ModalModel.ts'; import serverMessageModel from '@/shared/ServerMessage/model/ServerMessageModel.ts'; import MEDIATOR_EVENT from '@/shared/constants/events.ts'; import { ADDRESS_TYPE, type AddressTypeType } from '@/shared/constants/forms.ts'; import { MESSAGE_STATUS, SERVER_MESSAGE_KEYS } from '@/shared/constants/messages.ts'; -import { LOADER_SIZE } from '@/shared/constants/sizes.ts'; import showErrorMessage from '@/shared/utils/userMessage.ts'; import UserAddressView from '../view/UserAddressView.ts'; @@ -30,6 +29,23 @@ class UserAddressModel { this.setLabelClickHandler(); } + private async deleteAddress(address: Address): Promise { + try { + const user = await getCustomerModel().getCurrentUser(); + if (user) { + try { + await getCustomerModel().editCustomer([CustomerModel.actionRemoveAddress(address)], user); + EventMediatorModel.getInstance().notify(MEDIATOR_EVENT.REDRAW_USER_ADDRESSES, ''); + serverMessageModel.showServerMessage(SERVER_MESSAGE_KEYS.ADDRESS_DELETED, MESSAGE_STATUS.SUCCESS); + } catch (error) { + showErrorMessage(error); + } + } + } catch (error) { + showErrorMessage(error); + } + } + private async handleAddressType(user: User, activeType: AddressTypeType, inactive: boolean): Promise { const customerModel = getCustomerModel(); @@ -63,22 +79,15 @@ class UserAddressModel { } else { switch (activeType) { case ADDRESS_TYPE.BILLING: + case ADDRESS_TYPE.DEFAULT_BILLING: await customerModel.editCustomer([CustomerModel.actionRemoveBillingAddress(this.currentAddress)], user); break; case ADDRESS_TYPE.SHIPPING: + case ADDRESS_TYPE.DEFAULT_SHIPPING: await customerModel.editCustomer([CustomerModel.actionRemoveShippingAddress(this.currentAddress)], user); break; - // TBD Check the adding/removing default address - // case ADDRESS_TYPE.DEFAULT_BILLING: - // await customerModel.editCustomer([CustomerModel.actionEditDefaultBillingAddress(null)], user); - // break; - - // case ADDRESS_TYPE.DEFAULT_SHIPPING: - // await customerModel.editCustomer([CustomerModel.actionEditDefaultShippingAddress(null)], user); - // break; - default: break; } @@ -102,30 +111,14 @@ class UserAddressModel { this.view .getDeleteButton() .getHTML() - .addEventListener('click', async () => { - const loader = new LoaderModel(LOADER_SIZE.SMALL).getHTML(); - this.view.getDeleteButton().getHTML().append(loader); - try { - const user = await getCustomerModel().getCurrentUser(); - if (user) { - try { - await getCustomerModel().editCustomer([CustomerModel.actionRemoveAddress(address)], user); - EventMediatorModel.getInstance().notify(MEDIATOR_EVENT.REDRAW_USER_ADDRESSES, ''); - serverMessageModel.showServerMessage(SERVER_MESSAGE_KEYS.ADDRESS_DELETED, MESSAGE_STATUS.SUCCESS); - } catch (error) { - showErrorMessage(error); - } - } - } catch (error) { - showErrorMessage(error); - } finally { - loader.remove(); - } + .addEventListener('click', () => { + const confirmModel = new ConfirmModel(() => this.deleteAddress(address)); + modal.setContent(confirmModel.getHTML()); + modal.show(); }); } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - private setEditButtonHandler(_address: Address): void { + private setEditButtonHandler(address: Address): void { this.view .getEditButton() .getHTML() @@ -135,11 +128,11 @@ class UserAddressModel { if (!user) { return; } + const newAddressEditForm = new AddressEditModel(address, user).getHTML(); modal.show(); + modal.setContent(newAddressEditForm); } catch (error) { showErrorMessage(error); - } finally { - modal.hide(); } }); } diff --git a/src/entities/UserAddress/view/UserAddressView.ts b/src/entities/UserAddress/view/UserAddressView.ts index 4967a597..4288a7cf 100644 --- a/src/entities/UserAddress/view/UserAddressView.ts +++ b/src/entities/UserAddress/view/UserAddressView.ts @@ -117,6 +117,11 @@ class UserAddressView { } this.view.append(addressText, this.editButton.getHTML(), this.deleteButton.getHTML()); + + observeStore(selectCurrentLanguage, () => { + addressText.innerText = this.createAddressText(getStore().getState().currentLanguage); + }); + return this.view; } @@ -139,12 +144,12 @@ class UserAddressView { let addressType = null; switch (ActiveType) { case ADDRESS_TYPE.BILLING: - addressType = this.createLabel(ActiveType, [styles.billing], TOOLTIP_TEXT_KEYS.EDIT_BILLING_ADDRESS); + addressType = this.createLabel(ActiveType, [styles.billing], TOOLTIP_TEXT_KEYS.SWITCH_BILLING_ADDRESS); this.view.append(addressType); break; case ADDRESS_TYPE.SHIPPING: - addressType = this.createLabel(ActiveType, [styles.shipping], TOOLTIP_TEXT_KEYS.EDIT_SHIPPING_ADDRESS); + addressType = this.createLabel(ActiveType, [styles.shipping], TOOLTIP_TEXT_KEYS.SWITCH_SHIPPING_ADDRESS); this.view.append(addressType); break; @@ -152,7 +157,7 @@ class UserAddressView { addressType = this.createLabel( ActiveType, [styles.defaultBilling], - TOOLTIP_TEXT_KEYS.EDIT_DEFAULT_BILLING_ADDRESS, + TOOLTIP_TEXT_KEYS.SWITCH_DEFAULT_BILLING_ADDRESS, ); this.view.append(addressType); break; @@ -161,7 +166,7 @@ class UserAddressView { addressType = this.createLabel( ActiveType, [styles.defaultShipping], - TOOLTIP_TEXT_KEYS.EDIT_DEFAULT_SHIPPING_ADDRESS, + TOOLTIP_TEXT_KEYS.SWITCH_DEFAULT_SHIPPING_ADDRESS, ); this.view.append(addressType); break; diff --git a/src/features/AddressAdd/model/AddressAddModel.ts b/src/features/AddressAdd/model/AddressAddModel.ts index 86c3468f..7b031bdd 100644 --- a/src/features/AddressAdd/model/AddressAddModel.ts +++ b/src/features/AddressAdd/model/AddressAddModel.ts @@ -30,7 +30,7 @@ class AddressAddModel { constructor(type: AddressType, options: Record) { this.addressType = type; - this.newAddress = new AddressModel(this.addressType, options); + this.newAddress = new AddressModel(options, this.addressType); this.init(); } @@ -148,6 +148,7 @@ class AddressAddModel { const cancelButton = this.view.getCancelButton().getHTML(); cancelButton.addEventListener('click', () => { modal.hide(); + modal.removeContent(); }); return true; } diff --git a/src/features/AddressAdd/view/AddressAddView.ts b/src/features/AddressAdd/view/AddressAddView.ts index c0c8b9db..bb26f80e 100644 --- a/src/features/AddressAdd/view/AddressAddView.ts +++ b/src/features/AddressAdd/view/AddressAddView.ts @@ -38,7 +38,7 @@ class AddressAddView { private createSaveChangesButton(): ButtonModel { this.saveChangesButton = new ButtonModel({ classes: [styles.saveChangesButton], - text: BUTTON_TEXT[getStore().getState().currentLanguage].SAVE_CHANGES, + text: BUTTON_TEXT[getStore().getState().currentLanguage].ADD_ADDRESS, }); this.saveChangesButton.setDisabled(); return this.saveChangesButton; diff --git a/src/features/AddressEdit/model/AddressEditModel.ts b/src/features/AddressEdit/model/AddressEditModel.ts index f91accbd..b80ffdf1 100644 --- a/src/features/AddressEdit/model/AddressEditModel.ts +++ b/src/features/AddressEdit/model/AddressEditModel.ts @@ -1,115 +1,160 @@ -// import type InputFieldModel from '@/entities/InputField/model/InputFieldModel.ts'; -// import type { UserAddressType } from '@/shared/constants/forms.ts'; -// import type { Address } from '@/shared/types/user.ts'; - -// import AddressModel from '@/entities/Address/model/AddressModel.ts'; -// import getCustomerModel from '@/shared/API/customer/model/CustomerModel.ts'; -// import EventMediatorModel from '@/shared/EventMediator/model/EventMediatorModel.ts'; -// import LoaderModel from '@/shared/Loader/model/LoaderModel.ts'; -// import modal from '@/shared/Modal/model/ModalModel.ts'; -// import serverMessageModel from '@/shared/ServerMessage/model/ServerMessageModel.ts'; -// import MEDIATOR_EVENT from '@/shared/constants/events.ts'; -// import { MESSAGE_STATUS, SERVER_MESSAGE_KEYS } from '@/shared/constants/messages.ts'; -// import { LOADER_SIZE } from '@/shared/constants/sizes.ts'; -// import showErrorMessage from '@/shared/utils/userMessage.ts'; - -// import AddressEditView from '../view/AddressEditView.ts'; +import type InputFieldModel from '@/entities/InputField/model/InputFieldModel.ts'; +import type { Address, User } from '@/shared/types/user.ts'; + +import AddressModel from '@/entities/Address/model/AddressModel.ts'; +import getCustomerModel, { CustomerModel } from '@/shared/API/customer/model/CustomerModel.ts'; +import EventMediatorModel from '@/shared/EventMediator/model/EventMediatorModel.ts'; +import LoaderModel from '@/shared/Loader/model/LoaderModel.ts'; +import modal from '@/shared/Modal/model/ModalModel.ts'; +import serverMessageModel from '@/shared/ServerMessage/model/ServerMessageModel.ts'; +import getStore from '@/shared/Store/Store.ts'; +import { setBillingCountry } from '@/shared/Store/actions.ts'; +import COUNTRIES_LIST from '@/shared/constants/countriesList.ts'; +import MEDIATOR_EVENT from '@/shared/constants/events.ts'; +import { MESSAGE_STATUS, SERVER_MESSAGE_KEYS } from '@/shared/constants/messages.ts'; +import { LOADER_SIZE } from '@/shared/constants/sizes.ts'; +import findKeyByValue from '@/shared/utils/findKeyByValue.ts'; +import formattedText from '@/shared/utils/formattedText.ts'; +import getCountryIndex from '@/shared/utils/getCountryIndex.ts'; +import showErrorMessage from '@/shared/utils/userMessage.ts'; + +import AddressEditView from '../view/AddressEditView.ts'; class AddressEditModel { - // private address: AddressModel; - // private currentAddress: Address; - // private inputFields: InputFieldModel[] = []; - // private view = new AddressEditView(); - // constructor(address: Address, type: UserAddressType) { - // this.address = new AddressModel(type, { setDefault: true }); - // this.currentAddress = address; - // this.init(); - // } - // private async editPersonalInfo(): Promise { - // const loader = new LoaderModel(LOADER_SIZE.SMALL).getHTML(); - // this.view.getSaveChangesButton().getHTML().append(loader); - // try { - // const user = await getCustomerModel().getCurrentUser(); - // if (user) { - // // const {} = this.getFormPersonalData(); - // await getCustomerModel().editCustomer( - // [ - // // CustomerModel - // ], - // user, - // ); - // modal.hide(); - // serverMessageModel.showServerMessage(SERVER_MESSAGE_KEYS.ADDRESS_CHANGED, MESSAGE_STATUS.SUCCESS); - // EventMediatorModel.getInstance().notify(MEDIATOR_EVENT.REDRAW_USER_ADDRESS, ''); - // } - // } catch (error) { - // showErrorMessage(); - // } finally { - // loader.remove(); - // } - // } - // private getFormPersonalData(): Record { - // return { - // // dateOfBirth: this.personalInfo.getView().getDateOfBirthField().getView().getInput().getValue(), - // // email: this.view.getEmailField().getView().getInput().getValue(), - // // firstName: formattedText(this.personalInfo.getView().getFirstNameField().getView().getInput().getValue()), - // // lastName: formattedText(this.personalInfo.getView().getLastNameField().getView().getInput().getValue()), - // }; - // } - // private init(): void { - // this.initiateFieldsValues(); - // // this.getHTML().append(this.personalInfo.getHTML()); - // this.inputFields = [ - // this.personalInfo.getView().getFirstNameField(), - // this.personalInfo.getView().getLastNameField(), - // this.personalInfo.getView().getDateOfBirthField(), - // ]; - // this.inputFields.forEach((inputField) => this.setInputFieldHandlers(inputField)); - // this.setPreventDefaultToForm(); - // this.setSubmitFormHandler(); - // this.setCancelButtonHandler(); - // } - // private initiateFieldsValues(): void { - // this.personalInfo.getView().getFirstNameField().getView().getInput().setValue(this.currentUser.firstName); - // this.personalInfo.getView().getLastNameField().getView().getInput().setValue(this.currentUser.lastName); - // this.personalInfo.getView().getDateOfBirthField().getView().getInput().setValue(this.currentUser.birthDate); - // } - // private setCancelButtonHandler(): boolean { - // const cancelButton = this.view.getCancelButton().getHTML(); - // cancelButton.addEventListener('click', () => { - // modal.hide(); - // }); - // return true; - // } - // private setInputFieldHandlers(inputField: InputFieldModel): boolean { - // const inputHTML = inputField.getView().getInput().getHTML(); - // inputHTML.addEventListener('input', () => { - // this.switchSubmitFormButtonAccess(); - // }); - // return true; - // } - // private setPreventDefaultToForm(): boolean { - // this.getHTML().addEventListener('submit', (event) => { - // event.preventDefault(); - // }); - // return true; - // } - // private setSubmitFormHandler(): boolean { - // const submitButton = this.view.getSaveChangesButton().getHTML(); - // submitButton.addEventListener('click', () => this.editPersonalInfo()); - // return true; - // } - // private switchSubmitFormButtonAccess(): boolean { - // if (this.inputFields.every((inputField) => inputField.getIsValid())) { - // this.view.getSaveChangesButton().setEnabled(); - // } else { - // this.view.getSaveChangesButton().setDisabled(); - // } - // return true; - // } - // public getHTML(): HTMLFormElement { - // return this.view.getHTML(); - // } + private currentAddress: Address; + + private inputFields: InputFieldModel[] = []; + + private newAddress: AddressModel; + + private user: User; + + private view = new AddressEditView(); + + constructor(address: Address, user: User) { + this.user = user; + this.currentAddress = address; + this.newAddress = new AddressModel({}); + this.init(); + } + + private createAddress(user: User): Address { + const { email, firstName, lastName } = user; + const { city, country, postalCode, streetName } = this.getFormAddressData(); + return { + city, + country: getCountryIndex(formattedText(country)), + email, + firstName, + id: this.currentAddress.id, + lastName, + postalCode, + state: '', + streetName, + streetNumber: '', + }; + } + + private async editAddressInfo(): Promise { + const loader = new LoaderModel(LOADER_SIZE.SMALL).getHTML(); + this.view.getSaveChangesButton().getHTML().append(loader); + try { + const user = await getCustomerModel().getCurrentUser(); + if (user) { + await getCustomerModel().editCustomer([CustomerModel.actionEditAddress(this.createAddress(user))], user); + modal.hide(); + serverMessageModel.showServerMessage(SERVER_MESSAGE_KEYS.ADDRESS_CHANGED, MESSAGE_STATUS.SUCCESS); + EventMediatorModel.getInstance().notify(MEDIATOR_EVENT.REDRAW_USER_ADDRESSES, ''); + } + } catch (error) { + showErrorMessage(error); + } finally { + loader.remove(); + } + } + + private getFormAddressData(): Record { + return { + city: formattedText(this.newAddress.getView().getCityField().getView().getInput().getValue()), + country: this.newAddress.getView().getCountryField().getView().getInput().getValue(), + postalCode: this.newAddress.getView().getPostalCodeField().getView().getInput().getValue(), + streetName: formattedText(this.newAddress.getView().getStreetField().getView().getInput().getValue()), + }; + } + + private init(): void { + this.initiateFieldsValues(); + this.getHTML().append(this.newAddress.getHTML()); + this.inputFields = [ + this.newAddress.getView().getCityField(), + this.newAddress.getView().getCountryField(), + this.newAddress.getView().getPostalCodeField(), + this.newAddress.getView().getStreetField(), + ]; + this.inputFields.forEach((inputField) => this.setInputFieldHandlers(inputField)); + this.setPreventDefaultToForm(); + this.setSubmitFormHandler(); + this.setCancelButtonHandler(); + this.view.getHTML().append(this.newAddress.getHTML()); + getStore().dispatch(setBillingCountry(this.currentAddress.country)); + } + + private initiateFieldsValues(): void { + const { locale } = this.user; + const currentCountry = findKeyByValue(COUNTRIES_LIST[locale], this.currentAddress.country); + this.newAddress.getView().getCityField().getView().getInput().setValue(this.currentAddress.city); + this.newAddress + .getView() + .getCountryField() + .getView() + .getInput() + .setValue(currentCountry ?? ''); + this.newAddress.getView().getStreetField().getView().getInput().setValue(this.currentAddress.streetName); + this.newAddress.getView().getPostalCodeField().getView().getInput().setValue(this.currentAddress.postalCode); + } + + private setCancelButtonHandler(): boolean { + const cancelButton = this.view.getCancelButton().getHTML(); + cancelButton.addEventListener('click', () => { + modal.hide(); + modal.removeContent(); + }); + return true; + } + + private setInputFieldHandlers(inputField: InputFieldModel): boolean { + const inputHTML = inputField.getView().getInput().getHTML(); + inputHTML.addEventListener('input', () => { + this.switchSubmitFormButtonAccess(); + }); + return true; + } + + private setPreventDefaultToForm(): boolean { + this.getHTML().addEventListener('submit', (event) => { + event.preventDefault(); + }); + return true; + } + + private setSubmitFormHandler(): boolean { + const submitButton = this.view.getSaveChangesButton().getHTML(); + submitButton.addEventListener('click', () => this.editAddressInfo()); + return true; + } + + private switchSubmitFormButtonAccess(): boolean { + if (this.inputFields.every((inputField) => inputField.getIsValid())) { + this.view.getSaveChangesButton().setEnabled(); + } else { + this.view.getSaveChangesButton().setDisabled(); + } + return true; + } + + public getHTML(): HTMLFormElement { + return this.view.getHTML(); + } } export default AddressEditModel; diff --git a/src/features/AddressEdit/view/AddressEditView.ts b/src/features/AddressEdit/view/AddressEditView.ts index b108f31b..ce2963a5 100644 --- a/src/features/AddressEdit/view/AddressEditView.ts +++ b/src/features/AddressEdit/view/AddressEditView.ts @@ -28,9 +28,11 @@ class AddressEditView { private createHTML(): HTMLFormElement { this.view = createBaseElement({ - cssClasses: [styles.style], + cssClasses: [styles.wrapper], tag: 'form', }); + + this.view.append(this.cancelButton.getHTML(), this.saveChangesButton.getHTML()); return this.view; } diff --git a/src/features/AddressEdit/view/addressEditView.module.scss b/src/features/AddressEdit/view/addressEditView.module.scss index 0abd8a96..71fcc608 100644 --- a/src/features/AddressEdit/view/addressEditView.module.scss +++ b/src/features/AddressEdit/view/addressEditView.module.scss @@ -1,68 +1,35 @@ +@import 'src/app/styles/mixins'; + .wrapper { display: grid; place-items: center center; - grid-template-columns: repeat(2, 1fr); - grid-template-rows: repeat(3, auto); + grid-template-rows: repeat(auto, auto); border-bottom: var(--tiny-offset) solid var(--steam-green-800); padding: var(--small-offset); height: max-content; - max-width: max-content; background-color: var(--noble-white-100); - gap: calc(var(--extra-small-offset) * 1.5) var(--extra-small-offset); - - @media (max-width: 768px) { - grid-template-columns: repeat(1, 1fr); - grid-template-rows: repeat(4, auto); - padding: var(--medium-offset); - } } .saveChangesButton, .cancelButton { - margin: 0 auto; - border-radius: var(--medium-br); - padding: calc(var(--small-offset) / 3) var(--small-offset); - width: 100%; - height: max-content; - font: var(--regular-font); - letter-spacing: 1px; - color: var(--white); - background-color: var(--steam-green-800); - transition: - color 0.2s, - background-color 0.2s; + @include green-btn; - &:focus { - background-color: var(--steam-green-700); - } + grid-row: 5; + margin-top: var(--tiny-offset); +} - @media (hover: hover) { - &:hover { - background-color: var(--steam-green-700); - } - } +.cancelButton { + grid-column: 1; - &:disabled { - background-color: var(--noble-gray-300); - pointer-events: none; + @media (max-width: 768px) { + grid-row: 6; } } .saveChangesButton { - display: flex; grid-column: 2; - grid-row: 3; @media (max-width: 768px) { grid-column: 1; } } - -.cancelButton { - grid-column: 1; - grid-row: 3; - - @media (max-width: 768px) { - grid-row: 4; - } -} diff --git a/src/features/CountryChoice/model/CountryChoiceModel.ts b/src/features/CountryChoice/model/CountryChoiceModel.ts index abf02d41..5225d997 100644 --- a/src/features/CountryChoice/model/CountryChoiceModel.ts +++ b/src/features/CountryChoice/model/CountryChoiceModel.ts @@ -1,8 +1,9 @@ import getStore from '@/shared/Store/Store.ts'; -import { setBillingCountry, setShippingCountry } from '@/shared/Store/actions.ts'; +import { setBillingCountry, setDefaultCountry, setShippingCountry } from '@/shared/Store/actions.ts'; import observeStore, { selectBillingCountry, selectCurrentLanguage, + selectDefaultCountry, selectShippingCountry, } from '@/shared/Store/observer.ts'; import { DATA_KEYS } from '@/shared/constants/common.ts'; @@ -21,10 +22,19 @@ class CountryChoiceModel { this.setCountryItemsHandlers(input); this.setInputHandler(input); - const action = - input.getAttribute(DATA_KEYS.ADDRESS_TYPE) === USER_ADDRESS_TYPE.BILLING - ? selectBillingCountry - : selectShippingCountry; + let action; + + switch (input.getAttribute(DATA_KEYS.ADDRESS_TYPE)) { + case USER_ADDRESS_TYPE.BILLING: + action = selectBillingCountry; + break; + case USER_ADDRESS_TYPE.SHIPPING: + action = selectShippingCountry; + break; + default: + action = selectDefaultCountry; + break; + } observeStore(action, () => { const event = new Event('input'); @@ -66,7 +76,20 @@ class CountryChoiceModel { element instanceof HTMLDivElement ? formattedText(element.textContent ?? '') : formattedText(element.value), ); - const action = key === USER_ADDRESS_TYPE.BILLING ? setBillingCountry : setShippingCountry; + let action; + + switch (key) { + case USER_ADDRESS_TYPE.BILLING: + action = setBillingCountry; + break; + case USER_ADDRESS_TYPE.SHIPPING: + action = setShippingCountry; + break; + default: + action = setDefaultCountry; + break; + } + getStore().dispatch(action(currentCountryIndex)); return true; } diff --git a/src/features/PersonalInfoEdit/model/PersonalInfoEditModel.ts b/src/features/PersonalInfoEdit/model/PersonalInfoEditModel.ts index 08ddedbc..d055e70b 100644 --- a/src/features/PersonalInfoEdit/model/PersonalInfoEditModel.ts +++ b/src/features/PersonalInfoEdit/model/PersonalInfoEditModel.ts @@ -92,6 +92,7 @@ class PersonalInfoEditModel { const cancelButton = this.view.getCancelButton().getHTML(); cancelButton.addEventListener('click', () => { modal.hide(); + modal.removeContent(); }); return true; } diff --git a/src/shared/Confirm/model/ConfirmModel.ts b/src/shared/Confirm/model/ConfirmModel.ts new file mode 100644 index 00000000..ff5d9d1e --- /dev/null +++ b/src/shared/Confirm/model/ConfirmModel.ts @@ -0,0 +1,54 @@ +import LoaderModel from '@/shared/Loader/model/LoaderModel.ts'; +import modal from '@/shared/Modal/model/ModalModel.ts'; +import getStore from '@/shared/Store/Store.ts'; +import { USER_MESSAGE } from '@/shared/constants/confirmUserMessage.ts'; +import { LOADER_SIZE } from '@/shared/constants/sizes.ts'; +import showErrorMessage from '@/shared/utils/userMessage.ts'; + +import ConfirmView from '../view/ConfirmView.ts'; + +class ConfirmModel { + private callback: () => Promise | void; + + private view: ConfirmView; + + constructor(callback: () => Promise | void) { + this.callback = callback; + this.view = new ConfirmView(USER_MESSAGE[getStore().getState().currentLanguage].DELETE_ADDRESS); + this.setCancelButtonHandler(); + this.setConfirmButtonHandler(); + } + + private setCancelButtonHandler(): void { + this.view + .getCancelButton() + .getHTML() + .addEventListener('click', () => { + modal.hide(); + }); + } + + private setConfirmButtonHandler(): void { + this.view + .getConfirmButton() + .getHTML() + .addEventListener('click', async () => { + const loader = new LoaderModel(LOADER_SIZE.SMALL).getHTML(); + this.view.getConfirmButton().getHTML().append(loader); + try { + await this.callback(); + } catch (error) { + showErrorMessage(error); + } finally { + loader.remove(); + } + modal.hide(); + }); + } + + public getHTML(): HTMLDivElement { + return this.view.getHTML(); + } +} + +export default ConfirmModel; diff --git a/src/shared/Confirm/view/ConfirmView.ts b/src/shared/Confirm/view/ConfirmView.ts new file mode 100644 index 00000000..bcec0507 --- /dev/null +++ b/src/shared/Confirm/view/ConfirmView.ts @@ -0,0 +1,79 @@ +import ButtonModel from '@/shared/Button/model/ButtonModel.ts'; +import getStore from '@/shared/Store/Store.ts'; +import { BUTTON_TEXT, BUTTON_TEXT_KEYS } from '@/shared/constants/buttons.ts'; +import createBaseElement from '@/shared/utils/createBaseElement.ts'; +import observeCurrentLanguage from '@/shared/utils/observeCurrentLanguage.ts'; + +import styles from './confirmView.module.scss'; + +class ConfirmView { + private cancelButton: ButtonModel; + + private confirmButton: ButtonModel; + + private userMessage: HTMLSpanElement; + + private view: HTMLDivElement; + + constructor(userMessage: string) { + this.userMessage = this.createUserMessage(userMessage); + this.cancelButton = this.createCancelButton(); + this.confirmButton = this.createConfirmButton(); + this.view = this.createHTML(); + } + + private createCancelButton(): ButtonModel { + this.cancelButton = new ButtonModel({ + classes: [styles.cancelButton], + text: BUTTON_TEXT[getStore().getState().currentLanguage].CANCEL, + }); + + observeCurrentLanguage(this.cancelButton.getHTML(), BUTTON_TEXT, BUTTON_TEXT_KEYS.CANCEL); + + return this.cancelButton; + } + + private createConfirmButton(): ButtonModel { + this.confirmButton = new ButtonModel({ + classes: [styles.confirmButton], + text: BUTTON_TEXT[getStore().getState().currentLanguage].CONFIRM, + }); + + observeCurrentLanguage(this.confirmButton.getHTML(), BUTTON_TEXT, BUTTON_TEXT_KEYS.CONFIRM); + + return this.confirmButton; + } + + private createHTML(): HTMLDivElement { + this.view = createBaseElement({ + cssClasses: [styles.wrapper], + tag: 'div', + }); + this.view.append(this.userMessage, this.cancelButton.getHTML(), this.confirmButton.getHTML()); + return this.view; + } + + private createUserMessage(message: string): HTMLSpanElement { + this.userMessage = createBaseElement({ + cssClasses: [styles.userMessage], + innerContent: message, + tag: 'span', + }); + + return this.userMessage; + } + + public getCancelButton(): ButtonModel { + return this.cancelButton; + } + + public getConfirmButton(): ButtonModel { + return this.confirmButton; + } + + public getHTML(): HTMLDivElement { + return this.view; + } +} + +export default ConfirmView; diff --git a/src/shared/Confirm/view/confirmView.module.scss b/src/shared/Confirm/view/confirmView.module.scss new file mode 100644 index 00000000..0b03f335 --- /dev/null +++ b/src/shared/Confirm/view/confirmView.module.scss @@ -0,0 +1,41 @@ +@import 'src/app/styles/mixins'; + +.wrapper { + display: grid; + grid-column: 2 span; + grid-template-rows: repeat((2, max-content)); + margin: var(--small-offset) auto; + border-bottom: var(--tiny-offset) solid var(--steam-green-800); + padding: var(--small-offset); + width: 100%; + min-height: calc(var(--extra-large-offset) * 2.1); + max-width: calc(var(--extra-large-offset) * 4); + background-color: var(--noble-white-100); + gap: var(--extra-small-offset); +} + +.userMessage { + grid-column: 2 span; + grid-row: 1; + padding: var(--extra-small-offset); + font: var(--extra-regular-font); + letter-spacing: var(--one); + text-align: center; + color: var(--steam-green-800); + cursor: default; +} + +.cancelButton, +.confirmButton { + @include green-btn; + + grid-row: 2; +} + +.cancelButton { + grid-column: 1; +} + +.confirmButton { + grid-column: 2; +} diff --git a/src/shared/Modal/model/ModalModel.ts b/src/shared/Modal/model/ModalModel.ts index efd461eb..0226ae95 100644 --- a/src/shared/Modal/model/ModalModel.ts +++ b/src/shared/Modal/model/ModalModel.ts @@ -11,6 +11,10 @@ class ModalModel { this.view.hide(); } + public removeContent(): void { + this.view.removeContent(); + } + public setContent(content: HTMLElement): void { this.view.setContent(content); } diff --git a/src/shared/Modal/view/ModalView.ts b/src/shared/Modal/view/ModalView.ts index 53040e4f..41527372 100644 --- a/src/shared/Modal/view/ModalView.ts +++ b/src/shared/Modal/view/ModalView.ts @@ -1,3 +1,4 @@ +import clearOutElement from '@/shared/utils/clearOutElement.ts'; import createBaseElement from '@/shared/utils/createBaseElement.ts'; import styles from './modalView.module.scss'; @@ -76,8 +77,12 @@ class ModalView { document.body.classList.remove('stop-scroll'); } + public removeContent(): void { + clearOutElement(this.modalContent); + } + public setContent(content: HTMLElement): void { - this.modalContent.innerHTML = ''; + clearOutElement(this.modalContent); this.modalContent.append(content); } diff --git a/src/shared/Store/actions.ts b/src/shared/Store/actions.ts index a173276a..10bb4fac 100644 --- a/src/shared/Store/actions.ts +++ b/src/shared/Store/actions.ts @@ -11,6 +11,7 @@ const ACTION = { SET_BILLING_COUNTRY: 'setBillingCountry', SET_CURRENT_LANGUAGE: 'setCurrentLanguage', SET_CURRENT_PAGE: 'setCurrentPage', + SET_DEFAULT_COUNTRY: 'setDefaultCountry', SET_SHIPPING_COUNTRY: 'setShippingCountry', SWITCH_APP_THEME: 'switchAppTheme', SWITCH_IS_USER_LOGGED_IN: 'switchIsUserLoggedIn', @@ -65,6 +66,11 @@ export const setShippingCountry = (value: string): ActionWithPayload => ({ + payload: value, + type: ACTION.SET_DEFAULT_COUNTRY, +}); + export const setCurrentLanguage = ( value: LanguageChoiceType, ): ActionWithPayload => ({ diff --git a/src/shared/Store/observer.ts b/src/shared/Store/observer.ts index c514c9da..0d874897 100644 --- a/src/shared/Store/observer.ts +++ b/src/shared/Store/observer.ts @@ -50,6 +50,8 @@ export const selectBillingCountry = (state: State): string => state.billingCount export const selectShippingCountry = (state: State): string => state.shippingCountry; +export const selectDefaultCountry = (state: State): string => state.defaultCountry; + export const selectCurrentLanguage = (state: State): string => state.currentLanguage; export const selectIsUserLoggedIn = (state: State): boolean => state.isUserLoggedIn; diff --git a/src/shared/Store/reducer.ts b/src/shared/Store/reducer.ts index 2040f620..4e74adb7 100644 --- a/src/shared/Store/reducer.ts +++ b/src/shared/Store/reducer.ts @@ -14,6 +14,7 @@ export interface State { billingCountry: string; currentLanguage: LanguageChoiceType; currentPage: PageIdType | null; + defaultCountry: string; isAppThemeLight: boolean; isUserLoggedIn: boolean; shippingCountry: string; @@ -54,6 +55,11 @@ export const rootReducer: Reducer = (state: State, action: Action ...state, billingCountry: action.payload, }; + case 'setDefaultCountry': + return { + ...state, + defaultCountry: action.payload, + }; case 'setCurrentLanguage': return { ...state, diff --git a/src/shared/Store/test.spec.ts b/src/shared/Store/test.spec.ts index feaca518..678e2a49 100644 --- a/src/shared/Store/test.spec.ts +++ b/src/shared/Store/test.spec.ts @@ -61,6 +61,7 @@ vi.mock('./Store.ts', async (importOriginal) => { billingCountry: '', currentLanguage: 'en', currentPage: '/', + defaultCountry: '', isAppThemeLight: true, isUserLoggedIn: false, shippingCountry: '', @@ -176,6 +177,7 @@ describe('rootReducer', () => { billingCountry: '', currentLanguage: 'en', currentPage: '/', + defaultCountry: '', isAppThemeLight: true, isUserLoggedIn: false, shippingCountry: '', diff --git a/src/shared/constants/buttons.ts b/src/shared/constants/buttons.ts index 0035db11..f17587d8 100644 --- a/src/shared/constants/buttons.ts +++ b/src/shared/constants/buttons.ts @@ -6,9 +6,11 @@ export const BUTTON_TYPE = { export const BUTTON_TEXT = { en: { + ADD_ADDRESS: 'Add address', ADD_PRODUCT: 'Add to cart', BACK_TO_MAIN: 'Back to main', CANCEL: 'Cancel', + CONFIRM: 'Confirm', DELETE_PRODUCT: 'Remove from cart', EDIT_INFO: 'Edit', LOG_OUT: 'Log out', @@ -18,9 +20,11 @@ export const BUTTON_TEXT = { SAVE_CHANGES: 'Save changes', }, ru: { + ADD_ADDRESS: 'Добавить адрес', ADD_PRODUCT: 'Добавить в корзину', BACK_TO_MAIN: 'Вернуться на главную', CANCEL: 'Отмена', + CONFIRM: 'Подтвердить', DELETE_PRODUCT: 'Удалить из корзины', EDIT_INFO: 'Редактировать', LOG_OUT: 'Выйти', @@ -32,9 +36,11 @@ export const BUTTON_TEXT = { } as const; export const BUTTON_TEXT_KEYS = { + ADD_ADDRESS: 'ADD_ADDRESS', ADD_PRODUCT: 'ADD_PRODUCT', BACK_TO_MAIN: 'BACK_TO_MAIN', CANCEL: 'CANCEL', + CONFIRM: 'CONFIRM', DELETE_PRODUCT: 'DELETE_PRODUCT', EDIT_INFO: 'EDIT_INFO', LOG_OUT: 'LOG_OUT', diff --git a/src/shared/constants/confirmUserMessage.ts b/src/shared/constants/confirmUserMessage.ts new file mode 100644 index 00000000..0f225c48 --- /dev/null +++ b/src/shared/constants/confirmUserMessage.ts @@ -0,0 +1,17 @@ +export const USER_MESSAGE = { + en: { + CONFIRM: 'Are you sure you want to proceed?', + DELETE_ADDRESS: 'Are you sure you want to delete this address?', + }, + ru: { + CONFIRM: 'Вы уверены, что хотите продолжить?', + DELETE_ADDRESS: 'Вы уверены, что хотите удалить этот адрес?', + }, +} as const; + +export const USER_MESSAGE_KEYS = { + CONFIRM: 'CONFIRM', + DELETE_ADDRESS: 'DELETE_ADDRESS', +}; + +export type UserMessageKeysType = (typeof USER_MESSAGE_KEYS)[keyof typeof USER_MESSAGE_KEYS]; diff --git a/src/shared/constants/forms/text.ts b/src/shared/constants/forms/text.ts index 7b26a950..55e4ef7a 100644 --- a/src/shared/constants/forms/text.ts +++ b/src/shared/constants/forms/text.ts @@ -1,11 +1,13 @@ export const TITLE_TEXT = { en: { + ADDRESS: 'Address', BILLING_ADDRESS: 'Billing Address', CREDENTIALS: 'Credentials', PERSONAL: 'Personal', SHIPPING_ADDRESS: 'Shipping Address', }, ru: { + ADDRESS: 'Адрес', BILLING_ADDRESS: 'Адрес выставления счетов', CREDENTIALS: 'Логин и пароль', PERSONAL: 'Личные данные', @@ -14,6 +16,7 @@ export const TITLE_TEXT = { } as const; export const TITLE_TEXT_KEYS = { + ADDRESS: 'ADDRESS', BILLING_ADDRESS: 'BILLING_ADDRESS', CREDENTIALS: 'CREDENTIALS', PERSONAL: 'PERSONAL', diff --git a/src/shared/constants/initialState.ts b/src/shared/constants/initialState.ts index 28067d7e..6b374acd 100644 --- a/src/shared/constants/initialState.ts +++ b/src/shared/constants/initialState.ts @@ -10,6 +10,7 @@ const initialState: State = { billingCountry: '', currentLanguage: 'en', currentPage: PAGE_ID.DEFAULT_PAGE, + defaultCountry: '', isAppThemeLight: true, isUserLoggedIn: false, shippingCountry: '', diff --git a/src/shared/constants/tooltip.ts b/src/shared/constants/tooltip.ts index fabd927b..f364d439 100644 --- a/src/shared/constants/tooltip.ts +++ b/src/shared/constants/tooltip.ts @@ -2,24 +2,27 @@ const TOOLTIP_TEXT: Record> = { en: { ADD_BILLING_ADDRESS: 'Add new billing address', ADD_SHIPPING_ADDRESS: 'Add new shipping address', - DELETE_ADDRESS: 'Delete address', + DELETE_ADDRESS: 'Delete address completely', EDIT_ADDRESS: 'Edit address', - EDIT_BILLING_ADDRESS: 'Edit billing address', - EDIT_DEFAULT_BILLING_ADDRESS: 'Edit default billing address', - EDIT_DEFAULT_SHIPPING_ADDRESS: 'Edit default shipping address', EDIT_PASSWORD: 'Edit password', - EDIT_SHIPPING_ADDRESS: 'Edit shipping address', + EDIT_SHIPPING_ADDRESS: 'Switch shipping address status', + SWITCH_ADDRESS_STATUS: 'Change address status', + SWITCH_BILLING_ADDRESS: 'Switch billing address status', + SWITCH_DEFAULT_BILLING_ADDRESS: 'Switch default billing address status', + SWITCH_DEFAULT_SHIPPING_ADDRESS: 'Switch default shipping address status', + SWITCH_SHIPPING_ADDRESS: 'Switch shipping address status', }, ru: { ADD_BILLING_ADDRESS: 'Добавить новый адрес выставления счетов', ADD_SHIPPING_ADDRESS: 'Добавить новый адрес доставки', - DELETE_ADDRESS: 'Удалить адрес', + DELETE_ADDRESS: 'Удалить адрес полностью', EDIT_ADDRESS: 'Изменить адрес', - EDIT_BILLING_ADDRESS: 'Изменить адрес выставления счетов', - EDIT_DEFAULT_BILLING_ADDRESS: 'Изменить адрес выставления счетов по умолчанию', - EDIT_DEFAULT_SHIPPING_ADDRESS: 'Изменить адрес доставки по умолчанию', EDIT_PASSWORD: 'Изменить пароль', - EDIT_SHIPPING_ADDRESS: 'Изменить адрес доставки', + SWITCH_ADDRESS_STATUS: 'Изменить статус адреса', + SWITCH_BILLING_ADDRESS: 'Изменить статус адреса выставления счетов', + SWITCH_DEFAULT_BILLING_ADDRESS: 'Изменить статус адреса выставления счетов по умолчанию', + SWITCH_DEFAULT_SHIPPING_ADDRESS: 'Изменить статус адреса доставки по умолчанию', + SWITCH_SHIPPING_ADDRESS: 'Изменить статус адреса доставки', }, } as const; @@ -28,11 +31,12 @@ export const TOOLTIP_TEXT_KEYS = { ADD_SHIPPING_ADDRESS: 'ADD_SHIPPING_ADDRESS', DELETE_ADDRESS: 'DELETE_ADDRESS', EDIT_ADDRESS: 'EDIT_ADDRESS', - EDIT_BILLING_ADDRESS: 'EDIT_BILLING_ADDRESS', - EDIT_DEFAULT_BILLING_ADDRESS: 'EDIT_DEFAULT_BILLING_ADDRESS', - EDIT_DEFAULT_SHIPPING_ADDRESS: 'EDIT_DEFAULT_SHIPPING_ADDRESS', EDIT_PASSWORD: 'EDIT_PASSWORD', - EDIT_SHIPPING_ADDRESS: 'EDIT_SHIPPING_ADDRESS', + SWITCH_ADDRESS_STATUS: 'SWITCH_ADDRESS_STATUS', + SWITCH_BILLING_ADDRESS: 'SWITCH_BILLING_ADDRESS', + SWITCH_DEFAULT_BILLING_ADDRESS: 'SWITCH_DEFAULT_BILLING_ADDRESS', + SWITCH_DEFAULT_SHIPPING_ADDRESS: 'SWITCH_DEFAULT_SHIPPING_ADDRESS', + SWITCH_SHIPPING_ADDRESS: 'SWITCH_SHIPPING_ADDRESS', }; export type TooltipTextKeysType = (typeof TOOLTIP_TEXT_KEYS)[keyof typeof TOOLTIP_TEXT_KEYS]; diff --git a/src/shared/types/address.ts b/src/shared/types/address.ts index 9e4c587f..dbb0d38d 100644 --- a/src/shared/types/address.ts +++ b/src/shared/types/address.ts @@ -1,12 +1,13 @@ export const ADDRESS_TYPE = { BILLING: 'billing', + GENERAL: 'general', SHIPPING: 'shipping', } as const; -export const SINGLE_ADDRESS = 'asBilling'; - export type AddressType = (typeof ADDRESS_TYPE)[keyof typeof ADDRESS_TYPE]; +export const SINGLE_ADDRESS = 'asBilling'; + export interface AddressOptions { setAsBilling?: boolean; setDefault?: boolean; diff --git a/src/widgets/Header/view/headerView.module.scss b/src/widgets/Header/view/headerView.module.scss index bc77a222..ec4834d8 100644 --- a/src/widgets/Header/view/headerView.module.scss +++ b/src/widgets/Header/view/headerView.module.scss @@ -239,7 +239,7 @@ .burgerButton.open .burgerLine:nth-child(1) { left: calc(var(--five) + 0.04rem); - top: calc(var(--tiny-offset) * 1.1); + top: calc(var(--tiny-offset) * 1.1); // 11px width: var(--extra-small-offset); // 20px transform: rotate(90deg); transition-delay: 150ms; @@ -256,7 +256,7 @@ .burgerButton.open .burgerLine:nth-child(3) { left: calc(var(--tiny-offset) * 1.3); // 13px top: calc(var(--tiny-offset) * 1.7); // 17px - width: calc(var(--tiny-offset) * 1.4); // 14px + width: calc(var(--tiny-offset) * 1.5); // 15px transform: rotate(-45deg); transition-delay: 100ms; } @@ -289,13 +289,7 @@ + .switchThemeLabelSpan::before { background-color: #a7e599; - transform: translate(calc(var(--small-offset) + var(--small-offset) + calc(var(--two) * 2)), -50%); - } - - @media (max-width: 768px) { - + .switchThemeLabelSpan::before { - transform: translate(calc(var(--small-offset) + var(--small-offset) - calc(var(--two) * 2)), -50%); - } + transform: translate(calc(var(--small-offset) + var(--small-offset) + calc(var(--two) * 0.9)), -50%); } } } @@ -355,10 +349,6 @@ height: calc(calc(var(--small-offset) / 1.5) + var(--extra-small-offset)); cursor: pointer; - @media (max-width: 768px) { - width: var(--large-offset); - } - &:disabled { background-color: var(--noble-gray-300); pointer-events: none; @@ -379,12 +369,6 @@ background-color: #c4c4c4a8; transform: translate(calc(var(--small-offset) + calc(var(--one) * 3.5)), -50%); } - - @media (max-width: 768px) { - + .switchLanguageLabelSpan::before { - transform: translate(calc(var(--small-offset) - calc(var(--one) * 3.5)), -50%); - } - } } } diff --git a/src/widgets/RegistrationForm/model/RegistrationFormModel.ts b/src/widgets/RegistrationForm/model/RegistrationFormModel.ts index 17f79169..322d2e3c 100644 --- a/src/widgets/RegistrationForm/model/RegistrationFormModel.ts +++ b/src/widgets/RegistrationForm/model/RegistrationFormModel.ts @@ -17,14 +17,20 @@ import { ADDRESS_TYPE } from '@/shared/types/address.ts'; import RegistrationFormView from '../view/RegistrationFormView.ts'; class RegisterFormModel { - private addressWrappers: Record = { - [ADDRESS_TYPE.BILLING]: new AddressModel(ADDRESS_TYPE.BILLING, { - setDefault: true, - }), - [ADDRESS_TYPE.SHIPPING]: new AddressModel(ADDRESS_TYPE.SHIPPING, { - setAsBilling: true, - setDefault: true, - }), + private addressWrappers: Record, AddressModel> = { + [ADDRESS_TYPE.BILLING]: new AddressModel( + { + setDefault: true, + }, + ADDRESS_TYPE.BILLING, + ), + [ADDRESS_TYPE.SHIPPING]: new AddressModel( + { + setAsBilling: true, + setDefault: true, + }, + ADDRESS_TYPE.SHIPPING, + ), }; private credentialsWrapper = new CredentialsModel(); diff --git a/src/widgets/UserAddresses/model/UserAddressesModel.ts b/src/widgets/UserAddresses/model/UserAddressesModel.ts index ef6390b8..33f164a0 100644 --- a/src/widgets/UserAddresses/model/UserAddressesModel.ts +++ b/src/widgets/UserAddresses/model/UserAddressesModel.ts @@ -16,10 +16,9 @@ import showErrorMessage from '@/shared/utils/userMessage.ts'; import UserAddressesView from '../view/UserAddressesView.ts'; class UserAddressesModel { - private view: UserAddressesView; + private view = new UserAddressesView(); constructor(user: User) { - this.view = new UserAddressesView(); this.init(user); }