From 80840260e26d4f4176e61b65513a6e229317dbb0 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Fri, 8 Jul 2022 19:45:40 +0300 Subject: [PATCH 01/70] feat: index page layout --- README.md | 3 + astro.config.mjs | 4 +- public/assets/icons/social/email.svg | 3 - public/assets/icons/social/github.svg | 3 - public/assets/icons/social/telegram.svg | 3 - src/components/Footer/Footer.astro | 24 ++++ src/components/Footer/Footer.scss | 33 ++++++ src/components/Footer/index.ts | 1 + src/components/Header/Header.astro | 34 ++++++ src/components/Header/Header.scss | 51 +++++++++ src/components/Header/index.ts | 1 + .../RecentArticles/RecentArticles.astro | 32 ++++++ .../RecentArticles/RecentArticles.scss | 47 ++++++++ .../Sections/RecentArticles/index.ts | 1 + src/components/Sections/Welcome/Welcome.astro | 44 +++++++ src/components/Sections/Welcome/Welcome.scss | 45 ++++++++ src/components/Sections/Welcome/index.ts | 1 + src/components/Sections/index.ts | 2 + .../ThemeSwticher/ThemeSwitcher.astro | 8 ++ .../ThemeSwticher/ThemeSwitcher.scss | 9 ++ src/components/ThemeSwticher/index.ts | 1 + src/components/icons/AstroIcon.astro | 16 +++ src/components/icons/EmailIcon.astro | 21 ++++ src/components/icons/GithubIcon.astro | 13 +++ src/components/icons/MoonIcon.astro | 14 +++ src/components/icons/NetlifyIcon.astro | 27 +++++ src/components/icons/RssIcon.astro | 14 +++ src/components/icons/TelegramIcon.astro | 13 +++ src/components/icons/index.ts | 17 +++ src/config.ts | 9 ++ src/layouts/Page.astro | 26 +++++ src/pages/articles.astro | 13 +++ src/pages/index.astro | 70 ++---------- src/styles/global.scss | 107 +++++++++++++++++- tsconfig.json | 18 +-- 35 files changed, 645 insertions(+), 83 deletions(-) delete mode 100644 public/assets/icons/social/email.svg delete mode 100644 public/assets/icons/social/github.svg delete mode 100644 public/assets/icons/social/telegram.svg create mode 100644 src/components/Footer/Footer.astro create mode 100644 src/components/Footer/Footer.scss create mode 100644 src/components/Footer/index.ts create mode 100644 src/components/Header/Header.astro create mode 100644 src/components/Header/Header.scss create mode 100644 src/components/Header/index.ts create mode 100644 src/components/Sections/RecentArticles/RecentArticles.astro create mode 100644 src/components/Sections/RecentArticles/RecentArticles.scss create mode 100644 src/components/Sections/RecentArticles/index.ts create mode 100644 src/components/Sections/Welcome/Welcome.astro create mode 100644 src/components/Sections/Welcome/Welcome.scss create mode 100644 src/components/Sections/Welcome/index.ts create mode 100644 src/components/Sections/index.ts create mode 100644 src/components/ThemeSwticher/ThemeSwitcher.astro create mode 100644 src/components/ThemeSwticher/ThemeSwitcher.scss create mode 100644 src/components/ThemeSwticher/index.ts create mode 100644 src/components/icons/AstroIcon.astro create mode 100644 src/components/icons/EmailIcon.astro create mode 100644 src/components/icons/GithubIcon.astro create mode 100644 src/components/icons/MoonIcon.astro create mode 100644 src/components/icons/NetlifyIcon.astro create mode 100644 src/components/icons/RssIcon.astro create mode 100644 src/components/icons/TelegramIcon.astro create mode 100644 src/components/icons/index.ts create mode 100644 src/config.ts create mode 100644 src/layouts/Page.astro create mode 100644 src/pages/articles.astro diff --git a/README.md b/README.md index 4739a75..b979e35 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # yarkov.tech +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +[![Netlify Status](https://api.netlify.com/api/v1/badges/ccd0460a-9725-4e35-8263-1608c4186d9c/deploy-status)](https://app.netlify.com/sites/jade-froyo-876dfe/deploys) + Personal website created with Astro. ## License diff --git a/astro.config.mjs b/astro.config.mjs index 882e651..3ac6c0c 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,4 +1,6 @@ import { defineConfig } from 'astro/config'; // https://astro.build/config -export default defineConfig({}); +export default defineConfig({ + site: 'https://yarkov.tech', +}); diff --git a/public/assets/icons/social/email.svg b/public/assets/icons/social/email.svg deleted file mode 100644 index 289f965..0000000 --- a/public/assets/icons/social/email.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/assets/icons/social/github.svg b/public/assets/icons/social/github.svg deleted file mode 100644 index 78fae17..0000000 --- a/public/assets/icons/social/github.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/assets/icons/social/telegram.svg b/public/assets/icons/social/telegram.svg deleted file mode 100644 index d89fbe7..0000000 --- a/public/assets/icons/social/telegram.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/components/Footer/Footer.astro b/src/components/Footer/Footer.astro new file mode 100644 index 0000000..4f46d12 --- /dev/null +++ b/src/components/Footer/Footer.astro @@ -0,0 +1,24 @@ +--- +import './Footer.scss'; +import { AstroIcon, NetlifyIcon, RssIcon } from '@components/icons'; +--- + + diff --git a/src/components/Footer/Footer.scss b/src/components/Footer/Footer.scss new file mode 100644 index 0000000..70d7936 --- /dev/null +++ b/src/components/Footer/Footer.scss @@ -0,0 +1,33 @@ +.footer { + & .container { + margin-top: 5rem; + padding: 25px 0 10px 0; + font-weight: 500; + border-top: 1px solid var(--border-color); + display: flex; + flex-direction: column; + align-items: center; + row-gap: 15px; + } + &__links { + display: flex; + align-items: center; + column-gap: 25px; + list-style: none; + margin: 0; + padding: 0; + & li { + display: flex; + align-items: center; + column-gap: 7px; + & a { + color: var(--font-color); + font-size: var(--font-size-sm); + } + } + } + &__copy { + text-align: center; + font-size: var(--font-size-xs); + } +} diff --git a/src/components/Footer/index.ts b/src/components/Footer/index.ts new file mode 100644 index 0000000..aab1df4 --- /dev/null +++ b/src/components/Footer/index.ts @@ -0,0 +1 @@ +export { default } from './Footer.astro'; diff --git a/src/components/Header/Header.astro b/src/components/Header/Header.astro new file mode 100644 index 0000000..56b1e1a --- /dev/null +++ b/src/components/Header/Header.astro @@ -0,0 +1,34 @@ +--- +import './Header.scss'; +import { SITE_METADATA } from '@root/config'; +import { EmailIcon, GithubIcon, TelegramIcon } from '@components/icons'; +import ThemeSwitcher from '@components/ThemeSwticher'; +--- + +
+ +
diff --git a/src/components/Header/Header.scss b/src/components/Header/Header.scss new file mode 100644 index 0000000..da4ce61 --- /dev/null +++ b/src/components/Header/Header.scss @@ -0,0 +1,51 @@ +.header { + position: sticky; + top: 0; + border-bottom: 1px solid var(--border-color); + background-color: var(--background-header-color); + padding-top: 15px; + padding-bottom: 15px; + + & .container { + display: flex; + align-items: center; + justify-content: space-between; + } + + &__logo a { + text-decoration: none; + font-weight: 600; + font-size: var(--font-size-lg); + color: var(--font-color); + } + &__nav { + display: flex; + align-items: center; + & ul { + display: flex; + list-style: none; + column-gap: 20px; + margin: 0; + padding: 0; + margin-right: 35px; + & li a { + display: inline-block; + font-weight: 500; + color: var(--font-color); + &:hover { + color: var(--color-blue-500); + } + } + } + &-contacts { + display: flex; + align-items: center; + column-gap: 10px; + margin-right: 40px; + & a { + text-decoration: none; + font-size: 0; + } + } + } +} diff --git a/src/components/Header/index.ts b/src/components/Header/index.ts new file mode 100644 index 0000000..3e3fbb4 --- /dev/null +++ b/src/components/Header/index.ts @@ -0,0 +1 @@ +export { default } from './Header.astro'; diff --git a/src/components/Sections/RecentArticles/RecentArticles.astro b/src/components/Sections/RecentArticles/RecentArticles.astro new file mode 100644 index 0000000..eb7e990 --- /dev/null +++ b/src/components/Sections/RecentArticles/RecentArticles.astro @@ -0,0 +1,32 @@ +--- +import './RecentArticles.scss'; +--- + +
+
+
+

недавние публикации

+ смотреть все +
+
+ +
diff --git a/src/components/Sections/RecentArticles/RecentArticles.scss b/src/components/Sections/RecentArticles/RecentArticles.scss new file mode 100644 index 0000000..5972a04 --- /dev/null +++ b/src/components/Sections/RecentArticles/RecentArticles.scss @@ -0,0 +1,47 @@ +.publications { + &-heading { + display: flex; + align-items: center; + column-gap: 15px; + row-gap: 5px; + flex-wrap: wrap; + justify-content: space-between; + border-bottom: 1px solid var(--border-color); + padding-bottom: 10px; + & h2 { + margin: 0; + } + } + &-list { + margin-top: 10px; + max-width: calc(var(--content-width) + (var(--content-padding) * 2)); + & article { + border-radius: var(--border-radius-md); + & a { + display: flex; + justify-content: space-between; + align-items: center; + column-gap: 10px; + color: var(--font-color); + padding: 8px 15px; + text-decoration: none; + & h3 { + font-size: var(--font-size-md); + font-weight: normal; + margin: 0; + } + & p { + font-size: var(--font-size-xs); + font-family: monospace; + color: var(--font-color-gray); + text-transform: uppercase; + margin: 0; + text-align: right; + } + } + &:hover { + background-color: var(--background-color-hover); + } + } + } +} diff --git a/src/components/Sections/RecentArticles/index.ts b/src/components/Sections/RecentArticles/index.ts new file mode 100644 index 0000000..d99a12b --- /dev/null +++ b/src/components/Sections/RecentArticles/index.ts @@ -0,0 +1 @@ +export { default as RecentArticlesSection } from './RecentArticles.astro'; diff --git a/src/components/Sections/Welcome/Welcome.astro b/src/components/Sections/Welcome/Welcome.astro new file mode 100644 index 0000000..2e3ee4c --- /dev/null +++ b/src/components/Sections/Welcome/Welcome.astro @@ -0,0 +1,44 @@ +--- +import './Welcome.scss'; +--- + +
+
+
+

Hello, I'am Sergey

+

Fullstack web-developer and freelancer

+
+

+ Я занимаюсь разработкой веб-сайтов и веб-приложений разной сложности, а + также публикую различные статьи и туториалы на разные IT темы. +

+
+ +
diff --git a/src/components/Sections/Welcome/Welcome.scss b/src/components/Sections/Welcome/Welcome.scss new file mode 100644 index 0000000..cdfd327 --- /dev/null +++ b/src/components/Sections/Welcome/Welcome.scss @@ -0,0 +1,45 @@ +.welcome { + margin-top: 80px; + margin-bottom: 150px; + &-heading { + &__title { + & h1 { + font-size: var(--font-size-5xl); + font-weight: bold; + margin-bottom: 0.5rem; + } + & h2 { + font-size: var(--font-size-xl); + margin-bottom: 1.25rem; + font-weight: normal; + } + } + &__description { + font-size: var(--font-size-lg); + max-width: 570px; + line-height: 1.5; + } + } + &-links { + display: flex; + align-items: center; + column-gap: 20px; + &__link { + display: flex; + align-items: center; + column-gap: 5px; + & a { + color: var(--font-color-gray); + } + & svg { + fill: var(--font-color-gray); + } + } + } +} + +// @media screen and (max-width: 700px) { +// .welcome { + +// } +// } diff --git a/src/components/Sections/Welcome/index.ts b/src/components/Sections/Welcome/index.ts new file mode 100644 index 0000000..b9d7b30 --- /dev/null +++ b/src/components/Sections/Welcome/index.ts @@ -0,0 +1 @@ +export { default as WelcomeSection } from './Welcome.astro'; diff --git a/src/components/Sections/index.ts b/src/components/Sections/index.ts new file mode 100644 index 0000000..8348313 --- /dev/null +++ b/src/components/Sections/index.ts @@ -0,0 +1,2 @@ +export * from './Welcome'; +export * from './RecentArticles'; diff --git a/src/components/ThemeSwticher/ThemeSwitcher.astro b/src/components/ThemeSwticher/ThemeSwitcher.astro new file mode 100644 index 0000000..7ef389c --- /dev/null +++ b/src/components/ThemeSwticher/ThemeSwitcher.astro @@ -0,0 +1,8 @@ +--- +import './ThemeSwitcher.scss'; +import { MoonIcon } from '@components/icons'; +--- + + diff --git a/src/components/ThemeSwticher/ThemeSwitcher.scss b/src/components/ThemeSwticher/ThemeSwitcher.scss new file mode 100644 index 0000000..f74bb2b --- /dev/null +++ b/src/components/ThemeSwticher/ThemeSwitcher.scss @@ -0,0 +1,9 @@ +.theme-switcher { + background: none; + border: none; + display: flex; + align-items: center; + cursor: pointer; + padding: 0; + margin: 0; +} diff --git a/src/components/ThemeSwticher/index.ts b/src/components/ThemeSwticher/index.ts new file mode 100644 index 0000000..50e6b3d --- /dev/null +++ b/src/components/ThemeSwticher/index.ts @@ -0,0 +1 @@ +export { default } from './ThemeSwitcher.astro'; diff --git a/src/components/icons/AstroIcon.astro b/src/components/icons/AstroIcon.astro new file mode 100644 index 0000000..3774491 --- /dev/null +++ b/src/components/icons/AstroIcon.astro @@ -0,0 +1,16 @@ +--- +--- + + + + diff --git a/src/components/icons/EmailIcon.astro b/src/components/icons/EmailIcon.astro new file mode 100644 index 0000000..76a8302 --- /dev/null +++ b/src/components/icons/EmailIcon.astro @@ -0,0 +1,21 @@ +--- +--- + + + + + + + + + + + diff --git a/src/components/icons/GithubIcon.astro b/src/components/icons/GithubIcon.astro new file mode 100644 index 0000000..222144d --- /dev/null +++ b/src/components/icons/GithubIcon.astro @@ -0,0 +1,13 @@ +--- +--- + + + + diff --git a/src/components/icons/MoonIcon.astro b/src/components/icons/MoonIcon.astro new file mode 100644 index 0000000..d08427a --- /dev/null +++ b/src/components/icons/MoonIcon.astro @@ -0,0 +1,14 @@ +--- +--- + + + + diff --git a/src/components/icons/NetlifyIcon.astro b/src/components/icons/NetlifyIcon.astro new file mode 100644 index 0000000..d597bb2 --- /dev/null +++ b/src/components/icons/NetlifyIcon.astro @@ -0,0 +1,27 @@ +--- +--- + + + + + + + + + + diff --git a/src/components/icons/RssIcon.astro b/src/components/icons/RssIcon.astro new file mode 100644 index 0000000..47f8332 --- /dev/null +++ b/src/components/icons/RssIcon.astro @@ -0,0 +1,14 @@ +--- +--- + + + + diff --git a/src/components/icons/TelegramIcon.astro b/src/components/icons/TelegramIcon.astro new file mode 100644 index 0000000..b4affa2 --- /dev/null +++ b/src/components/icons/TelegramIcon.astro @@ -0,0 +1,13 @@ +--- +--- + + + + diff --git a/src/components/icons/index.ts b/src/components/icons/index.ts new file mode 100644 index 0000000..bf3a4ff --- /dev/null +++ b/src/components/icons/index.ts @@ -0,0 +1,17 @@ +import EmailIcon from './EmailIcon.astro'; +import GithubIcon from './GithubIcon.astro'; +import TelegramIcon from './TelegramIcon.astro'; +import MoonIcon from './MoonIcon.astro'; +import AstroIcon from './AstroIcon.astro'; +import NetlifyIcon from './NetlifyIcon.astro'; +import RssIcon from './RssIcon.astro'; + +export { + EmailIcon, + GithubIcon, + TelegramIcon, + MoonIcon, + AstroIcon, + NetlifyIcon, + RssIcon, +}; diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..b385b35 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,9 @@ +export const SITE_METADATA = { + name: 'yarkov.tech', + author: 'Sergey Yarkov', + contacts: { + email: 'serzh.yarkov@gmail.com', + githubUrl: 'https://github.com/sergeyyarkov', + telegramUrl: 'https://t.me/sergeyyarkov', + }, +}; diff --git a/src/layouts/Page.astro b/src/layouts/Page.astro new file mode 100644 index 0000000..2590927 --- /dev/null +++ b/src/layouts/Page.astro @@ -0,0 +1,26 @@ +--- +import '@styles/global.scss'; +import Header from '@components/Header'; +import Footer from '@components/Footer'; + +export interface Props { + title?: string | undefined; +} + +const { title = 'Sergey Yarkov' } = Astro.props as Props; +--- + + + + + + {title} + + +
+
+ +
+
@@ -96,9 +79,7 @@ const recent = utils.sortArtcilesByDate(utils.transformArticles(data)); & a { color: var(--font-color-gray); } - & svg { - fill: var(--font-color-gray); - } + } } } @@ -122,5 +103,13 @@ const recent = utils.sortArtcilesByDate(utils.transformArticles(data)); max-width: calc(var(--content-width) + (var(--content-padding) * 2)); } } + + [astro-icon="information"] { + fill: var(--color-gray-600) + } + + [astro-icon="email_filled"] { + fill: var(--color-gray-600) + } diff --git a/src/pages/projects.astro b/src/pages/projects.astro index e69de29..e0c79d1 100644 --- a/src/pages/projects.astro +++ b/src/pages/projects.astro @@ -0,0 +1,153 @@ +--- +import Page from '@layouts/Page.astro'; +import { PageHeading } from '@root/components/PageHeading'; +import { SITE_METADATA } from '@root/config'; +--- + + +
+ + +
+
+
+

+ + + + + yarkov.tech +

+ 2022 +
+
+

+ Мой персональный веб-сайт где находятся информация обо мне и список + различных статей, туториалов... +

+
+ +
+
+
+

+ + + + devthread +

+ 2021 +
+
+

+ Статический веб-сайт для публикации различных статей, разработанный + при помощи Gatsby.js и NetlifyCMS +

+
+ +
+
+
+ +
diff --git a/src/styles/global.scss b/src/styles/global.scss index d58579f..759fad2 100644 --- a/src/styles/global.scss +++ b/src/styles/global.scss @@ -76,6 +76,7 @@ --border-color: var(--color-gray-100); --border-color-hover: var(--color-gray-400); --border-radius-md: 3px; + --border-radius-lg: 5px; /* Sizes */ --content-width: 760px; @@ -84,20 +85,44 @@ /* Elements */ --background-body-color: var(--color-white); --background-header-color: var(--color-white); + --background-scrollbar-track-color: #EFF1F5; + --background-scrollbar-thumb-color: var(--color-gray-100); } +/* Text selection */ ::selection { background: var(--color-yellow-100); color: var(--color-black); } + +/* Scrollbar */ +::-webkit-scrollbar { + width: 10px; + height: 10px; +} + +::-webkit-scrollbar-track { + background: var(--background-scrollbar-track-color); +} + +::-webkit-scrollbar-thumb { + background: var(--background-scrollbar-thumb-color) +} + + html, body { + box-sizing: border-box; display: flex; flex-direction: column; height: 100%; } +*, *:before, *:after { + box-sizing: inherit; +} + html { font-size: 16px; font-weight: normal; @@ -112,6 +137,7 @@ body { background-color: var(--background-body-color); } + .site-content { flex: 1 0 auto; width: 100%; @@ -124,6 +150,63 @@ body { padding: 0 var(--content-padding); } +/* Buttons */ +.btn-link { + cursor: pointer; + display: inline-flex; + align-items: center; + column-gap: 5px; + padding: 3px 10px; + border-radius: var(--border-radius-md); + border: 1px solid var(--border-color); + text-decoration: none; + color: var(--font-color); + font-size: var(--font-size-sm); + font-weight: 400; + &:hover { + text-decoration: none; + color: inherit; + border-color: var(--border-color-hover); + } +} + +.article-content { + & p, + em, + q { + line-height: 1.5; + font-size: var(--font-size-lg); + } + + q { + font-style: italic; + quotes: "«" "»"; + } + + h1, + h2, + h3, + h4 { + margin: 3rem 0 1rem 0; + padding-bottom: 0.35rem; + } + + h1:not(:first-child), + h2:not(:first-child), + h3:not(:first-child), + h4:not(:first-child) { + margin-top: 3rem; + } + + & h2 { + border-bottom: 1px solid var(--border-color); + } + + & a { + font-weight: 600; + } +} + a { color: var(--color-blue-500); font-weight: 500; @@ -139,6 +222,13 @@ p { margin-bottom: 1.5rem; } +hr { + background-color: var(--border-color); + margin: 40px 0; + border: none; + height: 1px; +} + h1, h2, h3, @@ -148,21 +238,32 @@ h5 { margin-bottom: 1.5rem; } -input { +input, textarea { + font-family: var(--font-family-base); padding: 8px 15px; border: 1px solid var(--border-color); border-radius: var(--border-radius-md); font-size: var(--font-size-sm); width: 100%; outline-color: var(--color-blue-500); + resize: vertical; } -svg { - fill: var(--color-black); -} - -@media screen and (max-width: 700px) { - .site-content { - margin-top: 1.5rem; +button { + cursor: pointer; + font-family: var(--font-family-base); + font-weight: 500; + font-size: var(--font-size-sm); + padding: 4px 15px; + border: 1px solid var(--border-color); + border-radius: var(--border-radius-md); + background: none; + &:hover { + border: 1px solid var(--border-color-hover); } } + +textarea { + max-height: 500px; + min-height: 200px; +} From 099f580a6f5cbd006466ff1ddd18514bed89e08e Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Fri, 15 Jul 2022 23:56:29 +0300 Subject: [PATCH 07/70] feat: html layout pages --- .gitignore | 2 + .idea/.gitignore | 5 + .idea/codeStyles/Project.xml | 58 ++++++++ .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + .idea/yarkov.tech.iml | 12 ++ README.md | 2 +- src/components/ArticleItem/ArticleItem.tsx | 2 +- src/components/ArticlesList/ArticlesList.scss | 9 -- src/components/ArticlesList/ArticlesList.tsx | 53 ++++--- src/pages/[article].astro | 140 ++++++++++++++++++ src/styles/global.scss | 46 +++++- src/utils/articles.ts | 10 +- tsconfig.json | 1 + 15 files changed, 313 insertions(+), 46 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/yarkov.tech.iml create mode 100644 src/pages/[article].astro diff --git a/.gitignore b/.gitignore index c31d27d..6ef6414 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ yarn-debug.log* yarn-error.log* pnpm-debug.log* +.idea + # environment variables .env diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..f986f2f --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..161a707 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/yarkov.tech.iml b/.idea/yarkov.tech.iml new file mode 100644 index 0000000..0c8867d --- /dev/null +++ b/.idea/yarkov.tech.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 08731e9..71378f6 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Personal website created with Astro. ### Todo -- [ ] HTML layout +- [x] HTML layout - [ ] Adaptive & Responsive layout - [ ] Dark/Light Theme - [ ] Multilang web-site diff --git a/src/components/ArticleItem/ArticleItem.tsx b/src/components/ArticleItem/ArticleItem.tsx index 5e62eff..99c3be3 100644 --- a/src/components/ArticleItem/ArticleItem.tsx +++ b/src/components/ArticleItem/ArticleItem.tsx @@ -1,6 +1,6 @@ import './ArticleItem.scss'; import { Component } from 'solid-js'; -import { IArticle } from '@root/interfaces'; +import type { IArticle } from '@root/interfaces'; import { DateFormatter } from '@utils/date'; export type ArticleItemProps = { diff --git a/src/components/ArticlesList/ArticlesList.scss b/src/components/ArticlesList/ArticlesList.scss index 8629351..f388180 100644 --- a/src/components/ArticlesList/ArticlesList.scss +++ b/src/components/ArticlesList/ArticlesList.scss @@ -24,15 +24,6 @@ } &-tags { margin-bottom: 45px; - & nav ul { - display: flex; - flex-wrap: wrap; - column-gap: 5px; - row-gap: 10px; - list-style: none; - margin: 0; - padding: 0; - } } &-list { &__wrapper { diff --git a/src/components/ArticlesList/ArticlesList.tsx b/src/components/ArticlesList/ArticlesList.tsx index 02cbfca..3d69f3a 100644 --- a/src/components/ArticlesList/ArticlesList.tsx +++ b/src/components/ArticlesList/ArticlesList.tsx @@ -1,9 +1,9 @@ -import './ArticlesList.scss'; -import { Component, createSignal, Show } from 'solid-js'; -import { PageHeading } from '@components/PageHeading'; -import { IArticle } from '@root/interfaces'; -import * as utils from '@root/utils/articles'; -import { ArticleItem } from '../ArticleItem'; +import "./ArticlesList.scss"; +import { Component, createSignal, Show } from "solid-js"; +import { PageHeading } from "@components/PageHeading"; +import type { IArticle } from "@root/interfaces"; +import * as utils from "@root/utils/articles"; +import { ArticleItem } from "../ArticleItem"; export type ArticlesListProps = { data: IArticle[]; @@ -11,42 +11,39 @@ export type ArticlesListProps = { }; export const ArticlesList: Component = ({ data, tags }) => { - const [articles, setArticles] = createSignal( - utils.filterArticlesByYear(data) - ); - + const [articles, setArticles] = createSignal(utils.filterArticlesByYear(data)); const [selectedTags, setSelectedTags] = createSignal([]); - const [filteredArticles, setFilteredArticles] = createSignal([]); return ( -
+
- diff --git a/src/layouts/article.astro b/src/layouts/article.astro index 4b34305..265b5a9 100644 --- a/src/layouts/article.astro +++ b/src/layouts/article.astro @@ -18,7 +18,10 @@ const { lang = 'ru', content } = Astro.props as Props; - + + + + diff --git a/src/pages/[article].astro b/src/pages/[article].astro index 28e79f8..4828f16 100644 --- a/src/pages/[article].astro +++ b/src/pages/[article].astro @@ -1,5 +1,4 @@ --- -import '@root/styles/prism-one-light.css'; import ArticleLayout from '@root/layouts/article.astro'; import { Markdown } from 'astro/components'; diff --git a/src/styles/global.scss b/src/styles/global.scss index 3b2e08b..18c6507 100644 --- a/src/styles/global.scss +++ b/src/styles/global.scss @@ -210,8 +210,8 @@ button { cursor: pointer; font-family: var(--font-family-base); font-weight: 500; - font-size: var(--font-size-sm); - padding: 4px 15px; + font-size: var(--font-size-md); + padding: 5px 17px; border: 1px solid var(--border-color); border-radius: var(--border-radius-md); background: none; diff --git a/src/styles/prism-one-dark.css b/src/styles/prism-one-dark.css deleted file mode 100644 index 94f23e3..0000000 --- a/src/styles/prism-one-dark.css +++ /dev/null @@ -1,440 +0,0 @@ -/** - * One Dark theme for prism.js - * Based on Atom's One Dark theme: https://github.com/atom/atom/tree/master/packages/one-dark-syntax - */ - -/** - * One Dark colours (accurate as of commit 8ae45ca on 6 Sep 2018) - * From colors.less - * --mono-1: hsl(220, 14%, 71%); - * --mono-2: hsl(220, 9%, 55%); - * --mono-3: hsl(220, 10%, 40%); - * --hue-1: hsl(187, 47%, 55%); - * --hue-2: hsl(207, 82%, 66%); - * --hue-3: hsl(286, 60%, 67%); - * --hue-4: hsl(95, 38%, 62%); - * --hue-5: hsl(355, 65%, 65%); - * --hue-5-2: hsl(5, 48%, 51%); - * --hue-6: hsl(29, 54%, 61%); - * --hue-6-2: hsl(39, 67%, 69%); - * --syntax-fg: hsl(220, 14%, 71%); - * --syntax-bg: hsl(220, 13%, 18%); - * --syntax-gutter: hsl(220, 14%, 45%); - * --syntax-guide: hsla(220, 14%, 71%, 0.15); - * --syntax-accent: hsl(220, 100%, 66%); - * From syntax-variables.less - * --syntax-selection-color: hsl(220, 13%, 28%); - * --syntax-gutter-background-color-selected: hsl(220, 13%, 26%); - * --syntax-cursor-line: hsla(220, 100%, 80%, 0.04); - */ - - code[class*="language-"], - pre[class*="language-"] { - background: hsl(220, 13%, 18%); - color: hsl(220, 14%, 71%); - text-shadow: 0 1px rgba(0, 0, 0, 0.3); - font-family: "Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace; - direction: ltr; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - line-height: 1.5; - -moz-tab-size: 2; - -o-tab-size: 2; - tab-size: 2; - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; - } - - /* Selection */ - code[class*="language-"]::-moz-selection, - code[class*="language-"] *::-moz-selection, - pre[class*="language-"] *::-moz-selection { - background: hsl(220, 13%, 28%); - color: inherit; - text-shadow: none; - } - - code[class*="language-"]::selection, - code[class*="language-"] *::selection, - pre[class*="language-"] *::selection { - background: hsl(220, 13%, 28%); - color: inherit; - text-shadow: none; - } - - /* Code blocks */ - pre[class*="language-"] { - padding: 1em; - margin: 0.5em 0; - overflow: auto; - border-radius: 0.3em; - } - - /* Inline code */ - :not(pre) > code[class*="language-"] { - padding: 0.2em 0.3em; - border-radius: 0.3em; - white-space: normal; - } - - /* Print */ - @media print { - code[class*="language-"], - pre[class*="language-"] { - text-shadow: none; - } - } - - .token.comment, - .token.prolog, - .token.cdata { - color: hsl(220, 10%, 40%); - } - - .token.doctype, - .token.punctuation, - .token.entity { - color: hsl(220, 14%, 71%); - } - - .token.attr-name, - .token.class-name, - .token.boolean, - .token.constant, - .token.number, - .token.atrule { - color: hsl(29, 54%, 61%); - } - - .token.keyword { - color: hsl(286, 60%, 67%); - } - - .token.property, - .token.tag, - .token.symbol, - .token.deleted, - .token.important { - color: hsl(355, 65%, 65%); - } - - .token.selector, - .token.string, - .token.char, - .token.builtin, - .token.inserted, - .token.regex, - .token.attr-value, - .token.attr-value > .token.punctuation { - color: hsl(95, 38%, 62%); - } - - .token.variable, - .token.operator, - .token.function { - color: hsl(207, 82%, 66%); - } - - .token.url { - color: hsl(187, 47%, 55%); - } - - /* HTML overrides */ - .token.attr-value > .token.punctuation.attr-equals, - .token.special-attr > .token.attr-value > .token.value.css { - color: hsl(220, 14%, 71%); - } - - /* CSS overrides */ - .language-css .token.selector { - color: hsl(355, 65%, 65%); - } - - .language-css .token.property { - color: hsl(220, 14%, 71%); - } - - .language-css .token.function, - .language-css .token.url > .token.function { - color: hsl(187, 47%, 55%); - } - - .language-css .token.url > .token.string.url { - color: hsl(95, 38%, 62%); - } - - .language-css .token.important, - .language-css .token.atrule .token.rule { - color: hsl(286, 60%, 67%); - } - - /* JS overrides */ - .language-javascript .token.operator { - color: hsl(286, 60%, 67%); - } - - .language-javascript .token.template-string > .token.interpolation > .token.interpolation-punctuation.punctuation { - color: hsl(5, 48%, 51%); - } - - /* JSON overrides */ - .language-json .token.operator { - color: hsl(220, 14%, 71%); - } - - .language-json .token.null.keyword { - color: hsl(29, 54%, 61%); - } - - /* MD overrides */ - .language-markdown .token.url, - .language-markdown .token.url > .token.operator, - .language-markdown .token.url-reference.url > .token.string { - color: hsl(220, 14%, 71%); - } - - .language-markdown .token.url > .token.content { - color: hsl(207, 82%, 66%); - } - - .language-markdown .token.url > .token.url, - .language-markdown .token.url-reference.url { - color: hsl(187, 47%, 55%); - } - - .language-markdown .token.blockquote.punctuation, - .language-markdown .token.hr.punctuation { - color: hsl(220, 10%, 40%); - font-style: italic; - } - - .language-markdown .token.code-snippet { - color: hsl(95, 38%, 62%); - } - - .language-markdown .token.bold .token.content { - color: hsl(29, 54%, 61%); - } - - .language-markdown .token.italic .token.content { - color: hsl(286, 60%, 67%); - } - - .language-markdown .token.strike .token.content, - .language-markdown .token.strike .token.punctuation, - .language-markdown .token.list.punctuation, - .language-markdown .token.title.important > .token.punctuation { - color: hsl(355, 65%, 65%); - } - - /* General */ - .token.bold { - font-weight: bold; - } - - .token.comment, - .token.italic { - font-style: italic; - } - - .token.entity { - cursor: help; - } - - .token.namespace { - opacity: 0.8; - } - - /* Plugin overrides */ - /* Selectors should have higher specificity than those in the plugins' default stylesheets */ - - /* Show Invisibles plugin overrides */ - .token.token.tab:not(:empty):before, - .token.token.cr:before, - .token.token.lf:before, - .token.token.space:before { - color: hsla(220, 14%, 71%, 0.15); - text-shadow: none; - } - - /* Toolbar plugin overrides */ - /* Space out all buttons and move them away from the right edge of the code block */ - div.code-toolbar > .toolbar.toolbar > .toolbar-item { - margin-right: 0.4em; - } - - /* Styling the buttons */ - div.code-toolbar > .toolbar.toolbar > .toolbar-item > button, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > a, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > span { - background: hsl(220, 13%, 26%); - color: hsl(220, 9%, 55%); - padding: 0.1em 0.4em; - border-radius: 0.3em; - } - - div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:focus, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus { - background: hsl(220, 13%, 28%); - color: hsl(220, 14%, 71%); - } - - /* Line Highlight plugin overrides */ - /* The highlighted line itself */ - .line-highlight.line-highlight { - background: hsla(220, 100%, 80%, 0.04); - } - - /* Default line numbers in Line Highlight plugin */ - .line-highlight.line-highlight:before, - .line-highlight.line-highlight[data-end]:after { - background: hsl(220, 13%, 26%); - color: hsl(220, 14%, 71%); - padding: 0.1em 0.6em; - border-radius: 0.3em; - box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.2); /* same as Toolbar plugin default */ - } - - /* Hovering over a linkable line number (in the gutter area) */ - /* Requires Line Numbers plugin as well */ - pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before { - background-color: hsla(220, 100%, 80%, 0.04); - } - - /* Line Numbers and Command Line plugins overrides */ - /* Line separating gutter from coding area */ - .line-numbers.line-numbers .line-numbers-rows, - .command-line .command-line-prompt { - border-right-color: hsla(220, 14%, 71%, 0.15); - } - - /* Stuff in the gutter */ - .line-numbers .line-numbers-rows > span:before, - .command-line .command-line-prompt > span:before { - color: hsl(220, 14%, 45%); - } - - /* Match Braces plugin overrides */ - /* Note: Outline colour is inherited from the braces */ - .rainbow-braces .token.token.punctuation.brace-level-1, - .rainbow-braces .token.token.punctuation.brace-level-5, - .rainbow-braces .token.token.punctuation.brace-level-9 { - color: hsl(355, 65%, 65%); - } - - .rainbow-braces .token.token.punctuation.brace-level-2, - .rainbow-braces .token.token.punctuation.brace-level-6, - .rainbow-braces .token.token.punctuation.brace-level-10 { - color: hsl(95, 38%, 62%); - } - - .rainbow-braces .token.token.punctuation.brace-level-3, - .rainbow-braces .token.token.punctuation.brace-level-7, - .rainbow-braces .token.token.punctuation.brace-level-11 { - color: hsl(207, 82%, 66%); - } - - .rainbow-braces .token.token.punctuation.brace-level-4, - .rainbow-braces .token.token.punctuation.brace-level-8, - .rainbow-braces .token.token.punctuation.brace-level-12 { - color: hsl(286, 60%, 67%); - } - - /* Diff Highlight plugin overrides */ - /* Taken from https://github.com/atom/github/blob/master/styles/variables.less */ - pre.diff-highlight > code .token.token.deleted:not(.prefix), - pre > code.diff-highlight .token.token.deleted:not(.prefix) { - background-color: hsla(353, 100%, 66%, 0.15); - } - - pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection, - pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection, - pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection, - pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection { - background-color: hsla(353, 95%, 66%, 0.25); - } - - pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection, - pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection, - pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection, - pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection { - background-color: hsla(353, 95%, 66%, 0.25); - } - - pre.diff-highlight > code .token.token.inserted:not(.prefix), - pre > code.diff-highlight .token.token.inserted:not(.prefix) { - background-color: hsla(137, 100%, 55%, 0.15); - } - - pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection, - pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection, - pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection, - pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection { - background-color: hsla(135, 73%, 55%, 0.25); - } - - pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection, - pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection, - pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection, - pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection { - background-color: hsla(135, 73%, 55%, 0.25); - } - - /* Previewers plugin overrides */ - /* Based on https://github.com/atom-community/atom-ide-datatip/blob/master/styles/atom-ide-datatips.less and https://github.com/atom/atom/blob/master/packages/one-dark-ui */ - /* Border around popup */ - .prism-previewer.prism-previewer:before, - .prism-previewer-gradient.prism-previewer-gradient div { - border-color: hsl(224, 13%, 17%); - } - - /* Angle and time should remain as circles and are hence not included */ - .prism-previewer-color.prism-previewer-color:before, - .prism-previewer-gradient.prism-previewer-gradient div, - .prism-previewer-easing.prism-previewer-easing:before { - border-radius: 0.3em; - } - - /* Triangles pointing to the code */ - .prism-previewer.prism-previewer:after { - border-top-color: hsl(224, 13%, 17%); - } - - .prism-previewer-flipped.prism-previewer-flipped.after { - border-bottom-color: hsl(224, 13%, 17%); - } - - /* Background colour within the popup */ - .prism-previewer-angle.prism-previewer-angle:before, - .prism-previewer-time.prism-previewer-time:before, - .prism-previewer-easing.prism-previewer-easing { - background: hsl(219, 13%, 22%); - } - - /* For angle, this is the positive area (eg. 90deg will display one quadrant in this colour) */ - /* For time, this is the alternate colour */ - .prism-previewer-angle.prism-previewer-angle circle, - .prism-previewer-time.prism-previewer-time circle { - stroke: hsl(220, 14%, 71%); - stroke-opacity: 1; - } - - /* Stroke colours of the handle, direction point, and vector itself */ - .prism-previewer-easing.prism-previewer-easing circle, - .prism-previewer-easing.prism-previewer-easing path, - .prism-previewer-easing.prism-previewer-easing line { - stroke: hsl(220, 14%, 71%); - } - - /* Fill colour of the handle */ - .prism-previewer-easing.prism-previewer-easing circle { - fill: transparent; - } \ No newline at end of file diff --git a/src/styles/prism-one-light.css b/src/styles/prism-one-light.css deleted file mode 100644 index 58f651d..0000000 --- a/src/styles/prism-one-light.css +++ /dev/null @@ -1,428 +0,0 @@ -/** - * One Light theme for prism.js - * Based on Atom's One Light theme: https://github.com/atom/atom/tree/master/packages/one-light-syntax - */ - -/** - * One Light colours (accurate as of commit eb064bf on 19 Feb 2021) - * From colors.less - * --mono-1: hsl(230, 8%, 24%); - * --mono-2: hsl(230, 6%, 44%); - * --mono-3: hsl(230, 4%, 64%) - * --hue-1: hsl(198, 99%, 37%); - * --hue-2: hsl(221, 87%, 60%); - * --hue-3: hsl(301, 63%, 40%); - * --hue-4: hsl(119, 34%, 47%); - * --hue-5: hsl(5, 74%, 59%); - * --hue-5-2: hsl(344, 84%, 43%); - * --hue-6: hsl(35, 99%, 36%); - * --hue-6-2: hsl(35, 99%, 40%); - * --syntax-fg: hsl(230, 8%, 24%); - * --syntax-bg: hsl(230, 1%, 98%); - * --syntax-gutter: hsl(230, 1%, 62%); - * --syntax-guide: hsla(230, 8%, 24%, 0.2); - * --syntax-accent: hsl(230, 100%, 66%); - * From syntax-variables.less - * --syntax-selection-color: hsl(230, 1%, 90%); - * --syntax-gutter-background-color-selected: hsl(230, 1%, 90%); - * --syntax-cursor-line: hsla(230, 8%, 24%, 0.05); - */ - - code[class*="language-"], - pre[class*="language-"] { - background: hsl(230, 1%, 98%); - color: hsl(230, 8%, 24%); - font-family: "Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace; - direction: ltr; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - line-height: 1.5; - -moz-tab-size: 2; - -o-tab-size: 2; - tab-size: 2; - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; - } - - /* Selection */ - code[class*="language-"]::-moz-selection, - code[class*="language-"] *::-moz-selection, - pre[class*="language-"] *::-moz-selection { - background: hsl(230, 1%, 90%); - color: inherit; - } - - code[class*="language-"]::selection, - code[class*="language-"] *::selection, - pre[class*="language-"] *::selection { - background: hsl(230, 1%, 90%); - color: inherit; - } - - /* Code blocks */ - pre[class*="language-"] { - padding: 1em; - margin: 0.5em 0; - overflow: auto; - border-radius: 0.3em; - } - - /* Inline code */ - :not(pre) > code[class*="language-"] { - padding: 0.2em 0.3em; - border-radius: 0.3em; - white-space: normal; - } - - .token.comment, - .token.prolog, - .token.cdata { - color: hsl(230, 4%, 64%); - } - - .token.doctype, - .token.punctuation, - .token.entity { - color: hsl(230, 8%, 24%); - } - - .token.attr-name, - .token.class-name, - .token.boolean, - .token.constant, - .token.number, - .token.atrule { - color: hsl(35, 99%, 36%); - } - - .token.keyword { - color: hsl(301, 63%, 40%); - } - - .token.property, - .token.tag, - .token.symbol, - .token.deleted, - .token.important { - color: hsl(5, 74%, 59%); - } - - .token.selector, - .token.string, - .token.char, - .token.builtin, - .token.inserted, - .token.regex, - .token.attr-value, - .token.attr-value > .token.punctuation { - color: hsl(119, 34%, 47%); - } - - .token.variable, - .token.operator, - .token.function { - color: hsl(221, 87%, 60%); - } - - .token.url { - color: hsl(198, 99%, 37%); - } - - /* HTML overrides */ - .token.attr-value > .token.punctuation.attr-equals, - .token.special-attr > .token.attr-value > .token.value.css { - color: hsl(230, 8%, 24%); - } - - /* CSS overrides */ - .language-css .token.selector { - color: hsl(5, 74%, 59%); - } - - .language-css .token.property { - color: hsl(230, 8%, 24%); - } - - .language-css .token.function, - .language-css .token.url > .token.function { - color: hsl(198, 99%, 37%); - } - - .language-css .token.url > .token.string.url { - color: hsl(119, 34%, 47%); - } - - .language-css .token.important, - .language-css .token.atrule .token.rule { - color: hsl(301, 63%, 40%); - } - - /* JS overrides */ - .language-javascript .token.operator { - color: hsl(301, 63%, 40%); - } - - .language-javascript .token.template-string > .token.interpolation > .token.interpolation-punctuation.punctuation { - color: hsl(344, 84%, 43%); - } - - /* JSON overrides */ - .language-json .token.operator { - color: hsl(230, 8%, 24%); - } - - .language-json .token.null.keyword { - color: hsl(35, 99%, 36%); - } - - /* MD overrides */ - .language-markdown .token.url, - .language-markdown .token.url > .token.operator, - .language-markdown .token.url-reference.url > .token.string { - color: hsl(230, 8%, 24%); - } - - .language-markdown .token.url > .token.content { - color: hsl(221, 87%, 60%); - } - - .language-markdown .token.url > .token.url, - .language-markdown .token.url-reference.url { - color: hsl(198, 99%, 37%); - } - - .language-markdown .token.blockquote.punctuation, - .language-markdown .token.hr.punctuation { - color: hsl(230, 4%, 64%); - font-style: italic; - } - - .language-markdown .token.code-snippet { - color: hsl(119, 34%, 47%); - } - - .language-markdown .token.bold .token.content { - color: hsl(35, 99%, 36%); - } - - .language-markdown .token.italic .token.content { - color: hsl(301, 63%, 40%); - } - - .language-markdown .token.strike .token.content, - .language-markdown .token.strike .token.punctuation, - .language-markdown .token.list.punctuation, - .language-markdown .token.title.important > .token.punctuation { - color: hsl(5, 74%, 59%); - } - - /* General */ - .token.bold { - font-weight: bold; - } - - .token.comment, - .token.italic { - font-style: italic; - } - - .token.entity { - cursor: help; - } - - .token.namespace { - opacity: 0.8; - } - - /* Plugin overrides */ - /* Selectors should have higher specificity than those in the plugins' default stylesheets */ - - /* Show Invisibles plugin overrides */ - .token.token.tab:not(:empty):before, - .token.token.cr:before, - .token.token.lf:before, - .token.token.space:before { - color: hsla(230, 8%, 24%, 0.2); - } - - /* Toolbar plugin overrides */ - /* Space out all buttons and move them away from the right edge of the code block */ - div.code-toolbar > .toolbar.toolbar > .toolbar-item { - margin-right: 0.4em; - } - - /* Styling the buttons */ - div.code-toolbar > .toolbar.toolbar > .toolbar-item > button, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > a, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > span { - background: hsl(230, 1%, 90%); - color: hsl(230, 6%, 44%); - padding: 0.1em 0.4em; - border-radius: 0.3em; - } - - div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:focus, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover, - div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus { - background: hsl(230, 1%, 78%); /* custom: darken(--syntax-bg, 20%) */ - color: hsl(230, 8%, 24%); - } - - /* Line Highlight plugin overrides */ - /* The highlighted line itself */ - .line-highlight.line-highlight { - background: hsla(230, 8%, 24%, 0.05); - } - - /* Default line numbers in Line Highlight plugin */ - .line-highlight.line-highlight:before, - .line-highlight.line-highlight[data-end]:after { - background: hsl(230, 1%, 90%); - color: hsl(230, 8%, 24%); - padding: 0.1em 0.6em; - border-radius: 0.3em; - box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.2); /* same as Toolbar plugin default */ - } - - /* Hovering over a linkable line number (in the gutter area) */ - /* Requires Line Numbers plugin as well */ - pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before { - background-color: hsla(230, 8%, 24%, 0.05); - } - - /* Line Numbers and Command Line plugins overrides */ - /* Line separating gutter from coding area */ - .line-numbers.line-numbers .line-numbers-rows, - .command-line .command-line-prompt { - border-right-color: hsla(230, 8%, 24%, 0.2); - } - - /* Stuff in the gutter */ - .line-numbers .line-numbers-rows > span:before, - .command-line .command-line-prompt > span:before { - color: hsl(230, 1%, 62%); - } - - /* Match Braces plugin overrides */ - /* Note: Outline colour is inherited from the braces */ - .rainbow-braces .token.token.punctuation.brace-level-1, - .rainbow-braces .token.token.punctuation.brace-level-5, - .rainbow-braces .token.token.punctuation.brace-level-9 { - color: hsl(5, 74%, 59%); - } - - .rainbow-braces .token.token.punctuation.brace-level-2, - .rainbow-braces .token.token.punctuation.brace-level-6, - .rainbow-braces .token.token.punctuation.brace-level-10 { - color: hsl(119, 34%, 47%); - } - - .rainbow-braces .token.token.punctuation.brace-level-3, - .rainbow-braces .token.token.punctuation.brace-level-7, - .rainbow-braces .token.token.punctuation.brace-level-11 { - color: hsl(221, 87%, 60%); - } - - .rainbow-braces .token.token.punctuation.brace-level-4, - .rainbow-braces .token.token.punctuation.brace-level-8, - .rainbow-braces .token.token.punctuation.brace-level-12 { - color: hsl(301, 63%, 40%); - } - - /* Diff Highlight plugin overrides */ - /* Taken from https://github.com/atom/github/blob/master/styles/variables.less */ - pre.diff-highlight > code .token.token.deleted:not(.prefix), - pre > code.diff-highlight .token.token.deleted:not(.prefix) { - background-color: hsla(353, 100%, 66%, 0.15); - } - - pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection, - pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection, - pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection, - pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection { - background-color: hsla(353, 95%, 66%, 0.25); - } - - pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection, - pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection, - pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection, - pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection { - background-color: hsla(353, 95%, 66%, 0.25); - } - - pre.diff-highlight > code .token.token.inserted:not(.prefix), - pre > code.diff-highlight .token.token.inserted:not(.prefix) { - background-color: hsla(137, 100%, 55%, 0.15); - } - - pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection, - pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection, - pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection, - pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection { - background-color: hsla(135, 73%, 55%, 0.25); - } - - pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection, - pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection, - pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection, - pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection { - background-color: hsla(135, 73%, 55%, 0.25); - } - - /* Previewers plugin overrides */ - /* Based on https://github.com/atom-community/atom-ide-datatip/blob/master/styles/atom-ide-datatips.less and https://github.com/atom/atom/blob/master/packages/one-light-ui */ - /* Border around popup */ - .prism-previewer.prism-previewer:before, - .prism-previewer-gradient.prism-previewer-gradient div { - border-color: hsl(0, 0, 95%); - } - - /* Angle and time should remain as circles and are hence not included */ - .prism-previewer-color.prism-previewer-color:before, - .prism-previewer-gradient.prism-previewer-gradient div, - .prism-previewer-easing.prism-previewer-easing:before { - border-radius: 0.3em; - } - - /* Triangles pointing to the code */ - .prism-previewer.prism-previewer:after { - border-top-color: hsl(0, 0, 95%); - } - - .prism-previewer-flipped.prism-previewer-flipped.after { - border-bottom-color: hsl(0, 0, 95%); - } - - /* Background colour within the popup */ - .prism-previewer-angle.prism-previewer-angle:before, - .prism-previewer-time.prism-previewer-time:before, - .prism-previewer-easing.prism-previewer-easing { - background: hsl(0, 0%, 100%); - } - - /* For angle, this is the positive area (eg. 90deg will display one quadrant in this colour) */ - /* For time, this is the alternate colour */ - .prism-previewer-angle.prism-previewer-angle circle, - .prism-previewer-time.prism-previewer-time circle { - stroke: hsl(230, 8%, 24%); - stroke-opacity: 1; - } - - /* Stroke colours of the handle, direction point, and vector itself */ - .prism-previewer-easing.prism-previewer-easing circle, - .prism-previewer-easing.prism-previewer-easing path, - .prism-previewer-easing.prism-previewer-easing line { - stroke: hsl(230, 8%, 24%); - } - - /* Fill colour of the handle */ - .prism-previewer-easing.prism-previewer-easing circle { - fill: transparent; - } \ No newline at end of file From 5f76f318db5bc7bd47c9eba4658fe6d330e35fe9 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Tue, 26 Jul 2022 01:01:56 +0300 Subject: [PATCH 23/70] invert color svg icons --- public/assets/dark.css | 10 ++ public/assets/light.css | 4 + src/components/ContactsList/ContactsList.scss | 4 + src/components/Header/Header.scss | 96 +++++++++---------- .../Header/NavToggle/NavToggle.scss | 14 ++- src/components/Header/NavToggle/NavToggle.tsx | 23 ++++- src/components/SearchInput/SearchInput.scss | 2 + src/icons/email.svg | 2 +- src/icons/socket-io.svg | 8 +- src/styles/global.scss | 4 +- 10 files changed, 105 insertions(+), 62 deletions(-) diff --git a/public/assets/dark.css b/public/assets/dark.css index a4b81bd..b6ec3e2 100644 --- a/public/assets/dark.css +++ b/public/assets/dark.css @@ -16,4 +16,14 @@ --background-btn-link: var(--color-gray-800); --background-btn-link-active: var(--color-gray-700); --background-inputs-color: var(--color-gray-800); + + /* Icons */ + --icon-primary: var(--color-white); + --icon-secondary: var(--color-gray-100); + --icon-filter: invert(100%); +} + +.header svg, +.site-content svg { + filter: var(--icon-filter); } diff --git a/public/assets/light.css b/public/assets/light.css index 7e40887..1daf165 100644 --- a/public/assets/light.css +++ b/public/assets/light.css @@ -16,4 +16,8 @@ --background-btn-link: var(--color-white); --background-btn-link-active: var(--color-white); --background-inputs-color: var(--color-white); + + /* Icons */ + --icon-primary: var(--color-white); + --icon-secondary: var(--color-gray-700); } diff --git a/src/components/ContactsList/ContactsList.scss b/src/components/ContactsList/ContactsList.scss index 9619d4a..feec5f3 100644 --- a/src/components/ContactsList/ContactsList.scss +++ b/src/components/ContactsList/ContactsList.scss @@ -8,4 +8,8 @@ display: flex; column-gap: 5px; } + + & svg { + filter: none; + } } diff --git a/src/components/Header/Header.scss b/src/components/Header/Header.scss index 40bbdf9..b3e246e 100644 --- a/src/components/Header/Header.scss +++ b/src/components/Header/Header.scss @@ -65,55 +65,51 @@ } } &__button { - cursor: pointer; - width: 30px; - height: 21px; - position: relative; - transform: rotate(0deg); - background: none; - border: none; - &:hover { - border: none; - opacity: var(--opacity-hover); - } - & span { - pointer-events: none; - display: block; - position: absolute; - height: 3px; - width: 100%; - background: var(--font-color); - border-radius: 7px; - opacity: 1; - left: 0; - } - & span:nth-child(1) { - top: 2px; - transform-origin: left center; - } - & span:nth-child(2) { - top: 9px; - transform-origin: left center; - } - & span:nth-child(3) { - top: 16px; - transform-origin: left center; - } - &[aria-pressed='true'] { - & span:nth-child(1) { - transform: rotate(45deg); - top: -1px; - left: 5px; - } - & span:nth-child(2) { - display: none; - } - & span:nth-child(3) { - transform: rotate(-45deg); - top: 20px; - left: 5px; - } - } + // cursor: pointer; + // background: none; + // border: none; + // &:hover { + // border: none; + // opacity: var(--opacity-hover); + // } + // & span { + // pointer-events: none; + // display: block; + // position: absolute; + // height: 3px; + // width: 100%; + // background: var(--font-color); + // border-radius: 7px; + // opacity: 1; + // left: 0; + // } + // & span:nth-child(1) { + // top: 2px; + // transform-origin: left center; + // } + // & span:nth-child(2) { + // top: 9px; + // transform-origin: left center; + // } + // & span:nth-child(3) { + // top: 16px; + // transform-origin: left center; + // } + // &[aria-pressed='true'] { + // & span:nth-child(1) { + // transform: rotate(45deg); + // top: -1px; + // left: 5px; + // } + // & span:nth-child(2) { + // display: none; + // } + // & span:nth-child(3) { + // transform: rotate(-45deg); + // top: 20px; + // left: 5px; + // } + // } } } @@ -160,7 +156,7 @@ justify-content: center; } } - &__button { + & .nav-toggle { position: absolute; right: var(--content-padding); } diff --git a/src/components/Header/NavToggle/NavToggle.scss b/src/components/Header/NavToggle/NavToggle.scss index a708442..7ca42f4 100644 --- a/src/components/Header/NavToggle/NavToggle.scss +++ b/src/components/Header/NavToggle/NavToggle.scss @@ -1,5 +1,17 @@ +.nav-toggle { + display: flex; + padding: 0; + cursor: pointer; + // background: none; + border: none; + &:hover { + border: none; + opacity: var(--opacity-hover); + } +} + @media screen and (min-width: 769px) { - #nav-toggle { + .nav-toggle { display: none; } } diff --git a/src/components/Header/NavToggle/NavToggle.tsx b/src/components/Header/NavToggle/NavToggle.tsx index e858b7f..e8ca43a 100644 --- a/src/components/Header/NavToggle/NavToggle.tsx +++ b/src/components/Header/NavToggle/NavToggle.tsx @@ -3,6 +3,23 @@ import type { Component } from 'solid-js'; import { createSignal, createEffect } from 'solid-js'; import './NavToggle.scss'; +const MenuIcon: Component = () => ( + + + +); + +const CloseIcon: Component = () => ( + + + +); + const NavToggle: Component = () => { const [isNavShown, setIsNavShown] = createSignal(false); @@ -20,10 +37,8 @@ const NavToggle: Component = () => { }); return ( - ); }; diff --git a/src/components/SearchInput/SearchInput.scss b/src/components/SearchInput/SearchInput.scss index 1ba730e..a6ffffa 100644 --- a/src/components/SearchInput/SearchInput.scss +++ b/src/components/SearchInput/SearchInput.scss @@ -9,7 +9,9 @@ position: absolute; left: 8px; fill: var(--font-color-grayer); + filter: none; } + & input { padding-left: 40px; color: var(--font-color-gray); diff --git a/src/icons/email.svg b/src/icons/email.svg index 0983d16..7b38190 100644 --- a/src/icons/email.svg +++ b/src/icons/email.svg @@ -1,6 +1,6 @@ - + diff --git a/src/icons/socket-io.svg b/src/icons/socket-io.svg index 6d13e60..b68bfc4 100644 --- a/src/icons/socket-io.svg +++ b/src/icons/socket-io.svg @@ -1,11 +1,9 @@ - - - - + + - + diff --git a/src/styles/global.scss b/src/styles/global.scss index 18c6507..b6d7302 100644 --- a/src/styles/global.scss +++ b/src/styles/global.scss @@ -211,10 +211,12 @@ button { font-family: var(--font-family-base); font-weight: 500; font-size: var(--font-size-md); - padding: 5px 17px; + color: var(--font-color); + padding: 4px 16px; border: 1px solid var(--border-color); border-radius: var(--border-radius-md); background: none; + font-size: var(--font-size-sm); &:hover { border: 1px solid var(--border-color-hover); } From 75fa8117f66429a5c0640d58922f4898a11d35cf Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Wed, 27 Jul 2022 22:38:43 +0300 Subject: [PATCH 24/70] theme toggling --- package.json | 2 +- public/assets/dark.css | 29 ---- public/assets/light.css | 23 --- src/components/ArticleItem/ArticleItem.tsx | 4 +- src/components/ArticlePost/ArticlePost.astro | 2 - src/components/ArticlesList/ArticlesList.tsx | 1 - src/components/BaseHead.astro | 8 +- .../ContactsList/ContactsList.astro | 6 +- src/components/Header/Header.astro | 2 +- src/components/Header/Header.scss | 50 +------ .../Header/NavToggle/NavToggle.scss | 4 +- src/components/Header/NavToggle/NavToggle.tsx | 13 +- src/components/ProjectItem/ProjectItem.astro | 2 - .../RecentArticles/RecentArticles.astro | 2 - src/components/SearchInput/SearchInput.scss | 2 +- src/components/SearchInput/SearchInput.tsx | 2 +- src/components/SkillsBlock/SkillsBlock.astro | 2 - .../ThemeSwticher/ThemeSwitcher.astro | 8 - .../ThemeSwticher/ThemeSwitcher.scss | 5 + .../ThemeSwticher/ThemeSwitcher.tsx | 62 ++++++++ src/components/ThemeSwticher/index.ts | 2 +- src/config.ts | 4 + src/layouts/article.astro | 1 - src/layouts/default.astro | 2 +- src/pages/articles.astro | 2 - src/pages/index.astro | 2 - src/scripts/detect-theme.astro | 20 +++ src/scripts/index.ts | 1 + src/styles/global.scss | 101 +------------ src/styles/theme.scss | 140 ++++++++++++++++++ src/types/index.ts | 25 ---- src/types/main.d.ts | 39 +++++ src/utils/articles.ts | 2 - tsconfig.json | 3 +- 34 files changed, 304 insertions(+), 269 deletions(-) delete mode 100644 public/assets/dark.css delete mode 100644 public/assets/light.css delete mode 100644 src/components/ThemeSwticher/ThemeSwitcher.astro create mode 100644 src/components/ThemeSwticher/ThemeSwitcher.tsx create mode 100644 src/scripts/detect-theme.astro create mode 100644 src/scripts/index.ts create mode 100644 src/styles/theme.scss delete mode 100644 src/types/index.ts create mode 100644 src/types/main.d.ts diff --git a/package.json b/package.json index fcaa6d9..d6d80cf 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "scripts": { "dev": "astro dev --host", "start": "astro dev", - "build": "astro build", + "build": "astro check && tsc --noEmit && astro build", "preview": "astro preview --host", "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json}\"", "lint": "eslint '**/*.{js,mjs,ts,tsx}'" diff --git a/public/assets/dark.css b/public/assets/dark.css deleted file mode 100644 index b6ec3e2..0000000 --- a/public/assets/dark.css +++ /dev/null @@ -1,29 +0,0 @@ -:root { - /* Fonts */ - --font-color: var(--color-white); - --font-color-gray: var(--color-gray-100); - --font-color-grayer: var(--color-gray-200); - - /* Border */ - --border-color: var(--color-gray-700); - --border-color-hover: var(--color-gray-600); - - /* Elements */ - --background-body-color: var(--color-gray-900); - --background-header-color: var(--color-gray-900); - --background-inline-code: var(--color-gray-800); - --background-color-hover: var(--color-gray-800); - --background-btn-link: var(--color-gray-800); - --background-btn-link-active: var(--color-gray-700); - --background-inputs-color: var(--color-gray-800); - - /* Icons */ - --icon-primary: var(--color-white); - --icon-secondary: var(--color-gray-100); - --icon-filter: invert(100%); -} - -.header svg, -.site-content svg { - filter: var(--icon-filter); -} diff --git a/public/assets/light.css b/public/assets/light.css deleted file mode 100644 index 1daf165..0000000 --- a/public/assets/light.css +++ /dev/null @@ -1,23 +0,0 @@ -:root { - /* Fonts */ - --font-color: var(--color-black); - --font-color-gray: var(--color-gray-500); - --font-color-grayer: var(--color-gray-700); - - /* Border */ - --border-color: var(--color-gray-100); - --border-color-hover: var(--color-gray-400); - - /* Elements */ - --background-body-color: var(--color-white); - --background-header-color: var(--color-white); - --background-inline-code: rgba(0, 0, 0, 0.05); - --background-color-hover: var(--color-gray-50); - --background-btn-link: var(--color-white); - --background-btn-link-active: var(--color-white); - --background-inputs-color: var(--color-white); - - /* Icons */ - --icon-primary: var(--color-white); - --icon-secondary: var(--color-gray-700); -} diff --git a/src/components/ArticleItem/ArticleItem.tsx b/src/components/ArticleItem/ArticleItem.tsx index b23fe7c..7dd8672 100644 --- a/src/components/ArticleItem/ArticleItem.tsx +++ b/src/components/ArticleItem/ArticleItem.tsx @@ -1,8 +1,6 @@ -import type { ArticleType } from '@root/types'; - -import './ArticleItem.scss'; import { Component } from 'solid-js'; import { DateFormatter } from '@utils/date'; +import './ArticleItem.scss'; export type ArticleItemProps = { data: ArticleType; diff --git a/src/components/ArticlePost/ArticlePost.astro b/src/components/ArticlePost/ArticlePost.astro index 282e96f..9afa411 100644 --- a/src/components/ArticlePost/ArticlePost.astro +++ b/src/components/ArticlePost/ArticlePost.astro @@ -1,6 +1,4 @@ --- -import type { ArticleType } from '@root/types'; - import { DateFormatter } from '@root/utils'; import './ArticlePost.scss'; diff --git a/src/components/ArticlesList/ArticlesList.tsx b/src/components/ArticlesList/ArticlesList.tsx index f12f06e..9f5723f 100644 --- a/src/components/ArticlesList/ArticlesList.tsx +++ b/src/components/ArticlesList/ArticlesList.tsx @@ -1,5 +1,4 @@ import type { Component } from 'solid-js'; -import type { ArticleBlockType } from '@root/types'; import { createSignal, createEffect, For } from 'solid-js'; import { search, selectedTags } from '@stores/searchStore'; diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro index a24784c..f6609a8 100644 --- a/src/components/BaseHead.astro +++ b/src/components/BaseHead.astro @@ -1,5 +1,6 @@ --- import { SITE_METADATA } from '@root/config'; +import { DetectThemeScript } from '@root/scripts'; export interface Props { title?: string | undefined; @@ -12,8 +13,8 @@ const { title = SITE_METADATA.title, description } = Astro.props as Props; - - + + @@ -22,4 +23,7 @@ const { title = SITE_METADATA.title, description } = Astro.props as Props; + + + diff --git a/src/components/ContactsList/ContactsList.astro b/src/components/ContactsList/ContactsList.astro index 08374b5..3ab3f95 100644 --- a/src/components/ContactsList/ContactsList.astro +++ b/src/components/ContactsList/ContactsList.astro @@ -11,14 +11,14 @@ const { diff --git a/src/components/Header/Header.astro b/src/components/Header/Header.astro index fdf366e..1426d4a 100644 --- a/src/components/Header/Header.astro +++ b/src/components/Header/Header.astro @@ -38,7 +38,7 @@ const { pathname } = Astro.canonicalURL; - + diff --git a/src/components/Header/Header.scss b/src/components/Header/Header.scss index b3e246e..e890755 100644 --- a/src/components/Header/Header.scss +++ b/src/components/Header/Header.scss @@ -7,7 +7,6 @@ padding-bottom: 15px; user-select: none; z-index: 9999; - & .container { display: flex; align-items: center; @@ -64,57 +63,11 @@ } } } - &__button { - // cursor: pointer; - // background: none; - // border: none; - // &:hover { - // border: none; - // opacity: var(--opacity-hover); - // } - // & span { - // pointer-events: none; - // display: block; - // position: absolute; - // height: 3px; - // width: 100%; - // background: var(--font-color); - // border-radius: 7px; - // opacity: 1; - // left: 0; - // } - // & span:nth-child(1) { - // top: 2px; - // transform-origin: left center; - // } - // & span:nth-child(2) { - // top: 9px; - // transform-origin: left center; - // } - // & span:nth-child(3) { - // top: 16px; - // transform-origin: left center; - // } - // &[aria-pressed='true'] { - // & span:nth-child(1) { - // transform: rotate(45deg); - // top: -1px; - // left: 5px; - // } - // & span:nth-child(2) { - // display: none; - // } - // & span:nth-child(3) { - // transform: rotate(-45deg); - // top: 20px; - // left: 5px; - // } - // } - } } @media screen and (max-width: 768px) { .header { + padding: 10px 0; &__nav { display: none; } @@ -122,6 +75,7 @@ body[data-is-mobile-open='true'] { & .header { + padding: 15px 0; background-color: var(--background-header-color); position: fixed; right: 0; diff --git a/src/components/Header/NavToggle/NavToggle.scss b/src/components/Header/NavToggle/NavToggle.scss index 7ca42f4..9db71a9 100644 --- a/src/components/Header/NavToggle/NavToggle.scss +++ b/src/components/Header/NavToggle/NavToggle.scss @@ -1,9 +1,7 @@ .nav-toggle { - display: flex; - padding: 0; cursor: pointer; - // background: none; border: none; + padding: 0; &:hover { border: none; opacity: var(--opacity-hover); diff --git a/src/components/Header/NavToggle/NavToggle.tsx b/src/components/Header/NavToggle/NavToggle.tsx index e8ca43a..8af7531 100644 --- a/src/components/Header/NavToggle/NavToggle.tsx +++ b/src/components/Header/NavToggle/NavToggle.tsx @@ -4,19 +4,14 @@ import { createSignal, createEffect } from 'solid-js'; import './NavToggle.scss'; const MenuIcon: Component = () => ( - - + + ); const CloseIcon: Component = () => ( - - + + ); diff --git a/src/components/ProjectItem/ProjectItem.astro b/src/components/ProjectItem/ProjectItem.astro index a225f63..8c5bf74 100644 --- a/src/components/ProjectItem/ProjectItem.astro +++ b/src/components/ProjectItem/ProjectItem.astro @@ -1,6 +1,4 @@ --- -import type { ProjectType } from '@root/types'; - import './ProjectItem.scss'; import { Icon } from 'astro-icon'; diff --git a/src/components/RecentArticles/RecentArticles.astro b/src/components/RecentArticles/RecentArticles.astro index f495d37..8b5b7bc 100644 --- a/src/components/RecentArticles/RecentArticles.astro +++ b/src/components/RecentArticles/RecentArticles.astro @@ -1,6 +1,4 @@ --- -import type { ArticleType } from '@root/types'; - import './RecentArticles.scss'; import { ArticleItem } from '@components/ArticleItem'; import { sortArtcilesByDate } from '@utils/articles'; diff --git a/src/components/SearchInput/SearchInput.scss b/src/components/SearchInput/SearchInput.scss index a6ffffa..22fac36 100644 --- a/src/components/SearchInput/SearchInput.scss +++ b/src/components/SearchInput/SearchInput.scss @@ -20,7 +20,7 @@ & span { font-size: var(--font-size-lg); font-weight: 500; - color: var(--font-color-grayer); + color: var(--font-color-gray); min-width: 20px; text-align: center; } diff --git a/src/components/SearchInput/SearchInput.tsx b/src/components/SearchInput/SearchInput.tsx index d9ef696..9d0a8ad 100644 --- a/src/components/SearchInput/SearchInput.tsx +++ b/src/components/SearchInput/SearchInput.tsx @@ -54,7 +54,7 @@ const SearchInput: Component = (props) => { return (
- + diff --git a/src/components/SkillsBlock/SkillsBlock.astro b/src/components/SkillsBlock/SkillsBlock.astro index 7e91dec..66db2a3 100644 --- a/src/components/SkillsBlock/SkillsBlock.astro +++ b/src/components/SkillsBlock/SkillsBlock.astro @@ -1,6 +1,4 @@ --- -import type { SkillsType } from '@root/types'; - import { Icon } from 'astro-icon'; import './SkillsBlock.scss'; diff --git a/src/components/ThemeSwticher/ThemeSwitcher.astro b/src/components/ThemeSwticher/ThemeSwitcher.astro deleted file mode 100644 index 915d7c0..0000000 --- a/src/components/ThemeSwticher/ThemeSwitcher.astro +++ /dev/null @@ -1,8 +0,0 @@ ---- -import './ThemeSwitcher.scss'; -import { Icon } from 'astro-icon'; ---- - - diff --git a/src/components/ThemeSwticher/ThemeSwitcher.scss b/src/components/ThemeSwticher/ThemeSwitcher.scss index 2838418..7d7d4fa 100644 --- a/src/components/ThemeSwticher/ThemeSwitcher.scss +++ b/src/components/ThemeSwticher/ThemeSwitcher.scss @@ -6,8 +6,13 @@ cursor: pointer; padding: 0; margin: 0; + opacity: 0; &:hover { opacity: var(--opacity-hover); border: none; } + &.ready { + opacity: 1; + transition: all 0.1s linear 0s; + } } diff --git a/src/components/ThemeSwticher/ThemeSwitcher.tsx b/src/components/ThemeSwticher/ThemeSwitcher.tsx new file mode 100644 index 0000000..120fc20 --- /dev/null +++ b/src/components/ThemeSwticher/ThemeSwitcher.tsx @@ -0,0 +1,62 @@ +import type { Component, JSX } from 'solid-js'; + +import { SITE_SETTINGS } from '@root/config'; +import { createSignal, onMount, Switch, Match } from 'solid-js'; +import './ThemeSwitcher.scss'; + +const MoonIcon: Component = () => ( + + + +); + +const SunIcon: Component = () => ( + + + +); + +const ThemeSwitcher: Component = () => { + const [theme, setTheme] = createSignal(SITE_SETTINGS.defaultTheme); + const [isReady, setIsReady] = createSignal(false); + + const toggleTheme: JSX.EventHandler = (e) => { + const newTheme = theme() === 'light' ? 'dark' : 'light'; + setTheme(newTheme); + localStorage.setItem('theme', newTheme); + document.documentElement.setAttribute('data-theme', newTheme); + }; + + onMount(() => { + setIsReady(true); + if (window.theme) { + setTheme(window.theme); + /* Update theme state on changing OS the,e */ + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ({ matches: isDark }) => { + const theme = isDark ? 'dark' : 'light'; + setTheme(theme); + }); + } + }); + + return ( + + ); +}; + +export default ThemeSwitcher; diff --git a/src/components/ThemeSwticher/index.ts b/src/components/ThemeSwticher/index.ts index 50e6b3d..9b6b9ee 100644 --- a/src/components/ThemeSwticher/index.ts +++ b/src/components/ThemeSwticher/index.ts @@ -1 +1 @@ -export { default } from './ThemeSwitcher.astro'; +export { default } from './ThemeSwitcher'; diff --git a/src/config.ts b/src/config.ts index 4e46ed2..ad1320f 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,3 +1,7 @@ +export const SITE_SETTINGS: SiteConfigType = { + defaultTheme: 'dark', +}; + export const SITE_METADATA = { title: 'Sergey Yarkov', name: 'yarkov.tech', diff --git a/src/layouts/article.astro b/src/layouts/article.astro index 265b5a9..8306dce 100644 --- a/src/layouts/article.astro +++ b/src/layouts/article.astro @@ -1,6 +1,5 @@ --- import type { Props as BaseHeadProps } from '@root/components/BaseHead.astro'; -import type { ArticleType } from '@root/types'; import BaseHead from '@components/BaseHead.astro'; import BaseLayout from '@components/BaseLayout'; diff --git a/src/layouts/default.astro b/src/layouts/default.astro index 44ed720..304a553 100644 --- a/src/layouts/default.astro +++ b/src/layouts/default.astro @@ -1,9 +1,9 @@ --- import type { Props as BaseHeadProps } from '@components/BaseHead.astro'; +import { SITE_METADATA } from '@root/config'; import BaseHead from '@components/BaseHead.astro'; import BaseLayout from '@components/BaseLayout'; -import { SITE_METADATA } from '@root/config'; import PageHeading from '@components/PageHeading'; import '@styles/global.scss'; diff --git a/src/pages/articles.astro b/src/pages/articles.astro index 8735f7d..8f2974e 100644 --- a/src/pages/articles.astro +++ b/src/pages/articles.astro @@ -1,6 +1,4 @@ --- -import type { ArticleType } from '@root/types'; - import PageLayout from '@layouts/default.astro'; import ArticlesList from '@components/ArticlesList'; import { transformArticles, formatToArticleBlocks } from '@utils/articles'; diff --git a/src/pages/index.astro b/src/pages/index.astro index 9b474d6..df9c19a 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,6 +1,4 @@ --- -import type { ArticleType } from '@root/types'; - import * as utils from '@utils/index'; import PageLayout from '@layouts/default.astro'; import RecentArticles from '@components/RecentArticles'; diff --git a/src/scripts/detect-theme.astro b/src/scripts/detect-theme.astro new file mode 100644 index 0000000..dddb31e --- /dev/null +++ b/src/scripts/detect-theme.astro @@ -0,0 +1,20 @@ + diff --git a/src/scripts/index.ts b/src/scripts/index.ts new file mode 100644 index 0000000..008a7dc --- /dev/null +++ b/src/scripts/index.ts @@ -0,0 +1 @@ +export { default as DetectThemeScript } from './detect-theme.astro'; diff --git a/src/styles/global.scss b/src/styles/global.scss index b6d7302..6bad530 100644 --- a/src/styles/global.scss +++ b/src/styles/global.scss @@ -1,91 +1,4 @@ -:root { - color-scheme: light dark; - - /* Fonts */ - --font-fallback: -apple-system, BlinkMacSystemFont, Segoe UI, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji; - --font-family-base: 'Rubik', var(--font-fallback); - --font-size-xs: 0.75rem; - --font-size-sm: 0.875rem; - --font-size-md: 1rem; - --font-size-lg: 1.125rem; - --font-size-xl: 1.25rem; - --font-size-2xl: 1.5rem; - --font-size-3xl: 1.875rem; - --font-size-4xl: 2.25rem; - --font-size-5xl: 3rem; - --font-size-6xl: 3.75rem; - --font-size-7xl: 4.5rem; - --font-size-8xl: 6rem; - --font-size-9xl: 8rem; - - /* Line heights */ - --line-height-normal: 'normal'; - --line-height-none: 1; - --line-height-shorter: 1.25; - --line-height-short: 1.375; - --line-height-base: 1.5; - --line-height-tall: 1.625; - - /* Colors */ - --color-white: #ffffff; - --color-black: #010409; - - --color-blue-50: #cae8ff; - --color-blue-100: #a5d6ff; - --color-blue-200: #79c0ff; - --color-blue-300: #58a6ff; - --color-blue-400: #388bfd; - --color-blue-500: #1f6feb; - --color-blue-600: #1158c7; - --color-blue-700: #0d419d; - --color-blue-800: #0c2d6b; - --color-blue-900: #051d4d; - - --color-gray-50: #f0f6fc; - --color-gray-100: #c9d1d9; - --color-gray-200: #b1bac4; - --color-gray-300: #8b949e; - --color-gray-400: #6e7681; - --color-gray-500: #484f58; - --color-gray-600: #30363d; - --color-gray-700: #21262d; - --color-gray-800: #161b22; - --color-gray-900: #0d1117; - - --color-orange-50: #ffdfb6; - --color-orange-100: #ffc680; - --color-orange-200: #ffa657; - --color-orange-300: #f0883e; - --color-orange-400: #db6d28; - --color-orange-500: #bd561d; - --color-orange-600: #9b4215; - --color-orange-700: #762d0a; - --color-orange-800: #5a1e02; - --color-orange-900: #3d1300; - - --color-yellow-50: #f8e3a1; - --color-yellow-100: #f2cc60; - --color-yellow-200: #e3b341; - --color-yellow-300: #d29922; - --color-yellow-400: #bb8009; - --color-yellow-500: #9e6a03; - --color-yellow-600: #845306; - --color-yellow-700: #693e00; - --color-yellow-800: #4b2900; - --color-yellow-900: #341a00; - - /* Border */ - --border-radius-md: 3px; - --border-radius-lg: 5px; - - /* Sizes */ - --content-width: 760px; - --content-padding: 24px; - - --outline-color: var(--color-blue-500); - - --opacity-hover: 0.7; -} +@import './theme.scss'; ::selection { background: var(--color-yellow-100); @@ -115,13 +28,14 @@ html { font-weight: normal; font-kerning: normal; font-family: var(--font-family-base); + background: var(--background-body-color); } body { margin: 0; padding: 0; color: var(--font-color); - background-color: var(--background-body-color); + background: var(--background-body-color); } .container { @@ -197,13 +111,14 @@ textarea { -webkit-appearance: none; font-family: var(--font-family-base); padding: 8px 15px; - border: 1px solid var(--border-color); + border: none; border-radius: var(--border-radius-md); background-color: var(--background-inputs-color); font-size: var(--font-size-sm); width: 100%; - outline-color: var(--outline-color); resize: vertical; + border: 1px solid var(--border-color); + outline-color: var(--color-blue-500); } button { @@ -249,12 +164,12 @@ pre { } a { - color: var(--color-blue-500); + color: var(--color-blue-400); font-weight: 500; text-decoration: none; &:hover { text-decoration: underline; - color: var(--color-blue-500); + color: var(--color-blue-400); } } diff --git a/src/styles/theme.scss b/src/styles/theme.scss new file mode 100644 index 0000000..9f13b2c --- /dev/null +++ b/src/styles/theme.scss @@ -0,0 +1,140 @@ +:root, +:root[data-theme='light'] { + color-scheme: light; + + /* Fonts */ + --font-fallback: -apple-system, BlinkMacSystemFont, Segoe UI, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji; + --font-family-base: 'Rubik', var(--font-fallback); + --font-size-xs: 0.75rem; + --font-size-sm: 0.875rem; + --font-size-md: 1rem; + --font-size-lg: 1.125rem; + --font-size-xl: 1.25rem; + --font-size-2xl: 1.5rem; + --font-size-3xl: 1.875rem; + --font-size-4xl: 2.25rem; + --font-size-5xl: 3rem; + --font-size-6xl: 3.75rem; + --font-size-7xl: 4.5rem; + --font-size-8xl: 6rem; + --font-size-9xl: 8rem; + + /* Line heights */ + --line-height-normal: 'normal'; + --line-height-none: 1; + --line-height-shorter: 1.25; + --line-height-short: 1.375; + --line-height-base: 1.5; + --line-height-tall: 1.625; + + /* Colors */ + --color-white: #ffffff; + --color-black: #010409; + + --color-blue-50: #cae8ff; + --color-blue-100: #a5d6ff; + --color-blue-200: #79c0ff; + --color-blue-300: #58a6ff; + --color-blue-400: #388bfd; + --color-blue-500: #1f6feb; + --color-blue-600: #1158c7; + --color-blue-700: #0d419d; + --color-blue-800: #0c2d6b; + --color-blue-900: #051d4d; + + --color-gray-50: #f0f6fc; + --color-gray-100: #c9d1d9; + --color-gray-200: #b1bac4; + --color-gray-300: #8b949e; + --color-gray-400: #6e7681; + --color-gray-500: #484f58; + --color-gray-600: #30363d; + --color-gray-700: #21262d; + --color-gray-800: #161b22; + --color-gray-900: #0d1117; + + --color-orange-50: #ffdfb6; + --color-orange-100: #ffc680; + --color-orange-200: #ffa657; + --color-orange-300: #f0883e; + --color-orange-400: #db6d28; + --color-orange-500: #bd561d; + --color-orange-600: #9b4215; + --color-orange-700: #762d0a; + --color-orange-800: #5a1e02; + --color-orange-900: #3d1300; + + --color-yellow-50: #f8e3a1; + --color-yellow-100: #f2cc60; + --color-yellow-200: #e3b341; + --color-yellow-300: #d29922; + --color-yellow-400: #bb8009; + --color-yellow-500: #9e6a03; + --color-yellow-600: #845306; + --color-yellow-700: #693e00; + --color-yellow-800: #4b2900; + --color-yellow-900: #341a00; + + /* Border */ + --border-radius-md: 3px; + --border-radius-lg: 5px; + + /* Sizes */ + --content-width: 760px; + --content-padding: 24px; + + --opacity-hover: 0.7; + + /* Fonts */ + --font-color: var(--color-black); + --font-color-gray: var(--color-gray-500); + --font-color-grayer: var(--color-gray-700); + + /* Border */ + --border-color: var(--color-gray-100); + --border-color-hover: var(--color-gray-400); + + /* Elements */ + --background-body-color: var(--color-white); + --background-header-color: var(--color-white); + --background-inline-code: rgba(0, 0, 0, 0.05); + --background-color-hover: var(--color-gray-50); + --background-btn-link: var(--color-white); + --background-btn-link-active: var(--color-white); + --background-inputs-color: var(--color-white); + + /* Icons */ + --icon-primary: var(--color-white); + --icon-secondary: var(--color-gray-700); +} + +:root[data-theme='dark'] { + color-scheme: dark; + /* Fonts */ + --font-color: var(--color-white); + --font-color-gray: var(--color-gray-100); + --font-color-grayer: var(--color-gray-200); + + /* Border */ + --border-color: var(--color-gray-700); + --border-color-hover: var(--color-gray-600); + + /* Elements */ + --background-body-color: var(--color-gray-900); + --background-header-color: var(--color-gray-900); + --background-inline-code: var(--color-gray-800); + --background-color-hover: var(--color-gray-800); + --background-btn-link: var(--color-gray-800); + --background-btn-link-active: var(--color-gray-700); + --background-inputs-color: var(--color-gray-800); + + /* Icons */ + --icon-primary: var(--color-white); + --icon-secondary: var(--color-gray-100); + --icon-filter: invert(100%); + + & .header svg, + & .site-content svg:not([data-filter='none']) { + filter: var(--icon-filter); + } +} diff --git a/src/types/index.ts b/src/types/index.ts deleted file mode 100644 index 91132d0..0000000 --- a/src/types/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -export type ArticleType = { - title: string; - author: string; - tags: Array; - published_at: string; -}; - -export type ProjectType = { - icon: string; - name: string; - year: string; - description: string; - sourceUrl?: string | undefined; - articleUrl?: string | undefined; - demoUrl?: string | undefined; -}; - -export type SkillsType = { - title: string; - list: Array<{ icon?: string | undefined; name: string }>; -}; - -export type ArticleBlockType = { - [year: number]: ArticleType[]; -}; diff --git a/src/types/main.d.ts b/src/types/main.d.ts new file mode 100644 index 0000000..fa3ff37 --- /dev/null +++ b/src/types/main.d.ts @@ -0,0 +1,39 @@ +export {}; + +declare global { + interface Window { + theme?: ThemeModeType | undefined; + } + + type ArticleType = { + title: string; + author: string; + tags: Array; + published_at: string; + }; + + type ProjectType = { + icon: string; + name: string; + year: string; + description: string; + sourceUrl?: string | undefined; + articleUrl?: string | undefined; + demoUrl?: string | undefined; + }; + + type SkillsType = { + title: string; + list: Array<{ icon?: string | undefined; name: string }>; + }; + + type ArticleBlockType = { + [year: number]: ArticleType[]; + }; + + type ThemeModeType = 'light' | 'dark'; + + type SiteConfigType = { + defaultTheme: ThemeModeType; + }; +} diff --git a/src/utils/articles.ts b/src/utils/articles.ts index f63124b..845d8b6 100644 --- a/src/utils/articles.ts +++ b/src/utils/articles.ts @@ -1,5 +1,3 @@ -import type { ArticleType, ArticleBlockType } from '@root/types'; - import { MarkdownInstance } from 'astro'; export const transformArticles = (articles: MarkdownInstance[]): ArticleType[] => diff --git a/tsconfig.json b/tsconfig.json index 9adedda..cdc34f0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,7 +17,8 @@ "@utils/*": ["./src/utils/*"], "@stores/*": ["./src/stores/*"] }, - "outDir": "./dist" + "outDir": "./dist", + "typeRoots": ["./node_modules/@types", "./src/types"] }, "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts"] } From b0d7490ecb2d577b92c5992719007f096bc8c531 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Thu, 28 Jul 2022 00:05:02 +0300 Subject: [PATCH 25/70] moved theme-detector to public folder --- README.md | 4 ++-- package.json | 2 +- .../assets/{ => css}/prism-one-dark.min.css | 0 .../assets/{ => css}/prism-one-light.min.css | 0 public/assets/js/detect-theme.js | 23 +++++++++++++++++++ src/components/BaseHead.astro | 7 ++---- src/components/Header/Header.astro | 2 +- .../ThemeSwticher/ThemeSwitcher.tsx | 6 +++-- src/layouts/article.astro | 4 ++-- src/scripts/detect-theme.astro | 20 ---------------- src/scripts/index.ts | 1 - src/types/main.d.ts | 4 ---- 12 files changed, 35 insertions(+), 38 deletions(-) rename public/assets/{ => css}/prism-one-dark.min.css (100%) rename public/assets/{ => css}/prism-one-light.min.css (100%) create mode 100644 public/assets/js/detect-theme.js delete mode 100644 src/scripts/detect-theme.astro delete mode 100644 src/scripts/index.ts diff --git a/README.md b/README.md index 7b102dc..bc6f887 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,9 @@ Personal website created with Astro. - [x] HTML layout - [x] Adaptive & Responsive layout -- [ ] Dark/Light Theme +- [x] Search articles by title or description +- [x] Dark/Light Theme - [ ] Multilang web-site -- [ ] Search articles by title or description - [ ] Form handling via Netlify Forms - [ ] SEO optimized diff --git a/package.json b/package.json index d6d80cf..fcaa6d9 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "scripts": { "dev": "astro dev --host", "start": "astro dev", - "build": "astro check && tsc --noEmit && astro build", + "build": "astro build", "preview": "astro preview --host", "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json}\"", "lint": "eslint '**/*.{js,mjs,ts,tsx}'" diff --git a/public/assets/prism-one-dark.min.css b/public/assets/css/prism-one-dark.min.css similarity index 100% rename from public/assets/prism-one-dark.min.css rename to public/assets/css/prism-one-dark.min.css diff --git a/public/assets/prism-one-light.min.css b/public/assets/css/prism-one-light.min.css similarity index 100% rename from public/assets/prism-one-light.min.css rename to public/assets/css/prism-one-light.min.css diff --git a/public/assets/js/detect-theme.js b/public/assets/js/detect-theme.js new file mode 100644 index 0000000..bf46454 --- /dev/null +++ b/public/assets/js/detect-theme.js @@ -0,0 +1,23 @@ +/** + * This script is used to determine the theme of the site. + * The theme value is taken from localstorage, otherwise from the operating system. + * It is very important to include this script before loading the CSS + * and body markup to prevent FOUC (Flash of unstyled content). + */ + +const getTheme = () => { + const local = localStorage.getItem('theme'); + if (local && (local === 'dark' || local === 'light')) return local; + const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + return isDark ? 'dark' : 'light'; +}; + +window.theme = getTheme(); +document.documentElement.setAttribute('data-theme', window.theme); + +/* Sync with OS theme */ +window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ({ matches: isDark }) => { + window.theme = isDark ? 'dark' : 'light'; + localStorage.setItem('theme', window.theme); + document.documentElement.setAttribute('data-theme', window.theme); +}); diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro index f6609a8..edc32c7 100644 --- a/src/components/BaseHead.astro +++ b/src/components/BaseHead.astro @@ -1,6 +1,5 @@ --- import { SITE_METADATA } from '@root/config'; -import { DetectThemeScript } from '@root/scripts'; export interface Props { title?: string | undefined; @@ -13,8 +12,6 @@ const { title = SITE_METADATA.title, description } = Astro.props as Props; - - @@ -23,7 +20,7 @@ const { title = SITE_METADATA.title, description } = Astro.props as Props; + diff --git a/src/components/Header/Header.astro b/src/components/Header/Header.astro index 1426d4a..13c833b 100644 --- a/src/components/Header/Header.astro +++ b/src/components/Header/Header.astro @@ -38,7 +38,7 @@ const { pathname } = Astro.canonicalURL;
- + diff --git a/src/components/ThemeSwticher/ThemeSwitcher.tsx b/src/components/ThemeSwticher/ThemeSwitcher.tsx index 120fc20..e4895e4 100644 --- a/src/components/ThemeSwticher/ThemeSwitcher.tsx +++ b/src/components/ThemeSwticher/ThemeSwitcher.tsx @@ -26,7 +26,9 @@ const ThemeSwitcher: Component = () => { const [theme, setTheme] = createSignal(SITE_SETTINGS.defaultTheme); const [isReady, setIsReady] = createSignal(false); - const toggleTheme: JSX.EventHandler = (e) => { + const toggleTheme: JSX.EventHandler = () => { + if (!window.theme) return; + const newTheme = theme() === 'light' ? 'dark' : 'light'; setTheme(newTheme); localStorage.setItem('theme', newTheme); @@ -46,7 +48,7 @@ const ThemeSwitcher: Component = () => { }); return ( - )} - {!isError() && isSubmitted() && } - {isError() && isSubmitted() && } + {!isError() && isSubmitted() && } + {isError() && isSubmitted() && } ); diff --git a/src/components/ContactForm/Error.tsx b/src/components/ContactForm/Error.tsx index 0836ef3..a8976aa 100644 --- a/src/components/ContactForm/Error.tsx +++ b/src/components/ContactForm/Error.tsx @@ -1,7 +1,7 @@ import type { Component } from "solid-js"; -const Submitted: Component = () => { - return
❌ При отправке произошла ошибка. Повторите запрос позже.
; +const Submitted: Component<{ text: string }> = (props) => { + return
❌ {props.text}
; }; export default Submitted; diff --git a/src/components/ContactForm/Submitted.tsx b/src/components/ContactForm/Submitted.tsx index e06d187..980f305 100644 --- a/src/components/ContactForm/Submitted.tsx +++ b/src/components/ContactForm/Submitted.tsx @@ -1,7 +1,7 @@ import type { Component } from "solid-js"; -const Submitted: Component = () => { - return
✔️ Сообщение было успешно отправлено!
; +const Submitted: Component<{ text: string }> = (props) => { + return
✔️ {props.text}
; }; export default Submitted; diff --git a/src/components/ContactForm/validations.ts b/src/components/ContactForm/validations.ts index 5493763..9e9e195 100644 --- a/src/components/ContactForm/validations.ts +++ b/src/components/ContactForm/validations.ts @@ -1,3 +1,7 @@ import { isEmail } from "@utils/string"; -export const validateEmail = (field: HTMLInputElement) => (isEmail(field.value) ? false : "Заполните поле в формате e-mail."); +export default { + validateEmail: (error: string) => { + return (field: HTMLInputElement) => (isEmail(field.value) ? false : error); + }, +}; diff --git a/src/components/Header/Header.astro b/src/components/Header/Header.astro index e3ec58b..d11d738 100644 --- a/src/components/Header/Header.astro +++ b/src/components/Header/Header.astro @@ -2,9 +2,10 @@ import { Icon } from "astro-icon"; import { SITE_METADATA } from "@root/config"; import ThemeSwitcher from "@components/ThemeSwticher"; -import { removeSlashes } from "@utils/string"; +import UIString from "@components/UIString"; import NavToggle from "./NavToggle"; import "./Header.scss"; +import TranslatedLink from "@components/TranslatedLink"; const { name, nav, contacts } = SITE_METADATA; const { pathname } = Astro.url; @@ -13,23 +14,25 @@ const { pathname } = Astro.url;
diff --git a/src/components/Header/Header.scss b/src/components/Header/Header.scss index 03221ea..ee890a0 100644 --- a/src/components/Header/Header.scss +++ b/src/components/Header/Header.scss @@ -3,8 +3,8 @@ top: 0; border-bottom: 1px solid var(--border-color); background-color: var(--background-header-color); - padding-top: 15px; - padding-bottom: 15px; + padding-top: 13.5px; + padding-bottom: 13.5px; user-select: none; z-index: 9999; & .container { @@ -53,7 +53,7 @@ display: flex; align-items: center; column-gap: 10px; - margin-right: 40px; + margin-right: 30px; & a { text-decoration: none; font-size: 0; @@ -62,6 +62,9 @@ } } } + &-settings { + column-gap: 13.5px; + } } } diff --git a/src/components/ProjectItem/ProjectItem.astro b/src/components/ProjectItem/ProjectItem.astro index 415ac81..02773e0 100644 --- a/src/components/ProjectItem/ProjectItem.astro +++ b/src/components/ProjectItem/ProjectItem.astro @@ -1,12 +1,16 @@ --- -import { Icon } from 'astro-icon'; -import './ProjectItem.scss'; +import { FALLBACK_LANGUAGE } from "@root/config"; +import { getLanguageFromURL } from "@root/utils"; +import { Icon } from "astro-icon"; +import UIString from "../UIString"; +import "./ProjectItem.scss"; export interface Props { data: ProjectType; } const { data } = Astro.props as Props; +const lang = getLanguageFromURL(Astro.url.pathname); const { icon, name, year, description, articleUrl, sourceUrl, demoUrl } = data; --- @@ -19,25 +23,31 @@ const { icon, name, year, description, articleUrl, sourceUrl, demoUrl } = data; {year}
-

{description}

+

{description[lang] || description[FALLBACK_LANGUAGE]}

diff --git a/src/components/RecentArticles/EmptyList.astro b/src/components/RecentArticles/EmptyList.astro index fa3f0c1..dc4459e 100644 --- a/src/components/RecentArticles/EmptyList.astro +++ b/src/components/RecentArticles/EmptyList.astro @@ -1,5 +1,9 @@ +--- +import UIString from "@components/UIString"; +--- +
-

Пока что здесь ничего нет...

+

+ + diff --git a/src/components/LanguageSelect/index.ts b/src/components/LanguageSelect/index.ts new file mode 100644 index 0000000..9d165f9 --- /dev/null +++ b/src/components/LanguageSelect/index.ts @@ -0,0 +1 @@ +export { default } from "./LanguageSelect.astro"; diff --git a/src/components/ProjectItem/ProjectItem.astro b/src/components/ProjectItem/ProjectItem.astro index 02773e0..e8735df 100644 --- a/src/components/ProjectItem/ProjectItem.astro +++ b/src/components/ProjectItem/ProjectItem.astro @@ -1,5 +1,5 @@ --- -import { FALLBACK_LANGUAGE } from "@root/config"; +import { DEFAULT_LANGUAGE } from "@root/config"; import { getLanguageFromURL } from "@root/utils"; import { Icon } from "astro-icon"; import UIString from "../UIString"; @@ -23,7 +23,7 @@ const { icon, name, year, description, articleUrl, sourceUrl, demoUrl } = data; {year}
-

{description[lang] || description[FALLBACK_LANGUAGE]}

+

{description[lang] || description[DEFAULT_LANGUAGE]}

diff --git a/src/templates/Home.astro b/src/templates/Home.astro index 4b5b394..a94b881 100644 --- a/src/templates/Home.astro +++ b/src/templates/Home.astro @@ -4,13 +4,13 @@ import PageLayout from "@layouts/default.astro"; import RecentArticles from "@components/RecentArticles"; import { Splash, SplashHeading, SplashLinks, Link } from "@components/Splash"; import { getLanguageFromURL } from "@root/utils"; -import { useTranslation } from "@i18n/utils"; +import { getTranslatedArticles, useTranslation } from "@i18n/utils"; import UIString from "@components/UIString"; -const data = await Astro.glob("../../content/articles/**/*.mdx"); -const articles = utils.transformArticles(data); +const data = getTranslatedArticles(Astro); const t = useTranslation(Astro); const lang = getLanguageFromURL(Astro.url.pathname); +const articles = utils.transformArticles(data); --- @@ -27,5 +27,5 @@ const lang = getLanguageFromURL(Astro.url.pathname); - + diff --git a/src/types/main.d.ts b/src/types/main.d.ts index ee96d48..07e13bb 100644 --- a/src/types/main.d.ts +++ b/src/types/main.d.ts @@ -38,6 +38,7 @@ declare global { author: string; tags: Array; published_at: string; + lang?: string; }; type ProjectType = { diff --git a/src/utils/articles.ts b/src/utils/articles.ts index 60b8155..7ea06ce 100644 --- a/src/utils/articles.ts +++ b/src/utils/articles.ts @@ -8,6 +8,7 @@ export const transformArticles = (articles: MDXInstance[]): Article author: article.frontmatter.author, tags: article.frontmatter.tags, published_at: article.frontmatter.published_at, + lang: article.frontmatter.lang, })); export const sortArtcilesByDate = (articles: ArticleType[]): ArticleType[] => { From 628bae5bce1305ac984a509dccc9e9a9349e7aab Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Wed, 17 Aug 2022 14:01:32 +0300 Subject: [PATCH 57/70] upd readme --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 03c82cc..adae0fb 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,9 @@ Personal website created with Astro. - [x] Adaptive & Responsive layout - [x] Search articles by title or description - [x] Dark/Light Theme -- [x] Form handling via Netlify Forms -- [ ] Multilang web-site +- [x] Multilang web-site +- [x] Form handling via (Netlify Forms)(https://www.netlify.com/products/forms/) +- [ ] Comment system via [utterances](https://utteranc.es/) - [ ] SEO optimized ## License From a8be51891d4786809aec3a24afca314ea269f29d Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Wed, 17 Aug 2022 14:02:02 +0300 Subject: [PATCH 58/70] upd readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index adae0fb..101d4f2 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Personal website created with Astro. - [x] Search articles by title or description - [x] Dark/Light Theme - [x] Multilang web-site -- [x] Form handling via (Netlify Forms)(https://www.netlify.com/products/forms/) +- [x] Form handling via [Netlify Forms](https://www.netlify.com/products/forms/) - [ ] Comment system via [utterances](https://utteranc.es/) - [ ] SEO optimized From 8f7601101866e72fc7024ff2824fe3efb0d81669 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Wed, 17 Aug 2022 15:01:45 +0300 Subject: [PATCH 59/70] fix: fixed language changing on article post page --- src/components/ArticlePost/ArticlePost.astro | 3 ++- src/components/LanguageSelect/LanguageSelect.astro | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/ArticlePost/ArticlePost.astro b/src/components/ArticlePost/ArticlePost.astro index 844456d..e2dd9c9 100644 --- a/src/components/ArticlePost/ArticlePost.astro +++ b/src/components/ArticlePost/ArticlePost.astro @@ -3,6 +3,7 @@ import { createDateFormatter } from "@root/utils"; import { Image } from "@astrojs/image/components"; import ArticleComments from "@components/ArticleComments"; import "./ArticlePost.scss"; +import TranslatedLink from "../TranslatedLink"; export type Props = { data: ArticleType; @@ -20,7 +21,7 @@ const { title, tags, author, published_at } = data; { tags.map((tag) => (
  • - {`${tag}${tags.at(-1) === tag ? "" : ","}`} + {`${tag}${tags.at(-1) === tag ? "" : ","}`}
  • )) } diff --git a/src/components/LanguageSelect/LanguageSelect.astro b/src/components/LanguageSelect/LanguageSelect.astro index 1169939..2ef2e6c 100644 --- a/src/components/LanguageSelect/LanguageSelect.astro +++ b/src/components/LanguageSelect/LanguageSelect.astro @@ -52,6 +52,12 @@ const lang = getLanguageFromURL(Astro.url.pathname); const pathname = window.location.pathname; const url = newLang === DEFAULT_LANGUAGE ? pathname.slice(3) : `${newLang}${pathname}`; + /* Move user to articles page with new language */ + if (window.location.pathname.includes("/blog/")) { + window.location.pathname = `${newLang === DEFAULT_LANGUAGE ? "" : newLang + "/"}` + "articles/"; + return; + } + window.location.pathname = url; }; From 793d6213690c71a77a5fa7ffd3b98bfcbb038183 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Wed, 17 Aug 2022 16:43:35 +0300 Subject: [PATCH 60/70] feat: added utterances comment system --- README.md | 2 +- package-lock.json | 14 ++++++------ package.json | 2 +- .../ArticleComments/ArticleComments.astro | 22 +++++++++++++++++++ src/config.ts | 7 ++++++ src/pages/blog/[...slug].astro | 1 - src/types/main.d.ts | 7 ++++++ 7 files changed, 45 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 101d4f2..81aae62 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Personal website created with Astro. - [x] Dark/Light Theme - [x] Multilang web-site - [x] Form handling via [Netlify Forms](https://www.netlify.com/products/forms/) -- [ ] Comment system via [utterances](https://utteranc.es/) +- [x] Comment system via [utterances](https://utteranc.es/) - [ ] SEO optimized ## License diff --git a/package-lock.json b/package-lock.json index 168978c..7bea0c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@typescript-eslint/eslint-plugin": "^5.33.1", "@typescript-eslint/parser": "^5.33.1", "astro": "^1.0.6", - "astro-compress": "^0.0.19", + "astro-compress": "^1.0.1", "astro-icon": "^0.7.3", "eslint": "^8.22.0", "eslint-plugin-solid": "^0.7.1", @@ -1538,9 +1538,9 @@ } }, "node_modules/astro-compress": { - "version": "0.0.19", - "resolved": "https://registry.npmjs.org/astro-compress/-/astro-compress-0.0.19.tgz", - "integrity": "sha512-Hgv1wX43vOwzUNuqRm7hbCMUXoH2xF+kTjBR+6RqAbM6hjqIlB8aKEGOVdELj6BiwnMDLf1dl6C1TmYPPgDMAg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/astro-compress/-/astro-compress-1.0.1.tgz", + "integrity": "sha512-6w8n4KF5KbvEp86E5uUsRMB1uWNz04gml9EkyDXi5+7r8NKG/efOu+TVyhIaj7QWDevdDXLYPrMH//9HyNtCWA==", "dev": true, "dependencies": { "csso": "5.0.5", @@ -10382,9 +10382,9 @@ } }, "astro-compress": { - "version": "0.0.19", - "resolved": "https://registry.npmjs.org/astro-compress/-/astro-compress-0.0.19.tgz", - "integrity": "sha512-Hgv1wX43vOwzUNuqRm7hbCMUXoH2xF+kTjBR+6RqAbM6hjqIlB8aKEGOVdELj6BiwnMDLf1dl6C1TmYPPgDMAg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/astro-compress/-/astro-compress-1.0.1.tgz", + "integrity": "sha512-6w8n4KF5KbvEp86E5uUsRMB1uWNz04gml9EkyDXi5+7r8NKG/efOu+TVyhIaj7QWDevdDXLYPrMH//9HyNtCWA==", "dev": true, "requires": { "csso": "5.0.5", diff --git a/package.json b/package.json index 11808cc..c234b21 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@typescript-eslint/eslint-plugin": "^5.33.1", "@typescript-eslint/parser": "^5.33.1", "astro": "^1.0.6", - "astro-compress": "^0.0.19", + "astro-compress": "^1.0.1", "astro-icon": "^0.7.3", "eslint": "^8.22.0", "eslint-plugin-solid": "^0.7.1", diff --git a/src/components/ArticleComments/ArticleComments.astro b/src/components/ArticleComments/ArticleComments.astro index 58752e9..82edd42 100644 --- a/src/components/ArticleComments/ArticleComments.astro +++ b/src/components/ArticleComments/ArticleComments.astro @@ -1,7 +1,29 @@ --- +import { UTTERANCES_CONFIG } from "@root/config"; import UIString from "../UIString"; ---

    +
    + + diff --git a/src/config.ts b/src/config.ts index f144370..c1cca3d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,5 +1,12 @@ export const DEFAULT_LANGUAGE: LanguageKeys = "ru"; +export const UTTERANCES_CONFIG: UtterancesConfigType = { + repo: "sergeyyarkov/comments", + issueTerm: "title", + label: "Comments", + theme: "github-light", +}; + export const SITE_METADATA: SiteMetadataType = { title: "Sergey Yarkov", name: "yarkov.tech", diff --git a/src/pages/blog/[...slug].astro b/src/pages/blog/[...slug].astro index c5e3834..0f517d1 100644 --- a/src/pages/blog/[...slug].astro +++ b/src/pages/blog/[...slug].astro @@ -10,7 +10,6 @@ const lang = getLanguageFromURL(Astro.url.pathname); export async function getStaticPaths() { const modules = import.meta.glob>("../../../content/articles/**/*.mdx", { eager: true }); const entries = Object.keys(modules).map((key) => [key, key.split("/").slice(7)[0]]); - const data = await Astro.glob("../../../content/articles/**/*.mdx"); return entries.map(([key, lang]) => { const article = modules[key]; diff --git a/src/types/main.d.ts b/src/types/main.d.ts index 07e13bb..42a9eec 100644 --- a/src/types/main.d.ts +++ b/src/types/main.d.ts @@ -15,6 +15,13 @@ declare global { type LanguageKeys = keyof typeof languages; type UIDictionaryKeys = keyof typeof uiKeys; + type UtterancesConfigType = { + repo: string; + label?: string; + issueTerm: string; + theme: string; + }; + type SiteMetadataType = { title: string; name: string; From 11baec11779b2d88adf4d769984d250e2904b7e9 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Wed, 17 Aug 2022 16:56:08 +0300 Subject: [PATCH 61/70] fix: fixed rehype & remark plugins --- astro.config.mjs | 93 ++++++++++--------- .../ArticleContent/ArticleContent.scss | 5 +- 2 files changed, 52 insertions(+), 46 deletions(-) diff --git a/astro.config.mjs b/astro.config.mjs index b369cb6..e23c72c 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -6,6 +6,10 @@ import solid from "@astrojs/solid-js"; import image from "@astrojs/image"; // import compress from "astro-compress"; import mdx from "@astrojs/mdx"; +import remarkGfm from "remark-gfm"; +import remarkSmartypants from "remark-smartypants"; +import rehypeSlug from "rehype-slug"; +import rehypeAutolinkHeadings from "rehype-autolink-headings"; const createAnchorLabel = (heading) => { const node = h("span.anchor-label", escape(heading)); @@ -16,51 +20,56 @@ const createAnchorLabel = (heading) => { // https://astro.build/config export default defineConfig({ site: "https://yarkov.tech", - integrations: [solid(), image(), mdx()], + integrations: [ + solid(), + image(), + mdx({ + remarkPlugins: [remarkGfm, remarkSmartypants], + rehypePlugins: [ + rehypeSlug, + [ + rehypeAutolinkHeadings, + { + properties: { + class: "anchor-link", + }, + behavior: "after", + group: ({ tagName }) => + h(`div.heading-wrapper.level-${tagName}`, { + tabIndex: -1, + }), + content: (heading) => [ + h( + `span.anchor-icon`, + undefined, + h( + "svg", + { + width: 18, + height: 18, + version: 1.1, + viewBox: "0 0 16 16", + xlmns: "http://www.w3.org/2000/svg", + ariaHidden: "true", + "data-filter": "none", + }, + h("path", { + fillRule: "evenodd", + fill: "currentcolor", + d: "M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z", + }) + ) + ), + createAnchorLabel(toString(heading)), + ], + }, + ], + ], + }), + ], trailingSlash: "always", markdown: { syntaxHighlight: "prism", - remarkPlugins: ["remark-gfm", "remark-smartypants"], - rehypePlugins: [ - "rehype-slug", - [ - "rehype-autolink-headings", - { - properties: { - class: "anchor-link", - }, - behavior: "after", - group: ({ tagName }) => - h(`div.heading-wrapper.level-${tagName}`, { - tabIndex: -1, - }), - content: (heading) => [ - h( - `span.anchor-icon`, - undefined, - h( - "svg", - { - width: 18, - height: 18, - version: 1.1, - viewBox: "0 0 16 16", - xlmns: "http://www.w3.org/2000/svg", - ariaHidden: "true", - "data-filter": "none", - }, - h("path", { - fillRule: "evenodd", - fill: "currentcolor", - d: "M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z", - }) - ) - ), - createAnchorLabel(toString(heading)), - ], - }, - ], - ], }, vite: { ssr: { diff --git a/src/components/ArticleContent/ArticleContent.scss b/src/components/ArticleContent/ArticleContent.scss index 42db060..96e8a2c 100644 --- a/src/components/ArticleContent/ArticleContent.scss +++ b/src/components/ArticleContent/ArticleContent.scss @@ -17,10 +17,6 @@ padding-bottom: 5px; } - h2 { - border-bottom: 1px solid var(--border-color); - } - & ul { padding-left: 1.5rem; line-height: var(--line-height-base); @@ -177,6 +173,7 @@ & .anchor-icon { position: absolute; left: -25px; + top: -13px; } & svg { vertical-align: middle; From 2f11e6020bbc962fc9ce97af5455b8d00fd4cd68 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Wed, 17 Aug 2022 19:29:37 +0300 Subject: [PATCH 62/70] feat: added favicon --- public/android-chrome-192x192.png | Bin 0 -> 4663 bytes public/android-chrome-256x256.png | Bin 0 -> 6258 bytes public/apple-touch-icon.png | Bin 0 -> 4371 bytes public/browserconfig.xml | 9 +++++++++ public/favicon-dark-16x16.png | Bin 0 -> 617 bytes public/favicon-dark-32x32.png | Bin 0 -> 938 bytes public/favicon-light-16x16.png | Bin 0 -> 635 bytes public/favicon-light-32x32.png | Bin 0 -> 955 bytes public/favicon.ico | Bin 4286 -> 15086 bytes public/mstile-150x150.png | Bin 0 -> 3557 bytes public/safari-pinned-tab.svg | 23 +++++++++++++++++++++++ public/site.webmanifest | 19 +++++++++++++++++++ src/components/BaseHead.astro | 8 ++++++++ src/layouts/article.astro | 2 +- src/layouts/default.astro | 2 +- 15 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 public/android-chrome-192x192.png create mode 100644 public/android-chrome-256x256.png create mode 100644 public/apple-touch-icon.png create mode 100644 public/browserconfig.xml create mode 100644 public/favicon-dark-16x16.png create mode 100644 public/favicon-dark-32x32.png create mode 100644 public/favicon-light-16x16.png create mode 100644 public/favicon-light-32x32.png create mode 100644 public/mstile-150x150.png create mode 100644 public/safari-pinned-tab.svg create mode 100644 public/site.webmanifest diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..d005d3578c8e3d7c552a53feaf5acf28abe7a26a GIT binary patch literal 4663 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 literal 0 HcmV?d00001 diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e8637e08047fa8ab5d560033e4764a75734b28bf GIT binary patch literal 4371 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 MHGS0zWxJ671Bi-S$p8QV literal 0 HcmV?d00001 diff --git a/public/browserconfig.xml b/public/browserconfig.xml new file mode 100644 index 0000000..b3930d0 --- /dev/null +++ b/public/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #da532c + + + diff --git a/public/favicon-dark-16x16.png b/public/favicon-dark-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..6acf70577091427c39cb02d0f5c1153a2c7c1dee GIT binary patch literal 617 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|U1(2s1Lwnj--eWH0gbb!C6XAt=DF%CgMq4^Zf*r;B5V#`)HX8~qLih_wAL z*6i5sBCgBg&cyttPvzBtOX3BSkKAoB|Hyl1#vGXrKD9lJ(nr_@q{W=p?0xp_n}Nur zd(&QQpF3yr=l?(JA8F+kwp($S^)UEL2=jkr5a;aTXsJ+{x2UpU?z|cyeXjGmiXWd# zDKyp>yeU)`361y^CG#!C8<`)MX5lF!N|bKNY}tZ*U&t~(9Fuv)XLag+rYrez z3c0lGff~ZALLy3n63Z0|it^Jkb5a#bDhpB-G7CzQ85k<&JpRPPQ5dG7amxSn8PBId z49v>hddb|v%EI20MVN&ZTpCOcr!XsT4pBILk4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-yYD8R4EvdrlZP?MFXi(`n#@wZcLGlUZ*j@O^B zp5E>0p{v*$BI2UCE#lYK2-g6|5{^ginUT6VMe#LIRqdsnhfCv}h7EQ!zOMOwu>C7HR7eLfP9`Ma(8dInd~rajw#-K-LJ z-ruh$d02IcCByFQ8+kL-o@0JL+zj1)0234>xC?;Fx~k zpWM#*T`!W&nC#Ci*L}ap%A{dQ`K}kn^K61LKRXm#o8GdU^)suDO~HAoY~E_~m{sBN zApv3Uyo}EZFj(DTyghkd*5Cf^V!Kz>`nB)o`q1=#iIjiTK9_ZRN5A?%b~^a!wep*F zW%_G)FB{L~-xu=yO!dnAu>G6YDE$hlyvsLX>+?NHMmxTQ)$bSn`uSwdr)NpCx4%@M zyokNRqk4kz843O5Z8F=e@A^*aid<*9&1~2OC7#SED=^9w*8k&a~npqi| zS{a*b8yHv_7%+rSYDUqJo1c=IR*73fA(xgtP(yfCNJL3cV!1*=QGQxxPO3slWkIS! zW2I`Q&6e6=(&6r>mdKI;Vst09Y1wFaQ7m literal 0 HcmV?d00001 diff --git a/public/favicon-light-16x16.png b/public/favicon-light-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..a2e1e13ccc82bd331f3d4db4ae9ba80bf44e7b15 GIT binary patch literal 635 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 literal 4286 zcmchZF=!M)6ox0}Fc8GdTHG!cdIY>nA!3n2f|wxIl0rn}Hl#=uf>?-!2r&jMEF^_k zh**lGut*gwBmoNv7AaB&2~nbzULg{WBhPQ{ZVzvF_HL8Cb&hv$_s#qN|IO^o>?+mA zuTW6tU%k~z<&{z+7$G%*nRsTcEO|90xy<-G5&JTt%CgZZCDT4%R?+{Vd^wh>P8_)} z`+dF$HQb9!>1o`Ivn;GInlCw{9T@Rt%q+d^T3Ke%cxkk;$v`{s^zCB9nHAv6w$Vbn z8fb<+eQTNM`;rf9#obfGnV#3+OQEUv4gU;{oA@zol%keY9-e>4W>p7AHmH~&!P7f7!Uj` zwgFeQ=<3G4O;mwWO`L!=R-=y3_~-DPjH3W^3f&jjCfC$o#|oGaahSL`_=f?$&Aa+W z2h8oZ+@?NUcjGW|aWJfbM*ZzxzmCPY`b~RobNrrj=rd`=)8-j`iSW64@0_b6?;GYk zNB+-fzOxlqZ?`y{OA$WigtZXa8)#p#=DPYxH=VeC_Q5q9Cv`mvW6*zU&Gnp1;oPM6 zaK_B3j(l^FyJgYeE9RrmDyhE7W2}}nW%ic#0v@i1E!yTey$W)U>fyd+!@2hWQ!Wa==NAtKoj`f3tp4y$Al`e;?)76?AjdaRR>|?&r)~3Git> zb1)a?uiv|R0_{m#A9c;7)eZ1y6l@yQ#oE*>(Z2fG-&&smPa2QTW>m*^K65^~`coP$ z8y5Y?iS<4Gz{Zg##$1mk)u-0;X|!xu^FCr;ce~X<&UWE&pBgqfYmEJTzpK9I%vr%b z3Ksd6qlPJLI%HFfeXK_^|BXiKZC>Ocu(Kk6hD3G-8usLzVG^q00Qh gz)s7ge@$ApxGu7=(6IGIk+uG&HTev01^#CH3$(Wk5&!@I diff --git a/public/mstile-150x150.png b/public/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..c37abf32e8cee6d544e02335b0b08874fef7d90e GIT binary patch literal 3557 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 + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + diff --git a/public/site.webmanifest b/public/site.webmanifest new file mode 100644 index 0000000..3bb1b80 --- /dev/null +++ b/public/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "yarkov.tech", + "short_name": "yarkov.tech", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-256x256.png", + "sizes": "256x256", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro index a60d777..531d226 100644 --- a/src/components/BaseHead.astro +++ b/src/components/BaseHead.astro @@ -22,5 +22,13 @@ const { title = SITE_METADATA.title, description } = Astro.props as Props; + + + + + + + + diff --git a/src/layouts/article.astro b/src/layouts/article.astro index 34ad016..d35de24 100644 --- a/src/layouts/article.astro +++ b/src/layouts/article.astro @@ -15,7 +15,7 @@ export interface Props extends BaseHeadProps { const { lang = "ru", content } = Astro.props as Props; --- - + diff --git a/src/layouts/default.astro b/src/layouts/default.astro index 7a89a15..6979913 100644 --- a/src/layouts/default.astro +++ b/src/layouts/default.astro @@ -15,7 +15,7 @@ export interface Props extends BaseHeadProps { const { title, description, lang = "ru", showPageHeading = true } = Astro.props as Props; --- - + From 2550e807d38bdc36f52a9a5d0826ed30770e6c6b Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Wed, 17 Aug 2022 21:16:38 +0300 Subject: [PATCH 63/70] feat: added microdata to article post --- src/components/ArticleContent/ArticleContent.astro | 4 ++-- src/components/ArticlePost/ArticlePost.astro | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/ArticleContent/ArticleContent.astro b/src/components/ArticleContent/ArticleContent.astro index 45849c7..27cc78d 100644 --- a/src/components/ArticleContent/ArticleContent.astro +++ b/src/components/ArticleContent/ArticleContent.astro @@ -1,5 +1,5 @@ --- -import './ArticleContent.scss'; +import "./ArticleContent.scss"; --- -
    +
    diff --git a/src/components/ArticlePost/ArticlePost.astro b/src/components/ArticlePost/ArticlePost.astro index e2dd9c9..143db25 100644 --- a/src/components/ArticlePost/ArticlePost.astro +++ b/src/components/ArticlePost/ArticlePost.astro @@ -14,31 +14,31 @@ const { data, lang } = Astro.props as Props; const { title, tags, author, published_at } = data; --- -
    +
    -
      +
        { tags.map((tag) => (
      • - {`${tag}${tags.at(-1) === tag ? "" : ","}`} +
      • )) }
    -

    {title}

    +

    {title}

    - - {author} + +
    { data.coverImage && (
    - {data.title} + {data.title}
    ) From e2c3cd4779a714011d2a94edb123aef0e5e2e256 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Thu, 18 Aug 2022 08:21:55 +0300 Subject: [PATCH 64/70] feat: added rss feed for articles --- README.md | 1 + package-lock.json | 52 ++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/i18n/utils.ts | 34 +++++++++++++++++++---------- src/pages/rss.xml.ts | 35 +++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 12 deletions(-) create mode 100644 src/pages/rss.xml.ts diff --git a/README.md b/README.md index 81aae62..f3fc16c 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Personal website created with Astro. - [x] Multilang web-site - [x] Form handling via [Netlify Forms](https://www.netlify.com/products/forms/) - [x] Comment system via [utterances](https://utteranc.es/) +- [x] RSS Feed for articles - [ ] SEO optimized ## License diff --git a/package-lock.json b/package-lock.json index 7bea0c3..fa74583 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "yarkov.tech", "version": "0.0.1", "license": "MIT", + "dependencies": { + "@astrojs/rss": "^1.0.0" + }, "devDependencies": { "@astrojs/image": "^0.3.4", "@astrojs/mdx": "^0.10.0", @@ -183,6 +186,14 @@ "node": "^14.18.0 || >=16.12.0" } }, + "node_modules/@astrojs/rss": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@astrojs/rss/-/rss-1.0.0.tgz", + "integrity": "sha512-vOPocf/SC0TfHsCwQXupvLGm0y3oIwpRCnnF2igDP3gFSxQEOk4nmsuVTEU2N87hYyX1/5uxbjJhixuSV/L8Cw==", + "dependencies": { + "fast-xml-parser": "^4.0.8" + } + }, "node_modules/@astrojs/solid-js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@astrojs/solid-js/-/solid-js-1.0.0.tgz", @@ -3558,6 +3569,21 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-xml-parser": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.9.tgz", + "integrity": "sha512-4G8EzDg2Nb1Qurs3f7BpFV4+jpMVsdgLVuG1Uv8O2OHJfVCg7gcA53obuKbmVqzd4Y7YXVBK05oJG7hzGIdyzg==", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -8146,6 +8172,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, "node_modules/style-to-object": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", @@ -9335,6 +9366,14 @@ "prismjs": "^1.28.0" } }, + "@astrojs/rss": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@astrojs/rss/-/rss-1.0.0.tgz", + "integrity": "sha512-vOPocf/SC0TfHsCwQXupvLGm0y3oIwpRCnnF2igDP3gFSxQEOk4nmsuVTEU2N87hYyX1/5uxbjJhixuSV/L8Cw==", + "requires": { + "fast-xml-parser": "^4.0.8" + } + }, "@astrojs/solid-js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@astrojs/solid-js/-/solid-js-1.0.0.tgz", @@ -11761,6 +11800,14 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "fast-xml-parser": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.9.tgz", + "integrity": "sha512-4G8EzDg2Nb1Qurs3f7BpFV4+jpMVsdgLVuG1Uv8O2OHJfVCg7gcA53obuKbmVqzd4Y7YXVBK05oJG7hzGIdyzg==", + "requires": { + "strnum": "^1.0.5" + } + }, "fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -14979,6 +15026,11 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, + "strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, "style-to-object": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", diff --git a/package.json b/package.json index c234b21..4a4ecab 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "devDependencies": { "@astrojs/image": "^0.3.4", "@astrojs/mdx": "^0.10.0", + "@astrojs/rss": "^1.0.0", "@astrojs/solid-js": "^1.0.0", "@types/mdx": "^2.0.2", "@typescript-eslint/eslint-plugin": "^5.33.1", diff --git a/src/i18n/utils.ts b/src/i18n/utils.ts index f1f2566..4482df5 100644 --- a/src/i18n/utils.ts +++ b/src/i18n/utils.ts @@ -3,11 +3,10 @@ import * as utils from "@utils/url"; import { DEFAULT_LANGUAGE } from "@root/config"; import languages from "./languages"; -export function getTranslatedArticles(Astro: Readonly): MDXInstance[] { - const data = import.meta.glob>("../../content/articles/**/*.mdx", { eager: true }); - const modules: Record>> = {}; - const siteLang = utils.getLanguageFromURL(Astro.url.pathname); - const articles: MDXInstance[] = []; +type TranslatedArticlesType = Record> | Record>; + +export function formatArticlesByLangs(data: Record>): TranslatedArticlesType { + const modules: TranslatedArticlesType = {}; for (const module of Object.values(data)) { const splitted = module.file.split("/"); @@ -17,6 +16,15 @@ export function getTranslatedArticles(Astro: Readonly): MDXInstance modules[name][lang] = module; } + return modules; +} + +export function getTranslatedArticles(Astro: Readonly): MDXInstance[] { + const data = import.meta.glob>("../../content/articles/**/*.mdx", { eager: true }); + const modules = formatArticlesByLangs(data); + const siteLang = utils.getLanguageFromURL(Astro.url.pathname); + const articles: MDXInstance[] = []; + for (const key of Object.keys(modules)) { const langs = Object.keys(modules[key]); for (const articleLang of langs) { @@ -53,11 +61,13 @@ function transformExports(modules: Record) { const translations = transformExports(import.meta.glob("./*/ui.ts", { eager: true })); -export function useTranslation(Astro: Readonly): (key: UIDictionaryKeys) => string | undefined { - const lang = utils.getLanguageFromURL(Astro.url.pathname); - return function translate(key: UIDictionaryKeys): string | undefined { - const string: string | undefined = translations[lang]?.[key] || translations[DEFAULT_LANGUAGE][key]; - if (string === undefined) console.log(`Cannot find any string for translation key "${key}" on "${Astro.url.pathname}" page.`); - return string; - }; +export function translate(key: UIDictionaryKeys, lang: LanguageKeys): string | undefined { + const string: string | undefined = translations[lang]?.[key] || translations[DEFAULT_LANGUAGE][key]; + if (string === undefined) console.log(`Cannot find any string for translation key "${key}".`); + return string; +} + +export function useTranslation(Astro: Readonly): (key: UIDictionaryKeys) => string | undefined { + const lang: LanguageKeys = utils.getLanguageFromURL(Astro.url.pathname) as LanguageKeys; + return (key: UIDictionaryKeys) => translate(key, lang); } diff --git a/src/pages/rss.xml.ts b/src/pages/rss.xml.ts new file mode 100644 index 0000000..cdc152e --- /dev/null +++ b/src/pages/rss.xml.ts @@ -0,0 +1,35 @@ +import type { MDXInstance } from "astro"; + +import rss from "@astrojs/rss"; +import { DEFAULT_LANGUAGE, SITE_METADATA } from "@root/config"; +import * as utils from "@i18n/utils"; + +const data = import.meta.glob>("../../content/articles/**/*.mdx", { eager: true }); +const articles = Object.values(utils.formatArticlesByLangs(data)); +const items = []; + +for (const key of Object.keys(articles)) { + const article: Record> = articles[key]; + for (const lang of Object.keys(article)) { + const { title, description, slug, published_at, coverImage } = article[lang].frontmatter; + items.push({ + link: + `${import.meta.env.SITE}blog/` + + new Date(published_at).toLocaleDateString("en-CA") + + `${lang !== DEFAULT_LANGUAGE ? "/" + lang : ""}` + + `/${slug}/`, + title, + description: `${description}${coverImage !== undefined ? `${title}` : ""}`, + pubDate: published_at, + customData: `${lang}`, + }); + } +} + +export const get = () => + rss({ + title: SITE_METADATA.name, + description: utils.translate("site.description", "ru"), + site: import.meta.env.SITE, + items, + }); From ea7c1a7c10e0e3cc74e4204e5b56397a55b8a454 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Thu, 18 Aug 2022 11:40:30 +0300 Subject: [PATCH 65/70] feat: added header banner --- astro.config.mjs | 18 ++- package-lock.json | 120 +++++++++++++++++- package.json | 1 + src/components/BaseLayout/BaseLayout.astro | 22 +++- src/components/Header/Header.astro | 8 +- .../HeaderBanner/HeaderBanner.astro | 34 +++++ src/components/HeaderBanner/index.ts | 1 + src/config.ts | 3 + src/i18n/en/ui.ts | 1 + src/i18n/ru/ui.ts | 1 + src/utils/string.ts | 6 + 11 files changed, 197 insertions(+), 18 deletions(-) create mode 100644 src/components/HeaderBanner/HeaderBanner.astro create mode 100644 src/components/HeaderBanner/index.ts diff --git a/astro.config.mjs b/astro.config.mjs index e23c72c..7336b5f 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,11 +1,12 @@ +import solid from "@astrojs/solid-js"; +import image from "@astrojs/image"; +import mdx from "@astrojs/mdx"; +import sitemap from "@astrojs/sitemap"; +// import compress from "astro-compress"; import { defineConfig } from "astro/config"; import { h } from "hastscript"; import { toString } from "hast-util-to-string"; import { escape } from "html-escaper"; -import solid from "@astrojs/solid-js"; -import image from "@astrojs/image"; -// import compress from "astro-compress"; -import mdx from "@astrojs/mdx"; import remarkGfm from "remark-gfm"; import remarkSmartypants from "remark-smartypants"; import rehypeSlug from "rehype-slug"; @@ -23,6 +24,15 @@ export default defineConfig({ integrations: [ solid(), image(), + sitemap({ + i18n: { + defaultLocale: "ru", + locales: { + ru: "ru-RU", + en: "en-US", + }, + }, + }), mdx({ remarkPlugins: [remarkGfm, remarkSmartypants], rehypePlugins: [ diff --git a/package-lock.json b/package-lock.json index fa74583..8ead71b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,12 +8,11 @@ "name": "yarkov.tech", "version": "0.0.1", "license": "MIT", - "dependencies": { - "@astrojs/rss": "^1.0.0" - }, "devDependencies": { "@astrojs/image": "^0.3.4", "@astrojs/mdx": "^0.10.0", + "@astrojs/rss": "^1.0.0", + "@astrojs/sitemap": "^1.0.0", "@astrojs/solid-js": "^1.0.0", "@types/mdx": "^2.0.2", "@typescript-eslint/eslint-plugin": "^5.33.1", @@ -190,10 +189,21 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@astrojs/rss/-/rss-1.0.0.tgz", "integrity": "sha512-vOPocf/SC0TfHsCwQXupvLGm0y3oIwpRCnnF2igDP3gFSxQEOk4nmsuVTEU2N87hYyX1/5uxbjJhixuSV/L8Cw==", + "dev": true, "dependencies": { "fast-xml-parser": "^4.0.8" } }, + "node_modules/@astrojs/sitemap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-1.0.0.tgz", + "integrity": "sha512-42GxuF5FP7RaKXZrwGLBLOX3hPv+Wl7ExJC43O0J5e34ojJkLeKf7QfwN1UwrJlqH0Ywi0Fm4/xGe482G09+wg==", + "dev": true, + "dependencies": { + "sitemap": "^7.1.1", + "zod": "^3.17.3" + } + }, "node_modules/@astrojs/solid-js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@astrojs/solid-js/-/solid-js-1.0.0.tgz", @@ -1037,6 +1047,12 @@ "@types/unist": "*" } }, + "node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "dev": true + }, "node_modules/@types/parse5": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", @@ -1049,6 +1065,15 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, + "node_modules/@types/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/unist": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", @@ -1413,6 +1438,12 @@ "node": ">= 8" } }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3573,6 +3604,7 @@ "version": "4.0.9", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.9.tgz", "integrity": "sha512-4G8EzDg2Nb1Qurs3f7BpFV4+jpMVsdgLVuG1Uv8O2OHJfVCg7gcA53obuKbmVqzd4Y7YXVBK05oJG7hzGIdyzg==", + "dev": true, "dependencies": { "strnum": "^1.0.5" }, @@ -7751,6 +7783,12 @@ "suf-log": "^2.5.3" } }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, "node_modules/section-matter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", @@ -7943,6 +7981,25 @@ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, + "node_modules/sitemap": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", + "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", + "dev": true, + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.6.0" + } + }, "node_modules/slash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", @@ -8175,7 +8232,8 @@ "node_modules/strnum": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "dev": true }, "node_modules/style-to-object": { "version": "0.3.0", @@ -9370,10 +9428,21 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@astrojs/rss/-/rss-1.0.0.tgz", "integrity": "sha512-vOPocf/SC0TfHsCwQXupvLGm0y3oIwpRCnnF2igDP3gFSxQEOk4nmsuVTEU2N87hYyX1/5uxbjJhixuSV/L8Cw==", + "dev": true, "requires": { "fast-xml-parser": "^4.0.8" } }, + "@astrojs/sitemap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-1.0.0.tgz", + "integrity": "sha512-42GxuF5FP7RaKXZrwGLBLOX3hPv+Wl7ExJC43O0J5e34ojJkLeKf7QfwN1UwrJlqH0Ywi0Fm4/xGe482G09+wg==", + "dev": true, + "requires": { + "sitemap": "^7.1.1", + "zod": "^3.17.3" + } + }, "@astrojs/solid-js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@astrojs/solid-js/-/solid-js-1.0.0.tgz", @@ -10044,6 +10113,12 @@ "@types/unist": "*" } }, + "@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "dev": true + }, "@types/parse5": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", @@ -10056,6 +10131,15 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, + "@types/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/unist": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", @@ -10294,6 +10378,12 @@ "picomatch": "^2.0.4" } }, + "arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -11804,6 +11894,7 @@ "version": "4.0.9", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.9.tgz", "integrity": "sha512-4G8EzDg2Nb1Qurs3f7BpFV4+jpMVsdgLVuG1Uv8O2OHJfVCg7gcA53obuKbmVqzd4Y7YXVBK05oJG7hzGIdyzg==", + "dev": true, "requires": { "strnum": "^1.0.5" } @@ -14730,6 +14821,12 @@ "suf-log": "^2.5.3" } }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, "section-matter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", @@ -14867,6 +14964,18 @@ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, + "sitemap": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", + "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", + "dev": true, + "requires": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + } + }, "slash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", @@ -15029,7 +15138,8 @@ "strnum": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "dev": true }, "style-to-object": { "version": "0.3.0", diff --git a/package.json b/package.json index 4a4ecab..e30221c 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@astrojs/image": "^0.3.4", "@astrojs/mdx": "^0.10.0", "@astrojs/rss": "^1.0.0", + "@astrojs/sitemap": "^1.0.0", "@astrojs/solid-js": "^1.0.0", "@types/mdx": "^2.0.2", "@typescript-eslint/eslint-plugin": "^5.33.1", diff --git a/src/components/BaseLayout/BaseLayout.astro b/src/components/BaseLayout/BaseLayout.astro index 28f6f3f..390519e 100644 --- a/src/components/BaseLayout/BaseLayout.astro +++ b/src/components/BaseLayout/BaseLayout.astro @@ -1,13 +1,25 @@ --- -import './BaseLayout.scss'; -import Header from '@components/Header'; -import Footer from '@components/Footer'; +import { IS_SITE_UNDER_CONSTRUCTION } from "@root/config"; +import Header from "@components/Header"; +import Footer from "@components/Footer"; +import HeaderBanner from "@components/HeaderBanner"; +import UIString from "@components/UIString"; +import "./BaseLayout.scss"; --- + { + IS_SITE_UNDER_CONSTRUCTION && ( + + 🚧  + +  🚧 + + ) + }
    -
    - +
    +