From 269a5b67386f930214921432a0b3977fe8859dc2 Mon Sep 17 00:00:00 2001 From: Pavel Yasonau Date: Sun, 8 Dec 2024 15:21:25 +0100 Subject: [PATCH 1/2] =?UTF-8?q?=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=201:?= =?UTF-8?q?=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5=201.=20=D0=A0?= =?UTF-8?q?=D0=B0=D0=B7=D0=B1=D0=B8=D0=BB=20=D0=BC=D0=BE=D0=BD=D0=BE=D0=BB?= =?UTF-8?q?=D0=B8=D1=82=D0=BD=D1=8B=D0=B9=20=D1=84=D1=80=D0=BE=D0=BD=D1=82?= =?UTF-8?q?=D0=B5=D0=BD=D0=B4=20=D0=BD=D0=B0=20=D0=BC=D0=B8=D0=BA=D1=80?= =?UTF-8?q?=D0=BE=D1=84=D1=80=D0=BE=D0=BD=D1=82=D0=B5=D0=BD=D0=B4=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/microfrontend/Readme.md | 32 +++++++ frontend/microfrontend/auth/package.json | 38 ++++++++ frontend/microfrontend/auth/src/App.jsx | 19 ++++ .../auth}/src/components/Login.js | 4 +- .../auth}/src/components/Register.js | 2 +- frontend/microfrontend/auth/src/index.css | 10 +++ frontend/microfrontend/auth/src/index.html | 14 +++ frontend/microfrontend/auth/src/index.js | 1 + .../auth-form/__button/auth-form__button.css | 15 ++++ .../auth-form/__form/auth-form__form.css | 6 ++ .../auth-form/__input/auth-form__input.css | 5 ++ .../auth-form/__link/auth-form__link.css | 7 ++ .../auth-form/__text/auth-form__text.css | 8 ++ .../__textfield/auth-form__textfield.css | 16 ++++ .../auth-form/__title/auth-form__title.css | 8 ++ .../auth/src/styles/auth-form/auth-form.css | 15 ++++ .../auth/src/styles/login/login.css | 0 .../auth}/src/utils/auth.js | 0 frontend/microfrontend/auth/webpack.config.js | 90 +++++++++++++++++++ frontend/microfrontend/host/package.json | 38 ++++++++ frontend/microfrontend/host/src/App.jsx | 19 ++++ .../host}/src/components/App.js | 0 .../host}/src/components/Footer.js | 0 .../host}/src/components/Header.js | 0 .../host}/src/components/InfoTooltip.js | 0 .../host}/src/components/Main.js | 0 .../host}/src/components/PopupWithForm.js | 0 .../host}/src/components/ProtectedRoute.js | 0 .../host/src/contexts/CurrentUserContext.js | 4 + .../host/src/images/error-icon.svg | 15 ++++ .../host/src/images/success-icon.svg | 14 +++ frontend/microfrontend/host/src/index.css | 10 +++ frontend/microfrontend/host/src/index.html | 14 +++ frontend/microfrontend/host/src/index.js | 1 + .../footer/__copyright/footer__copyright.css | 13 +++ .../host/src/styles/footer/footer.css | 13 +++ .../header/__auth-link/header__auth-link.css | 10 +++ .../src/styles/header/__logo/header__logo.css | 13 +++ .../styles/header/__logout/header__logout.css | 8 ++ .../src/styles/header/__user/header__user.css | 7 ++ .../header/__wrapper/header__wrapper.css | 3 + .../host/src/styles/header/header.css | 39 ++++++++ .../styles/page/__content/page__content.css | 8 ++ .../styles/page/__section/page__section.css | 15 ++++ .../host/src/styles/page/page.css | 6 ++ .../__add-button/profile__add-button.css | 34 +++++++ .../__description/profile__description.css | 20 +++++ .../__edit-button/profile__edit-button.css | 29 ++++++ .../styles/profile/__image/profile__image.css | 72 +++++++++++++++ .../styles/profile/__info/profile__info.css | 30 +++++++ .../styles/profile/__title/profile__title.css | 30 +++++++ .../host/src/styles/profile/profile.css | 22 +++++ .../{ => microfrontend/host}/src/utils/api.js | 0 frontend/microfrontend/host/webpack.config.js | 90 +++++++++++++++++++ frontend/microfrontend/photo/package.json | 38 ++++++++ frontend/microfrontend/photo/src/App.jsx | 19 ++++ .../photo}/src/components/AddPlacePopup.js | 0 .../photo}/src/components/Card.js | 0 .../photo}/src/components/ImagePopup.js | 0 .../photo/src/components/PopupWithForm.js | 26 ++++++ .../photo/src/contexts/CurrentUserContext.js | 4 + frontend/microfrontend/photo/src/index.css | 10 +++ frontend/microfrontend/photo/src/index.html | 14 +++ frontend/microfrontend/photo/src/index.js | 1 + .../_disabled/popup__button_disabled.css | 4 + .../styles/popup/__button/popup__button.css | 26 ++++++ .../styles/popup/__caption/popup__caption.css | 9 ++ .../src/styles/popup/__close/popup__close.css | 23 +++++ .../_content/popup__content_content_image.css | 14 +++ .../styles/popup/__content/popup__content.css | 19 ++++ .../__error/_visible/popup__error_visible.css | 3 + .../src/styles/popup/__error/popup__error.css | 10 +++ .../src/styles/popup/__form/popup__form.css | 3 + .../src/styles/popup/__icon/popup__icon.css | 6 ++ .../src/styles/popup/__image/popup__image.css | 6 ++ .../__input/_type/popup__input_type_error.css | 3 + .../src/styles/popup/__input/popup__input.css | 26 ++++++ .../src/styles/popup/__label/popup__label.css | 5 ++ .../popup__status-message.css | 8 ++ .../src/styles/popup/__title/popup__title.css | 12 +++ .../popup/_is-opened/popup_is-opened.css | 6 ++ .../popup/_type/popup_type_edit-avatar.css | 3 + .../popup/_type/popup_type_remove-card.css | 3 + .../photo/src/styles/popup/popup.css | 37 ++++++++ .../microfrontend/photo/webpack.config.js | 90 +++++++++++++++++++ frontend/microfrontend/profile/package.json | 38 ++++++++ .../src/components/EditAvatarPopup.js | 0 .../src/components/EditProfilePopup.js | 0 .../profile/src/components/PopupWithForm.js | 26 ++++++ .../src/contexts/CurrentUserContext.js | 4 + .../microfrontend/profile/src/styles/App.jsx | 19 ++++ .../_hidden/card__delete-button_hidden.css | 0 .../_visible/card__delete-button_visible.css | 0 .../__delete-button/card__delete-button.css | 0 .../card/__description/card__description.css | 0 .../src/styles}/card/__image/card__image.css | 0 .../card__like-button_is-active.css | 0 .../card/__like-button/card__like-button.css | 0 .../card/__like-count/card__like-count.css | 0 .../src/styles}/card/__title/card__title.css | 0 .../profile/src/styles}/card/card.css | 0 .../profile/src/styles/index.css | 10 +++ .../profile/src/styles/index.html | 14 +++ .../microfrontend/profile/src/styles/index.js | 1 + .../_disabled/popup__button_disabled.css | 4 + .../styles/popup/__button/popup__button.css | 26 ++++++ .../styles/popup/__caption/popup__caption.css | 9 ++ .../src/styles/popup/__close/popup__close.css | 23 +++++ .../_content/popup__content_content_image.css | 14 +++ .../styles/popup/__content/popup__content.css | 19 ++++ .../__error/_visible/popup__error_visible.css | 3 + .../src/styles/popup/__error/popup__error.css | 10 +++ .../src/styles/popup/__form/popup__form.css | 3 + .../src/styles/popup/__icon/popup__icon.css | 6 ++ .../src/styles/popup/__image/popup__image.css | 6 ++ .../__input/_type/popup__input_type_error.css | 3 + .../src/styles/popup/__input/popup__input.css | 26 ++++++ .../src/styles/popup/__label/popup__label.css | 5 ++ .../popup__status-message.css | 8 ++ .../src/styles/popup/__title/popup__title.css | 12 +++ .../popup/_is-opened/popup_is-opened.css | 6 ++ .../popup/_type/popup_type_edit-avatar.css | 3 + .../popup/_type/popup_type_remove-card.css | 3 + .../profile/src/styles/popup/popup.css | 37 ++++++++ .../__add-button/profile__add-button.css | 34 +++++++ .../__description/profile__description.css | 20 +++++ .../__edit-button/profile__edit-button.css | 29 ++++++ .../styles/profile/__image/profile__image.css | 72 +++++++++++++++ .../styles/profile/__info/profile__info.css | 30 +++++++ .../styles/profile/__title/profile__title.css | 30 +++++++ .../profile/src/styles/profile/profile.css | 22 +++++ .../microfrontend/profile/webpack.config.js | 89 ++++++++++++++++++ 132 files changed, 1956 insertions(+), 3 deletions(-) create mode 100644 frontend/microfrontend/Readme.md create mode 100644 frontend/microfrontend/auth/package.json create mode 100644 frontend/microfrontend/auth/src/App.jsx rename frontend/{ => microfrontend/auth}/src/components/Login.js (95%) rename frontend/{ => microfrontend/auth}/src/components/Register.js (98%) create mode 100644 frontend/microfrontend/auth/src/index.css create mode 100644 frontend/microfrontend/auth/src/index.html create mode 100644 frontend/microfrontend/auth/src/index.js create mode 100644 frontend/microfrontend/auth/src/styles/auth-form/__button/auth-form__button.css create mode 100644 frontend/microfrontend/auth/src/styles/auth-form/__form/auth-form__form.css create mode 100644 frontend/microfrontend/auth/src/styles/auth-form/__input/auth-form__input.css create mode 100644 frontend/microfrontend/auth/src/styles/auth-form/__link/auth-form__link.css create mode 100644 frontend/microfrontend/auth/src/styles/auth-form/__text/auth-form__text.css create mode 100644 frontend/microfrontend/auth/src/styles/auth-form/__textfield/auth-form__textfield.css create mode 100644 frontend/microfrontend/auth/src/styles/auth-form/__title/auth-form__title.css create mode 100644 frontend/microfrontend/auth/src/styles/auth-form/auth-form.css create mode 100644 frontend/microfrontend/auth/src/styles/login/login.css rename frontend/{ => microfrontend/auth}/src/utils/auth.js (100%) create mode 100644 frontend/microfrontend/auth/webpack.config.js create mode 100644 frontend/microfrontend/host/package.json create mode 100644 frontend/microfrontend/host/src/App.jsx rename frontend/{ => microfrontend/host}/src/components/App.js (100%) rename frontend/{ => microfrontend/host}/src/components/Footer.js (100%) rename frontend/{ => microfrontend/host}/src/components/Header.js (100%) rename frontend/{ => microfrontend/host}/src/components/InfoTooltip.js (100%) rename frontend/{ => microfrontend/host}/src/components/Main.js (100%) rename frontend/{ => microfrontend/host}/src/components/PopupWithForm.js (100%) rename frontend/{ => microfrontend/host}/src/components/ProtectedRoute.js (100%) create mode 100644 frontend/microfrontend/host/src/contexts/CurrentUserContext.js create mode 100644 frontend/microfrontend/host/src/images/error-icon.svg create mode 100644 frontend/microfrontend/host/src/images/success-icon.svg create mode 100644 frontend/microfrontend/host/src/index.css create mode 100644 frontend/microfrontend/host/src/index.html create mode 100644 frontend/microfrontend/host/src/index.js create mode 100644 frontend/microfrontend/host/src/styles/footer/__copyright/footer__copyright.css create mode 100644 frontend/microfrontend/host/src/styles/footer/footer.css create mode 100644 frontend/microfrontend/host/src/styles/header/__auth-link/header__auth-link.css create mode 100644 frontend/microfrontend/host/src/styles/header/__logo/header__logo.css create mode 100644 frontend/microfrontend/host/src/styles/header/__logout/header__logout.css create mode 100644 frontend/microfrontend/host/src/styles/header/__user/header__user.css create mode 100644 frontend/microfrontend/host/src/styles/header/__wrapper/header__wrapper.css create mode 100644 frontend/microfrontend/host/src/styles/header/header.css create mode 100644 frontend/microfrontend/host/src/styles/page/__content/page__content.css create mode 100644 frontend/microfrontend/host/src/styles/page/__section/page__section.css create mode 100644 frontend/microfrontend/host/src/styles/page/page.css create mode 100644 frontend/microfrontend/host/src/styles/profile/__add-button/profile__add-button.css create mode 100644 frontend/microfrontend/host/src/styles/profile/__description/profile__description.css create mode 100644 frontend/microfrontend/host/src/styles/profile/__edit-button/profile__edit-button.css create mode 100644 frontend/microfrontend/host/src/styles/profile/__image/profile__image.css create mode 100644 frontend/microfrontend/host/src/styles/profile/__info/profile__info.css create mode 100644 frontend/microfrontend/host/src/styles/profile/__title/profile__title.css create mode 100644 frontend/microfrontend/host/src/styles/profile/profile.css rename frontend/{ => microfrontend/host}/src/utils/api.js (100%) create mode 100644 frontend/microfrontend/host/webpack.config.js create mode 100644 frontend/microfrontend/photo/package.json create mode 100644 frontend/microfrontend/photo/src/App.jsx rename frontend/{ => microfrontend/photo}/src/components/AddPlacePopup.js (100%) rename frontend/{ => microfrontend/photo}/src/components/Card.js (100%) rename frontend/{ => microfrontend/photo}/src/components/ImagePopup.js (100%) create mode 100644 frontend/microfrontend/photo/src/components/PopupWithForm.js create mode 100644 frontend/microfrontend/photo/src/contexts/CurrentUserContext.js create mode 100644 frontend/microfrontend/photo/src/index.css create mode 100644 frontend/microfrontend/photo/src/index.html create mode 100644 frontend/microfrontend/photo/src/index.js create mode 100644 frontend/microfrontend/photo/src/styles/popup/__button/_disabled/popup__button_disabled.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__button/popup__button.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__caption/popup__caption.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__close/popup__close.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__content/_content/popup__content_content_image.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__content/popup__content.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__error/_visible/popup__error_visible.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__error/popup__error.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__form/popup__form.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__icon/popup__icon.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__image/popup__image.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__input/_type/popup__input_type_error.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__input/popup__input.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__label/popup__label.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__status-message/popup__status-message.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/__title/popup__title.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/_is-opened/popup_is-opened.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/_type/popup_type_edit-avatar.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/_type/popup_type_remove-card.css create mode 100644 frontend/microfrontend/photo/src/styles/popup/popup.css create mode 100644 frontend/microfrontend/photo/webpack.config.js create mode 100644 frontend/microfrontend/profile/package.json rename frontend/{ => microfrontend/profile}/src/components/EditAvatarPopup.js (100%) rename frontend/{ => microfrontend/profile}/src/components/EditProfilePopup.js (100%) create mode 100644 frontend/microfrontend/profile/src/components/PopupWithForm.js create mode 100644 frontend/microfrontend/profile/src/contexts/CurrentUserContext.js create mode 100644 frontend/microfrontend/profile/src/styles/App.jsx rename frontend/{src/blocks => microfrontend/profile/src/styles}/card/__delete-button/_hidden/card__delete-button_hidden.css (100%) rename frontend/{src/blocks => microfrontend/profile/src/styles}/card/__delete-button/_visible/card__delete-button_visible.css (100%) rename frontend/{src/blocks => microfrontend/profile/src/styles}/card/__delete-button/card__delete-button.css (100%) rename frontend/{src/blocks => microfrontend/profile/src/styles}/card/__description/card__description.css (100%) rename frontend/{src/blocks => microfrontend/profile/src/styles}/card/__image/card__image.css (100%) rename frontend/{src/blocks => microfrontend/profile/src/styles}/card/__like-button/_is-active/card__like-button_is-active.css (100%) rename frontend/{src/blocks => microfrontend/profile/src/styles}/card/__like-button/card__like-button.css (100%) rename frontend/{src/blocks => microfrontend/profile/src/styles}/card/__like-count/card__like-count.css (100%) rename frontend/{src/blocks => microfrontend/profile/src/styles}/card/__title/card__title.css (100%) rename frontend/{src/blocks => microfrontend/profile/src/styles}/card/card.css (100%) create mode 100644 frontend/microfrontend/profile/src/styles/index.css create mode 100644 frontend/microfrontend/profile/src/styles/index.html create mode 100644 frontend/microfrontend/profile/src/styles/index.js create mode 100644 frontend/microfrontend/profile/src/styles/popup/__button/_disabled/popup__button_disabled.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__button/popup__button.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__caption/popup__caption.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__close/popup__close.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__content/_content/popup__content_content_image.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__content/popup__content.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__error/_visible/popup__error_visible.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__error/popup__error.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__form/popup__form.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__icon/popup__icon.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__image/popup__image.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__input/_type/popup__input_type_error.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__input/popup__input.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__label/popup__label.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__status-message/popup__status-message.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/__title/popup__title.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/_is-opened/popup_is-opened.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/_type/popup_type_edit-avatar.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/_type/popup_type_remove-card.css create mode 100644 frontend/microfrontend/profile/src/styles/popup/popup.css create mode 100644 frontend/microfrontend/profile/src/styles/profile/__add-button/profile__add-button.css create mode 100644 frontend/microfrontend/profile/src/styles/profile/__description/profile__description.css create mode 100644 frontend/microfrontend/profile/src/styles/profile/__edit-button/profile__edit-button.css create mode 100644 frontend/microfrontend/profile/src/styles/profile/__image/profile__image.css create mode 100644 frontend/microfrontend/profile/src/styles/profile/__info/profile__info.css create mode 100644 frontend/microfrontend/profile/src/styles/profile/__title/profile__title.css create mode 100644 frontend/microfrontend/profile/src/styles/profile/profile.css create mode 100644 frontend/microfrontend/profile/webpack.config.js diff --git a/frontend/microfrontend/Readme.md b/frontend/microfrontend/Readme.md new file mode 100644 index 00000000..042120d2 --- /dev/null +++ b/frontend/microfrontend/Readme.md @@ -0,0 +1,32 @@ +Использовал Webpack - Module Federation. Если я правильно разобрался, то все микрофоронтенды написаны на React и можно предоставить общий код во время выполнения. + +Использовал подход DDD для разделения, на основании бизнес-логики определил следующие микрофронтенды + +Микрофронтенды: +auth - удаленный модуль аутентификации +photo - удаленный модуль для работы с изображениями +profile - удаленный модуль для работы с профилем пользователя +host - основное приложение , динамически загружает модули auth/photo/profile + +Компоненты auth : +Login // Компонент для логина пользователя +Register // Компонент регистрации пользователя + +Компоненты photo : +AddPlacePopup // Компонент добавления изображдения +ImagePopup // Компонент - показ изображения +PopupWithForm // Компонент - попап сохранения +Card // Компонент - карточка с изображением + +Компоненты profile : +EditAvatarPopup // Компонент - редактирования аватарки пользователя EditProfilePopup // Компонент - редактирования профиля пользователя PopupWithForm // Компонент - диалоговое окно сохранения + +Компоненты host : + +App // Компонент основной +Footer // Компонент футер +Header // Компонент хеадер +ProtectedRoute // Компонент маршрутизатор +InfoTooltip // Компонент - тултип информационное окно +Main // Компонент - главный компонент для отображения основного списка с карточками изображений +PopupWithForm // Компонент - диалоговое окно сохранения diff --git a/frontend/microfrontend/auth/package.json b/frontend/microfrontend/auth/package.json new file mode 100644 index 00000000..beca948e --- /dev/null +++ b/frontend/microfrontend/auth/package.json @@ -0,0 +1,38 @@ +{ + "name": "auth", + "version": "1.0.0", + "scripts": { + "build": "webpack --mode production", + "build:dev": "webpack --mode development", + "build:start": "cd dist && PORT=8091 npx serve", + "start": "webpack serve --mode development", + "start:live": "webpack serve --mode development --live-reload --hot" + }, + "license": "MIT", + "author": { + "name": "Jack Herrington", + "email": "jherr@pobox.com" + }, + "devDependencies": { + "@babel/core": "^7.15.8", + "@babel/plugin-transform-runtime": "^7.15.8", + "@babel/preset-env": "^7.15.8", + "@babel/preset-react": "^7.14.5", + "autoprefixer": "^10.1.0", + "babel-loader": "^8.2.2", + "css-loader": "^6.3.0", + "html-webpack-plugin": "^5.3.2", + "postcss": "^8.2.1", + "postcss-loader": "^4.1.0", + "style-loader": "^3.3.0", + "webpack": "^5.57.1", + "webpack-cli": "^4.10.0", + "webpack-dev-server": "^4.3.1", + "dotenv-webpack": "^8.0.1" + }, + "dependencies": { + "@babel/runtime": "^7.13.10", + "react": "^18.2.0", + "react-dom": "^18.2.0" + } +} \ No newline at end of file diff --git a/frontend/microfrontend/auth/src/App.jsx b/frontend/microfrontend/auth/src/App.jsx new file mode 100644 index 00000000..71200f05 --- /dev/null +++ b/frontend/microfrontend/auth/src/App.jsx @@ -0,0 +1,19 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; + +import "./index.css"; + +const App = () => ( +
+
Name: auth
+
Framework: react
+
Language: JavaScript
+
CSS: Empty CSS
+
+); +const rootElement = document.getElementById("app") +if (!rootElement) throw new Error("Failed to find the root element") + +const root = ReactDOM.createRoot(rootElement) + +root.render() \ No newline at end of file diff --git a/frontend/src/components/Login.js b/frontend/microfrontend/auth/src/components/Login.js similarity index 95% rename from frontend/src/components/Login.js rename to frontend/microfrontend/auth/src/components/Login.js index 8b4196d1..6fe3a48f 100644 --- a/frontend/src/components/Login.js +++ b/frontend/microfrontend/auth/src/components/Login.js @@ -1,6 +1,6 @@ import React from 'react'; -import '../blocks/login/login.css'; +import '../styles/login/login.css'; function Login ({ onLogin }){ const [email, setEmail] = React.useState(''); @@ -36,4 +36,4 @@ function Login ({ onLogin }){ ) } -export default Login; +export default Login; \ No newline at end of file diff --git a/frontend/src/components/Register.js b/frontend/microfrontend/auth/src/components/Register.js similarity index 98% rename from frontend/src/components/Register.js rename to frontend/microfrontend/auth/src/components/Register.js index f72fd4dd..621d1cc9 100644 --- a/frontend/src/components/Register.js +++ b/frontend/microfrontend/auth/src/components/Register.js @@ -38,4 +38,4 @@ function Register ({ onRegister }){ ) } -export default Register; +export default Register; \ No newline at end of file diff --git a/frontend/microfrontend/auth/src/index.css b/frontend/microfrontend/auth/src/index.css new file mode 100644 index 00000000..20e225c5 --- /dev/null +++ b/frontend/microfrontend/auth/src/index.css @@ -0,0 +1,10 @@ +body { + font-family: Arial, Helvetica, sans-serif; +} + +.container { + font-size: 3rem; + margin: auto; + max-width: 800px; + margin-top: 20px; +} \ No newline at end of file diff --git a/frontend/microfrontend/auth/src/index.html b/frontend/microfrontend/auth/src/index.html new file mode 100644 index 00000000..b6976da3 --- /dev/null +++ b/frontend/microfrontend/auth/src/index.html @@ -0,0 +1,14 @@ + + + + + + + auth + + + +
+ + + \ No newline at end of file diff --git a/frontend/microfrontend/auth/src/index.js b/frontend/microfrontend/auth/src/index.js new file mode 100644 index 00000000..ed6e00cd --- /dev/null +++ b/frontend/microfrontend/auth/src/index.js @@ -0,0 +1 @@ +import("./App"); \ No newline at end of file diff --git a/frontend/microfrontend/auth/src/styles/auth-form/__button/auth-form__button.css b/frontend/microfrontend/auth/src/styles/auth-form/__button/auth-form__button.css new file mode 100644 index 00000000..c3d85651 --- /dev/null +++ b/frontend/microfrontend/auth/src/styles/auth-form/__button/auth-form__button.css @@ -0,0 +1,15 @@ +.auth-form__button { + width: 358px; + height: 50px; + background-color: #fff; + border: 0; + border-radius: 2px; + font-family: Inter, sans-serif; + font-size: 18px; + line-height: 22px; + cursor: pointer; +} + +.auth-form__button:hover { + opacity: .85; +} \ No newline at end of file diff --git a/frontend/microfrontend/auth/src/styles/auth-form/__form/auth-form__form.css b/frontend/microfrontend/auth/src/styles/auth-form/__form/auth-form__form.css new file mode 100644 index 00000000..30ebdfe7 --- /dev/null +++ b/frontend/microfrontend/auth/src/styles/auth-form/__form/auth-form__form.css @@ -0,0 +1,6 @@ +.auth-form__form { + display: flex; + flex-direction: column; + min-height: 60vh; + justify-content: space-between; +} \ No newline at end of file diff --git a/frontend/microfrontend/auth/src/styles/auth-form/__input/auth-form__input.css b/frontend/microfrontend/auth/src/styles/auth-form/__input/auth-form__input.css new file mode 100644 index 00000000..27c5a510 --- /dev/null +++ b/frontend/microfrontend/auth/src/styles/auth-form/__input/auth-form__input.css @@ -0,0 +1,5 @@ +.auth-form__input { + width: 358px; + margin-bottom: 30px; + display: block; +} \ No newline at end of file diff --git a/frontend/microfrontend/auth/src/styles/auth-form/__link/auth-form__link.css b/frontend/microfrontend/auth/src/styles/auth-form/__link/auth-form__link.css new file mode 100644 index 00000000..ba43bd91 --- /dev/null +++ b/frontend/microfrontend/auth/src/styles/auth-form/__link/auth-form__link.css @@ -0,0 +1,7 @@ +.auth-form__link { + color: #fff; +} + +.auth-form__link:hover { + opacity: .85; +} \ No newline at end of file diff --git a/frontend/microfrontend/auth/src/styles/auth-form/__text/auth-form__text.css b/frontend/microfrontend/auth/src/styles/auth-form/__text/auth-form__text.css new file mode 100644 index 00000000..c756474c --- /dev/null +++ b/frontend/microfrontend/auth/src/styles/auth-form/__text/auth-form__text.css @@ -0,0 +1,8 @@ +.auth-form__text { + color: #fff; + font-family: Inter, sans-serif; + text-align: center; + font-size: 14px; + line-height: 17px; + margin-top: 15px; +} \ No newline at end of file diff --git a/frontend/microfrontend/auth/src/styles/auth-form/__textfield/auth-form__textfield.css b/frontend/microfrontend/auth/src/styles/auth-form/__textfield/auth-form__textfield.css new file mode 100644 index 00000000..136b1ee5 --- /dev/null +++ b/frontend/microfrontend/auth/src/styles/auth-form/__textfield/auth-form__textfield.css @@ -0,0 +1,16 @@ +.auth-form__textfield { + font-family: Inter, sans-serif; + background-color: transparent; + border: 0; + border-bottom: 2px solid #CCCCCC; + font-size: 14px; + padding: 13px 0; + width: 100%; + color: #fff; +} + +.auth-form__textfield::-webkit-input-placeholder {color:#CCCCCC;} +.auth-form__textfield::-moz-placeholder {color:#CCCCCC;} +.auth-form__textfield:-moz-placeholder {color:#CCCCCC;} +.auth-form__textfield:-ms-input-placeholder {color:#CCCCCC;} +.auth-form__textfield::placeholder {color:#CCCCCC;} diff --git a/frontend/microfrontend/auth/src/styles/auth-form/__title/auth-form__title.css b/frontend/microfrontend/auth/src/styles/auth-form/__title/auth-form__title.css new file mode 100644 index 00000000..ec21e0f9 --- /dev/null +++ b/frontend/microfrontend/auth/src/styles/auth-form/__title/auth-form__title.css @@ -0,0 +1,8 @@ +.auth-form__title { + color: #fff; + font-weight: 900; + font-size: 24px; + line-height: 29px; + font-family: Inter, sans-serif; + text-align: center; +} \ No newline at end of file diff --git a/frontend/microfrontend/auth/src/styles/auth-form/auth-form.css b/frontend/microfrontend/auth/src/styles/auth-form/auth-form.css new file mode 100644 index 00000000..460be902 --- /dev/null +++ b/frontend/microfrontend/auth/src/styles/auth-form/auth-form.css @@ -0,0 +1,15 @@ +@import url('./__title/auth-form__title.css'); +@import url('./__form/auth-form__form.css'); +@import url('./__input/auth-form__input.css'); +@import url('./__textfield/auth-form__textfield.css'); +@import url('./__button/auth-form__button.css'); +@import url('./__text/auth-form__text.css'); +@import url('./__link/auth-form__link.css'); + +.auth-form { + flex-grow: 1; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +} \ No newline at end of file diff --git a/frontend/microfrontend/auth/src/styles/login/login.css b/frontend/microfrontend/auth/src/styles/login/login.css new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/utils/auth.js b/frontend/microfrontend/auth/src/utils/auth.js similarity index 100% rename from frontend/src/utils/auth.js rename to frontend/microfrontend/auth/src/utils/auth.js diff --git a/frontend/microfrontend/auth/webpack.config.js b/frontend/microfrontend/auth/webpack.config.js new file mode 100644 index 00000000..1224665d --- /dev/null +++ b/frontend/microfrontend/auth/webpack.config.js @@ -0,0 +1,90 @@ + +const HtmlWebPackPlugin = require("html-webpack-plugin"); +const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); +const path = require('path'); +const Dotenv = require('dotenv-webpack'); + +const deps = require("./package.json").dependencies; + +const printCompilationMessage = require('./compilation.config.js'); + +module.exports = (_, argv) => ({ + output: { + publicPath: "http://localhost:8091/", + }, + + resolve: { + extensions: [".tsx", ".ts", ".jsx", ".js", ".json"], + }, + + devServer: { + port: 8091, + historyApiFallback: true, + watchFiles: [path.resolve(__dirname, 'src')], + onListening: function (devServer) { + const port = devServer.server.address().port + + printCompilationMessage('compiling', port) + + devServer.compiler.hooks.done.tap('OutputMessagePlugin', (stats) => { + setImmediate(() => { + if (stats.hasErrors()) { + printCompilationMessage('failure', port) + } else { + printCompilationMessage('success', port) + } + }) + }) + } + }, + + module: { + rules: [ + { + test: /\.m?js/, + type: "javascript/auto", + resolve: { + fullySpecified: false, + }, + }, + { + test: /\.(css|s[ac]ss)$/i, + use: ["style-loader", "css-loader", "postcss-loader"], + }, + { + test: /\.(ts|tsx|js|jsx)$/, + exclude: /node_modules/, + use: { + loader: "babel-loader", + }, + }, + ], + }, + + plugins: [ + new ModuleFederationPlugin({ + name: "auth", + filename: "remoteEntry.js", + remotes: {}, + exposes: { + './Login': './src/components/Login.js', + './Register': './src/components/Register.js' + }, + shared: { + ...deps, + react: { + singleton: true, + requiredVersion: deps.react, + }, + "react-dom": { + singleton: true, + requiredVersion: deps["react-dom"], + }, + }, + }), + new HtmlWebPackPlugin({ + template: "./src/index.html", + }), + new Dotenv() + ], +}); diff --git a/frontend/microfrontend/host/package.json b/frontend/microfrontend/host/package.json new file mode 100644 index 00000000..b0fa7027 --- /dev/null +++ b/frontend/microfrontend/host/package.json @@ -0,0 +1,38 @@ +{ + "name": "host", + "version": "1.0.0", + "scripts": { + "build": "webpack --mode production", + "build:dev": "webpack --mode development", + "build:start": "cd dist && PORT=8090 npx serve", + "start": "webpack serve --mode development", + "start:live": "webpack serve --mode development --live-reload --hot" + }, + "license": "MIT", + "author": { + "name": "Jack Herrington", + "email": "jherr@pobox.com" + }, + "devDependencies": { + "@babel/core": "^7.15.8", + "@babel/plugin-transform-runtime": "^7.15.8", + "@babel/preset-env": "^7.15.8", + "@babel/preset-react": "^7.14.5", + "autoprefixer": "^10.1.0", + "babel-loader": "^8.2.2", + "css-loader": "^6.3.0", + "html-webpack-plugin": "^5.3.2", + "postcss": "^8.2.1", + "postcss-loader": "^4.1.0", + "style-loader": "^3.3.0", + "webpack": "^5.57.1", + "webpack-cli": "^4.10.0", + "webpack-dev-server": "^4.3.1", + "dotenv-webpack": "^8.0.1" + }, + "dependencies": { + "@babel/runtime": "^7.13.10", + "react": "^18.2.0", + "react-dom": "^18.2.0" + } +} \ No newline at end of file diff --git a/frontend/microfrontend/host/src/App.jsx b/frontend/microfrontend/host/src/App.jsx new file mode 100644 index 00000000..2378f927 --- /dev/null +++ b/frontend/microfrontend/host/src/App.jsx @@ -0,0 +1,19 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; + +import "./index.css"; + +const App = () => ( +
+
Name: host
+
Framework: react
+
Language: JavaScript
+
CSS: Empty CSS
+
+); +const rootElement = document.getElementById("app") +if (!rootElement) throw new Error("Failed to find the root element") + +const root = ReactDOM.createRoot(rootElement) + +root.render() \ No newline at end of file diff --git a/frontend/src/components/App.js b/frontend/microfrontend/host/src/components/App.js similarity index 100% rename from frontend/src/components/App.js rename to frontend/microfrontend/host/src/components/App.js diff --git a/frontend/src/components/Footer.js b/frontend/microfrontend/host/src/components/Footer.js similarity index 100% rename from frontend/src/components/Footer.js rename to frontend/microfrontend/host/src/components/Footer.js diff --git a/frontend/src/components/Header.js b/frontend/microfrontend/host/src/components/Header.js similarity index 100% rename from frontend/src/components/Header.js rename to frontend/microfrontend/host/src/components/Header.js diff --git a/frontend/src/components/InfoTooltip.js b/frontend/microfrontend/host/src/components/InfoTooltip.js similarity index 100% rename from frontend/src/components/InfoTooltip.js rename to frontend/microfrontend/host/src/components/InfoTooltip.js diff --git a/frontend/src/components/Main.js b/frontend/microfrontend/host/src/components/Main.js similarity index 100% rename from frontend/src/components/Main.js rename to frontend/microfrontend/host/src/components/Main.js diff --git a/frontend/src/components/PopupWithForm.js b/frontend/microfrontend/host/src/components/PopupWithForm.js similarity index 100% rename from frontend/src/components/PopupWithForm.js rename to frontend/microfrontend/host/src/components/PopupWithForm.js diff --git a/frontend/src/components/ProtectedRoute.js b/frontend/microfrontend/host/src/components/ProtectedRoute.js similarity index 100% rename from frontend/src/components/ProtectedRoute.js rename to frontend/microfrontend/host/src/components/ProtectedRoute.js diff --git a/frontend/microfrontend/host/src/contexts/CurrentUserContext.js b/frontend/microfrontend/host/src/contexts/CurrentUserContext.js new file mode 100644 index 00000000..38344d08 --- /dev/null +++ b/frontend/microfrontend/host/src/contexts/CurrentUserContext.js @@ -0,0 +1,4 @@ +import React from 'react'; + +// Объект контекста CurrentUserContext экспортируется из отдельного файла директории contexts +export const CurrentUserContext = React.createContext(); diff --git a/frontend/microfrontend/host/src/images/error-icon.svg b/frontend/microfrontend/host/src/images/error-icon.svg new file mode 100644 index 00000000..cc5d979b --- /dev/null +++ b/frontend/microfrontend/host/src/images/error-icon.svg @@ -0,0 +1,15 @@ + + + Group 2 + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/microfrontend/host/src/images/success-icon.svg b/frontend/microfrontend/host/src/images/success-icon.svg new file mode 100644 index 00000000..226537a2 --- /dev/null +++ b/frontend/microfrontend/host/src/images/success-icon.svg @@ -0,0 +1,14 @@ + + + Group + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/microfrontend/host/src/index.css b/frontend/microfrontend/host/src/index.css new file mode 100644 index 00000000..20e225c5 --- /dev/null +++ b/frontend/microfrontend/host/src/index.css @@ -0,0 +1,10 @@ +body { + font-family: Arial, Helvetica, sans-serif; +} + +.container { + font-size: 3rem; + margin: auto; + max-width: 800px; + margin-top: 20px; +} \ No newline at end of file diff --git a/frontend/microfrontend/host/src/index.html b/frontend/microfrontend/host/src/index.html new file mode 100644 index 00000000..b6555d59 --- /dev/null +++ b/frontend/microfrontend/host/src/index.html @@ -0,0 +1,14 @@ + + + + + + + host + + + +
+ + + \ No newline at end of file diff --git a/frontend/microfrontend/host/src/index.js b/frontend/microfrontend/host/src/index.js new file mode 100644 index 00000000..ed6e00cd --- /dev/null +++ b/frontend/microfrontend/host/src/index.js @@ -0,0 +1 @@ +import("./App"); \ No newline at end of file diff --git a/frontend/microfrontend/host/src/styles/footer/__copyright/footer__copyright.css b/frontend/microfrontend/host/src/styles/footer/__copyright/footer__copyright.css new file mode 100644 index 00000000..5941b681 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/footer/__copyright/footer__copyright.css @@ -0,0 +1,13 @@ +.footer__copyright { + font-size: 18px; + line-height: 22px; + color: #545454; + margin: 0; +} + +@media screen and (max-width: 568px) { + .footer__copyright { + font-size: 14px; + line-height: 17px; + } +} diff --git a/frontend/microfrontend/host/src/styles/footer/footer.css b/frontend/microfrontend/host/src/styles/footer/footer.css new file mode 100644 index 00000000..9455f1b2 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/footer/footer.css @@ -0,0 +1,13 @@ +@import url('./__copyright/footer__copyright.css'); + +.footer { + font-family: 'Inter', Arial, sans-serif; + flex-shrink: 0; + padding: 30px 0 60px; +} + +@media screen and (max-width: 568px) { + .footer { + padding: 30px 0 36px; + } +} diff --git a/frontend/microfrontend/host/src/styles/header/__auth-link/header__auth-link.css b/frontend/microfrontend/host/src/styles/header/__auth-link/header__auth-link.css new file mode 100644 index 00000000..18a11e1a --- /dev/null +++ b/frontend/microfrontend/host/src/styles/header/__auth-link/header__auth-link.css @@ -0,0 +1,10 @@ +.header__auth-link { + font-size: 18px; + line-height: 22px; + color: #FFFFFF; + text-decoration: none; +} + +.header__auth-link:hover { + opacity: .85; +} \ No newline at end of file diff --git a/frontend/microfrontend/host/src/styles/header/__logo/header__logo.css b/frontend/microfrontend/host/src/styles/header/__logo/header__logo.css new file mode 100644 index 00000000..2fec6e16 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/header/__logo/header__logo.css @@ -0,0 +1,13 @@ +.header__logo { + width: 142px; + height: 33px; + object-fit: contain; +} + +@media screen and (max-width: 480px) { + .header__logo { + width: 104px; + height: 24px; + margin: 0 0 0 7px; + } +} diff --git a/frontend/microfrontend/host/src/styles/header/__logout/header__logout.css b/frontend/microfrontend/host/src/styles/header/__logout/header__logout.css new file mode 100644 index 00000000..77bad6e7 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/header/__logout/header__logout.css @@ -0,0 +1,8 @@ +.header__logout { + font-size: 18px; + line-height: 22px; + color: #A9A9A9; + background-color: transparent; + border: 0; + cursor: pointer; +} \ No newline at end of file diff --git a/frontend/microfrontend/host/src/styles/header/__user/header__user.css b/frontend/microfrontend/host/src/styles/header/__user/header__user.css new file mode 100644 index 00000000..8b0b29d1 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/header/__user/header__user.css @@ -0,0 +1,7 @@ +.header__user { + color: #fff; + font-weight: 500; + font-size: 18px; + line-height: 22px; + margin-right: 24px; +} \ No newline at end of file diff --git a/frontend/microfrontend/host/src/styles/header/__wrapper/header__wrapper.css b/frontend/microfrontend/host/src/styles/header/__wrapper/header__wrapper.css new file mode 100644 index 00000000..3470dc44 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/header/__wrapper/header__wrapper.css @@ -0,0 +1,3 @@ +.header__wrapper { + display: flex; +} \ No newline at end of file diff --git a/frontend/microfrontend/host/src/styles/header/header.css b/frontend/microfrontend/host/src/styles/header/header.css new file mode 100644 index 00000000..80611d86 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/header/header.css @@ -0,0 +1,39 @@ +@import url('./__logo/header__logo.css'); +@import url('./__auth-link/header__auth-link.css'); +@import url('./__wrapper/header__wrapper.css'); +@import url('./__user/header__user.css'); +@import url('./__logout/header__logout.css'); + +.header { + min-height: 120px; + font-family: 'Inter', Arial, sans-serif; + display: flex; + align-items: center; + flex-shrink: 0; + justify-content: space-between; +} + +.header::before { + content: ''; + width: 100%; + height: 1px; + opacity: 0.7; + background: #545454; + position: absolute; + left: 50%; + -webkit-transform: translateX(-50%); + -moz-transform: translateX(-50%); + -ms-transform: translateX(-50%); + -o-transform: translateX(-50%); + transform: translateX(-50%); + bottom: 0; +} + +@media screen and (max-width: 480px) { + .header { + min-height: 85px; + } + .header::before { + width: calc(100% + 40px); + } +} diff --git a/frontend/microfrontend/host/src/styles/page/__content/page__content.css b/frontend/microfrontend/host/src/styles/page/__content/page__content.css new file mode 100644 index 00000000..91bc1443 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/page/__content/page__content.css @@ -0,0 +1,8 @@ +.page__content { + background-color: black; + min-height: 100vh; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + display: flex; + flex-direction: column; +} diff --git a/frontend/microfrontend/host/src/styles/page/__section/page__section.css b/frontend/microfrontend/host/src/styles/page/__section/page__section.css new file mode 100644 index 00000000..460c63d3 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/page/__section/page__section.css @@ -0,0 +1,15 @@ +.page__section { + width: 100%; + max-width: 882px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + position: relative; + margin: 0 auto; +} + +@media screen and (max-width: 1140px) { + .page__section { + width: calc(100% - 40px); + } +} diff --git a/frontend/microfrontend/host/src/styles/page/page.css b/frontend/microfrontend/host/src/styles/page/page.css new file mode 100644 index 00000000..fddc4256 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/page/page.css @@ -0,0 +1,6 @@ +@import url('./__content/page__content.css'); +@import url('./__section/page__section.css'); + +.page { + background: #000; +} diff --git a/frontend/microfrontend/host/src/styles/profile/__add-button/profile__add-button.css b/frontend/microfrontend/host/src/styles/profile/__add-button/profile__add-button.css new file mode 100644 index 00000000..06dee3d4 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/profile/__add-button/profile__add-button.css @@ -0,0 +1,34 @@ +.profile__add-button { + width: 150px; + height: 50px; + background: transparent url("../../../images/add-icon.svg") center no-repeat; + background-size: 22px; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + border: 2px solid #fff; + -webkit-transition: 0.3s; + -moz-transition: 0.3s; + -ms-transition: 0.3s; + -o-transition: 0.3s; + transition: 0.3s; + cursor: pointer; + margin-left: auto; +} + +.profile__add-button:hover { + opacity: 0.6; +} + +@media screen and (max-width: 740px) { + .profile__add-button { + width: 50px; + height: 50px; + } +} + +@media screen and (max-width: 480px) { + .profile__add-button { + width: 100%; + } +} diff --git a/frontend/microfrontend/host/src/styles/profile/__description/profile__description.css b/frontend/microfrontend/host/src/styles/profile/__description/profile__description.css new file mode 100644 index 00000000..67b0d18b --- /dev/null +++ b/frontend/microfrontend/host/src/styles/profile/__description/profile__description.css @@ -0,0 +1,20 @@ +.profile__description { + font-size: 18px; + line-height: 22px; + grid-area: description; + margin: 0; +} + +@media screen and (max-width: 568px) { + .profile__description { + font-size: 14px; + line-height: 17px; + } +} + +@media screen and (max-width: 480px) { + .profile__description { + width: 100%; + margin: 7px 0 0 0; + } +} diff --git a/frontend/microfrontend/host/src/styles/profile/__edit-button/profile__edit-button.css b/frontend/microfrontend/host/src/styles/profile/__edit-button/profile__edit-button.css new file mode 100644 index 00000000..9816cdf1 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/profile/__edit-button/profile__edit-button.css @@ -0,0 +1,29 @@ +.profile__edit-button { + width: 24px; + height: 24px; + background: transparent url('../../../images/edit-icon.svg') center no-repeat; + background-size: 10px 10px; + border: 1px solid #fff; + grid-area: button; + align-self: center; + cursor: pointer; + -webkit-transition: 0.3s; + -moz-transition: 0.3s; + -ms-transition: 0.3s; + -o-transition: 0.3s; + transition: 0.3s; + padding: 0; + margin: 0; +} + +.profile__edit-button:hover { + opacity: 0.6; +} + +@media screen and (max-width: 480px) { + .profile__edit-button { + width: 18px; + height: 18px; + background-size: 8px 8px; + } +} diff --git a/frontend/microfrontend/host/src/styles/profile/__image/profile__image.css b/frontend/microfrontend/host/src/styles/profile/__image/profile__image.css new file mode 100644 index 00000000..a8c43084 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/profile/__image/profile__image.css @@ -0,0 +1,72 @@ +.profile__image { + width: 120px; + height: 120px; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + background-size: cover; + background-position: center; + position: relative; + margin: 0 29px 0 0; +} + +.profile__image:hover { + cursor: pointer; +} + +.profile__image::before, +.profile__image::after { + content: ''; + position: absolute; + -webkit-transition: 0.3s; + -moz-transition: 0.3s; + -ms-transition: 0.3s; + -o-transition: 0.3s; + transition: 0.3s; + pointer-events: none; +} + +.profile__image::before { + background: rgba(0, 0, 0, 0); + top: 0; + right: 0; + left: 0; + bottom: 0; +} + +.profile__image::after { + width: 26px; + height: 26px; + background-image: url('../../../images/edit-icon.svg'); + -webkit-background-size: contain; + background-size: contain; + opacity: 0; + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -moz-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + -o-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.profile__image:hover::before { + background: rgba(0, 0, 0, 0.8); +} + +.profile__image:hover::after { + opacity: 1; +} + + +@media screen and (max-width: 740px) { + .profile__image { + margin: 0 10px 0 0; + } +} + +@media screen and (max-width: 480px) { + .profile__image { + margin-right: 0; + } +} diff --git a/frontend/microfrontend/host/src/styles/profile/__info/profile__info.css b/frontend/microfrontend/host/src/styles/profile/__info/profile__info.css new file mode 100644 index 00000000..7aaefee7 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/profile/__info/profile__info.css @@ -0,0 +1,30 @@ +.profile__info { + display: grid; + grid-template-areas: "title button" + "description description"; + grid-template-columns: minmax(auto, 295px) auto; + grid-gap: 9px 17px; +} + +@media screen and (max-width: 740px) { + .profile__info { + grid-template-columns: minmax(auto, 228px) auto; + grid-gap: 9px 5px; + } +} + +@media screen and (max-width: 568px) { + .profile__info { + grid-template-columns: minmax(auto, 195px) auto; + } +} + +@media screen and (max-width: 480px) { + .profile__info { + width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: center; + margin: 26px 0 33px 0; + } +} diff --git a/frontend/microfrontend/host/src/styles/profile/__title/profile__title.css b/frontend/microfrontend/host/src/styles/profile/__title/profile__title.css new file mode 100644 index 00000000..4c7e2ddf --- /dev/null +++ b/frontend/microfrontend/host/src/styles/profile/__title/profile__title.css @@ -0,0 +1,30 @@ +.profile__title { + font-size: 42px; + line-height: 48px; + font-weight: 400; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + grid-area: title; + margin: 0; +} + +@media screen and (max-width: 740px) { + .profile__title { + font-size: 32px; + line-height: 38px; + } +} + +@media screen and (max-width: 568px) { + .profile__title { + font-size: 27px; + line-height: 33px; + } +} + +@media screen and (max-width: 480px) { + .profile__title { + min-width: 201px; + } +} diff --git a/frontend/microfrontend/host/src/styles/profile/profile.css b/frontend/microfrontend/host/src/styles/profile/profile.css new file mode 100644 index 00000000..01d738e7 --- /dev/null +++ b/frontend/microfrontend/host/src/styles/profile/profile.css @@ -0,0 +1,22 @@ +@import url('./__description/profile__description.css'); +@import url('./__add-button/profile__add-button.css'); +@import url('./__edit-button/profile__edit-button.css'); +@import url('./__info/profile__info.css'); +@import url('./__title/profile__title.css'); +@import url('./__image/profile__image.css'); + +.profile { + font-family: 'Inter', Arial, sans-serif; + color: #fff; + display: flex; + align-items: center; + padding: 36px 0; +} + +@media screen and (max-width: 480px) { + .profile { + padding: 43px 0; + flex-direction: column; + text-align: center; + } +} diff --git a/frontend/src/utils/api.js b/frontend/microfrontend/host/src/utils/api.js similarity index 100% rename from frontend/src/utils/api.js rename to frontend/microfrontend/host/src/utils/api.js diff --git a/frontend/microfrontend/host/webpack.config.js b/frontend/microfrontend/host/webpack.config.js new file mode 100644 index 00000000..67a4f6d6 --- /dev/null +++ b/frontend/microfrontend/host/webpack.config.js @@ -0,0 +1,90 @@ +const HtmlWebPackPlugin = require("html-webpack-plugin"); +const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); +const path = require('path'); +const Dotenv = require('dotenv-webpack'); + +const deps = require("./package.json").dependencies; + +const printCompilationMessage = require('./compilation.config.js'); + +module.exports = (_, argv) => ({ + output: { + publicPath: "http://localhost:8090/", + }, + + resolve: { + extensions: [".tsx", ".ts", ".jsx", ".js", ".json"], + }, + + devServer: { + port: 8090, + historyApiFallback: true, + watchFiles: [path.resolve(__dirname, 'src')], + onListening: function (devServer) { + const port = devServer.server.address().port + + printCompilationMessage('compiling', port) + + devServer.compiler.hooks.done.tap('OutputMessagePlugin', (stats) => { + setImmediate(() => { + if (stats.hasErrors()) { + printCompilationMessage('failure', port) + } else { + printCompilationMessage('success', port) + } + }) + }) + } + }, + + module: { + rules: [ + { + test: /\.m?js/, + type: "javascript/auto", + resolve: { + fullySpecified: false, + }, + }, + { + test: /\.(css|s[ac]ss)$/i, + use: ["style-loader", "css-loader", "postcss-loader"], + }, + { + test: /\.(ts|tsx|js|jsx)$/, + exclude: /node_modules/, + use: { + loader: "babel-loader", + }, + }, + ], + }, + + plugins: [ + new ModuleFederationPlugin({ + name: "host", + filename: "remoteEntry.js", + remotes: { + 'auth': 'users@http://localhost:8091/remoteEntry.js', + 'photo': 'tasks@http://localhost:8093/remoteEntry.js', + 'profile': 'tasks@http://localhost:8092/remoteEntry.js', + }, + exposes: {}, + shared: { + ...deps, + react: { + singleton: true, + requiredVersion: deps.react, + }, + "react-dom": { + singleton: true, + requiredVersion: deps["react-dom"], + }, + }, + }), + new HtmlWebPackPlugin({ + template: "./src/index.html", + }), + new Dotenv() + ], +}); \ No newline at end of file diff --git a/frontend/microfrontend/photo/package.json b/frontend/microfrontend/photo/package.json new file mode 100644 index 00000000..68f56af2 --- /dev/null +++ b/frontend/microfrontend/photo/package.json @@ -0,0 +1,38 @@ +{ + "name": "photo", + "version": "1.0.0", + "scripts": { + "build": "webpack --mode production", + "build:dev": "webpack --mode development", + "build:start": "cd dist && PORT=8093 npx serve", + "start": "webpack serve --mode development", + "start:live": "webpack serve --mode development --live-reload --hot" + }, + "license": "MIT", + "author": { + "name": "Jack Herrington", + "email": "jherr@pobox.com" + }, + "devDependencies": { + "@babel/core": "^7.15.8", + "@babel/plugin-transform-runtime": "^7.15.8", + "@babel/preset-env": "^7.15.8", + "@babel/preset-react": "^7.14.5", + "autoprefixer": "^10.1.0", + "babel-loader": "^8.2.2", + "css-loader": "^6.3.0", + "html-webpack-plugin": "^5.3.2", + "postcss": "^8.2.1", + "postcss-loader": "^4.1.0", + "style-loader": "^3.3.0", + "webpack": "^5.57.1", + "webpack-cli": "^4.10.0", + "webpack-dev-server": "^4.3.1", + "dotenv-webpack": "^8.0.1" + }, + "dependencies": { + "@babel/runtime": "^7.13.10", + "react": "^18.2.0", + "react-dom": "^18.2.0" + } +} \ No newline at end of file diff --git a/frontend/microfrontend/photo/src/App.jsx b/frontend/microfrontend/photo/src/App.jsx new file mode 100644 index 00000000..b485d19e --- /dev/null +++ b/frontend/microfrontend/photo/src/App.jsx @@ -0,0 +1,19 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; + +import "./index.css"; + +const App = () => ( +
+
Name: photo
+
Framework: react
+
Language: JavaScript
+
CSS: Empty CSS
+
+); +const rootElement = document.getElementById("app") +if (!rootElement) throw new Error("Failed to find the root element") + +const root = ReactDOM.createRoot(rootElement) + +root.render() \ No newline at end of file diff --git a/frontend/src/components/AddPlacePopup.js b/frontend/microfrontend/photo/src/components/AddPlacePopup.js similarity index 100% rename from frontend/src/components/AddPlacePopup.js rename to frontend/microfrontend/photo/src/components/AddPlacePopup.js diff --git a/frontend/src/components/Card.js b/frontend/microfrontend/photo/src/components/Card.js similarity index 100% rename from frontend/src/components/Card.js rename to frontend/microfrontend/photo/src/components/Card.js diff --git a/frontend/src/components/ImagePopup.js b/frontend/microfrontend/photo/src/components/ImagePopup.js similarity index 100% rename from frontend/src/components/ImagePopup.js rename to frontend/microfrontend/photo/src/components/ImagePopup.js diff --git a/frontend/microfrontend/photo/src/components/PopupWithForm.js b/frontend/microfrontend/photo/src/components/PopupWithForm.js new file mode 100644 index 00000000..418bd0cf --- /dev/null +++ b/frontend/microfrontend/photo/src/components/PopupWithForm.js @@ -0,0 +1,26 @@ +import React from 'react'; + +function PopupWithForm({ + title, + name, + isOpen, + buttonText = 'Сохранить', + onSubmit, + onClose, + children, +}) { + return ( +
+
+
+ +

{title}

+ {children} + +
+
+
+ ); +} + +export default PopupWithForm; diff --git a/frontend/microfrontend/photo/src/contexts/CurrentUserContext.js b/frontend/microfrontend/photo/src/contexts/CurrentUserContext.js new file mode 100644 index 00000000..38344d08 --- /dev/null +++ b/frontend/microfrontend/photo/src/contexts/CurrentUserContext.js @@ -0,0 +1,4 @@ +import React from 'react'; + +// Объект контекста CurrentUserContext экспортируется из отдельного файла директории contexts +export const CurrentUserContext = React.createContext(); diff --git a/frontend/microfrontend/photo/src/index.css b/frontend/microfrontend/photo/src/index.css new file mode 100644 index 00000000..20e225c5 --- /dev/null +++ b/frontend/microfrontend/photo/src/index.css @@ -0,0 +1,10 @@ +body { + font-family: Arial, Helvetica, sans-serif; +} + +.container { + font-size: 3rem; + margin: auto; + max-width: 800px; + margin-top: 20px; +} \ No newline at end of file diff --git a/frontend/microfrontend/photo/src/index.html b/frontend/microfrontend/photo/src/index.html new file mode 100644 index 00000000..31703d7d --- /dev/null +++ b/frontend/microfrontend/photo/src/index.html @@ -0,0 +1,14 @@ + + + + + + + photo + + + +
+ + + \ No newline at end of file diff --git a/frontend/microfrontend/photo/src/index.js b/frontend/microfrontend/photo/src/index.js new file mode 100644 index 00000000..ed6e00cd --- /dev/null +++ b/frontend/microfrontend/photo/src/index.js @@ -0,0 +1 @@ +import("./App"); \ No newline at end of file diff --git a/frontend/microfrontend/photo/src/styles/popup/__button/_disabled/popup__button_disabled.css b/frontend/microfrontend/photo/src/styles/popup/__button/_disabled/popup__button_disabled.css new file mode 100644 index 00000000..1ad56853 --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__button/_disabled/popup__button_disabled.css @@ -0,0 +1,4 @@ +.popup__button_disabled { + opacity: 0.2; + pointer-events: none; +} diff --git a/frontend/microfrontend/photo/src/styles/popup/__button/popup__button.css b/frontend/microfrontend/photo/src/styles/popup/__button/popup__button.css new file mode 100644 index 00000000..7552a022 --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__button/popup__button.css @@ -0,0 +1,26 @@ +.popup__button { + width: 100%; + height: 50px; + font-size: 18px; + line-height: 22px; + color: white; + display: flex; + align-items: center; + justify-content: center; + background: #000; + border-radius: 2px; + border: none; + transition: visibility 0s, background 0.3s; + margin-top: 48px; +} + +.popup__button:hover { + background: rgba(0, 0, 0, 0.8); +} + +@media screen and (max-width: 568px) { + .popup__button { + font-size: 14px; + line-height: 17px; + } +} diff --git a/frontend/microfrontend/photo/src/styles/popup/__caption/popup__caption.css b/frontend/microfrontend/photo/src/styles/popup/__caption/popup__caption.css new file mode 100644 index 00000000..35ef2b88 --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__caption/popup__caption.css @@ -0,0 +1,9 @@ +.popup__caption { + font-size: 12px; + line-height: 15px; + color: #fff; + position: absolute; + left: 0; + top: calc(100% + 10px); + margin: 0; +} diff --git a/frontend/microfrontend/photo/src/styles/popup/__close/popup__close.css b/frontend/microfrontend/photo/src/styles/popup/__close/popup__close.css new file mode 100644 index 00000000..db3a2db6 --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__close/popup__close.css @@ -0,0 +1,23 @@ +.popup__close { + width: 35px; + height: 35px; + background: transparent url('../../../images/close.svg') center no-repeat; + background-size: 35px 35px; + border: none; + position: absolute; + top: -36px; + right: -34px; + -webkit-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -ms-transform: rotate(90deg); + -o-transform: rotate(90deg); + transform: rotate(90deg); + transition: visibility 0s, opacity 0.3s; + padding: 0; + margin: 0; + cursor: pointer; +} + +.popup__close:hover { + opacity: 0.6; +} diff --git a/frontend/microfrontend/photo/src/styles/popup/__content/_content/popup__content_content_image.css b/frontend/microfrontend/photo/src/styles/popup/__content/_content/popup__content_content_image.css new file mode 100644 index 00000000..ad7ff951 --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__content/_content/popup__content_content_image.css @@ -0,0 +1,14 @@ +.popup__content_content_image { + max-width: 75vw; + max-height: 75vh; + height: auto; + width: auto; + display: flex; + background: transparent; + -webkit-background-size: cover; + background-size: cover; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + padding: 0; +} diff --git a/frontend/microfrontend/photo/src/styles/popup/__content/popup__content.css b/frontend/microfrontend/photo/src/styles/popup/__content/popup__content.css new file mode 100644 index 00000000..668c80eb --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__content/popup__content.css @@ -0,0 +1,19 @@ +.popup__content { + max-width: 430px; + width: 100%; + min-height: 330px; + background-color: #fff; + border-radius: 10px; + position: relative; + box-sizing: border-box; + padding: 34px 36px; +} + +@media screen and (max-width: 568px) { + .popup__content { + width: 100%; + max-width: calc(100% - 80px); + margin-top: 40px; + padding: 30px 20px; + } +} diff --git a/frontend/microfrontend/photo/src/styles/popup/__error/_visible/popup__error_visible.css b/frontend/microfrontend/photo/src/styles/popup/__error/_visible/popup__error_visible.css new file mode 100644 index 00000000..4293d5cc --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__error/_visible/popup__error_visible.css @@ -0,0 +1,3 @@ +.popup__error_visible { + opacity: 1; +} diff --git a/frontend/microfrontend/photo/src/styles/popup/__error/popup__error.css b/frontend/microfrontend/photo/src/styles/popup/__error/popup__error.css new file mode 100644 index 00000000..017e1dd9 --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__error/popup__error.css @@ -0,0 +1,10 @@ +.popup__error { + font-size: 12px; + line-height: 15px; + color: #FF0000; + opacity: 0; + position: absolute; + top: calc(100% + 5px); + left: 0; + transition: opacity 0.3s; +} diff --git a/frontend/microfrontend/photo/src/styles/popup/__form/popup__form.css b/frontend/microfrontend/photo/src/styles/popup/__form/popup__form.css new file mode 100644 index 00000000..425f78ca --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__form/popup__form.css @@ -0,0 +1,3 @@ +.popup__form { + margin-top: 27px; +} diff --git a/frontend/microfrontend/photo/src/styles/popup/__icon/popup__icon.css b/frontend/microfrontend/photo/src/styles/popup/__icon/popup__icon.css new file mode 100644 index 00000000..3ea53b9c --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__icon/popup__icon.css @@ -0,0 +1,6 @@ +.popup__icon { + display: block; + margin: auto; + width: 120px; + height: 120px; +} \ No newline at end of file diff --git a/frontend/microfrontend/photo/src/styles/popup/__image/popup__image.css b/frontend/microfrontend/photo/src/styles/popup/__image/popup__image.css new file mode 100644 index 00000000..20effa1c --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__image/popup__image.css @@ -0,0 +1,6 @@ +.popup__image { + max-height: 100%; + max-width: 100%; + object-fit: cover; + display: block; +} diff --git a/frontend/microfrontend/photo/src/styles/popup/__input/_type/popup__input_type_error.css b/frontend/microfrontend/photo/src/styles/popup/__input/_type/popup__input_type_error.css new file mode 100644 index 00000000..79876daf --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__input/_type/popup__input_type_error.css @@ -0,0 +1,3 @@ +.popup__input_type_error { + border-bottom: 1px solid #FF0000; +} diff --git a/frontend/microfrontend/photo/src/styles/popup/__input/popup__input.css b/frontend/microfrontend/photo/src/styles/popup/__input/popup__input.css new file mode 100644 index 00000000..8dc0a28f --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__input/popup__input.css @@ -0,0 +1,26 @@ +.popup__input { + width: 100%; + border: 0; + border-bottom: 1px solid rgba(0, 0, 0, .2); + font-size: 14px; + line-height: 18px; + box-sizing: border-box; + margin-bottom: 10px; + padding: 0 0 13px; + -webkit-transition: 0.3s; + -moz-transition: 0.3s; + -ms-transition: 0.3s; + -o-transition: 0.3s; + transition: border-bottom 0.3s; +} + +.popup__input:last-of-type { + margin-bottom: 0; +} + +@media screen and (max-width: 568px) { + .popup__title { + font-size: 12px; + line-height: 15px; + } +} diff --git a/frontend/microfrontend/photo/src/styles/popup/__label/popup__label.css b/frontend/microfrontend/photo/src/styles/popup/__label/popup__label.css new file mode 100644 index 00000000..a9122bc5 --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__label/popup__label.css @@ -0,0 +1,5 @@ +.popup__label { + position: relative; + display: block; + padding: 30px 0 0; +} diff --git a/frontend/microfrontend/photo/src/styles/popup/__status-message/popup__status-message.css b/frontend/microfrontend/photo/src/styles/popup/__status-message/popup__status-message.css new file mode 100644 index 00000000..577b880a --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__status-message/popup__status-message.css @@ -0,0 +1,8 @@ +.popup__status-message { + font-family: Inter, sans-serif; + font-weight: 900; + font-size: 24px; + line-height: 29px; + text-align: center; + margin-top: 32px; +} \ No newline at end of file diff --git a/frontend/microfrontend/photo/src/styles/popup/__title/popup__title.css b/frontend/microfrontend/photo/src/styles/popup/__title/popup__title.css new file mode 100644 index 00000000..1092b827 --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/__title/popup__title.css @@ -0,0 +1,12 @@ +.popup__title { + margin: 0; + font-size: 24px; + line-height: 30px; +} + +@media screen and (max-width: 568px) { + .popup__title { + font-size: 18px; + line-height: 22px; + } +} diff --git a/frontend/microfrontend/photo/src/styles/popup/_is-opened/popup_is-opened.css b/frontend/microfrontend/photo/src/styles/popup/_is-opened/popup_is-opened.css new file mode 100644 index 00000000..207e395e --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/_is-opened/popup_is-opened.css @@ -0,0 +1,6 @@ +.popup_is-opened { + visibility: visible; + opacity: 1; + pointer-events: all; + transition: visibility 0s, opacity 0.6s; +} diff --git a/frontend/microfrontend/photo/src/styles/popup/_type/popup_type_edit-avatar.css b/frontend/microfrontend/photo/src/styles/popup/_type/popup_type_edit-avatar.css new file mode 100644 index 00000000..b357b631 --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/_type/popup_type_edit-avatar.css @@ -0,0 +1,3 @@ +.popup_type_edit-avatar .popup__content { + min-height: auto; +} diff --git a/frontend/microfrontend/photo/src/styles/popup/_type/popup_type_remove-card.css b/frontend/microfrontend/photo/src/styles/popup/_type/popup_type_remove-card.css new file mode 100644 index 00000000..ac639298 --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/_type/popup_type_remove-card.css @@ -0,0 +1,3 @@ +.popup_type_remove-card .popup__content { + min-height: auto; +} diff --git a/frontend/microfrontend/photo/src/styles/popup/popup.css b/frontend/microfrontend/photo/src/styles/popup/popup.css new file mode 100644 index 00000000..c5f3b2cb --- /dev/null +++ b/frontend/microfrontend/photo/src/styles/popup/popup.css @@ -0,0 +1,37 @@ +@import url('./__content/popup__content.css'); +@import url('./__content/_content/popup__content_content_image.css'); +@import url('./__close/popup__close.css'); +@import url('./__title/popup__title.css'); +@import url('./__form/popup__form.css'); +@import url('./__input/popup__input.css'); +@import url('./__input/_type/popup__input_type_error.css'); +@import url('./__button/popup__button.css'); +@import url('./__button/_disabled/popup__button_disabled.css'); +@import url('./__caption/popup__caption.css'); +@import url('./__image/popup__image.css'); +@import url('./__label/popup__label.css'); +@import url('./__error/popup__error.css'); +@import url('./__error/_visible/popup__error_visible.css'); +@import url('./_type/popup_type_remove-card.css'); +@import url('./_type/popup_type_edit-avatar.css'); +@import url('./__icon/popup__icon.css'); +@import url('./__status-message/popup__status-message.css'); + +.popup { + font-family: 'Inter', Arial, sans-serif; + display: flex; + align-items: center; + justify-content: center; + background-color: rgba(0, 0, 0, .5); + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + visibility: hidden; + opacity: 0; + pointer-events: none; + user-select: none; + transition: visibility 0s 0.6s, opacity 0.6s; + z-index: 10; +} diff --git a/frontend/microfrontend/photo/webpack.config.js b/frontend/microfrontend/photo/webpack.config.js new file mode 100644 index 00000000..6447cc7b --- /dev/null +++ b/frontend/microfrontend/photo/webpack.config.js @@ -0,0 +1,90 @@ +const HtmlWebPackPlugin = require("html-webpack-plugin"); +const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); +const path = require('path'); +const Dotenv = require('dotenv-webpack'); + +const deps = require("./package.json").dependencies; + +const printCompilationMessage = require('./compilation.config.js'); + +module.exports = (_, argv) => ({ + output: { + publicPath: "http://localhost:8093/", + }, + + resolve: { + extensions: [".tsx", ".ts", ".jsx", ".js", ".json"], + }, + + devServer: { + port: 8093, + historyApiFallback: true, + watchFiles: [path.resolve(__dirname, 'src')], + onListening: function (devServer) { + const port = devServer.server.address().port + + printCompilationMessage('compiling', port) + + devServer.compiler.hooks.done.tap('OutputMessagePlugin', (stats) => { + setImmediate(() => { + if (stats.hasErrors()) { + printCompilationMessage('failure', port) + } else { + printCompilationMessage('success', port) + } + }) + }) + } + }, + + module: { + rules: [ + { + test: /\.m?js/, + type: "javascript/auto", + resolve: { + fullySpecified: false, + }, + }, + { + test: /\.(css|s[ac]ss)$/i, + use: ["style-loader", "css-loader", "postcss-loader"], + }, + { + test: /\.(ts|tsx|js|jsx)$/, + exclude: /node_modules/, + use: { + loader: "babel-loader", + }, + }, + ], + }, + + plugins: [ + new ModuleFederationPlugin({ + name: "photo", + filename: "remoteEntry.js", + remotes: {}, + exposes: { + './AddPlacePopup': './src/components/AddPlacePopup.js', + './Card': './src/components/Card.js', + './ImagePopup': './src/components/ImagePopup.js' + }, + shared: { + ...deps, + react: { + singleton: true, + requiredVersion: deps.react, + }, + "react-dom": { + singleton: true, + requiredVersion: deps["react-dom"], + }, + }, + }), + new HtmlWebPackPlugin({ + template: "./src/index.html", + }), + new Dotenv() + ], +}); \ No newline at end of file diff --git a/frontend/microfrontend/profile/package.json b/frontend/microfrontend/profile/package.json new file mode 100644 index 00000000..c2be3d04 --- /dev/null +++ b/frontend/microfrontend/profile/package.json @@ -0,0 +1,38 @@ +{ + "name": "profile", + "version": "1.0.0", + "scripts": { + "build": "webpack --mode production", + "build:dev": "webpack --mode development", + "build:start": "cd dist && PORT=8092 npx serve", + "start": "webpack serve --mode development", + "start:live": "webpack serve --mode development --live-reload --hot" + }, + "license": "MIT", + "author": { + "name": "Jack Herrington", + "email": "jherr@pobox.com" + }, + "devDependencies": { + "@babel/core": "^7.15.8", + "@babel/plugin-transform-runtime": "^7.15.8", + "@babel/preset-env": "^7.15.8", + "@babel/preset-react": "^7.14.5", + "autoprefixer": "^10.1.0", + "babel-loader": "^8.2.2", + "css-loader": "^6.3.0", + "html-webpack-plugin": "^5.3.2", + "postcss": "^8.2.1", + "postcss-loader": "^4.1.0", + "style-loader": "^3.3.0", + "webpack": "^5.57.1", + "webpack-cli": "^4.10.0", + "webpack-dev-server": "^4.3.1", + "dotenv-webpack": "^8.0.1" + }, + "dependencies": { + "@babel/runtime": "^7.13.10", + "react": "^18.2.0", + "react-dom": "^18.2.0" + } +} \ No newline at end of file diff --git a/frontend/src/components/EditAvatarPopup.js b/frontend/microfrontend/profile/src/components/EditAvatarPopup.js similarity index 100% rename from frontend/src/components/EditAvatarPopup.js rename to frontend/microfrontend/profile/src/components/EditAvatarPopup.js diff --git a/frontend/src/components/EditProfilePopup.js b/frontend/microfrontend/profile/src/components/EditProfilePopup.js similarity index 100% rename from frontend/src/components/EditProfilePopup.js rename to frontend/microfrontend/profile/src/components/EditProfilePopup.js diff --git a/frontend/microfrontend/profile/src/components/PopupWithForm.js b/frontend/microfrontend/profile/src/components/PopupWithForm.js new file mode 100644 index 00000000..418bd0cf --- /dev/null +++ b/frontend/microfrontend/profile/src/components/PopupWithForm.js @@ -0,0 +1,26 @@ +import React from 'react'; + +function PopupWithForm({ + title, + name, + isOpen, + buttonText = 'Сохранить', + onSubmit, + onClose, + children, +}) { + return ( +
+
+
+ +

{title}

+ {children} + +
+
+
+ ); +} + +export default PopupWithForm; diff --git a/frontend/microfrontend/profile/src/contexts/CurrentUserContext.js b/frontend/microfrontend/profile/src/contexts/CurrentUserContext.js new file mode 100644 index 00000000..38344d08 --- /dev/null +++ b/frontend/microfrontend/profile/src/contexts/CurrentUserContext.js @@ -0,0 +1,4 @@ +import React from 'react'; + +// Объект контекста CurrentUserContext экспортируется из отдельного файла директории contexts +export const CurrentUserContext = React.createContext(); diff --git a/frontend/microfrontend/profile/src/styles/App.jsx b/frontend/microfrontend/profile/src/styles/App.jsx new file mode 100644 index 00000000..ab1ca813 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/App.jsx @@ -0,0 +1,19 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; + +import "./index.css"; + +const App = () => ( +
+
Name: profile
+
Framework: react
+
Language: JavaScript
+
CSS: Empty CSS
+
+); +const rootElement = document.getElementById("app") +if (!rootElement) throw new Error("Failed to find the root element") + +const root = ReactDOM.createRoot(rootElement) + +root.render() \ No newline at end of file diff --git a/frontend/src/blocks/card/__delete-button/_hidden/card__delete-button_hidden.css b/frontend/microfrontend/profile/src/styles/card/__delete-button/_hidden/card__delete-button_hidden.css similarity index 100% rename from frontend/src/blocks/card/__delete-button/_hidden/card__delete-button_hidden.css rename to frontend/microfrontend/profile/src/styles/card/__delete-button/_hidden/card__delete-button_hidden.css diff --git a/frontend/src/blocks/card/__delete-button/_visible/card__delete-button_visible.css b/frontend/microfrontend/profile/src/styles/card/__delete-button/_visible/card__delete-button_visible.css similarity index 100% rename from frontend/src/blocks/card/__delete-button/_visible/card__delete-button_visible.css rename to frontend/microfrontend/profile/src/styles/card/__delete-button/_visible/card__delete-button_visible.css diff --git a/frontend/src/blocks/card/__delete-button/card__delete-button.css b/frontend/microfrontend/profile/src/styles/card/__delete-button/card__delete-button.css similarity index 100% rename from frontend/src/blocks/card/__delete-button/card__delete-button.css rename to frontend/microfrontend/profile/src/styles/card/__delete-button/card__delete-button.css diff --git a/frontend/src/blocks/card/__description/card__description.css b/frontend/microfrontend/profile/src/styles/card/__description/card__description.css similarity index 100% rename from frontend/src/blocks/card/__description/card__description.css rename to frontend/microfrontend/profile/src/styles/card/__description/card__description.css diff --git a/frontend/src/blocks/card/__image/card__image.css b/frontend/microfrontend/profile/src/styles/card/__image/card__image.css similarity index 100% rename from frontend/src/blocks/card/__image/card__image.css rename to frontend/microfrontend/profile/src/styles/card/__image/card__image.css diff --git a/frontend/src/blocks/card/__like-button/_is-active/card__like-button_is-active.css b/frontend/microfrontend/profile/src/styles/card/__like-button/_is-active/card__like-button_is-active.css similarity index 100% rename from frontend/src/blocks/card/__like-button/_is-active/card__like-button_is-active.css rename to frontend/microfrontend/profile/src/styles/card/__like-button/_is-active/card__like-button_is-active.css diff --git a/frontend/src/blocks/card/__like-button/card__like-button.css b/frontend/microfrontend/profile/src/styles/card/__like-button/card__like-button.css similarity index 100% rename from frontend/src/blocks/card/__like-button/card__like-button.css rename to frontend/microfrontend/profile/src/styles/card/__like-button/card__like-button.css diff --git a/frontend/src/blocks/card/__like-count/card__like-count.css b/frontend/microfrontend/profile/src/styles/card/__like-count/card__like-count.css similarity index 100% rename from frontend/src/blocks/card/__like-count/card__like-count.css rename to frontend/microfrontend/profile/src/styles/card/__like-count/card__like-count.css diff --git a/frontend/src/blocks/card/__title/card__title.css b/frontend/microfrontend/profile/src/styles/card/__title/card__title.css similarity index 100% rename from frontend/src/blocks/card/__title/card__title.css rename to frontend/microfrontend/profile/src/styles/card/__title/card__title.css diff --git a/frontend/src/blocks/card/card.css b/frontend/microfrontend/profile/src/styles/card/card.css similarity index 100% rename from frontend/src/blocks/card/card.css rename to frontend/microfrontend/profile/src/styles/card/card.css diff --git a/frontend/microfrontend/profile/src/styles/index.css b/frontend/microfrontend/profile/src/styles/index.css new file mode 100644 index 00000000..20e225c5 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/index.css @@ -0,0 +1,10 @@ +body { + font-family: Arial, Helvetica, sans-serif; +} + +.container { + font-size: 3rem; + margin: auto; + max-width: 800px; + margin-top: 20px; +} \ No newline at end of file diff --git a/frontend/microfrontend/profile/src/styles/index.html b/frontend/microfrontend/profile/src/styles/index.html new file mode 100644 index 00000000..57c9ac30 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/index.html @@ -0,0 +1,14 @@ + + + + + + + profile + + + +
+ + + \ No newline at end of file diff --git a/frontend/microfrontend/profile/src/styles/index.js b/frontend/microfrontend/profile/src/styles/index.js new file mode 100644 index 00000000..ed6e00cd --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/index.js @@ -0,0 +1 @@ +import("./App"); \ No newline at end of file diff --git a/frontend/microfrontend/profile/src/styles/popup/__button/_disabled/popup__button_disabled.css b/frontend/microfrontend/profile/src/styles/popup/__button/_disabled/popup__button_disabled.css new file mode 100644 index 00000000..1ad56853 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__button/_disabled/popup__button_disabled.css @@ -0,0 +1,4 @@ +.popup__button_disabled { + opacity: 0.2; + pointer-events: none; +} diff --git a/frontend/microfrontend/profile/src/styles/popup/__button/popup__button.css b/frontend/microfrontend/profile/src/styles/popup/__button/popup__button.css new file mode 100644 index 00000000..7552a022 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__button/popup__button.css @@ -0,0 +1,26 @@ +.popup__button { + width: 100%; + height: 50px; + font-size: 18px; + line-height: 22px; + color: white; + display: flex; + align-items: center; + justify-content: center; + background: #000; + border-radius: 2px; + border: none; + transition: visibility 0s, background 0.3s; + margin-top: 48px; +} + +.popup__button:hover { + background: rgba(0, 0, 0, 0.8); +} + +@media screen and (max-width: 568px) { + .popup__button { + font-size: 14px; + line-height: 17px; + } +} diff --git a/frontend/microfrontend/profile/src/styles/popup/__caption/popup__caption.css b/frontend/microfrontend/profile/src/styles/popup/__caption/popup__caption.css new file mode 100644 index 00000000..35ef2b88 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__caption/popup__caption.css @@ -0,0 +1,9 @@ +.popup__caption { + font-size: 12px; + line-height: 15px; + color: #fff; + position: absolute; + left: 0; + top: calc(100% + 10px); + margin: 0; +} diff --git a/frontend/microfrontend/profile/src/styles/popup/__close/popup__close.css b/frontend/microfrontend/profile/src/styles/popup/__close/popup__close.css new file mode 100644 index 00000000..db3a2db6 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__close/popup__close.css @@ -0,0 +1,23 @@ +.popup__close { + width: 35px; + height: 35px; + background: transparent url('../../../images/close.svg') center no-repeat; + background-size: 35px 35px; + border: none; + position: absolute; + top: -36px; + right: -34px; + -webkit-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -ms-transform: rotate(90deg); + -o-transform: rotate(90deg); + transform: rotate(90deg); + transition: visibility 0s, opacity 0.3s; + padding: 0; + margin: 0; + cursor: pointer; +} + +.popup__close:hover { + opacity: 0.6; +} diff --git a/frontend/microfrontend/profile/src/styles/popup/__content/_content/popup__content_content_image.css b/frontend/microfrontend/profile/src/styles/popup/__content/_content/popup__content_content_image.css new file mode 100644 index 00000000..ad7ff951 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__content/_content/popup__content_content_image.css @@ -0,0 +1,14 @@ +.popup__content_content_image { + max-width: 75vw; + max-height: 75vh; + height: auto; + width: auto; + display: flex; + background: transparent; + -webkit-background-size: cover; + background-size: cover; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + padding: 0; +} diff --git a/frontend/microfrontend/profile/src/styles/popup/__content/popup__content.css b/frontend/microfrontend/profile/src/styles/popup/__content/popup__content.css new file mode 100644 index 00000000..668c80eb --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__content/popup__content.css @@ -0,0 +1,19 @@ +.popup__content { + max-width: 430px; + width: 100%; + min-height: 330px; + background-color: #fff; + border-radius: 10px; + position: relative; + box-sizing: border-box; + padding: 34px 36px; +} + +@media screen and (max-width: 568px) { + .popup__content { + width: 100%; + max-width: calc(100% - 80px); + margin-top: 40px; + padding: 30px 20px; + } +} diff --git a/frontend/microfrontend/profile/src/styles/popup/__error/_visible/popup__error_visible.css b/frontend/microfrontend/profile/src/styles/popup/__error/_visible/popup__error_visible.css new file mode 100644 index 00000000..4293d5cc --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__error/_visible/popup__error_visible.css @@ -0,0 +1,3 @@ +.popup__error_visible { + opacity: 1; +} diff --git a/frontend/microfrontend/profile/src/styles/popup/__error/popup__error.css b/frontend/microfrontend/profile/src/styles/popup/__error/popup__error.css new file mode 100644 index 00000000..017e1dd9 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__error/popup__error.css @@ -0,0 +1,10 @@ +.popup__error { + font-size: 12px; + line-height: 15px; + color: #FF0000; + opacity: 0; + position: absolute; + top: calc(100% + 5px); + left: 0; + transition: opacity 0.3s; +} diff --git a/frontend/microfrontend/profile/src/styles/popup/__form/popup__form.css b/frontend/microfrontend/profile/src/styles/popup/__form/popup__form.css new file mode 100644 index 00000000..425f78ca --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__form/popup__form.css @@ -0,0 +1,3 @@ +.popup__form { + margin-top: 27px; +} diff --git a/frontend/microfrontend/profile/src/styles/popup/__icon/popup__icon.css b/frontend/microfrontend/profile/src/styles/popup/__icon/popup__icon.css new file mode 100644 index 00000000..3ea53b9c --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__icon/popup__icon.css @@ -0,0 +1,6 @@ +.popup__icon { + display: block; + margin: auto; + width: 120px; + height: 120px; +} \ No newline at end of file diff --git a/frontend/microfrontend/profile/src/styles/popup/__image/popup__image.css b/frontend/microfrontend/profile/src/styles/popup/__image/popup__image.css new file mode 100644 index 00000000..20effa1c --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__image/popup__image.css @@ -0,0 +1,6 @@ +.popup__image { + max-height: 100%; + max-width: 100%; + object-fit: cover; + display: block; +} diff --git a/frontend/microfrontend/profile/src/styles/popup/__input/_type/popup__input_type_error.css b/frontend/microfrontend/profile/src/styles/popup/__input/_type/popup__input_type_error.css new file mode 100644 index 00000000..79876daf --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__input/_type/popup__input_type_error.css @@ -0,0 +1,3 @@ +.popup__input_type_error { + border-bottom: 1px solid #FF0000; +} diff --git a/frontend/microfrontend/profile/src/styles/popup/__input/popup__input.css b/frontend/microfrontend/profile/src/styles/popup/__input/popup__input.css new file mode 100644 index 00000000..8dc0a28f --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__input/popup__input.css @@ -0,0 +1,26 @@ +.popup__input { + width: 100%; + border: 0; + border-bottom: 1px solid rgba(0, 0, 0, .2); + font-size: 14px; + line-height: 18px; + box-sizing: border-box; + margin-bottom: 10px; + padding: 0 0 13px; + -webkit-transition: 0.3s; + -moz-transition: 0.3s; + -ms-transition: 0.3s; + -o-transition: 0.3s; + transition: border-bottom 0.3s; +} + +.popup__input:last-of-type { + margin-bottom: 0; +} + +@media screen and (max-width: 568px) { + .popup__title { + font-size: 12px; + line-height: 15px; + } +} diff --git a/frontend/microfrontend/profile/src/styles/popup/__label/popup__label.css b/frontend/microfrontend/profile/src/styles/popup/__label/popup__label.css new file mode 100644 index 00000000..a9122bc5 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__label/popup__label.css @@ -0,0 +1,5 @@ +.popup__label { + position: relative; + display: block; + padding: 30px 0 0; +} diff --git a/frontend/microfrontend/profile/src/styles/popup/__status-message/popup__status-message.css b/frontend/microfrontend/profile/src/styles/popup/__status-message/popup__status-message.css new file mode 100644 index 00000000..577b880a --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__status-message/popup__status-message.css @@ -0,0 +1,8 @@ +.popup__status-message { + font-family: Inter, sans-serif; + font-weight: 900; + font-size: 24px; + line-height: 29px; + text-align: center; + margin-top: 32px; +} \ No newline at end of file diff --git a/frontend/microfrontend/profile/src/styles/popup/__title/popup__title.css b/frontend/microfrontend/profile/src/styles/popup/__title/popup__title.css new file mode 100644 index 00000000..1092b827 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/__title/popup__title.css @@ -0,0 +1,12 @@ +.popup__title { + margin: 0; + font-size: 24px; + line-height: 30px; +} + +@media screen and (max-width: 568px) { + .popup__title { + font-size: 18px; + line-height: 22px; + } +} diff --git a/frontend/microfrontend/profile/src/styles/popup/_is-opened/popup_is-opened.css b/frontend/microfrontend/profile/src/styles/popup/_is-opened/popup_is-opened.css new file mode 100644 index 00000000..207e395e --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/_is-opened/popup_is-opened.css @@ -0,0 +1,6 @@ +.popup_is-opened { + visibility: visible; + opacity: 1; + pointer-events: all; + transition: visibility 0s, opacity 0.6s; +} diff --git a/frontend/microfrontend/profile/src/styles/popup/_type/popup_type_edit-avatar.css b/frontend/microfrontend/profile/src/styles/popup/_type/popup_type_edit-avatar.css new file mode 100644 index 00000000..b357b631 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/_type/popup_type_edit-avatar.css @@ -0,0 +1,3 @@ +.popup_type_edit-avatar .popup__content { + min-height: auto; +} diff --git a/frontend/microfrontend/profile/src/styles/popup/_type/popup_type_remove-card.css b/frontend/microfrontend/profile/src/styles/popup/_type/popup_type_remove-card.css new file mode 100644 index 00000000..ac639298 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/_type/popup_type_remove-card.css @@ -0,0 +1,3 @@ +.popup_type_remove-card .popup__content { + min-height: auto; +} diff --git a/frontend/microfrontend/profile/src/styles/popup/popup.css b/frontend/microfrontend/profile/src/styles/popup/popup.css new file mode 100644 index 00000000..c5f3b2cb --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/popup/popup.css @@ -0,0 +1,37 @@ +@import url('./__content/popup__content.css'); +@import url('./__content/_content/popup__content_content_image.css'); +@import url('./__close/popup__close.css'); +@import url('./__title/popup__title.css'); +@import url('./__form/popup__form.css'); +@import url('./__input/popup__input.css'); +@import url('./__input/_type/popup__input_type_error.css'); +@import url('./__button/popup__button.css'); +@import url('./__button/_disabled/popup__button_disabled.css'); +@import url('./__caption/popup__caption.css'); +@import url('./__image/popup__image.css'); +@import url('./__label/popup__label.css'); +@import url('./__error/popup__error.css'); +@import url('./__error/_visible/popup__error_visible.css'); +@import url('./_type/popup_type_remove-card.css'); +@import url('./_type/popup_type_edit-avatar.css'); +@import url('./__icon/popup__icon.css'); +@import url('./__status-message/popup__status-message.css'); + +.popup { + font-family: 'Inter', Arial, sans-serif; + display: flex; + align-items: center; + justify-content: center; + background-color: rgba(0, 0, 0, .5); + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + visibility: hidden; + opacity: 0; + pointer-events: none; + user-select: none; + transition: visibility 0s 0.6s, opacity 0.6s; + z-index: 10; +} diff --git a/frontend/microfrontend/profile/src/styles/profile/__add-button/profile__add-button.css b/frontend/microfrontend/profile/src/styles/profile/__add-button/profile__add-button.css new file mode 100644 index 00000000..06dee3d4 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/profile/__add-button/profile__add-button.css @@ -0,0 +1,34 @@ +.profile__add-button { + width: 150px; + height: 50px; + background: transparent url("../../../images/add-icon.svg") center no-repeat; + background-size: 22px; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + border: 2px solid #fff; + -webkit-transition: 0.3s; + -moz-transition: 0.3s; + -ms-transition: 0.3s; + -o-transition: 0.3s; + transition: 0.3s; + cursor: pointer; + margin-left: auto; +} + +.profile__add-button:hover { + opacity: 0.6; +} + +@media screen and (max-width: 740px) { + .profile__add-button { + width: 50px; + height: 50px; + } +} + +@media screen and (max-width: 480px) { + .profile__add-button { + width: 100%; + } +} diff --git a/frontend/microfrontend/profile/src/styles/profile/__description/profile__description.css b/frontend/microfrontend/profile/src/styles/profile/__description/profile__description.css new file mode 100644 index 00000000..67b0d18b --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/profile/__description/profile__description.css @@ -0,0 +1,20 @@ +.profile__description { + font-size: 18px; + line-height: 22px; + grid-area: description; + margin: 0; +} + +@media screen and (max-width: 568px) { + .profile__description { + font-size: 14px; + line-height: 17px; + } +} + +@media screen and (max-width: 480px) { + .profile__description { + width: 100%; + margin: 7px 0 0 0; + } +} diff --git a/frontend/microfrontend/profile/src/styles/profile/__edit-button/profile__edit-button.css b/frontend/microfrontend/profile/src/styles/profile/__edit-button/profile__edit-button.css new file mode 100644 index 00000000..9816cdf1 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/profile/__edit-button/profile__edit-button.css @@ -0,0 +1,29 @@ +.profile__edit-button { + width: 24px; + height: 24px; + background: transparent url('../../../images/edit-icon.svg') center no-repeat; + background-size: 10px 10px; + border: 1px solid #fff; + grid-area: button; + align-self: center; + cursor: pointer; + -webkit-transition: 0.3s; + -moz-transition: 0.3s; + -ms-transition: 0.3s; + -o-transition: 0.3s; + transition: 0.3s; + padding: 0; + margin: 0; +} + +.profile__edit-button:hover { + opacity: 0.6; +} + +@media screen and (max-width: 480px) { + .profile__edit-button { + width: 18px; + height: 18px; + background-size: 8px 8px; + } +} diff --git a/frontend/microfrontend/profile/src/styles/profile/__image/profile__image.css b/frontend/microfrontend/profile/src/styles/profile/__image/profile__image.css new file mode 100644 index 00000000..a8c43084 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/profile/__image/profile__image.css @@ -0,0 +1,72 @@ +.profile__image { + width: 120px; + height: 120px; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + background-size: cover; + background-position: center; + position: relative; + margin: 0 29px 0 0; +} + +.profile__image:hover { + cursor: pointer; +} + +.profile__image::before, +.profile__image::after { + content: ''; + position: absolute; + -webkit-transition: 0.3s; + -moz-transition: 0.3s; + -ms-transition: 0.3s; + -o-transition: 0.3s; + transition: 0.3s; + pointer-events: none; +} + +.profile__image::before { + background: rgba(0, 0, 0, 0); + top: 0; + right: 0; + left: 0; + bottom: 0; +} + +.profile__image::after { + width: 26px; + height: 26px; + background-image: url('../../../images/edit-icon.svg'); + -webkit-background-size: contain; + background-size: contain; + opacity: 0; + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -moz-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + -o-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.profile__image:hover::before { + background: rgba(0, 0, 0, 0.8); +} + +.profile__image:hover::after { + opacity: 1; +} + + +@media screen and (max-width: 740px) { + .profile__image { + margin: 0 10px 0 0; + } +} + +@media screen and (max-width: 480px) { + .profile__image { + margin-right: 0; + } +} diff --git a/frontend/microfrontend/profile/src/styles/profile/__info/profile__info.css b/frontend/microfrontend/profile/src/styles/profile/__info/profile__info.css new file mode 100644 index 00000000..7aaefee7 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/profile/__info/profile__info.css @@ -0,0 +1,30 @@ +.profile__info { + display: grid; + grid-template-areas: "title button" + "description description"; + grid-template-columns: minmax(auto, 295px) auto; + grid-gap: 9px 17px; +} + +@media screen and (max-width: 740px) { + .profile__info { + grid-template-columns: minmax(auto, 228px) auto; + grid-gap: 9px 5px; + } +} + +@media screen and (max-width: 568px) { + .profile__info { + grid-template-columns: minmax(auto, 195px) auto; + } +} + +@media screen and (max-width: 480px) { + .profile__info { + width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: center; + margin: 26px 0 33px 0; + } +} diff --git a/frontend/microfrontend/profile/src/styles/profile/__title/profile__title.css b/frontend/microfrontend/profile/src/styles/profile/__title/profile__title.css new file mode 100644 index 00000000..4c7e2ddf --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/profile/__title/profile__title.css @@ -0,0 +1,30 @@ +.profile__title { + font-size: 42px; + line-height: 48px; + font-weight: 400; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + grid-area: title; + margin: 0; +} + +@media screen and (max-width: 740px) { + .profile__title { + font-size: 32px; + line-height: 38px; + } +} + +@media screen and (max-width: 568px) { + .profile__title { + font-size: 27px; + line-height: 33px; + } +} + +@media screen and (max-width: 480px) { + .profile__title { + min-width: 201px; + } +} diff --git a/frontend/microfrontend/profile/src/styles/profile/profile.css b/frontend/microfrontend/profile/src/styles/profile/profile.css new file mode 100644 index 00000000..01d738e7 --- /dev/null +++ b/frontend/microfrontend/profile/src/styles/profile/profile.css @@ -0,0 +1,22 @@ +@import url('./__description/profile__description.css'); +@import url('./__add-button/profile__add-button.css'); +@import url('./__edit-button/profile__edit-button.css'); +@import url('./__info/profile__info.css'); +@import url('./__title/profile__title.css'); +@import url('./__image/profile__image.css'); + +.profile { + font-family: 'Inter', Arial, sans-serif; + color: #fff; + display: flex; + align-items: center; + padding: 36px 0; +} + +@media screen and (max-width: 480px) { + .profile { + padding: 43px 0; + flex-direction: column; + text-align: center; + } +} diff --git a/frontend/microfrontend/profile/webpack.config.js b/frontend/microfrontend/profile/webpack.config.js new file mode 100644 index 00000000..4485948b --- /dev/null +++ b/frontend/microfrontend/profile/webpack.config.js @@ -0,0 +1,89 @@ +const HtmlWebPackPlugin = require("html-webpack-plugin"); +const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); +const path = require('path'); +const Dotenv = require('dotenv-webpack'); + +const deps = require("./package.json").dependencies; + +const printCompilationMessage = require('./compilation.config.js'); + +module.exports = (_, argv) => ({ + output: { + publicPath: "http://localhost:8092/", + }, + + resolve: { + extensions: [".tsx", ".ts", ".jsx", ".js", ".json"], + }, + + devServer: { + port: 8092, + historyApiFallback: true, + watchFiles: [path.resolve(__dirname, 'src')], + onListening: function (devServer) { + const port = devServer.server.address().port + + printCompilationMessage('compiling', port) + + devServer.compiler.hooks.done.tap('OutputMessagePlugin', (stats) => { + setImmediate(() => { + if (stats.hasErrors()) { + printCompilationMessage('failure', port) + } else { + printCompilationMessage('success', port) + } + }) + }) + } + }, + + module: { + rules: [ + { + test: /\.m?js/, + type: "javascript/auto", + resolve: { + fullySpecified: false, + }, + }, + { + test: /\.(css|s[ac]ss)$/i, + use: ["style-loader", "css-loader", "postcss-loader"], + }, + { + test: /\.(ts|tsx|js|jsx)$/, + exclude: /node_modules/, + use: { + loader: "babel-loader", + }, + }, + ], + }, + + plugins: [ + new ModuleFederationPlugin({ + name: "profile", + filename: "remoteEntry.js", + remotes: {}, + exposes: { + './EditAvatarPopup': './src/components/EditAvatarPopup.js', + './EditProfilePopup': './src/components/EditProfilePopup.js' + }, + shared: { + ...deps, + react: { + singleton: true, + requiredVersion: deps.react, + }, + "react-dom": { + singleton: true, + requiredVersion: deps["react-dom"], + }, + }, + }), + new HtmlWebPackPlugin({ + template: "./src/index.html", + }), + new Dotenv() + ], +}); \ No newline at end of file From 512697d0adc90fb2b34326b4dbaa27efd23a63e8 Mon Sep 17 00:00:00 2001 From: Pavel Yasonau Date: Sun, 8 Dec 2024 21:52:44 +0100 Subject: [PATCH 2/2] =?UTF-8?q?=D0=97=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=202=20=D0=B8=D0=B7=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82?= =?UTF-8?q?=D0=B0=20=D0=B8=20=D0=BE=D0=B1=D1=89=D0=B8=D0=B9=20README.md=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/README.md b/README.md index e69de29b..693d959c 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,97 @@ +# Задание 1 + +[ReadMe для микрофронтендов](https://github.com/PYasonau/architecture-sprint-1/tree/sprint_1/frontend/microfrontend#readme) + +В данном проекте использован Webpack Module Federation. Если я правильно разобрался, все микрофронтенды написаны на React, и возможно предоставить общий код во время выполнения. + +## Подход DDD для разбиения + +На основании бизнес-логики определены следующие микрофронтенды: + +- **auth** – удаленный модуль аутентификации +- **photo** – удаленный модуль для работы с изображениями +- **profile** – удаленный модуль для работы с профилем пользователя +- **host** – основное приложение, динамически загружает модули auth/photo/profile + +### Компоненты + +**auth:** +- `Login` – компонент для логина пользователя +- `Register` – компонент регистрации пользователя + +**photo:** +- `AddPlacePopup` – компонент добавления изображения +- `ImagePopup` – компонент просмотра изображения +- `PopupWithForm` – компонент диалогового окна сохранения +- `Card` – компонент карточки с изображением + +**profile:** +- `EditAvatarPopup` – компонент для редактирования аватарки пользователя +- `EditProfilePopup` – компонент для редактирования профиля пользователя +- `PopupWithForm` – компонент диалогового окна сохранения (используется и тут) + +**host:** +- `App` – основной компонент приложения +- `Footer` – подвал сайта +- `Header` – шапка сайта +- `ProtectedRoute` – защищенный маршрут +- `InfoTooltip` – информационный тултип +- `Main` – основной компонент для отображения списка карточек изображений +- `PopupWithForm` – диалоговое окно сохранения (используется и тут) + +--- + +# Задание 2 + +Ниже приведена схема приложения онлайн аукционов. + +Исходя из бизнес-логики онлайн-аукциона можно выделить следующие бизнес-фичи (сервисы): + +1. **Профиль пользователя** – управление жизненным циклом пользователя +2. **Управление заказами пользователей** +3. **Товары и услуги** – управление товарами/услугами +4. **Аукцион** – управление жизненным циклом аукционов +5. **Платеж** – управление платежами +6. **Техподдержка** – управление обращениями в техподдержку +7. **Отчеты** – создание отчетов для пользователей системы + +## Акторы + +В приложении будут 4 актора: + +1. **Продавец** +2. **Покупатель** +3. **Администратор приложения** +4. **Сотрудник технической поддержки** + +Общие действия (авторизация, регистрация, обращение в техподдержку и т.д.) по возможности пропустим при детальном описании. + +Для каждого актора есть уникальные бизнес-пути: + +### Продавец +- Добавляет, удаляет, редактирует свои товары и услуги в каталоге +- Подает заявку на участие в аукционе +- Обращается в службу поддержки (вопросы по профилю, аукционам и т.д.) +- Получает статистику (продажи, возвраты, неуспешные аукционы) +- Получает нотификации о своих аукционах + +### Покупатель +- Размещает заказ на покупку товара/услуги или создает заявку на участие в аукционе +- В случае победы в аукционе – оплачивает товар через систему платежей +- При технических проблемах – обращается в техподдержку +- При несогласии с результатом аукциона – обращается в техподдержку с апелляцией + +### Администратор +- Процесс регистрации администратора может отличаться от обычного пользователя +- Принимает решения о правилах проведения аукционов, аппеляциях, корректности данных в профиле/каталоге +- Получает статистику и отчеты по товарам, аукционам, продавцам, покупателям +- Обладает прочими необходимыми функциональностями + +### Сотрудник технической поддержки +- Регистрация сотрудника техподдержки может отличаться от регистрации покупателя +- Имеет доступ к базе обращений в техподдержку +- Управляет жизненным циклом заявки в техподдержку (обновление статуса, назначение исполнителя) + +## Диаграмма + +[Ссылка на диаграмму разбиения монолитного приложения на компоненты](https://viewer.diagrams.net/?tags=%7B%7D&lightbox=1&highlight=0000ff&edit=_blank&layers=1&nav=1&title=arch__task2_yasonau.drawio#Uhttps%3A%2F%2Fdrive.google.com%2Fuc%3Fid%3D1acFjIKv2jqJoPkU58RAvWHguM8ZXDcof%26export%3Ddownload)