From 6f7da786b4b9389cf8d62b4d6382371ac4f33b4a Mon Sep 17 00:00:00 2001 From: ybortnikov Date: Wed, 6 Mar 2024 03:21:43 +0300 Subject: [PATCH 01/19] Sprint 1 - 1 attempt reviewing --- .eslintrc.cjs | 34 +++++++ .gitignore | 26 +++++ .prettierrc | 6 ++ .stylelintrc | 3 + LICENSE | 21 ++++ README.md | 101 ++++++------------- package.json | 35 +++++++ postcss.config.js | 6 ++ src/constants/routes.ts | 8 ++ src/index.html | 18 ++++ src/main.ts | 69 +++++++++++++ src/pages/errorPage/errorPage.css | 10 ++ src/pages/errorPage/errorPage.ts | 9 ++ src/pages/index.ts | 13 +++ src/pages/loginPage/loginPage.css | 13 +++ src/pages/loginPage/loginPage.ts | 18 ++++ src/pages/mainPage/mainPage.css | 10 ++ src/pages/mainPage/mainPage.ts | 9 ++ src/pages/profilePage/profilePage.css | 99 ++++++++++++++++++ src/pages/profilePage/profilePage.ts | 57 +++++++++++ src/pages/registerPage/registerPage.css | 13 +++ src/pages/registerPage/registerPage.ts | 23 +++++ src/partials/avatar/avatar.css | 13 +++ src/partials/avatar/avatar.ts | 8 ++ src/partials/button/button.css | 8 ++ src/partials/button/button.ts | 6 ++ src/partials/index.ts | 9 ++ src/partials/input/input.css | 21 ++++ src/partials/input/input.ts | 10 ++ src/server.js | 17 ++++ src/style.css | 3 + src/styles/base.css | 42 ++++++++ src/styles/mixins.css | 22 ++++ src/styles/reset.css | 128 ++++++++++++++++++++++++ src/styles/variables.css | 18 ++++ src/types.ts | 1 + src/utils/registerPartials.ts | 8 ++ tsconfig.json | 25 +++++ tsconfig.node.json | 10 ++ vite.config.js | 14 +++ 40 files changed, 891 insertions(+), 73 deletions(-) create mode 100644 .eslintrc.cjs create mode 100644 .gitignore create mode 100644 .prettierrc create mode 100644 .stylelintrc create mode 100644 LICENSE create mode 100644 package.json create mode 100644 postcss.config.js create mode 100644 src/constants/routes.ts create mode 100644 src/index.html create mode 100644 src/main.ts create mode 100644 src/pages/errorPage/errorPage.css create mode 100644 src/pages/errorPage/errorPage.ts create mode 100644 src/pages/index.ts create mode 100644 src/pages/loginPage/loginPage.css create mode 100644 src/pages/loginPage/loginPage.ts create mode 100644 src/pages/mainPage/mainPage.css create mode 100644 src/pages/mainPage/mainPage.ts create mode 100644 src/pages/profilePage/profilePage.css create mode 100644 src/pages/profilePage/profilePage.ts create mode 100644 src/pages/registerPage/registerPage.css create mode 100644 src/pages/registerPage/registerPage.ts create mode 100644 src/partials/avatar/avatar.css create mode 100644 src/partials/avatar/avatar.ts create mode 100644 src/partials/button/button.css create mode 100644 src/partials/button/button.ts create mode 100644 src/partials/index.ts create mode 100644 src/partials/input/input.css create mode 100644 src/partials/input/input.ts create mode 100644 src/server.js create mode 100644 src/style.css create mode 100644 src/styles/base.css create mode 100644 src/styles/mixins.css create mode 100644 src/styles/reset.css create mode 100644 src/styles/variables.css create mode 100644 src/types.ts create mode 100644 src/utils/registerPartials.ts create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.js diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 000000000..da994d3a1 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,34 @@ +module.exports = { + "env": { + "browser": true, + "node": true, + "es2021": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "overrides": [ + { + "env": { + "node": true + }, + "files": [ + ".eslintrc.{js,cjs}" + ], + "parserOptions": { + "sourceType": "script" + } + } + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + }, +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..914172752 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +.stylelintcache +package-lock.json diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..fa51da29e --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "trailingComma": "es5", + "tabWidth": 2, + "semi": false, + "singleQuote": true +} diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 000000000..40db42c66 --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,3 @@ +{ + "extends": "stylelint-config-standard" +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..9d32eb3a6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Yan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index bcd1a1367..44ba73076 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,38 @@ -### Ветка, в которой делаете задания спринта, должна называться sprint_i, где i - номер спринта. Не переименовывайте её. +# Тренировочный проект мессенджера. -### Откройте pull request в ветку main из ветки, где вы разрабатывали проект, и добавьте ссылку на этот pr в README.md в ветке main. -### ВАЖНО: pull request должен называться “Sprint i” (i — номер спринта). +Использовался сборщик Vite, линтеры Eslint и Stylelint, шаблонизатор Handlebars -### Например, задания для проектной работы во втором спринте вы делаете в ветке sprint_2. Открываете из неё pull request в ветку main. Ссылку на этот pr добавляете в README.md в ветке main. После этого на платформе Практикума нажимаете «Проверить задание». +### Макеты приложения -### Также не забудьте проверить, что репозиторий публичный. ---- +[Figma](https://www.figma.com/file/EhwzOuHmvUtGVE62At4ZgK/Chat_external_link-(Copy)?type=design&mode=design&t=bhHRbfH2S9ivRlpz-1 "Макеты в Figma") +### Ссылки на страницы приложения при запуске локально -Даже законченный проект остаётся только заготовкой, пока им не начнут пользоваться. Но сначала пользователь должен понять, зачем ему пользоваться вашим кодом. В этом помогает файл README. +| Экран | Ссылка | +|:------------|------------------------------------| +| Логин | http://localhost:3000/#login | +| Регистрация | http://localhost:3000/#register | +| Мессенджер | http://localhost:3000/#main | +| Профиль | http://localhost:3000/#profile | +| 404 | http://localhost:3000/#notFound | +| 500 | http://localhost:3000/#serverError | -README — первое, что прочитает пользователь, когда попадёт в репозиторий на «Гитхабе». Хороший REAMDE отвечает на четыре вопроса: +### Ссылки на страницы приложения на Netlify -- Готов ли проект к использованию? -- В чём его польза? -- Как установить? -- Как применять? +| Экран | Ссылка | +|:------------|-----------------------------------------| +| Логин | https://yamess.netlify.app/#login | +| Регистрация | https://yamess.netlify.app/#register | +| Мессенджер | https://yamess.netlify.app/#main | +| Профиль | https://yamess.netlify.app/#profile | +| 404 | https://yamess.netlify.app/#notFound | +| 500 | https://yamess.netlify.app/#serverError | -## Бейджи +### Команды npm -Быстро понять статус проекта помогают бейджи на «Гитхабе». Иногда разработчики ограничиваются парой бейджев, которые сообщат о статусе тестов кода: +| Команда | Результат | +|:--------------|-----------------------------------| +| npm run start | сборка и запуск сервера Express | +| npm run dev | запуск dev сервера для разработки | +| npm run build | запуск сборки проекта | -![Бэйджи](https://github.com/yandex-praktikum/mf.messenger.praktikum.yandex.images/blob/master/mf/b.png) - -Если пользователь увидит ошибку в работе тестов, то поймёт: использовать текущую версию в важном проекте — не лучшая идея. - -Бейджи помогают похвастаться достижениями: насколько популярен проект, как много разработчиков создавало этот код. Через бейджи можно даже пригласить пользователя в чат: - -![Версии](https://github.com/yandex-praktikum/mf.messenger.praktikum.yandex.images/blob/master/mf/vers.png) - -В README **Webpack** строка бейджев подробно рассказывает о покрытии кода тестами. Когда проект протестирован, это вызывает доверие пользователя. Последний бейдж приглашает присоединиться к разработке. - -Другая строка убедит пользователя в стабильности инфраструктуры и популярности проекта. Последний бейдж зовёт в чат проекта. - -## Описание - -Краткое опишите, какую задачу решает проект. Пользователь не верит обещаниям и не готов читать «полотна» текста. Поэтому в описании достаточно нескольких строк: - -![Описание](https://github.com/yandex-praktikum/mf.messenger.praktikum.yandex.images/blob/master/mf/desc.png) - -Авторы **React** дробят описание на абзацы и списки — так проще пробежаться глазами по тексту и найти ключевую информацию. - -Если у проекта есть сайт, добавьте ссылку в заголовок. - -## Установка - -Лучше всего пользователя убеждает собственный опыт. Чем быстрее он начнёт пользоваться проектом, тем раньше почувствует пользу. Для этого помогите ему установить приложение: напишите краткую пошаговую инструкцию. - -Если проект предназначен для разработчиков, добавьте информацию об установке тестовых версий. Например: - -- `npm install` — установка стабильной версии, -- `npm start` — запуск версии для разработчика, -- `npm run build:prod` — сборка стабильной версии. - -## **Примеры использования** - -Хорошо, если сразу после установки пользователь сможет решить свои задачи без изучения проекта. Это особенно верно, если ваш пользователь — не профессиональный разработчик. Но даже профессионал поймёт вас лучше, если показать примеры использования: - -![Ссылки](https://github.com/yandex-praktikum/mf.messenger.praktikum.yandex.images/blob/master/mf/link.png) - -Для более подробных инструкции добавьте новые разделы или ссылки: - -- на документацию, -- вики проекта, -- описание API. - -В учебном проекте будут полезен раздел с описанием стиля кода и правилами разработки: как работать с ветками, пул-реквестами и релизами. - -### **Команда** - -Если вы работаете в команде, укажите основных участников: им будет приятно, а новые разработчики охотнее присоединятся к проекту. «Гитхаб» — не просто инструмент, это социальная сеть разработчиков. - -![Команда](https://github.com/yandex-praktikum/mf.messenger.praktikum.yandex.images/blob/master/mf/team.png) - -### **Примеры README** - -- «[Реакт](https://github.com/facebook/react)», -- «[Эхо](https://github.com/labstack/echo)», -- «[Вебпак](https://github.com/webpack/webpack)», -- «[ТДенгине](https://github.com/taosdata/TDengine)», -- «[Соул-хантинг](https://github.com/vladpereskokov/soul-hunting/)». diff --git a/package.json b/package.json new file mode 100644 index 000000000..034607a70 --- /dev/null +++ b/package.json @@ -0,0 +1,35 @@ +{ + "name": "yamess", + "private": true, + "version": "0.0.1", + "type": "module", + "engines" : { + "node" : ">=18.14.0" + }, + "scripts": { + "start": "tsc && vite build && node src/server.js", + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@netlify/functions": "^2.6.0", + "@types/express": "^4.17.21", + "express": "^4.18.3", + "handlebars": "^4.7.6" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^7.1.0", + "@typescript-eslint/parser": "^7.1.0", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.1.3", + "postcss-mixins": "^9.0.4", + "postcss-nested": "^6.0.1", + "prettier": "3.2.5", + "stylelint-config-standard": "^36.0.0", + "typescript": "^5.3.3", + "vite": "^5.1.4", + "vite-plugin-eslint": "^1.8.1" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 000000000..583dfdb48 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +import postcssMixins from 'postcss-mixins' +import postcssNested from 'postcss-nested' + +export default { + plugins: [postcssMixins, postcssNested], +} diff --git a/src/constants/routes.ts b/src/constants/routes.ts new file mode 100644 index 000000000..098fa2af0 --- /dev/null +++ b/src/constants/routes.ts @@ -0,0 +1,8 @@ +export enum Routes { + login = '#login', + register = '#register', + main = '#main', + profile = '#profile', + notFound = '#notFound', + serverError = '#serverError', +} diff --git a/src/index.html b/src/index.html new file mode 100644 index 000000000..ee68b3a67 --- /dev/null +++ b/src/index.html @@ -0,0 +1,18 @@ + + + + + + YaMess + + + +
+
+
+ + + + + + diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 000000000..68a9ca3ea --- /dev/null +++ b/src/main.ts @@ -0,0 +1,69 @@ +import Handlebars from 'handlebars' +import pages from './pages' +import { Routes } from './constants/routes' +import registerPartials from './utils/registerPartials' +import partials from './partials' +import './style.css' + +const navigate = () => { + const rootDiv = document.querySelector('#app') as Element + + const mainPage = Handlebars.compile(pages.mainPageTmpl)({}) + const profilePage = Handlebars.compile(pages.profilePageTmpl)({ + userdata: { + username: 'Иван', + email: 'pochta@yandex.ru', + login: 'ivanivanov', + firstName: 'Иван', + lastName: 'Иванов', + displayName: 'Иван', + phone: '+7 (909) 967 30 30', + }, + }) + const loginPage = Handlebars.compile(pages.loginPageTmpl)({}) + const registerPage = Handlebars.compile(pages.registerPageTmpl)({}) + const notFoundPage = Handlebars.compile(pages.errorPageTmpl)({ + errorCode: '404', + errorText: 'Не туда попали', + }) + const serverErrorPage = Handlebars.compile(pages.errorPageTmpl)({ + errorCode: '500', + errorText: 'Мы уже фиксим', + }) + + switch (window.location.hash) { + case Routes.main: + rootDiv.innerHTML = mainPage + break + case Routes.profile: + rootDiv.innerHTML = profilePage + break + case Routes.login: + rootDiv.innerHTML = loginPage + break + case Routes.register: + rootDiv.innerHTML = registerPage + break + case Routes.notFound: + rootDiv.innerHTML = notFoundPage + break + case Routes.serverError: + rootDiv.innerHTML = serverErrorPage + break + default: + rootDiv.innerHTML = notFoundPage + } +} + +document.addEventListener('DOMContentLoaded', () => { + registerPartials(partials) + + if (!window.location.hash) { + const rootDiv = document.querySelector('#app') as Element + rootDiv.innerHTML = Handlebars.compile(pages.loginPageTmpl)({}) + } else { + navigate() + } +}) + +window.addEventListener('hashchange', navigate) diff --git a/src/pages/errorPage/errorPage.css b/src/pages/errorPage/errorPage.css new file mode 100644 index 000000000..357f46d9d --- /dev/null +++ b/src/pages/errorPage/errorPage.css @@ -0,0 +1,10 @@ +@import '../../styles/mixins.css'; + +.error { + @mixin dialog; + flex-direction: column; + + &__description { + padding-bottom: 30px; + } +} diff --git a/src/pages/errorPage/errorPage.ts b/src/pages/errorPage/errorPage.ts new file mode 100644 index 000000000..3ea8b292a --- /dev/null +++ b/src/pages/errorPage/errorPage.ts @@ -0,0 +1,9 @@ +import './errorPage.css' + +export default ` +
+

{{ errorCode }}

+

{{ errorText }}

+ Назад к чатам +
+` diff --git a/src/pages/index.ts b/src/pages/index.ts new file mode 100644 index 000000000..8f75849cf --- /dev/null +++ b/src/pages/index.ts @@ -0,0 +1,13 @@ +import errorPageTmpl from './errorPage/errorPage' +import loginPageTmpl from './loginPage/loginPage' +import mainPageTmpl from './mainPage/mainPage' +import profilePageTmpl from './profilePage/profilePage' +import registerPageTmpl from './registerPage/registerPage' + +export default { + errorPageTmpl: errorPageTmpl, + loginPageTmpl: loginPageTmpl, + mainPageTmpl: mainPageTmpl, + profilePageTmpl: profilePageTmpl, + registerPageTmpl: registerPageTmpl, +} diff --git a/src/pages/loginPage/loginPage.css b/src/pages/loginPage/loginPage.css new file mode 100644 index 000000000..a039dcc43 --- /dev/null +++ b/src/pages/loginPage/loginPage.css @@ -0,0 +1,13 @@ +@import '../../styles/mixins.css'; + +.login { + @mixin dialog; +} + +.wrapper { + @mixin dialog-wrapper; +} + +.login-form { + @mixin dialog-form; +} diff --git a/src/pages/loginPage/loginPage.ts b/src/pages/loginPage/loginPage.ts new file mode 100644 index 000000000..be1709a03 --- /dev/null +++ b/src/pages/loginPage/loginPage.ts @@ -0,0 +1,18 @@ +// language=hbs +import './loginPage.css' + +export default ` +
+
+

Вход

+ + + + Нет аккаунта? +
+
+` diff --git a/src/pages/mainPage/mainPage.css b/src/pages/mainPage/mainPage.css new file mode 100644 index 000000000..78d74e220 --- /dev/null +++ b/src/pages/mainPage/mainPage.css @@ -0,0 +1,10 @@ +.main { + display: grid; + grid-template-columns: 310px 1fr; + height: 100%; + + .sidebar { + background: var(--sidebar-bg); + border-right: 1px solid var(--border); + } +} diff --git a/src/pages/mainPage/mainPage.ts b/src/pages/mainPage/mainPage.ts new file mode 100644 index 000000000..9e38b2943 --- /dev/null +++ b/src/pages/mainPage/mainPage.ts @@ -0,0 +1,9 @@ +// language=hbs +import './mainPage.css' + +export default ` +
+ +
Lorem ipsum
+
+` diff --git a/src/pages/profilePage/profilePage.css b/src/pages/profilePage/profilePage.css new file mode 100644 index 000000000..f83bef34a --- /dev/null +++ b/src/pages/profilePage/profilePage.css @@ -0,0 +1,99 @@ +.profile { + display: grid; + grid-template-columns: 64px 1fr; + height: 100%; + + .back { + display: flex; + justify-content: center; + align-items: center; + background: var(--sidebar-bg); + border-right: 1px solid var(--border); + + &__button { + display: flex; + justify-content: center; + align-items: center; + width: 28px; + height: 28px; + background: var(--color-blue); + border: none; + border-radius: 50%; + cursor: pointer; + + .lni { + color: var(--color-white); + } + } + } + + .profile-content { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 0 30%; + + &__username { + padding: 20px 0 60px; + font-size: 18px; + font-weight: 600; + } + + .profile-info { + width: 100%; + padding-bottom: 60px; + + .profile-info-row { + display: flex; + justify-content: space-between; + padding: 10px 0; + + &:not(:last-child) { + border-bottom: 1px solid var(--border); + } + + &__name { + font-size: 14px; + font-weight: 600; + } + + &__value { + color: var(--color-gray); + font-size: 14px; + } + } + } + + .profile-actions { + display: flex; + flex-direction: column; + align-self: flex-start; + width: 100%; + + &__wrapper { + padding: 10px 0; + + &:not(:last-child) { + border-bottom: 1px solid var(--border); + } + } + + &__button { + border: none; + outline: none; + background: none; + cursor: pointer; + font-weight: 500; + + &_blue { + color: var(--color-blue); + } + + &_red { + color: var(--color-red); + } + } + } + } +} diff --git a/src/pages/profilePage/profilePage.ts b/src/pages/profilePage/profilePage.ts new file mode 100644 index 000000000..ceb4b913b --- /dev/null +++ b/src/pages/profilePage/profilePage.ts @@ -0,0 +1,57 @@ +// language=hbs +import './profilePage.css' + +export default ` +
+
+ +
+ +
+ {{> avatar src="https://images.pexels.com/photos/276267/pexels-photo-276267.jpeg" alt="avatar"}} + + {{userdata.displayName}} + +
+
+ Почта + {{userdata.email}} +
+
+ Логин + {{userdata.login}} +
+
+ Имя + {{userdata.firstName}} +
+
+ Фамилия + {{userdata.lastName}} +
+
+ Имя в чате + {{userdata.displayName}} +
+
+ Телефон + {{userdata.phone}} +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+` diff --git a/src/pages/registerPage/registerPage.css b/src/pages/registerPage/registerPage.css new file mode 100644 index 000000000..870d9a42a --- /dev/null +++ b/src/pages/registerPage/registerPage.css @@ -0,0 +1,13 @@ +@import '../../styles/mixins.css'; + +.register { + @mixin dialog; +} + +.wrapper { + @mixin dialog-wrapper; +} + +.register-form { + @mixin dialog-form; +} diff --git a/src/pages/registerPage/registerPage.ts b/src/pages/registerPage/registerPage.ts new file mode 100644 index 000000000..a555f2a2a --- /dev/null +++ b/src/pages/registerPage/registerPage.ts @@ -0,0 +1,23 @@ +// language=hbs +import './registerPage.css' + +export default ` +
+
+

Регистрация

+ +
+ {{> input type="text" name="email" label="Почта" placeholder="Почта..."}} + {{> input type="text" name="login" label="Логин" placeholder="Логин..."}} + {{> input type="text" name="first_name" label="Имя" placeholder="Имя..."}} + {{> input type="text" name="second_name" label="Фамилия" placeholder="Фамилия..."}} + {{> input type="text" name="phone" label="Телефон" placeholder="Телефон..."}} + {{> input type="password" name="password" label="Пароль" placeholder="Пароль..."}} + {{> input type="password" name="password-verify" label="Пароль ещё раз" placeholder="Повторите пароль..."}} + {{> button label="Зарегистрироваться" }} +
+ + Войти +
+
+` diff --git a/src/partials/avatar/avatar.css b/src/partials/avatar/avatar.css new file mode 100644 index 000000000..4c5c1f865 --- /dev/null +++ b/src/partials/avatar/avatar.css @@ -0,0 +1,13 @@ +.avatar { + width: 130px; + height: 130px; + overflow: hidden; + border-radius: 50%; + + &__img { + width: 100%; + height: 100%; + object-fit: cover; + object-position: center; + } +} diff --git a/src/partials/avatar/avatar.ts b/src/partials/avatar/avatar.ts new file mode 100644 index 000000000..c96710b0f --- /dev/null +++ b/src/partials/avatar/avatar.ts @@ -0,0 +1,8 @@ +// language=hbs +import './avatar.css' + +export default ` +
+ {{alt}} +
+` diff --git a/src/partials/button/button.css b/src/partials/button/button.css new file mode 100644 index 000000000..d0b7fa729 --- /dev/null +++ b/src/partials/button/button.css @@ -0,0 +1,8 @@ +.button { + width: 100%; + padding: 12px 0; + background: var(--color-blue); + color: var(--color-white); + border: none; + border-radius: var(--border-radius); +} diff --git a/src/partials/button/button.ts b/src/partials/button/button.ts new file mode 100644 index 000000000..82b59e358 --- /dev/null +++ b/src/partials/button/button.ts @@ -0,0 +1,6 @@ +// language=hbs +import './button.css' + +export default ` + +` diff --git a/src/partials/index.ts b/src/partials/index.ts new file mode 100644 index 000000000..5de438d95 --- /dev/null +++ b/src/partials/index.ts @@ -0,0 +1,9 @@ +import avatarTmpl from './avatar/avatar' +import buttonTmpl from './button/button' +import inputTmpl from './input/input' + +export default [ + { name: 'avatar', template: avatarTmpl }, + { name: 'button', template: buttonTmpl }, + { name: 'input', template: inputTmpl }, +] diff --git a/src/partials/input/input.css b/src/partials/input/input.css new file mode 100644 index 000000000..eb512645a --- /dev/null +++ b/src/partials/input/input.css @@ -0,0 +1,21 @@ +.input { + display: flex; + flex-direction: column; + padding: 10px 0; + + &__label { + margin-bottom: 4px; + font-size: 10px; + font-weight: 300; + } + + &__input { + width: 100%; + padding: 8px 0; + font-size: 16px; + font-weight: 300; + border: none; + border-bottom: 1px solid var(--color-blue); + outline: none; + } +} diff --git a/src/partials/input/input.ts b/src/partials/input/input.ts new file mode 100644 index 000000000..b923057e2 --- /dev/null +++ b/src/partials/input/input.ts @@ -0,0 +1,10 @@ +// language=hbs +import './input.css' +export default ` +
+ +
+` diff --git a/src/server.js b/src/server.js new file mode 100644 index 000000000..f31637d23 --- /dev/null +++ b/src/server.js @@ -0,0 +1,17 @@ +import path from 'path' +import { fileURLToPath } from 'url' +import express from 'express' + +const app = express() + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) + +app.use(express.static(path.join(__dirname, '../dist'))) +app.get('/', function (req, res) { + res.sendFile(path.join(__dirname, '../dist/index.html')) +}) + +app.listen(3000, () => { + console.log('Server started at port 3000') +}) diff --git a/src/style.css b/src/style.css new file mode 100644 index 000000000..0eff38ab1 --- /dev/null +++ b/src/style.css @@ -0,0 +1,3 @@ +@import url('styles/reset.css'); +@import url('styles/variables.css'); +@import url('styles/base.css'); diff --git a/src/styles/base.css b/src/styles/base.css new file mode 100644 index 000000000..a45e6f9ec --- /dev/null +++ b/src/styles/base.css @@ -0,0 +1,42 @@ +* { + font-family: var(--font-family); + color: var(--color-text); +} + +html { + height: 100%; +} + +body { + height: 100%; +} + +main { + height: 100%; +} + +h1 { + padding-bottom: 20px; + font-size: 40px; + font-weight: 500; +} + +h2 { + font-size: 24px; + font-weight: 500; +} + +h4 { + font-size: 20px; + font-weight: 400; +} + +#app { + height: 100%; +} + +.link { + color: var(--color-blue); + font-size: 12px; + cursor: pointer; +} diff --git a/src/styles/mixins.css b/src/styles/mixins.css new file mode 100644 index 000000000..ce33f0e96 --- /dev/null +++ b/src/styles/mixins.css @@ -0,0 +1,22 @@ +@define-mixin dialog { + display: flex; + justify-content: center; + align-items: center; + height: 100%; +} + +@define-mixin dialog-wrapper { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + min-width: 320px; + padding: 50px 30px 30px; + box-shadow: var(--box-shadow); + border-radius: var(--border-radius); +} + +@define-mixin dialog-form { + width: 100%; + padding-bottom: 16px; +} diff --git a/src/styles/reset.css b/src/styles/reset.css new file mode 100644 index 000000000..f76f6d0ba --- /dev/null +++ b/src/styles/reset.css @@ -0,0 +1,128 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/src/styles/variables.css b/src/styles/variables.css new file mode 100644 index 000000000..ace3360c7 --- /dev/null +++ b/src/styles/variables.css @@ -0,0 +1,18 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap'); + +:root { + --color1: #efefef; + --color2: #e4edfd; + --color-gray: #999999; + --color-blue: #3369f3; + --color-red: #ff2f2f; + --color-white: #ffffff; + --color-text: #1e1e1e; + --sidebar-bg: #fbfbfb; + --border: #eaeaea; + + --box-shadow: 0 0 3px 3px var(--color1); + --border-radius: 8px; + + --font-family: 'Inter', sans-serif; +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 000000000..9da5c7176 --- /dev/null +++ b/src/types.ts @@ -0,0 +1 @@ +export type Partial = { name: string; template: string } diff --git a/src/utils/registerPartials.ts b/src/utils/registerPartials.ts new file mode 100644 index 000000000..d58521166 --- /dev/null +++ b/src/utils/registerPartials.ts @@ -0,0 +1,8 @@ +import Handlebars from 'handlebars' +import { Partial } from '../types' + +export default (partials: Array) => { + partials.forEach((partial) => { + Handlebars.registerPartial(partial.name, partial.template) + }) +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..5ec59a804 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "allowJs": false, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "moduleResolution": "Node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + }, + "ts-node": { + "esm": true, + }, + "include": ["src"], + "exclude": ["node_modules"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 000000000..3ac8b9503 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "module": "esnext", + "moduleResolution": "node" + }, + "include": [ + "vite.config.js" + ] +} diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 000000000..1f3a87200 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,14 @@ +import { defineConfig } from "vite"; +import eslint from "vite-plugin-eslint"; + +export default defineConfig({ + root: "./src", + build: { + outDir: "../dist", + }, + server: { + port: 3000, + open: true, + }, + plugins: [eslint()], +}); From d08b378bf0184246a83a1bcd9922e552650ed172 Mon Sep 17 00:00:00 2001 From: ybortnikov Date: Wed, 6 Mar 2024 13:28:33 +0300 Subject: [PATCH 02/19] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B4=D0=BB=D1=8F=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D1=85=D0=BE=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=B0=D0=B2=D1=82=D0=BE=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 - postcss.config.js | 3 +- src/pages/errorPage/errorPage.css | 3 - src/pages/errorPage/errorPage.ts | 2 +- src/pages/loginPage/loginPage.css | 16 ++- src/pages/loginPage/loginPage.ts | 8 +- src/pages/registerPage/registerPage.css | 14 +-- src/pages/registerPage/registerPage.ts | 8 +- src/style.css | 2 +- src/styles/base.css | 24 +++++ src/styles/mixins.css | 22 ---- src/styles/reset.css | 128 ------------------------ src/styles/variables.css | 6 +- 13 files changed, 46 insertions(+), 191 deletions(-) delete mode 100644 src/styles/mixins.css delete mode 100644 src/styles/reset.css diff --git a/package.json b/package.json index 034607a70..9c06c0242 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", - "postcss-mixins": "^9.0.4", "postcss-nested": "^6.0.1", "prettier": "3.2.5", "stylelint-config-standard": "^36.0.0", diff --git a/postcss.config.js b/postcss.config.js index 583dfdb48..361dbff56 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,5 @@ -import postcssMixins from 'postcss-mixins' import postcssNested from 'postcss-nested' export default { - plugins: [postcssMixins, postcssNested], + plugins: [postcssNested], } diff --git a/src/pages/errorPage/errorPage.css b/src/pages/errorPage/errorPage.css index 357f46d9d..6ba1b982a 100644 --- a/src/pages/errorPage/errorPage.css +++ b/src/pages/errorPage/errorPage.css @@ -1,7 +1,4 @@ -@import '../../styles/mixins.css'; - .error { - @mixin dialog; flex-direction: column; &__description { diff --git a/src/pages/errorPage/errorPage.ts b/src/pages/errorPage/errorPage.ts index 3ea8b292a..f8087282a 100644 --- a/src/pages/errorPage/errorPage.ts +++ b/src/pages/errorPage/errorPage.ts @@ -1,7 +1,7 @@ import './errorPage.css' export default ` -
+

{{ errorCode }}

{{ errorText }}

Назад к чатам diff --git a/src/pages/loginPage/loginPage.css b/src/pages/loginPage/loginPage.css index a039dcc43..80276d988 100644 --- a/src/pages/loginPage/loginPage.css +++ b/src/pages/loginPage/loginPage.css @@ -1,13 +1,9 @@ -@import '../../styles/mixins.css'; - .login { - @mixin dialog; -} - -.wrapper { - @mixin dialog-wrapper; -} + &__title { + margin-bottom: 40px; + } -.login-form { - @mixin dialog-form; + #login-btn { + margin-top: 130px; + } } diff --git a/src/pages/loginPage/loginPage.ts b/src/pages/loginPage/loginPage.ts index be1709a03..2a65208b5 100644 --- a/src/pages/loginPage/loginPage.ts +++ b/src/pages/loginPage/loginPage.ts @@ -2,11 +2,11 @@ import './loginPage.css' export default ` -