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 @@
+
+
\ 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 @@
+
+
\ 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 (
+
+ );
+}
+
+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 (
+
+ );
+}
+
+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)