This commit is contained in:
Sergey Yarkov 2020-07-21 23:14:50 +03:00
parent 96f29a1a74
commit 42df591c08
69 changed files with 1683 additions and 1236 deletions

View File

@ -1,3 +1,4 @@
# devthread.ru # devthread.ru
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![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/bde70986-e5af-4e69-b62c-ff0ed4b76401/deploy-status)](https://app.netlify.com/sites/devthread/deploys) [![Netlify Status](https://api.netlify.com/api/v1/badges/bde70986-e5af-4e69-b62c-ff0ed4b76401/deploy-status)](https://app.netlify.com/sites/devthread/deploys)

View File

@ -1,38 +1,40 @@
module.exports = { module.exports = {
title: 'devthread.ru', title: "devthread.ru",
keywords: 'веб разработка, javascript, seo, программирование, reactjs, graphql', keywords:
siteName: 'Cборник статей и руководств - devthread.ru', "веб разработка, javascript, seo, программирование, reactjs, graphql",
titleTemplate: '%s · статьи и руководства по веб-разработке', siteName: "Cборник статей и руководств - devthread.ru",
description: 'Cборник статей и руководств по тематике веб-разработки и IT для того чтобы помочь вам', titleTemplate: "%s · статьи и руководства по веб-разработке",
url: 'https://devthread.netlify.app', description:
"Cборник статей и руководств по тематике веб-разработки и IT для того чтобы помочь вам",
url: "https://devthread.netlify.app",
menuLinks: [ menuLinks: [
{ {
name: 'Статьи', name: "Статьи",
link: '/articles' link: "/articles",
}, },
{ {
name: 'О сайте', name: "О сайте",
link: '/about' link: "/about",
}, },
{ {
name: 'Контакты', name: "Контакты",
link: '/contacts' link: "/contacts",
}, },
{ {
name: 'Сниппеты', name: "Сниппеты",
link: '/snippets' link: "/snippets",
} },
], ],
social: { social: {
email: 'support@devthread.ru', email: "support@devthread.ru",
telegram: 'https://t.me/devthread', telegram: "https://t.me/devthread",
twitter: 'https://twitter.com/devthread', twitter: "https://twitter.com/devthread",
yadzen: 'https://zen.yandex.ru/' yadzen: "https://zen.yandex.ru/",
}, },
options: { options: {
articles: { articles: {
onPage: 6, onPage: 6,
onLoadMore: 2 onLoadMore: 2,
} },
} },
} }

View File

@ -20,11 +20,13 @@ tags:
- graphql - graphql
- reactjs - reactjs
--- ---
## this is second article ## this is second article
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
@ -38,13 +40,13 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligu
![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg) ![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg)
```js ```js
module.exports = { module.exports = {
plugins: [ plugins: [
{ {
resolve: `plugin` resolve: `plugin`,
} },
] ],
} }
``` ```
## List ## List

View File

@ -20,17 +20,18 @@ tags:
- graphql - graphql
- reactjs - reactjs
--- ---
## Lorem ipsum dolor ## Lorem ipsum dolor
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
@ -39,17 +40,17 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligu
![wallpaper](/assets/javascript.png) ![wallpaper](/assets/javascript.png)
```js ```js
module.exports = { module.exports = {
plugins: [ plugins: [
{ {
resolve: `plugin` resolve: `plugin`,
} },
] ],
} }
``` ```
## List ## List
1. First 1. First
2. Second 2. Second
3. Third 3. Third

View File

@ -19,35 +19,37 @@ description: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
tags: tags:
- javascript - javascript
--- ---
## Lorem ipsum dolor
## Lorem ipsum dolor
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula? Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. - Nunc non fermentum ligula?
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg) > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
```js ![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg)
module.exports = {
plugins: [ ```js
{ module.exports = {
resolve: `plugin` plugins: [
} {
] resolve: `plugin`,
} },
``` ],
}
## List ```
1. First ## List
2. Second
3. Third 1. First
2. Second
3. Third

View File

@ -22,36 +22,37 @@ tags:
- javascript - javascript
- graphql - graphql
--- ---
## Lorem ipsum dolor
## Lorem ipsum dolor
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](/assets/javascript.png)
![wallpaper](/assets/javascript.png)
```js
module.exports = { ```js
plugins: [ module.exports = {
{ plugins: [
resolve: `plugin` {
} resolve: `plugin`,
] },
} ],
``` }
```
## List
## List
1. First
2. Second 1. First
3. Third 2. Second
3. Third

View File

@ -19,41 +19,49 @@ tags:
- graphql - graphql
- reactjs - reactjs
--- ---
## this is second article
## this is second article
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula? Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. - Nunc non fermentum ligula?
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg) > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
```js ![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg)
const { siteMetadata: { title, menuLinks, social: { twitter, telegram } } } = useSiteMetadataQuery() //L1
const [isScrolled, setIsScrolled] = React.useState(false) ```js
const [isMobileOpen, setIsMobileOpen] = React.useState(false) const {
const [isDark, setIsDark] = React.useState(false) siteMetadata: {
title,
React.useEffect(() => { menuLinks,
setIsDark(window.__isDarkTheme) social: { twitter, telegram },
isMobileOpen },
? document.body.style.overflowY = 'hidden' } = useSiteMetadataQuery() //L1
: document.body.style.overflowY = '' const [isScrolled, setIsScrolled] = React.useState(false)
document.body.onscroll = () => const [isMobileOpen, setIsMobileOpen] = React.useState(false)
window.pageYOffset >= 100 ? setIsScrolled(true) : setIsScrolled(false) const [isDark, setIsDark] = React.useState(false)
}, [setIsDark, isMobileOpen])
``` React.useEffect(() => {
setIsDark(window.__isDarkTheme)
## List isMobileOpen
? (document.body.style.overflowY = "hidden")
1. First : (document.body.style.overflowY = "")
2. Second document.body.onscroll = () =>
3. Third window.pageYOffset >= 100 ? setIsScrolled(true) : setIsScrolled(false)
}, [setIsDark, isMobileOpen])
```
## List
1. First
2. Second
3. Third

View File

@ -18,35 +18,37 @@ description: |-
tags: tags:
- reactjs - reactjs
--- ---
## this is second article
## this is second article
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula? Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. - Nunc non fermentum ligula?
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg) > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
```js ![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg)
module.exports = {
plugins: [ ```js
{ module.exports = {
resolve: `plugin` plugins: [
} {
] resolve: `plugin`,
} },
``` ],
}
## List ```
1. First ## List
2. Second
3. Third 1. First
2. Second
3. Third

View File

@ -19,35 +19,37 @@ tags:
- reactjs - reactjs
- javascript - javascript
--- ---
## this is second article
## this is second article
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula? Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. - Nunc non fermentum ligula?
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg) > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
```js ![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg)
module.exports = {
plugins: [ ```js
{ module.exports = {
resolve: `plugin` plugins: [
} {
] resolve: `plugin`,
} },
``` ],
}
## List ```
1. First ## List
2. Second
3. Third 1. First
2. Second
3. Third

View File

@ -1,59 +1,67 @@
--- ---
templateKey: article templateKey: article
slug: article-12 slug: article-12
keywords: keywords:
- art - art
time: "4" time: "4"
title: Статья 12 title: Статья 12
popular: true popular: true
image: /assets/reactjs.jpg image: /assets/reactjs.jpg
category: Новости category: Новости
date: 2020-07-14T20:22:30.393Z date: 2020-07-14T20:22:30.393Z
description: |- description: |-
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit
esse cillum dolore eu fugiat nulla pariatur. esse cillum dolore eu fugiat nulla pariatur.
tags: tags:
- reactjs - reactjs
- javascript - javascript
--- ---
## this is second article
## this is second article
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula? Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. - Nunc non fermentum ligula?
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg) > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
```js ![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg)
const { siteMetadata: { title, menuLinks, social: { twitter, telegram } } } = useSiteMetadataQuery() //L1
const [isScrolled, setIsScrolled] = React.useState(false) ```js
const [isMobileOpen, setIsMobileOpen] = React.useState(false) const {
const [isDark, setIsDark] = React.useState(false) siteMetadata: {
title,
React.useEffect(() => { menuLinks,
setIsDark(window.__isDarkTheme) social: { twitter, telegram },
isMobileOpen },
? document.body.style.overflowY = 'hidden' } = useSiteMetadataQuery() //L1
: document.body.style.overflowY = '' const [isScrolled, setIsScrolled] = React.useState(false)
document.body.onscroll = () => const [isMobileOpen, setIsMobileOpen] = React.useState(false)
window.pageYOffset >= 100 ? setIsScrolled(true) : setIsScrolled(false) const [isDark, setIsDark] = React.useState(false)
}, [setIsDark, isMobileOpen])
``` React.useEffect(() => {
setIsDark(window.__isDarkTheme)
## List isMobileOpen
? (document.body.style.overflowY = "hidden")
1. First : (document.body.style.overflowY = "")
2. Second document.body.onscroll = () =>
3. Third window.pageYOffset >= 100 ? setIsScrolled(true) : setIsScrolled(false)
}, [setIsDark, isMobileOpen])
```
## List
1. First
2. Second
3. Third

View File

@ -20,35 +20,37 @@ tags:
- javascript - javascript
- graphql - graphql
--- ---
## this is second article
## this is second article
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula? Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. - Nunc non fermentum ligula?
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg) > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
```js ![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg)
module.exports = {
plugins: [ ```js
{ module.exports = {
resolve: `plugin` plugins: [
} {
] resolve: `plugin`,
} },
``` ],
}
## List ```
1. First ## List
2. Second
3. Third 1. First
2. Second
3. Third

View File

@ -20,35 +20,37 @@ tags:
- javascript - javascript
- graphql - graphql
--- ---
## this is second article
## this is second article
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula? Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. - Nunc non fermentum ligula?
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg) > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
```js ![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg)
module.exports = {
plugins: [ ```js
{ module.exports = {
resolve: `plugin` plugins: [
} {
] resolve: `plugin`,
} },
``` ],
}
## List ```
1. First ## List
2. Second
3. Third 1. First
2. Second
3. Third

View File

@ -21,35 +21,37 @@ tags:
- javascript - javascript
- graphql - graphql
--- ---
## this is second article
## this is second article
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula? Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. - Nunc non fermentum ligula?
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg) > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
```js ![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg)
module.exports = {
plugins: [ ```js
{ module.exports = {
resolve: `plugin` plugins: [
} {
] resolve: `plugin`,
} },
``` ],
}
## List ```
1. First ## List
2. Second
3. Third 1. First
2. Second
3. Third

View File

@ -20,35 +20,37 @@ tags:
- javascript - javascript
- graphql - graphql
--- ---
## this is second article
## this is second article
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula? Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. - Nunc non fermentum ligula?
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg) > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
```js ![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg)
module.exports = {
plugins: [ ```js
{ module.exports = {
resolve: `plugin` plugins: [
} {
] resolve: `plugin`,
} },
``` ],
}
## List ```
1. First ## List
2. Second
3. Third 1. First
2. Second
3. Third

View File

@ -20,35 +20,37 @@ tags:
- javascript - javascript
- graphql - graphql
--- ---
## this is second article
## this is second article
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula? Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. - Nunc non fermentum ligula?
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg) > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
```js ![wallpaper](https://wallpaperplay.com/walls/full/2/9/7/164604.jpg)
module.exports = {
plugins: [ ```js
{ module.exports = {
resolve: `plugin` plugins: [
} {
] resolve: `plugin`,
} },
``` ],
}
## List ```
1. First ## List
2. Second
3. Third 1. First
2. Second
3. Third

View File

@ -13,36 +13,37 @@ tags:
description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non
fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo.
--- ---
## Lorem ipsum dolor
## Lorem ipsum dolor
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](/assets/javascript.png)
![wallpaper](/assets/javascript.png)
```js
module.exports = { ```js
plugins: [ module.exports = {
{ plugins: [
resolve: `plugin` {
} resolve: `plugin`,
] },
} ],
``` }
```
## List
## List
1. First
2. Second 1. First
3. Third 2. Second
3. Third

View File

@ -13,36 +13,37 @@ tags:
description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non
fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo.
--- ---
## Lorem ipsum dolor
## Lorem ipsum dolor
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](/assets/javascript.png)
![wallpaper](/assets/javascript.png)
```js
module.exports = { ```js
plugins: [ module.exports = {
{ plugins: [
resolve: `plugin` {
} resolve: `plugin`,
] },
} ],
``` }
```
## List
## List
1. First
2. Second 1. First
3. Third 2. Second
3. Third

View File

@ -13,36 +13,37 @@ tags:
description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non
fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo.
--- ---
## Lorem ipsum dolor
## Lorem ipsum dolor
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
* Nunc non fermentum ligula? - Nunc non fermentum ligula?
- Nunc non fermentum ligula?
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non fermentum ligula. Aenean et ex nec magna faucibus congue eu ac justo. Cras malesuada diam lectus, vitae feugiat nulla condimentum id. Duis interdum sodales eros ornare mattis. Nunc id viverra ante. Maecenas suscipit est sed rhoncus condimentum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur vehicula risus nisi, quis hendrerit magna tincidunt eu. Phasellus fringilla accumsan viverra. Mauris a cursus orci.
![wallpaper](/assets/javascript.png)
![wallpaper](/assets/javascript.png)
```js
module.exports = { ```js
plugins: [ module.exports = {
{ plugins: [
resolve: `plugin` {
} resolve: `plugin`,
] },
} ],
``` }
```
## List
## List
1. First
2. Second 1. First
3. Third 2. Second
3. Third

View File

@ -1,29 +1,27 @@
import 'firebase/database'; import "firebase/database"
import 'gatsby-remark-vscode/styles.css' import "gatsby-remark-vscode/styles.css"
import './src/styles/global.scss' import "./src/styles/global.scss"
import './src/components/Header/Header.scss' import "./src/components/Header/Header.scss"
import './src/components/About/About.scss' import "./src/components/About/About.scss"
import './src/components/Offers/Offers.scss' import "./src/components/Offers/Offers.scss"
import './src/components/Articles/Articles.scss' import "./src/components/Articles/Articles.scss"
import './src/components/Articles/ArticleCard/ArticleCard.scss' import "./src/components/Articles/ArticleCard/ArticleCard.scss"
import './src/components/Newsletter/Newsletter.scss' import "./src/components/Newsletter/Newsletter.scss"
import './src/components/Article/Article.scss' import "./src/components/Article/Article.scss"
import './src/components/Snippet/Snippet.scss' import "./src/components/Snippet/Snippet.scss"
import './src/components/Snippets/Snippets.scss' import "./src/components/Snippets/Snippets.scss"
import './src/components/Articles/MoreArticles/MoreArticles.scss' import "./src/components/Articles/MoreArticles/MoreArticles.scss"
import './src/components/Books/Books.scss' import "./src/components/Books/Books.scss"
import './src/components/Contacts/Contacts.scss' import "./src/components/Contacts/Contacts.scss"
import './src/components/Footer/Footer.scss' import "./src/components/Footer/Footer.scss"
export const shouldUpdateScroll = ({ export const shouldUpdateScroll = ({ routerProps: { location } }) => {
routerProps: { location }
}) => {
const { pathname } = location const { pathname } = location
const stopScrollLinks = ['/articles/'] const stopScrollLinks = ["/articles/"]
if (stopScrollLinks.includes(pathname)) return false if (stopScrollLinks.includes(pathname)) return false
return window.scrollTo(0, 0) return window.scrollTo(0, 0)
} }

View File

@ -1,19 +1,19 @@
require('dotenv').config() require("dotenv").config()
const siteConfig = require('./config') const siteConfig = require("./config")
module.exports = { module.exports = {
siteMetadata: { siteMetadata: {
...siteConfig ...siteConfig,
}, },
plugins: [ plugins: [
'gatsby-plugin-react-helmet', "gatsby-plugin-react-helmet",
'gatsby-plugin-sass', "gatsby-plugin-sass",
{ {
resolve: 'gatsby-source-filesystem', resolve: "gatsby-source-filesystem",
options: { options: {
path: `${__dirname}/static/assets`, path: `${__dirname}/static/assets`,
name: 'assets', name: "assets",
}, },
}, },
{ {
@ -40,7 +40,7 @@ module.exports = {
}, },
}, },
{ {
resolve: 'gatsby-plugin-firebase', resolve: "gatsby-plugin-firebase",
options: { options: {
credentials: { credentials: {
apiKey: process.env.API_KEY, apiKey: process.env.API_KEY,
@ -61,7 +61,7 @@ module.exports = {
}, },
}, },
"gatsby-plugin-sharp", "gatsby-plugin-sharp",
"gatsby-transformer-sharp", "gatsby-transformer-sharp",
{ {
resolve: `gatsby-transformer-remark`, resolve: `gatsby-transformer-remark`,
options: { options: {
@ -69,8 +69,8 @@ module.exports = {
{ {
resolve: `gatsby-remark-relative-images`, resolve: `gatsby-remark-relative-images`,
options: { options: {
name: "assets" name: "assets",
} },
}, },
{ {
resolve: `gatsby-remark-images`, resolve: `gatsby-remark-images`,
@ -89,41 +89,41 @@ module.exports = {
removeAccents: true, removeAccents: true,
isIconAfterHeader: true, isIconAfterHeader: true,
elements: [`h1`, `h2`, `h3`, `h4`], elements: [`h1`, `h2`, `h3`, `h4`],
} },
}, },
{ {
resolve: `gatsby-remark-vscode`, resolve: `gatsby-remark-vscode`,
options: { options: {
extensions: ['material-theme'], extensions: ["material-theme"],
theme: { theme: {
default: 'Light+ (default light)', default: "Light+ (default light)",
parentSelector: { parentSelector: {
'body.dark': 'One Dark Pro' "body.dark": "One Dark Pro",
} },
}, },
} },
} },
] ],
} },
} },
], ],
}, },
}, },
{ {
resolve: 'gatsby-plugin-react-svg', resolve: "gatsby-plugin-react-svg",
options: { options: {
rule: { rule: {
include: /images/ include: /images/,
} },
} },
}, },
{ {
resolve: 'gatsby-source-filesystem', resolve: "gatsby-source-filesystem",
options: { options: {
name: 'content', name: "content",
path: `${__dirname}/content` path: `${__dirname}/content`,
} },
}, },
'gatsby-plugin-netlify-cms', "gatsby-plugin-netlify-cms",
], ],
} }

View File

@ -1,14 +1,14 @@
import slugify from './src/helpers/slugify' import slugify from "./src/helpers/slugify"
import { fmImagesToRelative } from 'gatsby-remark-relative-images' import { fmImagesToRelative } from "gatsby-remark-relative-images"
import path from 'path' import path from "path"
exports.createPages = async ({ actions, graphql }) => { exports.createPages = async ({ actions, graphql }) => {
const { createPage } = actions const { createPage } = actions
const articleTemplate = path.resolve('src/templates/articleTemplate.js') const articleTemplate = path.resolve("src/templates/articleTemplate.js")
const snippetTemplate = path.resolve('src/templates/snippetTemplate.js') const snippetTemplate = path.resolve("src/templates/snippetTemplate.js")
const categoryTemplate = path.resolve('src/templates/categoryTemplate.js') const categoryTemplate = path.resolve("src/templates/categoryTemplate.js")
const tagTemplate = path.resolve('src/templates/tagTemplate.js') const tagTemplate = path.resolve("src/templates/tagTemplate.js")
const result = await graphql( const result = await graphql(
` `
@ -24,7 +24,7 @@ exports.createPages = async ({ actions, graphql }) => {
} }
} }
} }
} }
` `
) )
@ -33,19 +33,25 @@ exports.createPages = async ({ actions, graphql }) => {
} }
const all = result.data.allMarkdownRemark.edges const all = result.data.allMarkdownRemark.edges
const articles = all.filter(article => article.node.frontmatter.templateKey === 'article') const articles = all.filter(
const snippets = all.filter(snippet => snippet.node.frontmatter.templateKey === 'snippet') article => article.node.frontmatter.templateKey === "article"
const categories = all.filter(category => category.node.frontmatter.templateKey === 'category') )
const tags = all.filter(tag => tag.node.frontmatter.templateKey === 'tag') const snippets = all.filter(
snippet => snippet.node.frontmatter.templateKey === "snippet"
)
const categories = all.filter(
category => category.node.frontmatter.templateKey === "category"
)
const tags = all.filter(tag => tag.node.frontmatter.templateKey === "tag")
articles.forEach(({ node }) => { articles.forEach(({ node }) => {
createPage({ createPage({
path: `article/${node.frontmatter.slug}`, path: `article/${node.frontmatter.slug}`,
component: articleTemplate, component: articleTemplate,
context: { context: {
slug: node.frontmatter.slug slug: node.frontmatter.slug,
}, },
}); })
}) })
snippets.forEach(({ node }) => { snippets.forEach(({ node }) => {
@ -53,7 +59,7 @@ exports.createPages = async ({ actions, graphql }) => {
path: `snippet/${node.frontmatter.slug}`, path: `snippet/${node.frontmatter.slug}`,
component: snippetTemplate, component: snippetTemplate,
context: { context: {
slug: node.frontmatter.slug slug: node.frontmatter.slug,
}, },
}) })
}) })
@ -63,9 +69,9 @@ exports.createPages = async ({ actions, graphql }) => {
path: `category/${slugify(node.frontmatter.title)}`, path: `category/${slugify(node.frontmatter.title)}`,
component: categoryTemplate, component: categoryTemplate,
context: { context: {
title: node.frontmatter.title title: node.frontmatter.title,
}, },
}); })
}) })
tags.forEach(({ node }) => { tags.forEach(({ node }) => {
@ -73,12 +79,12 @@ exports.createPages = async ({ actions, graphql }) => {
path: `tag/${slugify(node.frontmatter.title)}`, path: `tag/${slugify(node.frontmatter.title)}`,
component: tagTemplate, component: tagTemplate,
context: { context: {
title: node.frontmatter.title title: node.frontmatter.title,
} },
}) })
}) })
} }
exports.onCreateNode = ({ node }) => { exports.onCreateNode = ({ node }) => {
fmImagesToRelative(node); fmImagesToRelative(node)
}; }

View File

@ -1,2 +1,2 @@
require = require('esm')(module) require = require("esm")(module)
module.exports = require('./gatsby-node.esm.js') module.exports = require("./gatsby-node.esm.js")

View File

@ -1,10 +1,11 @@
import React from 'react'; import React from "react"
import 'firebase/database'; import "firebase/database"
const OnDark = () => { const OnDark = () => {
return ( return (
<script <script
dangerouslySetInnerHTML={{ __html: ` dangerouslySetInnerHTML={{
__html: `
(() => { (() => {
window.__isDarkTheme = false window.__isDarkTheme = false
@ -31,11 +32,12 @@ const OnDark = () => {
} }
} }
})() })()
` }} `,
}}
/> />
) )
} }
export const onRenderBody = ({ setPreBodyComponents }) => { export const onRenderBody = ({ setPreBodyComponents }) => {
setPreBodyComponents(<OnDark key='isDarkTheme' />) setPreBodyComponents(<OnDark key="isDarkTheme" />)
} }

View File

@ -1,8 +1,8 @@
import React from 'react'; import React from "react"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import { Link } from 'gatsby' import { Link } from "gatsby"
import ContactsIcon from '../../images/contacts-icon.svg' import ContactsIcon from "../../images/contacts-icon.svg"
const About = ({ title, pageTitle, social }) => { const About = ({ title, pageTitle, social }) => {
return ( return (
@ -15,11 +15,12 @@ const About = ({ title, pageTitle, social }) => {
<h2>{title}</h2> <h2>{title}</h2>
<h3>публикуем статьи о мире веб-разрабоки и IT</h3> <h3>публикуем статьи о мире веб-разрабоки и IT</h3>
<p> <p>
этот сайт придуман для того, чтобы помочь вам разобраться с вашей проблемой и решить её. Сайт содержит этот сайт придуман для того, чтобы помочь вам разобраться с вашей
в себе статьи и руководства. проблемой и решить её. Сайт содержит в себе статьи и руководства.
</p> </p>
<p> <p>
~ к тому же здесь публикуются различные новости которые произошли за последнее время ~ к тому же здесь публикуются различные новости которые произошли за
последнее время
</p> </p>
</div> </div>
<div className="about-content__contacts"> <div className="about-content__contacts">
@ -28,9 +29,15 @@ const About = ({ title, pageTitle, social }) => {
<span>контакты</span> <span>контакты</span>
</div> </div>
<ul> <ul>
<li><a href={`mailto:${social.email}`}>{social.email}</a></li> <li>
<li><a href={social.telegram} target='_blank' rel='noreferrer'>telegram</a></li> <a href={`mailto:${social.email}`}>{social.email}</a>
<Link to='/contacts'>форма обратной связи</Link> </li>
<li>
<a href={social.telegram} target="_blank" rel="noreferrer">
telegram
</a>
</li>
<Link to="/contacts">форма обратной связи</Link>
</ul> </ul>
</div> </div>
</div> </div>
@ -43,5 +50,5 @@ export default About
About.propTypes = { About.propTypes = {
title: PropTypes.string, title: PropTypes.string,
pageTitle: PropTypes.string, pageTitle: PropTypes.string,
email: PropTypes.string email: PropTypes.string,
} }

View File

@ -1,25 +1,47 @@
import React from 'react'; import React from "react"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import SEO from '../SEO/SEO' import SEO from "../SEO/SEO"
import Img from "gatsby-image" import Img from "gatsby-image"
import ViewCounter from '../ViewCounter/ViewCounter' import ViewCounter from "../ViewCounter/ViewCounter"
import useSiteMetadataQuery from '../../hooks/useSiteMetadataQuery' import useSiteMetadataQuery from "../../hooks/useSiteMetadataQuery"
import slugify from '../../helpers/slugify' import slugify from "../../helpers/slugify"
import { Link } from 'gatsby' import { Link } from "gatsby"
import { useLocation } from '@reach/router' import { useLocation } from "@reach/router"
import ViewsIcon from '../../images/views-icon.svg' import ViewsIcon from "../../images/views-icon.svg"
import VkIcon from '../../images/vk-icon.svg' import VkIcon from "../../images/vk-icon.svg"
import TwitterIcon from '../../images/twitter-icon__large.svg' import TwitterIcon from "../../images/twitter-icon__large.svg"
import FacebookIcon from '../../images/facebook-icon__large.svg' import FacebookIcon from "../../images/facebook-icon__large.svg"
const Article = ({ data: { slug, keywords, title, image, description, category, tags, time, date }, html }) => { const Article = ({
const { siteMetadata: { siteUrl } } = useSiteMetadataQuery() data: {
slug,
keywords,
title,
image,
description,
category,
tags,
time,
date,
},
html,
}) => {
const {
siteMetadata: { siteUrl },
} = useSiteMetadataQuery()
const { pathname } = useLocation() const { pathname } = useLocation()
return ( return (
<> <>
<SEO title={title} titleTemplate={false} keywords={keywords.join(', ')} description={description} image={`${siteUrl}${image.childImageSharp.fluid.src}`} type='article' /> <SEO
title={title}
titleTemplate={false}
keywords={keywords.join(", ")}
description={description}
image={`${siteUrl}${image.childImageSharp.fluid.src}`}
type="article"
/>
<div className="article"> <div className="article">
<article> <article>
<div className="article-info"> <div className="article-info">
@ -30,23 +52,35 @@ const Article = ({ data: { slug, keywords, title, image, description, category,
<div className="article-info__views"> <div className="article-info__views">
<ViewsIcon /> <ViewsIcon />
<ViewCounter id={pathname} /> <ViewCounter id={pathname} />
</div> </div>
</div> </div>
<div className="right-info"> <div className="right-info">
<div className="article-info__date"> <div className="article-info__date">
<span>{date}</span> <span>{date}</span>
</div> </div>
</div> </div>
</div> </div>
<div className="article-share"> <div className="article-share">
<div className="article-share__social"> <div className="article-share__social">
<a href={`https://vk.com/share.php?url=${siteUrl}/article/${slug}&title=${title}&image=${siteUrl}${image.childImageSharp.fluid.src}`} target='_blank' rel='noreferrer'> <a
href={`https://vk.com/share.php?url=${siteUrl}/article/${slug}&title=${title}&image=${siteUrl}${image.childImageSharp.fluid.src}`}
target="_blank"
rel="noreferrer"
>
<VkIcon /> <VkIcon />
</a> </a>
<a href={`https://twitter.com/intent/tweet?text=${title}&url=${siteUrl}/article/${slug}&image=${siteUrl}${image.childImageSharp.fluid.src}`} target='_blank' rel='noreferrer'> <a
href={`https://twitter.com/intent/tweet?text=${title}&url=${siteUrl}/article/${slug}&image=${siteUrl}${image.childImageSharp.fluid.src}`}
target="_blank"
rel="noreferrer"
>
<TwitterIcon /> <TwitterIcon />
</a> </a>
<a href={`https://www.facebook.com/sharer/sharer.php?u=${siteUrl}/article/${slug}&t=${title}`} target='_blank' rel='noreferrer'> <a
href={`https://www.facebook.com/sharer/sharer.php?u=${siteUrl}/article/${slug}&t=${title}`}
target="_blank"
rel="noreferrer"
>
<FacebookIcon /> <FacebookIcon />
</a> </a>
</div> </div>
@ -58,30 +92,37 @@ const Article = ({ data: { slug, keywords, title, image, description, category,
<Link to={`/category/${slugify(category)}`}>{category}</Link> <Link to={`/category/${slugify(category)}`}>{category}</Link>
</div> </div>
<div className="article-description"> <div className="article-description">
<p> <p>{description}</p>
{description}
</p>
</div> </div>
<div className="article-tags"> <div className="article-tags">
{tags.map((tag, i) => <div key={i} className="tag-item"> {tags.map((tag, i) => (
<Link to={`/tag/${slugify(tag)}`}>{tag}</Link> <div key={i} className="tag-item">
</div>)} <Link to={`/tag/${slugify(tag)}`}>{tag}</Link>
</div>
))}
</div> </div>
<div className="article-image"> <div className="article-image">
<Img loading="eager" fadeIn={false} fluid={image.childImageSharp.fluid} alt={title} /> <Img
loading="eager"
fadeIn={false}
fluid={image.childImageSharp.fluid}
alt={title}
/>
</div> </div>
<div className="article-inner inner"> <div className="article-inner inner">
<div dangerouslySetInnerHTML={{__html: html}}></div> <div dangerouslySetInnerHTML={{ __html: html }}></div>
</div> </div>
<div className="article-more"> <div className="article-more">
<span>Смотреть еще в категории <Link to={`/category/${slugify(category)}`}>{category}</Link></span> <span>
Смотреть еще в категории{" "}
<Link to={`/category/${slugify(category)}`}>{category}</Link>
</span>
</div> </div>
<div className="article-comments"> <div className="article-comments">
<div className="article-comments__heading"> <div className="article-comments__heading">
<h2>Комментарии</h2> <h2>Комментарии</h2>
</div> </div>
<div className="article-comments__content"> <div className="article-comments__content"></div>
</div>
</div> </div>
</article> </article>
</div> </div>
@ -101,7 +142,7 @@ Article.propTypes = {
category: PropTypes.string, category: PropTypes.string,
tags: PropTypes.array, tags: PropTypes.array,
time: PropTypes.string, time: PropTypes.string,
date: PropTypes.string date: PropTypes.string,
}), }),
html: PropTypes.string html: PropTypes.string,
} }

View File

@ -1,32 +1,43 @@
import React from 'react'; import React from "react"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import slugify from '../../../helpers/slugify' import slugify from "../../../helpers/slugify"
import Img from "gatsby-image" import Img from "gatsby-image"
import { Link } from 'gatsby' import { Link } from "gatsby"
const ArticleCard = ({ data: { slug, title, image, category, description, tags } }) => { const ArticleCard = ({
data: { slug, title, image, category, description, tags },
}) => {
return ( return (
<article className="article-card"> <article className="article-card">
<div className="article-card__image"> <div className="article-card__image">
<Link to={`/article/${slug}`}> <Link to={`/article/${slug}`}>
<Img loading="eager" fadeIn={false} fluid={image.childImageSharp.fluid} alt={title} /> <Img
loading="eager"
fadeIn={false}
fluid={image.childImageSharp.fluid}
alt={title}
/>
</Link> </Link>
</div> </div>
<div className="article-card__heading"> <div className="article-card__heading">
<h2><Link to={`/article/${slug}`}>{title}</Link></h2> <h2>
<Link to={`/article/${slug}`}>{title}</Link>
</h2>
</div> </div>
<div className="article-card__category"> <div className="article-card__category">
<Link to={`/category/${slugify(category)}`}>{category}</Link> <Link to={`/category/${slugify(category)}`}>{category}</Link>
</div> </div>
<div className="article-card__tags"> <div className="article-card__tags">
<ul> <ul>
{tags.map((tag, i) => <li key={i}><Link to={`/tag/${tag}`}>{tag}</Link></li>)} {tags.map((tag, i) => (
<li key={i}>
<Link to={`/tag/${tag}`}>{tag}</Link>
</li>
))}
</ul> </ul>
</div> </div>
<div className="article-card__description"> <div className="article-card__description">
<p> <p>{description}</p>
{description}
</p>
</div> </div>
</article> </article>
) )
@ -41,6 +52,6 @@ ArticleCard.propTypes = {
image: PropTypes.object, image: PropTypes.object,
category: PropTypes.string, category: PropTypes.string,
description: PropTypes.string, description: PropTypes.string,
tags: PropTypes.array tags: PropTypes.array,
}) }),
} }

View File

@ -1,10 +1,16 @@
import React from 'react'; import React from "react"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import useSiteMetadataQuery from '../../hooks/useSiteMetadataQuery' import useSiteMetadataQuery from "../../hooks/useSiteMetadataQuery"
import ArticleCard from './ArticleCard/ArticleCard' import ArticleCard from "./ArticleCard/ArticleCard"
const Articles = ({ data: { edges }, limit = 6, setLimit = () => null }) => { const Articles = ({ data: { edges }, limit = 6, setLimit = () => null }) => {
const { siteMetadata: { options: { articles: { onLoadMore } } } } = useSiteMetadataQuery() const {
siteMetadata: {
options: {
articles: { onLoadMore },
},
},
} = useSiteMetadataQuery()
return ( return (
<> <>
<div className="articles"> <div className="articles">
@ -16,14 +22,20 @@ const Articles = ({ data: { edges }, limit = 6, setLimit = () => null }) => {
return <ArticleCard key={i} data={node.frontmatter} /> return <ArticleCard key={i} data={node.frontmatter} />
} }
return null return null
}) })}
}
</div> </div>
<div className="articles-loadMore"> <div className="articles-loadMore">
{edges.length === limit || edges.length <= limit {edges.length === limit || edges.length <= limit ? null : (
? null <button
: <button className='btn-loadMore' onClick={() => setLimit(limit + onLoadMore)}>Загрузить еще&nbsp;&nbsp;<span role='img' aria-label='load more'>👇</span></button> className="btn-loadMore"
} onClick={() => setLimit(limit + onLoadMore)}
>
Загрузить еще&nbsp;&nbsp;
<span role="img" aria-label="load more">
👇
</span>
</button>
)}
</div> </div>
</div> </div>
</> </>
@ -36,6 +48,6 @@ Articles.propTypes = {
data: PropTypes.shape({ data: PropTypes.shape({
edges: PropTypes.array, edges: PropTypes.array,
limit: PropTypes.number, limit: PropTypes.number,
setLimit: PropTypes.func setLimit: PropTypes.func,
}) }),
} }

View File

@ -1,18 +1,23 @@
import React from 'react'; import React from "react"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import { useLocation } from '@reach/router' import { useLocation } from "@reach/router"
import { Link } from 'gatsby' import { Link } from "gatsby"
const Categories = ({ children, setQuery = () => null }) => { const Categories = ({ children, setQuery = () => null }) => {
const { search, pathname } = useLocation() const { search, pathname } = useLocation()
return ( return (
<div className="articles-categories"> <div className="articles-categories">
<div className={ <div
pathname === `/articles` || (pathname === `/articles/` && search === '') className={
? 'tag-item active' pathname === `/articles` ||
: 'tag-item' (pathname === `/articles/` && search === "")
}> ? "tag-item active"
<Link onClick={() => setQuery('')} to='/articles'>Все</Link> : "tag-item"
}
>
<Link onClick={() => setQuery("")} to="/articles">
Все
</Link>
</div> </div>
{children} {children}
</div> </div>
@ -22,5 +27,5 @@ const Categories = ({ children, setQuery = () => null }) => {
export default Categories export default Categories
Categories.propTypes = { Categories.propTypes = {
setQuery: PropTypes.func setQuery: PropTypes.func,
} }

View File

@ -1,13 +1,20 @@
import React from 'react'; import React from "react"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import { useLocation } from '@reach/router' import { useLocation } from "@reach/router"
import { Link } from 'gatsby' import { Link } from "gatsby"
import slugify from '../../../helpers/slugify' import slugify from "../../../helpers/slugify"
const CategoryItem = ({ title }) => { const CategoryItem = ({ title }) => {
const { pathname } = useLocation() const { pathname } = useLocation()
return ( return (
<div className={pathname === `/category/${slugify(title)}` || pathname === `/category/${slugify(title)}/` ? 'tag-item active' : 'tag-item'}> <div
className={
pathname === `/category/${slugify(title)}` ||
pathname === `/category/${slugify(title)}/`
? "tag-item active"
: "tag-item"
}
>
<Link to={`/category/${slugify(title)}`}>{title}</Link> <Link to={`/category/${slugify(title)}`}>{title}</Link>
</div> </div>
) )
@ -16,6 +23,5 @@ const CategoryItem = ({ title }) => {
export default CategoryItem export default CategoryItem
CategoryItem.propTypes = { CategoryItem.propTypes = {
title: PropTypes.string title: PropTypes.string,
} }

View File

@ -1,12 +1,12 @@
import React from 'react'; import React from "react"
import { useLocation } from '@reach/router' import { useLocation } from "@reach/router"
import useMoreArticlesQuery from '../../../hooks/useMoreArticlesQuery' import useMoreArticlesQuery from "../../../hooks/useMoreArticlesQuery"
import ArticleCard from '../ArticleCard/ArticleCard' import ArticleCard from "../ArticleCard/ArticleCard"
const MoreArticles = () => { const MoreArticles = () => {
const { edges } = useMoreArticlesQuery() const { edges } = useMoreArticlesQuery()
const { pathname } = useLocation() const { pathname } = useLocation()
const query = pathname.split('/')[pathname.split('/').length - 1] const query = pathname.split("/")[pathname.split("/").length - 1]
return ( return (
<div className="more-articles"> <div className="more-articles">
@ -14,15 +14,18 @@ const MoreArticles = () => {
<h2>Вам также может понравится...</h2> <h2>Вам также может понравится...</h2>
</div> </div>
<div className="more-articles__content"> <div className="more-articles__content">
{edges.filter(({ node }) => node.frontmatter.slug !== query).sort(() => Math.random() - 0.5).map(({ node }, i) => { {edges
if (i < 4) { .filter(({ node }) => node.frontmatter.slug !== query)
return <ArticleCard key={i} data={node.frontmatter} /> .sort(() => Math.random() - 0.5)
} .map(({ node }, i) => {
return null if (i < 4) {
})} return <ArticleCard key={i} data={node.frontmatter} />
}
return null
})}
</div> </div>
</div> </div>
) )
} }
export default MoreArticles export default MoreArticles

View File

@ -1,40 +1,55 @@
import React from 'react' import React from "react"
import { navigate } from 'gatsby' import { navigate } from "gatsby"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
const Search = ({ allArticles, filterArticles, articlesLength, resultsLength, query, setQuery, setFiltredArticles, setLimit, onPage }) => { const Search = ({
const handleInput = e => { allArticles,
const query = e.target.value filterArticles,
if (query === '') { articlesLength,
navigate('/articles/') resultsLength,
setQuery('') query,
setLimit(onPage) setQuery,
return null setFiltredArticles,
} setLimit,
navigate(`/articles/?search=${query.trim()}`) onPage,
setQuery(query) }) => {
setFiltredArticles(filterArticles(allArticles)) const handleInput = e => {
setLimit(onPage) const query = e.target.value
} if (query === "") {
navigate("/articles/")
setQuery("")
setLimit(onPage)
return null
}
navigate(`/articles/?search=${query.trim()}`)
setQuery(query)
setFiltredArticles(filterArticles(allArticles))
setLimit(onPage)
}
return ( return (
<div className="articles-search"> <div className="articles-search">
<input onChange={e => handleInput(e)} value={query} placeholder="Напишите сюда чтобы отфильтровать статьи" type="text" /> <input
<span>{query === '' ? articlesLength : resultsLength}</span> onChange={e => handleInput(e)}
value={query}
placeholder="Напишите сюда чтобы отфильтровать статьи"
type="text"
/>
<span>{query === "" ? articlesLength : resultsLength}</span>
</div> </div>
) )
} }
export default Search export default Search
Search.propTypes = { Search.propTypes = {
allArticles: PropTypes.array, allArticles: PropTypes.array,
filterArticles: PropTypes.func, filterArticles: PropTypes.func,
articlesLength: PropTypes.number, articlesLength: PropTypes.number,
resultsLength: PropTypes.number, resultsLength: PropTypes.number,
query: PropTypes.string, query: PropTypes.string,
setQuery: PropTypes.func, setQuery: PropTypes.func,
setFiltredArticles: PropTypes.func, setFiltredArticles: PropTypes.func,
setLimit: PropTypes.func, setLimit: PropTypes.func,
onPage: PropTypes.number onPage: PropTypes.number,
} }

View File

@ -1,17 +1,36 @@
import React from 'react'; import React from "react"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import slugify from '../../helpers/slugify' import slugify from "../../helpers/slugify"
import Img from "gatsby-image" import Img from "gatsby-image"
const Books = ({ data: { edges } }) => { const Books = ({ data: { edges } }) => {
return ( return (
<div className="books"> <div className="books">
<div className="books-inner inner"> <div className="books-inner inner">
{edges.map(({ node }, i) => <div key={i}> {edges.map(({ node }, i) => (
<h2>{node.frontmatter.title} <a id={slugify(node.frontmatter.title)} href={`/books#${slugify(node.frontmatter.title)}`} className='anchor'>{node.frontmatter.title}</a></h2> <div key={i}>
<Img loading="eager" fadeIn={false} fluid={node.frontmatter.image.childImageSharp.fluid} alt={node.frontmatter.title} /> <h2>
<div className='md' dangerouslySetInnerHTML={{__html: node.html}}></div> {node.frontmatter.title}{" "}
</div>)} <a
id={slugify(node.frontmatter.title)}
href={`/books#${slugify(node.frontmatter.title)}`}
className="anchor"
>
{node.frontmatter.title}
</a>
</h2>
<Img
loading="eager"
fadeIn={false}
fluid={node.frontmatter.image.childImageSharp.fluid}
alt={node.frontmatter.title}
/>
<div
className="md"
dangerouslySetInnerHTML={{ __html: node.html }}
></div>
</div>
))}
</div> </div>
</div> </div>
) )
@ -21,6 +40,6 @@ export default Books
Books.propTypes = { Books.propTypes = {
data: PropTypes.shape({ data: PropTypes.shape({
edges: PropTypes.array edges: PropTypes.array,
}) }),
} }

View File

@ -1,27 +1,33 @@
import React from 'react'; import React from "react"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import ContactsFrom from './ContactsForm/ContactsForm'; import ContactsFrom from "./ContactsForm/ContactsForm"
import MemoIcon from '../../images/memo-icon.svg' import MemoIcon from "../../images/memo-icon.svg"
const Contacts = ({ email, telegram }) => { const Contacts = ({ email, telegram }) => {
return ( return (
<div className="contacts"> <div className="contacts">
<div className="contacts-heading"> <div className="contacts-heading">
<MemoIcon /> <MemoIcon />
<h1>Контакты</h1> <h1>Контакты</h1>
</div> </div>
<div className="contacts-description"> <div className="contacts-description">
<p> <p>
Для того чтобы задать вопрос, сообщить об ошибках или просто поздороваться, вы можете воспользоваться формой обратной связи или использовать контактные данные. Для того чтобы задать вопрос, сообщить об ошибках или просто
поздороваться, вы можете воспользоваться формой обратной связи или
использовать контактные данные.
</p> </p>
</div> </div>
<ContactsFrom /> <ContactsFrom />
<div className="contacts-info"> <div className="contacts-info">
<h2>контактные данные</h2> <h2>контактные данные</h2>
<ul> <ul>
<li><a href={`mailto:${email}`}>{email}</a></li> <li>
<li><a href={telegram}>telegram</a></li> <a href={`mailto:${email}`}>{email}</a>
</li>
<li>
<a href={telegram}>telegram</a>
</li>
</ul> </ul>
</div> </div>
</div> </div>
@ -32,5 +38,5 @@ export default Contacts
Contacts.propTypes = { Contacts.propTypes = {
email: PropTypes.string, email: PropTypes.string,
telegram: PropTypes.string telegram: PropTypes.string,
} }

View File

@ -1,4 +1,4 @@
import React from 'react'; import React from "react"
const ContactsFrom = () => { const ContactsFrom = () => {
return ( return (
@ -17,4 +17,4 @@ const ContactsFrom = () => {
) )
} }
export default ContactsFrom export default ContactsFrom

View File

@ -1,54 +1,92 @@
import React from 'react'; import React from "react"
import { Link } from 'gatsby' import { Link } from "gatsby"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import useSiteMetadataQuery from '../../hooks/useSiteMetadataQuery' import useSiteMetadataQuery from "../../hooks/useSiteMetadataQuery"
import LogoIcon from '../../images/logo-icon.svg' import LogoIcon from "../../images/logo-icon.svg"
import GatsbyIcon from '../../images/gatsby-icon.svg' import GatsbyIcon from "../../images/gatsby-icon.svg"
import NetlifyIcon from '../../images/netlify-icon.svg' import NetlifyIcon from "../../images/netlify-icon.svg"
const Footer = () => { const Footer = () => {
const { siteMetadata: { title, menuLinks, social: { email, telegram, twitter, yadzen } } } = useSiteMetadataQuery() const {
siteMetadata: {
title,
menuLinks,
social: { email, telegram, twitter, yadzen },
},
} = useSiteMetadataQuery()
return ( return (
<footer> <footer>
<div className="footer-content"> <div className="footer-content">
<div className="footer-content__logo"> <div className="footer-content__logo">
<LogoIcon /> <LogoIcon />
<Link to='/'>{title}</Link> <Link to="/">{title}</Link>
</div> </div>
<div className="footer-content__nav"> <div className="footer-content__nav">
<div className="footer-nav__links"> <div className="footer-nav__links">
<div className="links-nav"> <div className="links-nav">
<p>Навигация</p> <p>Навигация</p>
<ul> <ul>
{menuLinks.map((page, i) => page.link !== '/contacts' ? <li key={i}><Link to={page.link}>{page.name}</Link></li> : null)} {menuLinks.map((page, i) =>
page.link !== "/contacts" ? (
<li key={i}>
<Link to={page.link}>{page.name}</Link>
</li>
) : null
)}
</ul> </ul>
</div> </div>
<div className="links-contacts"> <div className="links-contacts">
<p>Контакты</p> <p>Контакты</p>
<ul> <ul>
<li><Link to='/contacts'>Форма обратной связи</Link></li> <li>
<li><a href={telegram}>Телеграмм</a></li> <Link to="/contacts">Форма обратной связи</Link>
<li><a href={`mailto:${email}`}>Почта</a></li> </li>
<li>
<a href={telegram}>Телеграмм</a>
</li>
<li>
<a href={`mailto:${email}`}>Почта</a>
</li>
</ul> </ul>
</div> </div>
<div className="links-social"> <div className="links-social">
<p>Социальные сети</p> <p>Социальные сети</p>
<ul> <ul>
<li><a href={telegram} rel='noreferrer' target='_blank'>Наш телеграмм канал</a></li> <li>
<li><a href={yadzen} rel='noreferrer' target='_blank'>Яндекс.Дзен</a></li> <a href={telegram} rel="noreferrer" target="_blank">
<li><a href={twitter} rel='noreferrer' target='_blank'>Твиттер</a></li> Наш телеграмм канал
</a>
</li>
<li>
<a href={yadzen} rel="noreferrer" target="_blank">
Яндекс.Дзен
</a>
</li>
<li>
<a href={twitter} rel="noreferrer" target="_blank">
Твиттер
</a>
</li>
</ul> </ul>
</div> </div>
</div> </div>
<div className="footer-nav__helpers"> <div className="footer-nav__helpers">
<span>Разработка при помощи:</span> <span>Разработка при помощи:</span>
<div className="helpers-icons"> <div className="helpers-icons">
<a href="https://www.gatsbyjs.org/" rel='noreferrer' target="_blank"> <a
href="https://www.gatsbyjs.org/"
rel="noreferrer"
target="_blank"
>
<GatsbyIcon /> <GatsbyIcon />
GatsbyJS GatsbyJS
</a> </a>
<a href="https://www.netlify.com/" rel='noreferrer' target="_blank"> <a
href="https://www.netlify.com/"
rel="noreferrer"
target="_blank"
>
<NetlifyIcon /> <NetlifyIcon />
Netlify Netlify
</a> </a>
@ -66,9 +104,9 @@ const Footer = () => {
export default Footer export default Footer
Footer.propTypes = { Footer.propTypes = {
title: PropTypes.string title: PropTypes.string,
} }
Footer.defaultProps = { Footer.defaultProps = {
title: null title: null,
} }

View File

@ -1,26 +1,35 @@
import React from 'react' import React from "react"
import { useLocation } from '@reach/router' import { useLocation } from "@reach/router"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import { Link } from 'gatsby' import { Link } from "gatsby"
import useSiteMetadataQuery from '../../hooks/useSiteMetadataQuery' import useSiteMetadataQuery from "../../hooks/useSiteMetadataQuery"
import LogoIcon from '../../images/logo-icon.svg' import LogoIcon from "../../images/logo-icon.svg"
import TelegramIcon from '../../images/telegram-icon.svg' import TelegramIcon from "../../images/telegram-icon.svg"
import TwitterIcon from '../../images/twitter-icon.svg' import TwitterIcon from "../../images/twitter-icon.svg"
import MoonIcon from '../../images/moon-icon.svg' import MoonIcon from "../../images/moon-icon.svg"
import SunIcon from '../../images/sun-icon.svg' import SunIcon from "../../images/sun-icon.svg"
const Header = () => { const Header = () => {
const { siteMetadata: { title, menuLinks, social: { twitter, telegram } } } = useSiteMetadataQuery() const {
siteMetadata: {
title,
menuLinks,
social: { twitter, telegram },
},
} = useSiteMetadataQuery()
const [isScrolled, setIsScrolled] = React.useState(false) const [isScrolled, setIsScrolled] = React.useState(false)
const [isMobileOpen, setIsMobileOpen] = React.useState(false) const [isMobileOpen, setIsMobileOpen] = React.useState(false)
const [isDark, setIsDark] = React.useState(false) const [isDark, setIsDark] = React.useState(false)
const { pathname } = useLocation() const { pathname } = useLocation()
React.useEffect(() => { React.useEffect(() => {
setIsDark(window.__isDarkTheme) setIsDark(window.__isDarkTheme)
isMobileOpen ? document.body.style.overflowY = 'hidden' : document.body.style.overflowY = '' isMobileOpen
document.body.onscroll = () => window.pageYOffset >= 100 ? setIsScrolled(true) : setIsScrolled(false) ? (document.body.style.overflowY = "hidden")
: (document.body.style.overflowY = "")
document.body.onscroll = () =>
window.pageYOffset >= 100 ? setIsScrolled(true) : setIsScrolled(false)
}, [setIsDark, isMobileOpen]) }, [setIsDark, isMobileOpen])
const mobileHandler = () => { const mobileHandler = () => {
@ -30,62 +39,90 @@ const Header = () => {
const renderLinks = () => { const renderLinks = () => {
return ( return (
<ul> <ul>
{menuLinks.map((page, i) => <li key={i} className={page.link === pathname || pathname === `${page.link}/` ? 'active' : null}><Link to={page.link}>{page.name}</Link></li>)} {menuLinks.map((page, i) => (
<li
key={i}
className={
page.link === pathname || pathname === `${page.link}/`
? "active"
: null
}
>
<Link to={page.link}>{page.name}</Link>
</li>
))}
</ul> </ul>
) )
} }
return ( return (
<header className={isScrolled ? 'headerScrolled' : null}> <header className={isScrolled ? "headerScrolled" : null}>
<div className="header-content"> <div className="header-content">
<div className="header-content__logo"> <div className="header-content__logo">
<LogoIcon /> <LogoIcon />
<Link to='/'>{title}</Link> <Link to="/">{title}</Link>
</div> </div>
<div className="header-content__nav desktop"> <div className="header-content__nav desktop">
<div className="header-nav__social"> <div className="header-nav__social">
<a href={telegram} target="_blank" rel='noreferrer'> <a href={telegram} target="_blank" rel="noreferrer">
<TelegramIcon /> <TelegramIcon />
</a> </a>
<a href={twitter} target="_blank" rel='noreferrer'> <a href={twitter} target="_blank" rel="noreferrer">
<TwitterIcon /> <TwitterIcon />
</a> </a>
</div> </div>
<div className="header-nav__links"> <div className="header-nav__links">
<nav> <nav>{renderLinks()}</nav>
{renderLinks()}
</nav>
</div> </div>
<div className="header-nav__theme"> <div className="header-nav__theme">
{isDark ? <SunIcon onClick={() => { {isDark ? (
window.__setTheme('light') <SunIcon
setIsDark(!isDark) onClick={() => {
}} /> : <MoonIcon onClick={() => { window.__setTheme("light")
window.__setTheme('dark') setIsDark(!isDark)
setIsDark(!isDark) }}
}} />} />
) : (
<MoonIcon
onClick={() => {
window.__setTheme("dark")
setIsDark(!isDark)
}}
/>
)}
</div> </div>
</div> </div>
<div className={isMobileOpen ? 'header-content__nav mobile mobileOpen' : 'header-content__nav mobile'}> <div
{isMobileOpen className={
? <> isMobileOpen
<span>{title}</span> ? "header-content__nav mobile mobileOpen"
<nav> : "header-content__nav mobile"
{renderLinks()}
</nav>
<div className="mobile-social">
<a href="/" target="_blank">
<TelegramIcon />
</a>
<a href="/" target="_blank">
<TwitterIcon />
</a>
</div>
</>
: null
} }
>
{isMobileOpen ? (
<>
<span>{title}</span>
<nav>{renderLinks()}</nav>
<div className="mobile-social">
<a href="/" target="_blank">
<TelegramIcon />
</a>
<a href="/" target="_blank">
<TwitterIcon />
</a>
</div>
</>
) : null}
</div> </div>
<button aria-label='menu' onClick={mobileHandler} className={isMobileOpen ? "header-content__button mobile active" : 'header-content__button mobile'}> <button
aria-label="menu"
onClick={mobileHandler}
className={
isMobileOpen
? "header-content__button mobile active"
: "header-content__button mobile"
}
>
<span /> <span />
<span /> <span />
<span /> <span />
@ -102,12 +139,12 @@ Header.propTypes = {
menuLinks: PropTypes.arrayOf( menuLinks: PropTypes.arrayOf(
PropTypes.shape({ PropTypes.shape({
link: PropTypes.string, link: PropTypes.string,
name: PropTypes.string name: PropTypes.string,
}) })
) ),
} }
Header.defaultProps = { Header.defaultProps = {
title: null, title: null,
menuLinks: null menuLinks: null,
} }

View File

@ -1,15 +1,15 @@
import React from 'react' import React from "react"
import Header from '../Header/Header' import Header from "../Header/Header"
import Footer from '../Footer/Footer' import Footer from "../Footer/Footer"
const Layout = ({ children }) => { const Layout = ({ children }) => {
return ( return (
<> <>
<Header /> <Header />
{children} {children}
<Footer /> <Footer />
</> </>
) )
} }
export default Layout export default Layout

View File

@ -1,17 +1,20 @@
import React from 'react'; import React from "react"
const Newsletter = () => { const Newsletter = () => {
return ( return (
<div className="newsletter"> <div className="newsletter">
<div className="newsletter-heading"> <div className="newsletter-heading">Новостная рассылка</div>
Новостная рассылка
</div>
<div className="newsletter-content"> <div className="newsletter-content">
<form action="#"> <form action="#">
<p> <p>
<span role="img" aria-label="hot" >🔥</span> At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum <span role="img" aria-label="hot">
deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non 🔥
provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga </span>{" "}
At vero eos et accusamus et iusto odio dignissimos ducimus qui
blanditiis praesentium voluptatum deleniti atque corrupti quos
dolores et quas molestias excepturi sint occaecati cupiditate non
provident, similique sunt in culpa qui officia deserunt mollitia
animi, id est laborum et dolorum fuga
</p> </p>
<div className="email-field"> <div className="email-field">
<input placeholder="ваш e-mail" type="text" name="email" /> <input placeholder="ваш e-mail" type="text" name="email" />
@ -23,4 +26,4 @@ const Newsletter = () => {
) )
} }
export default Newsletter export default Newsletter

View File

@ -1,30 +1,41 @@
import React from 'react'; import React from "react"
import { useLocation } from '@reach/router' import { useLocation } from "@reach/router"
import usePopularArticlesQuery from '../../hooks/usePopularArticlesQuery' import usePopularArticlesQuery from "../../hooks/usePopularArticlesQuery"
import useTagsQuery from '../../hooks/useTagsQuery' import useTagsQuery from "../../hooks/useTagsQuery"
import Popular from './Popular/Popular' import Popular from "./Popular/Popular"
import Tags from './Tags/Tags' import Tags from "./Tags/Tags"
import Subscription from './Subscription/Subscription' import Subscription from "./Subscription/Subscription"
import PopularItem from './Popular/PopularItem' import PopularItem from "./Popular/PopularItem"
import TagItem from './Tags/TagItem' import TagItem from "./Tags/TagItem"
const Offers = () => { const Offers = () => {
const { pathname } = useLocation() const { pathname } = useLocation()
const { articles } = usePopularArticlesQuery() const { articles } = usePopularArticlesQuery()
const { tags } = useTagsQuery() const { tags } = useTagsQuery()
return ( return (
<div style={{ height: pathname === '/' ? '78%' : '78.5%' }} className="offers"> <div
style={{ height: pathname === "/" ? "78%" : "78.5%" }}
className="offers"
>
<Popular> <Popular>
{articles.map(({ node }, i) => <PopularItem key={i} slug={node.frontmatter.slug} title={node.frontmatter.title} />)} {articles.map(({ node }, i) => (
<PopularItem
key={i}
slug={node.frontmatter.slug}
title={node.frontmatter.title}
/>
))}
</Popular> </Popular>
<Tags> <Tags>
{tags.map(({ node }, i) => <TagItem key={i} title={node.frontmatter.title} />)} {tags.map(({ node }, i) => (
<TagItem key={i} title={node.frontmatter.title} />
))}
</Tags> </Tags>
<Subscription /> <Subscription />
</div> </div>
) )
} }
export default Offers export default Offers

View File

@ -1,18 +1,17 @@
import React from 'react'; import React from "react"
import PopularIcon from '../../../images/popular-icon.svg' import PopularIcon from "../../../images/popular-icon.svg"
const Popular = ({ children }) => { const Popular = ({ children }) => {
return ( return (
<div className="offers-popular offer-box"> <div className="offers-popular offer-box">
<div className="offers-popular__heading offer-heading"> <div className="offers-popular__heading offer-heading">
<PopularIcon /> <PopularIcon />
Популярные статьи</div> Популярные статьи
<div className="offers-popular__content">
{children}
</div> </div>
<div className="offers-popular__content">{children}</div>
</div> </div>
) )
} }
export default Popular export default Popular

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from "react"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import { Link } from 'gatsby' import { Link } from "gatsby"
const PopularItem = ({ slug, title }) => { const PopularItem = ({ slug, title }) => {
return ( return (
@ -8,8 +8,7 @@ const PopularItem = ({ slug, title }) => {
<div className="article-item__title"> <div className="article-item__title">
<Link to={`/article/${slug}`}>{title}</Link> <Link to={`/article/${slug}`}>{title}</Link>
</div> </div>
<div className="article-item__views"> <div className="article-item__views"></div>
</div>
</div> </div>
) )
} }
@ -18,5 +17,5 @@ export default PopularItem
PopularItem.propTypes = { PopularItem.propTypes = {
slug: PropTypes.string, slug: PropTypes.string,
title: PropTypes.string title: PropTypes.string,
} }

View File

@ -1,22 +1,43 @@
import React from 'react'; import React from "react"
import { useLocation } from '@reach/router' import { useLocation } from "@reach/router"
const Subscription = () => { const Subscription = () => {
const { pathname } = useLocation() const { pathname } = useLocation()
return ( return (
<div style={pathname !== '/about' && pathname !== '/about/' ? { height: '100%' } : null}> <div
<div style={pathname !== '/about' && pathname !== '/about/' ? { position: 'sticky', top: 75 } : null} className="offers-subscription offer-box"> style={
pathname !== "/about" && pathname !== "/about/"
? { height: "100%" }
: null
}
>
<div
style={
pathname !== "/about" && pathname !== "/about/"
? { position: "sticky", top: 75 }
: null
}
className="offers-subscription offer-box"
>
<div className="offers-subscription__heading offer-heading"> <div className="offers-subscription__heading offer-heading">
Канал в Telegram Канал в Telegram
</div> </div>
<div className="offers-subscription__content"> <div className="offers-subscription__content">
<p> <p>
В нашем канале telegram вы не пропустите статьи и новости, присоединяйтесь к другим разработчикам В нашем канале telegram вы не пропустите статьи и новости,
присоединяйтесь к другим разработчикам
</p> </p>
<a href="https://t.me/devthread" rel='noreferrer' target="_blank" className="btn-primary">Подписаться</a> <a
href="https://t.me/devthread"
rel="noreferrer"
target="_blank"
className="btn-primary"
>
Подписаться
</a>
</div> </div>
</div> </div>
</div> </div>
) )
} }
export default Subscription export default Subscription

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from "react"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import { Link } from 'gatsby' import { Link } from "gatsby"
import sligify from '../../../helpers/slugify' import sligify from "../../../helpers/slugify"
const TagItem = ({ title }) => { const TagItem = ({ title }) => {
return ( return (
@ -14,5 +14,5 @@ const TagItem = ({ title }) => {
export default TagItem export default TagItem
TagItem.propTypes = { TagItem.propTypes = {
title: PropTypes.string title: PropTypes.string,
} }

View File

@ -1,20 +1,17 @@
import React from 'react' import React from "react"
import TagIcon from '../../../images/tag-icon.svg' import TagIcon from "../../../images/tag-icon.svg"
const Tags = ({ children }) => { const Tags = ({ children }) => {
return ( return (
<div className="offers-tags offer-box"> <div className="offers-tags offer-box">
<div className="offers-tags__heading offer-heading"> <div className="offers-tags__heading offer-heading">
<TagIcon /> <TagIcon />
Тэги Тэги
</div> </div>
<div className="offers-tags__content"> <div className="offers-tags__content">{children}</div>
{children}
</div>
</div> </div>
) )
} }
export default Tags export default Tags

View File

@ -1,10 +1,18 @@
import React from 'react'; import React from "react"
import useSiteMetadataQuery from '../../hooks/useSiteMetadataQuery' import useSiteMetadataQuery from "../../hooks/useSiteMetadataQuery"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import { Helmet } from 'react-helmet' import { Helmet } from "react-helmet"
import { useLocation } from '@reach/router' import { useLocation } from "@reach/router"
const SEO = ({ title, titleTemplate, keywords, description, image, type, canonical }) => { const SEO = ({
title,
titleTemplate,
keywords,
description,
image,
type,
canonical,
}) => {
const { pathname } = useLocation() const { pathname } = useLocation()
const { siteMetadata } = useSiteMetadataQuery() const { siteMetadata } = useSiteMetadataQuery()
@ -12,55 +20,62 @@ const SEO = ({ title, titleTemplate, keywords, description, image, type, canonic
title: title || siteMetadata.title, title: title || siteMetadata.title,
titleTemplate: true, titleTemplate: true,
siteName: siteMetadata.siteName, siteName: siteMetadata.siteName,
type: type || 'website', type: type || "website",
image: image || 'custom image url...', image: image || "custom image url...",
description: description || siteMetadata.description, description: description || siteMetadata.description,
keywords: keywords || siteMetadata.keywords, keywords: keywords || siteMetadata.keywords,
url: `${siteMetadata.siteUrl}${pathname}`, url: `${siteMetadata.siteUrl}${pathname}`,
canonical: canonical || `${siteMetadata.siteUrl}${pathname}` canonical: canonical || `${siteMetadata.siteUrl}${pathname}`,
} }
return ( return (
<Helmet title={seo.title} titleTemplate={titleTemplate === false ? null : siteMetadata.titleTemplate}> <Helmet
title={seo.title}
titleTemplate={
titleTemplate === false ? null : siteMetadata.titleTemplate
}
>
<html lang="ru" /> <html lang="ru" />
<meta name="description" content={seo.description} /> <meta name="description" content={seo.description} />
{seo.keywords && ( {seo.keywords && <meta name="keywords" content={seo.keywords} />}
<meta name='keywords' content={seo.keywords} /> <meta property="og:locale" content="ru_RU" />
)}
<meta property='og:locale' content='ru_RU' />
<meta property="og:url" content={seo.url} /> <meta property="og:url" content={seo.url} />
<meta property='og:title' content={seo.title} <meta property="og:title" content={seo.title} />
/> <meta property="og:site_name" content={seo.siteName} />
<meta property='og:site_name' content={seo.siteName} {seo.type && <meta property="og:type" content={seo.type} />}
/> {seo.image && <meta property="og:image" content={seo.image} />}
{seo.type && (
<meta property='og:type' content={seo.type} />
)}
{seo.image && (
<meta property="og:image" content={seo.image} />
)}
{seo.description && ( {seo.description && (
<meta property="og:description" content={seo.description} /> <meta property="og:description" content={seo.description} />
)} )}
<link rel="canonical" href={seo.canonical} /> <link rel="canonical" href={seo.canonical} />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" /> <link
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" /> rel="apple-touch-icon"
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" /> sizes="180x180"
href="/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon-16x16.png"
/>
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#191919" /> <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#191919" />
<meta name="msapplication-TileColor" content="#ffffff" /> <meta name="msapplication-TileColor" content="#ffffff" />
<meta name="theme-color" content="#ffffff" /> <meta name="theme-color" content="#ffffff" />
<script type="application/ld+json"> <script type="application/ld+json">
{ {JSON.stringify({
JSON.stringify({ "@context": "http://schema.org",
'@context': 'http://schema.org', "@type": "Organization",
'@type': 'Organization', name: "devthread",
name: 'devthread', url: siteMetadata.siteUrl,
url: siteMetadata.siteUrl, sameAs: [siteMetadata.social.twitter],
sameAs : [ })}
siteMetadata.social.twitter,
]
})
}
</script> </script>
</Helmet> </Helmet>
) )
@ -75,6 +90,5 @@ SEO.propTypes = {
description: PropTypes.string, description: PropTypes.string,
image: PropTypes.string, image: PropTypes.string,
type: PropTypes.string, type: PropTypes.string,
canonical: PropTypes.string canonical: PropTypes.string,
} }

View File

@ -1,33 +1,34 @@
import React from 'react'; import React from "react"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import SEO from '../SEO/SEO' import SEO from "../SEO/SEO"
const Snippet = ({ data: { keywords, description, title, date }, html }) => { const Snippet = ({ data: { keywords, description, title, date }, html }) => {
return ( return (
<> <>
<SEO title={title} titleTemplate={false} description={description} keywords={keywords.join(', ')} type='article' /> <SEO
title={title}
titleTemplate={false}
description={description}
keywords={keywords.join(", ")}
type="article"
/>
<div className="snippet"> <div className="snippet">
<article> <article>
<div className="snippet-date"> <div className="snippet-date">{date}</div>
{date}
</div>
<div className="snippet-heading"> <div className="snippet-heading">
<h1>{title}</h1> <h1>{title}</h1>
</div> </div>
<div className="snippet-description"> <div className="snippet-description">
<p> <p>{description}</p>
{description}
</p>
</div> </div>
<div className="snippet-inner inner"> <div className="snippet-inner inner">
<div dangerouslySetInnerHTML={{__html: html}}></div> <div dangerouslySetInnerHTML={{ __html: html }}></div>
</div> </div>
<div className="snippet-comments"> <div className="snippet-comments">
<div className="snippet-comments__heading"> <div className="snippet-comments__heading">
<h2>Комментарии</h2> <h2>Комментарии</h2>
</div> </div>
<div className="snippet-comments__content"> <div className="snippet-comments__content"></div>
</div>
</div> </div>
</article> </article>
</div> </div>
@ -42,7 +43,7 @@ Snippet.propTypes = {
keywords: PropTypes.array, keywords: PropTypes.array,
title: PropTypes.string, title: PropTypes.string,
description: PropTypes.string, description: PropTypes.string,
date: PropTypes.string date: PropTypes.string,
}), }),
html: PropTypes.string html: PropTypes.string,
} }

View File

@ -1,13 +1,11 @@
import React from 'react'; import React from "react"
import { Link } from 'gatsby' import { Link } from "gatsby"
const SnippetItem = ({ slug, title, date, tags }) => { const SnippetItem = ({ slug, title, date, tags }) => {
return ( return (
<div className='snippet-item'> <div className="snippet-item">
<div className="left-info"> <div className="left-info">
<div className="snippet-item__date"> <div className="snippet-item__date">{date}</div>
{date}
</div>
<div className="snippet-item__heading"> <div className="snippet-item__heading">
<Link to={`/snippet/${slug}`}>{title}</Link> <Link to={`/snippet/${slug}`}>{title}</Link>
</div> </div>
@ -15,7 +13,9 @@ const SnippetItem = ({ slug, title, date, tags }) => {
<div className="right-info"> <div className="right-info">
<div className="snippet-item__tags"> <div className="snippet-item__tags">
{tags.map((tag, i) => ( {tags.map((tag, i) => (
<div key={i} className="tag-item">{tag}</div> <div key={i} className="tag-item">
{tag}
</div>
))} ))}
</div> </div>
</div> </div>
@ -23,4 +23,4 @@ const SnippetItem = ({ slug, title, date, tags }) => {
) )
} }
export default SnippetItem export default SnippetItem

View File

@ -1,11 +1,7 @@
import React from 'react'; import React from "react"
const Snippets = ({ children }) => { const Snippets = ({ children }) => {
return ( return <div className="snippets">{children}</div>
<div className='snippets'>
{children}
</div>
)
} }
export default Snippets export default Snippets

View File

@ -1,36 +1,32 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from "react"
import PropTypes from 'prop-types' import PropTypes from "prop-types"
import firebase from 'gatsby-plugin-firebase'; import firebase from "gatsby-plugin-firebase"
import incrementViews from '../../lib/increment-views'; import incrementViews from "../../lib/increment-views"
const ViewCounter = ({ id }) => { const ViewCounter = ({ id }) => {
const [viewCount, setViewCount] = useState(''); const [viewCount, setViewCount] = useState("")
useEffect(() => { useEffect(() => {
const onViews = (newViews) => { const onViews = newViews => {
setViewCount(newViews.val() === 1 ? 0 : newViews.val()); setViewCount(newViews.val() === 1 ? 0 : newViews.val())
}; }
incrementViews(id); incrementViews(id)
firebase.database().ref(`/views`).child(id).on(`value`, onViews); firebase.database().ref(`/views`).child(id).on(`value`, onViews)
return () => { return () => {
if (firebase.database()) { if (firebase.database()) {
firebase.database().ref(`/views`).child(id).off(`value`, onViews); firebase.database().ref(`/views`).child(id).off(`value`, onViews)
} }
}; }
}, [id]); }, [id])
return ( return <span>{viewCount ? viewCount : `---`}</span>
<span> }
{viewCount ? viewCount : `---`}
</span>
);
};
export default ViewCounter; export default ViewCounter
ViewCounter.propTypes = { ViewCounter.propTypes = {
id: PropTypes.string id: PropTypes.string,
} }

View File

@ -1,8 +1,8 @@
const slugify = str => { const slugify = str => {
const patterns = { const patterns = {
rus: /^[0-9а-яё-\s]*$/i rus: /^[0-9а-яё-\s]*$/i,
} }
const translit = str => { const translit = str => {
if (str.match(patterns.rus)) { if (str.match(patterns.rus)) {
const ru = { const ru = {
@ -35,33 +35,33 @@ const slugify = str => {
ы: "y", ы: "y",
э: "e", э: "e",
ю: "u", ю: "u",
я: "ya" я: "ya",
}, },
newStr = []; newStr = []
for (var i = 0; i < str.length; ++i) { for (var i = 0; i < str.length; ++i) {
const candidate = str[i].toLowerCase() const candidate = str[i].toLowerCase()
if (ru[candidate]) { if (ru[candidate]) {
newStr.push(ru[candidate]); newStr.push(ru[candidate])
} }
if (candidate === '-' || !isNaN(candidate)) { if (candidate === "-" || !isNaN(candidate)) {
newStr.push(candidate) newStr.push(candidate)
} }
} }
return newStr.join(""); return newStr.join("")
} }
return 'not rus' return "not rus"
} }
if (str.match(patterns.rus)) { if (str.match(patterns.rus)) {
return translit(str).split(' ').join('-').toLowerCase() return translit(str).split(" ").join("-").toLowerCase()
} }
return str.split(' ').join('-').toLowerCase() return str.split(" ").join("-").toLowerCase()
}; }
export default slugify export default slugify

View File

@ -3,11 +3,11 @@ const toFrontmatter = array => {
edges: array.map(el => { edges: array.map(el => {
return { return {
node: { node: {
frontmatter: el frontmatter: el,
} },
} }
}) }),
} }
} }
export default toFrontmatter export default toFrontmatter

View File

@ -1,9 +1,13 @@
import { useStaticQuery, graphql } from 'gatsby' import { useStaticQuery, graphql } from "gatsby"
const useCategoriesQuery = () => { const useCategoriesQuery = () => {
const { allMarkdownRemark: { edges } } = useStaticQuery(graphql` const {
allMarkdownRemark: { edges },
} = useStaticQuery(graphql`
{ {
allMarkdownRemark(filter: {frontmatter: {templateKey: {eq: "category"}}}) { allMarkdownRemark(
filter: { frontmatter: { templateKey: { eq: "category" } } }
) {
edges { edges {
node { node {
frontmatter { frontmatter {
@ -17,4 +21,4 @@ const useCategoriesQuery = () => {
return { categories: edges } return { categories: edges }
} }
export default useCategoriesQuery export default useCategoriesQuery

View File

@ -1,9 +1,15 @@
import { useStaticQuery, graphql } from 'gatsby' import { useStaticQuery, graphql } from "gatsby"
const useMoreArticlesQuery = () => { const useMoreArticlesQuery = () => {
const { allMarkdownRemark: { edges } } = useStaticQuery(graphql` const {
allMarkdownRemark: { edges },
} = useStaticQuery(graphql`
{ {
allMarkdownRemark(filter: {frontmatter: {templateKey: {eq: "article"}}}, sort: {order: DESC, fields: frontmatter___date}, limit: 6) { allMarkdownRemark(
filter: { frontmatter: { templateKey: { eq: "article" } } }
sort: { order: DESC, fields: frontmatter___date }
limit: 6
) {
edges { edges {
node { node {
frontmatter { frontmatter {
@ -28,4 +34,4 @@ const useMoreArticlesQuery = () => {
return { edges } return { edges }
} }
export default useMoreArticlesQuery export default useMoreArticlesQuery

View File

@ -1,9 +1,17 @@
import { useStaticQuery, graphql } from 'gatsby' import { useStaticQuery, graphql } from "gatsby"
const usePopularArticlesQuery = () => { const usePopularArticlesQuery = () => {
const { allMarkdownRemark: { edges } } = useStaticQuery(graphql` const {
allMarkdownRemark: { edges },
} = useStaticQuery(graphql`
{ {
allMarkdownRemark(filter: {frontmatter: {templateKey: {eq: "article"}, popular: {eq: true}}}, sort: {fields: frontmatter___date, order: DESC}, limit: 5) { allMarkdownRemark(
filter: {
frontmatter: { templateKey: { eq: "article" }, popular: { eq: true } }
}
sort: { fields: frontmatter___date, order: DESC }
limit: 5
) {
edges { edges {
node { node {
frontmatter { frontmatter {
@ -18,4 +26,4 @@ const usePopularArticlesQuery = () => {
return { articles: edges } return { articles: edges }
} }
export default usePopularArticlesQuery export default usePopularArticlesQuery

View File

@ -1,7 +1,9 @@
import { useStaticQuery, graphql } from 'gatsby' import { useStaticQuery, graphql } from "gatsby"
const useSiteMetadata = () => { const useSiteMetadata = () => {
const { site: { siteMetadata } } = useStaticQuery(graphql` const {
site: { siteMetadata },
} = useStaticQuery(graphql`
{ {
site { site {
siteMetadata { siteMetadata {
@ -34,4 +36,4 @@ const useSiteMetadata = () => {
return { siteMetadata } return { siteMetadata }
} }
export default useSiteMetadata export default useSiteMetadata

View File

@ -1,9 +1,14 @@
import { useStaticQuery, graphql } from 'gatsby' import { useStaticQuery, graphql } from "gatsby"
const useSnippetsQuery = () => { const useSnippetsQuery = () => {
const { allMarkdownRemark: { edges } } = useStaticQuery(graphql` const {
allMarkdownRemark: { edges },
} = useStaticQuery(graphql`
{ {
allMarkdownRemark(filter: {frontmatter: {templateKey: {eq: "snippet"}}}, sort: {order: DESC, fields: frontmatter___date}) { allMarkdownRemark(
filter: { frontmatter: { templateKey: { eq: "snippet" } } }
sort: { order: DESC, fields: frontmatter___date }
) {
edges { edges {
node { node {
frontmatter { frontmatter {
@ -22,4 +27,4 @@ const useSnippetsQuery = () => {
return { snippets: edges } return { snippets: edges }
} }
export default useSnippetsQuery export default useSnippetsQuery

View File

@ -1,9 +1,13 @@
import { useStaticQuery, graphql } from 'gatsby' import { useStaticQuery, graphql } from "gatsby"
const useTagsQuery = () => { const useTagsQuery = () => {
const { allMarkdownRemark: { edges } } = useStaticQuery(graphql` const {
allMarkdownRemark: { edges },
} = useStaticQuery(graphql`
{ {
allMarkdownRemark(filter: {frontmatter: {templateKey: {eq: "tag"}}}) { allMarkdownRemark(
filter: { frontmatter: { templateKey: { eq: "tag" } } }
) {
edges { edges {
node { node {
frontmatter { frontmatter {
@ -17,4 +21,4 @@ const useTagsQuery = () => {
return { tags: edges } return { tags: edges }
} }
export default useTagsQuery export default useTagsQuery

View File

@ -1,9 +1,9 @@
import firebase from 'gatsby-plugin-firebase'; import firebase from "gatsby-plugin-firebase"
const incrementViews = async id => { const incrementViews = async id => {
const ref = firebase.database().ref(`/views`).child(id); const ref = firebase.database().ref(`/views`).child(id)
ref.transaction(currentViews => currentViews + 1) ref.transaction(currentViews => currentViews + 1)
} }
export default incrementViews; export default incrementViews

View File

@ -1,9 +1,9 @@
import React from 'react'; import React from "react"
import { Main } from '../ui/ui' import { Main } from "../ui/ui"
import { Grid } from 'react-flexbox-grid' import { Grid } from "react-flexbox-grid"
import { Link } from 'gatsby' import { Link } from "gatsby"
import SEO from '../components/SEO/SEO' import SEO from "../components/SEO/SEO"
import Layout from '../components/Layout/Layout' import Layout from "../components/Layout/Layout"
const NotFound = () => { const NotFound = () => {
return ( return (
@ -14,7 +14,7 @@ const NotFound = () => {
<div className="error"> <div className="error">
<span>#404</span> <span>#404</span>
<h1>страница не найдена</h1> <h1>страница не найдена</h1>
<Link to='/'>вернуться на главную</Link> <Link to="/">вернуться на главную</Link>
</div> </div>
</Grid> </Grid>
</Main> </Main>
@ -22,4 +22,4 @@ const NotFound = () => {
) )
} }
export default NotFound export default NotFound

View File

@ -1,22 +1,33 @@
import React from 'react'; import React from "react"
import { Grid, Row, Col } from 'react-flexbox-grid' import { Grid, Row, Col } from "react-flexbox-grid"
import { Main } from '../ui/ui' import { Main } from "../ui/ui"
import useSiteMetadataQuery from '../hooks/useSiteMetadataQuery' import useSiteMetadataQuery from "../hooks/useSiteMetadataQuery"
import SEO from '../components/SEO/SEO' import SEO from "../components/SEO/SEO"
import Layout from '../components/Layout/Layout' import Layout from "../components/Layout/Layout"
import Offers from '../components/Offers/Offers' import Offers from "../components/Offers/Offers"
import About from '../components/About/About' import About from "../components/About/About"
const AboutPage = () => { const AboutPage = () => {
const { siteMetadata: { title, menuLinks, social } } = useSiteMetadataQuery() const {
siteMetadata: { title, menuLinks, social },
} = useSiteMetadataQuery()
return ( return (
<Layout> <Layout>
<SEO title='О сайте' description='Этот сайт придуман для того, чтобы помочь вам разобраться с вашей проблемой и решить её. Сайт содержит в себе статьи и руководства.' /> <SEO
title="О сайте"
description="Этот сайт придуман для того, чтобы помочь вам разобраться с вашей проблемой и решить её. Сайт содержит в себе статьи и руководства."
/>
<Main> <Main>
<Grid fluid> <Grid fluid>
<Row> <Row>
<Col lg={9} xs={12}> <Col lg={9} xs={12}>
<About title={title} pageTitle={menuLinks.filter(page => page.link === '/about')[0].name} social={social} /> <About
title={title}
pageTitle={
menuLinks.filter(page => page.link === "/about")[0].name
}
social={social}
/>
</Col> </Col>
<Col lg={3} xs={12}> <Col lg={3} xs={12}>
<Offers /> <Offers />
@ -28,4 +39,4 @@ const AboutPage = () => {
) )
} }
export default AboutPage export default AboutPage

View File

@ -1,51 +1,71 @@
import React from "react" import React from "react"
import { Main } from '../ui/ui' import { Main } from "../ui/ui"
import { Grid, Row, Col } from 'react-flexbox-grid' import { Grid, Row, Col } from "react-flexbox-grid"
import { graphql } from 'gatsby' import { graphql } from "gatsby"
import { useLocation } from '@reach/router' import { useLocation } from "@reach/router"
import * as queryString from 'query-string' import * as queryString from "query-string"
import useCategoriesQuery from '../hooks/useCategoriesQuery' import useCategoriesQuery from "../hooks/useCategoriesQuery"
import useSiteMetadataQuery from '../hooks/useSiteMetadataQuery' import useSiteMetadataQuery from "../hooks/useSiteMetadataQuery"
import SEO from '../components/SEO/SEO' import SEO from "../components/SEO/SEO"
import Layout from '../components/Layout/Layout' import Layout from "../components/Layout/Layout"
import Articles from '../components/Articles/Articles' import Articles from "../components/Articles/Articles"
import Categories from '../components/Articles/Categories/Categories' import Categories from "../components/Articles/Categories/Categories"
import CategoryItem from '../components/Articles/Categories/CategoryItem' import CategoryItem from "../components/Articles/Categories/CategoryItem"
import Search from '../components/Articles/Search/Search' import Search from "../components/Articles/Search/Search"
import Offers from '../components/Offers/Offers' import Offers from "../components/Offers/Offers"
import SearchIcon from '../images/search-icon.svg' import SearchIcon from "../images/search-icon.svg"
const ArticlesPage = ({ data: { allMarkdownRemark: edges }, }) => { const ArticlesPage = ({ data: { allMarkdownRemark: edges } }) => {
const { categories } = useCategoriesQuery() const { categories } = useCategoriesQuery()
const { siteMetadata: { options: { articles: { onPage } } } } = useSiteMetadataQuery() const {
siteMetadata: {
options: {
articles: { onPage },
},
},
} = useSiteMetadataQuery()
const { search } = useLocation() const { search } = useLocation()
let [limit, setLimit] = React.useState(onPage) let [limit, setLimit] = React.useState(onPage)
const [filtredArticles, setFiltredArticles] = React.useState([]) const [filtredArticles, setFiltredArticles] = React.useState([])
const [query, setQuery] = React.useState(queryString.parse(search).search || '') const [query, setQuery] = React.useState(
queryString.parse(search).search || ""
)
const allArticles = edges const allArticles = edges
const filterArticles = React.useCallback(arr => { const filterArticles = React.useCallback(
return arr.filter(({ node: { frontmatter } }) => arr => {
frontmatter.title.toLowerCase().includes(query.toLowerCase().trim()) return arr.filter(
|| frontmatter.description.toLowerCase().includes(query.toLowerCase().trim()) ({ node: { frontmatter } }) =>
|| frontmatter.category.toLowerCase().includes(query.toLowerCase().trim()) frontmatter.title
|| frontmatter.tags.join('').toLowerCase().includes(query.toLowerCase().trim()) .toLowerCase()
) .includes(query.toLowerCase().trim()) ||
}, [query]) frontmatter.description
.toLowerCase()
.includes(query.toLowerCase().trim()) ||
frontmatter.category
.toLowerCase()
.includes(query.toLowerCase().trim()) ||
frontmatter.tags
.join("")
.toLowerCase()
.includes(query.toLowerCase().trim())
)
},
[query]
)
React.useEffect(() => { React.useEffect(() => {
setLimit(onPage) setLimit(onPage)
if (query !== '') setFiltredArticles(filterArticles(allArticles.edges)) if (query !== "") setFiltredArticles(filterArticles(allArticles.edges))
}, [setFiltredArticles, filterArticles, allArticles.edges, query, onPage]) }, [setFiltredArticles, filterArticles, allArticles.edges, query, onPage])
return ( return (
<Layout> <Layout>
<SEO title='Статьи' /> <SEO title="Статьи" />
<Main> <Main>
<Grid fluid> <Grid fluid>
<Row> <Row>
@ -55,25 +75,51 @@ const ArticlesPage = ({ data: { allMarkdownRemark: edges }, }) => {
<h1>Статьи</h1> <h1>Статьи</h1>
</div> </div>
<Categories setQuery={setQuery}> <Categories setQuery={setQuery}>
{categories.map(({ node }, i) => <CategoryItem key={i} title={node.frontmatter.title} />)} {categories.map(({ node }, i) => (
<CategoryItem key={i} title={node.frontmatter.title} />
))}
</Categories> </Categories>
<Search allArticles={allArticles.edges} filterArticles={filterArticles} articlesLength={edges.edges.length} resultsLength={filtredArticles.length} query={query} setQuery={setQuery} setFiltredArticles={setFiltredArticles} setLimit={setLimit} onPage={onPage} /> <Search
allArticles={allArticles.edges}
filterArticles={filterArticles}
articlesLength={edges.edges.length}
resultsLength={filtredArticles.length}
query={query}
setQuery={setQuery}
setFiltredArticles={setFiltredArticles}
setLimit={setLimit}
onPage={onPage}
/>
<div className="articles-info"> <div className="articles-info">
{query && query !== '' ? filtredArticles.length === 0 ? <p><SearchIcon />&nbsp;&nbsp;Ничего не найдено</p> : null : null} {query && query !== "" ? (
filtredArticles.length === 0 ? (
<p>
<SearchIcon />
&nbsp;&nbsp;Ничего не найдено
</p>
) : null
) : null}
</div> </div>
</div> </div>
</Col> </Col>
</Row> </Row>
<Row> <Row>
<Col lg={9} xs={12}> <Col lg={9} xs={12}>
{query && query !== '' {query && query !== "" ? (
? filtredArticles.length > 0 ? <Articles data={{edges: filtredArticles}} limit={limit} setLimit={setLimit} /> : null filtredArticles.length > 0 ? (
: <Articles data={edges} limit={limit} setLimit={setLimit} /> <Articles
} data={{ edges: filtredArticles }}
</Col > limit={limit}
setLimit={setLimit}
/>
) : null
) : (
<Articles data={edges} limit={limit} setLimit={setLimit} />
)}
</Col>
<Col lg={3} xs={12}> <Col lg={3} xs={12}>
<Offers /> <Offers />
</Col > </Col>
</Row> </Row>
</Grid> </Grid>
</Main> </Main>
@ -83,7 +129,9 @@ const ArticlesPage = ({ data: { allMarkdownRemark: edges }, }) => {
export const query = graphql` export const query = graphql`
{ {
allMarkdownRemark(filter: {frontmatter: {templateKey: {eq: "article"}}}) { allMarkdownRemark(
filter: { frontmatter: { templateKey: { eq: "article" } } }
) {
edges { edges {
node { node {
frontmatter { frontmatter {
@ -103,7 +151,7 @@ export const query = graphql`
} }
} }
} }
} }
` `
export default ArticlesPage export default ArticlesPage

View File

@ -1,16 +1,23 @@
import React from 'react'; import React from "react"
import { Main } from '../ui/ui' import { Main } from "../ui/ui"
import { Grid, Row, Col } from 'react-flexbox-grid' import { Grid, Row, Col } from "react-flexbox-grid"
import useSiteMetadataQuery from '../hooks/useSiteMetadataQuery' import useSiteMetadataQuery from "../hooks/useSiteMetadataQuery"
import SEO from '../components/SEO/SEO' import SEO from "../components/SEO/SEO"
import Layout from '../components/Layout/Layout' import Layout from "../components/Layout/Layout"
import Contacts from '../components/Contacts/Contacts' import Contacts from "../components/Contacts/Contacts"
const ContactsPage = () => { const ContactsPage = () => {
const { siteMetadata: { social: { email, telegram } } } = useSiteMetadataQuery() const {
siteMetadata: {
social: { email, telegram },
},
} = useSiteMetadataQuery()
return ( return (
<Layout> <Layout>
<SEO title='📝 Контакты' description='Для того чтобы задать вопрос, сообщить об ошибках или просто поздороваться, вы можете воспользоваться формой обратной связи или использовать контактные данные.' /> <SEO
title="📝 Контакты"
description="Для того чтобы задать вопрос, сообщить об ошибках или просто поздороваться, вы можете воспользоваться формой обратной связи или использовать контактные данные."
/>
<Main> <Main>
<Grid fluid> <Grid fluid>
<Row> <Row>
@ -24,4 +31,4 @@ const ContactsPage = () => {
) )
} }
export default ContactsPage export default ContactsPage

View File

@ -1,18 +1,24 @@
import React from "react" import React from "react"
import { Link, graphql } from 'gatsby' import { Link, graphql } from "gatsby"
import { Main } from '../ui/ui' import { Main } from "../ui/ui"
import { Grid, Row, Col } from 'react-flexbox-grid' import { Grid, Row, Col } from "react-flexbox-grid"
import useSiteMetadataQuery from '../hooks/useSiteMetadataQuery' import useSiteMetadataQuery from "../hooks/useSiteMetadataQuery"
import useSnippetsQuery from '../hooks/useSnippetsQuery' import useSnippetsQuery from "../hooks/useSnippetsQuery"
import SEO from '../components/SEO/SEO' import SEO from "../components/SEO/SEO"
import Layout from '../components/Layout/Layout' import Layout from "../components/Layout/Layout"
import Articles from '../components/Articles/Articles' import Articles from "../components/Articles/Articles"
import Snippets from '../components/Snippets/Snippets' import Snippets from "../components/Snippets/Snippets"
import SnippetItem from '../components/Snippets/SnippetItem/SnippetItem' import SnippetItem from "../components/Snippets/SnippetItem/SnippetItem"
import Offers from '../components/Offers/Offers' import Offers from "../components/Offers/Offers"
const IndexPage = ({ data: { allMarkdownRemark: edges } }) => { const IndexPage = ({ data: { allMarkdownRemark: edges } }) => {
const { siteMetadata: { options: { articles: { onPage } } } } = useSiteMetadataQuery() const {
siteMetadata: {
options: {
articles: { onPage },
},
},
} = useSiteMetadataQuery()
const { snippets } = useSnippetsQuery() const { snippets } = useSnippetsQuery()
let [limit, setLimit] = React.useState(onPage) let [limit, setLimit] = React.useState(onPage)
@ -26,29 +32,29 @@ const IndexPage = ({ data: { allMarkdownRemark: edges } }) => {
<div className="articles"> <div className="articles">
<div className="articles-heading"> <div className="articles-heading">
<h1>Последние статьи</h1> <h1>Последние статьи</h1>
<Link to='/articles'>смотреть все</Link> <Link to="/articles">смотреть все</Link>
</div> </div>
</div> </div>
</Col> </Col>
</Row> </Row>
<Row> <Row>
<Col lg={9} xs={12}> <Col lg={9} xs={12}>
<Articles data={edges} limit={limit} setLimit={setLimit} /> <Articles data={edges} limit={limit} setLimit={setLimit} />
<Snippets> <Snippets>
<h2>Сниппеты</h2> <h2>Сниппеты</h2>
{snippets.map(({ node: { frontmatter } }, i) => {snippets.map(({ node: { frontmatter } }, i) => (
<SnippetItem <SnippetItem
key={i} key={i}
slug={frontmatter.slug} slug={frontmatter.slug}
title={frontmatter.title} title={frontmatter.title}
date={frontmatter.date} date={frontmatter.date}
tags={frontmatter.tags} tags={frontmatter.tags}
/> />
)} ))}
</Snippets> </Snippets>
</Col> </Col>
<Col lg={3} xs={12}> <Col lg={3} xs={12}>
<Offers /> <Offers />
</Col> </Col>
</Row> </Row>
</Grid> </Grid>
@ -59,7 +65,10 @@ const IndexPage = ({ data: { allMarkdownRemark: edges } }) => {
export const query = graphql` export const query = graphql`
{ {
allMarkdownRemark(filter: {frontmatter: {templateKey: {eq: "article"}}}, sort: {order: DESC, fields: frontmatter___date}) { allMarkdownRemark(
filter: { frontmatter: { templateKey: { eq: "article" } } }
sort: { order: DESC, fields: frontmatter___date }
) {
edges { edges {
node { node {
frontmatter { frontmatter {
@ -79,7 +88,7 @@ export const query = graphql`
} }
} }
} }
} }
` `
export default IndexPage export default IndexPage

View File

@ -1,13 +1,17 @@
import React from "react" import React from "react"
import { graphql } from "gatsby" import { graphql } from "gatsby"
import { Main } from '../ui/ui' import { Main } from "../ui/ui"
import { Grid, Row, Col } from 'react-flexbox-grid' import { Grid, Row, Col } from "react-flexbox-grid"
import SEO from '../components/SEO/SEO' import SEO from "../components/SEO/SEO"
import Layout from '../components/Layout/Layout' import Layout from "../components/Layout/Layout"
import Snippets from '../components/Snippets/Snippets' import Snippets from "../components/Snippets/Snippets"
import SnippetItem from '../components/Snippets/SnippetItem/SnippetItem' import SnippetItem from "../components/Snippets/SnippetItem/SnippetItem"
const SnippetsPage = ({ data: { allMarkdownRemark: { snippets } } }) => { const SnippetsPage = ({
data: {
allMarkdownRemark: { snippets },
},
}) => {
return ( return (
<Layout> <Layout>
<SEO /> <SEO />
@ -17,16 +21,19 @@ const SnippetsPage = ({ data: { allMarkdownRemark: { snippets } } }) => {
<Col lg={12}> <Col lg={12}>
<Snippets> <Snippets>
<h1>Сниппеты</h1> <h1>Сниппеты</h1>
<p>Сниппеты это готовые решения некоторых проблем, которые можно скопировать и вставить</p> <p>
{snippets.map(({ node: { frontmatter } }, i) => Сниппеты это готовые решения некоторых проблем, которые можно
<SnippetItem скопировать и вставить
key={i} </p>
slug={frontmatter.slug} {snippets.map(({ node: { frontmatter } }, i) => (
title={frontmatter.title} <SnippetItem
date={frontmatter.date} key={i}
tags={frontmatter.tags} slug={frontmatter.slug}
title={frontmatter.title}
date={frontmatter.date}
tags={frontmatter.tags}
/> />
)} ))}
</Snippets> </Snippets>
</Col> </Col>
</Row> </Row>
@ -37,21 +44,24 @@ const SnippetsPage = ({ data: { allMarkdownRemark: { snippets } } }) => {
} }
export const query = graphql` export const query = graphql`
{ {
allMarkdownRemark(filter: {frontmatter: {templateKey: {eq: "snippet"}}}, sort: {order: DESC, fields: frontmatter___date}) { allMarkdownRemark(
snippets: edges { filter: { frontmatter: { templateKey: { eq: "snippet" } } }
node { sort: { order: DESC, fields: frontmatter___date }
frontmatter { ) {
slug snippets: edges {
title node {
tags frontmatter {
description slug
date(formatString: "D MMMM YYYY", locale: "ru-RU") title
tags
description
date(formatString: "D MMMM YYYY", locale: "ru-RU")
}
} }
} }
} }
} }
}
` `
export default SnippetsPage export default SnippetsPage

View File

@ -1,14 +1,18 @@
import React from 'react' import React from "react"
import { Main } from '../ui/ui' import { Main } from "../ui/ui"
import { Grid, Row, Col } from 'react-flexbox-grid' import { Grid, Row, Col } from "react-flexbox-grid"
import Layout from '../components/Layout/Layout' import Layout from "../components/Layout/Layout"
import Article from '../components/Article/Article' import Article from "../components/Article/Article"
import Offers from '../components/Offers/Offers' import Offers from "../components/Offers/Offers"
import MoreArticles from '../components/Articles/MoreArticles/MoreArticles' import MoreArticles from "../components/Articles/MoreArticles/MoreArticles"
import Newsletter from '../components/Newsletter/Newsletter' import Newsletter from "../components/Newsletter/Newsletter"
import { graphql } from "gatsby" import { graphql } from "gatsby"
const articleTemplate = ({ data: { markdownRemark: { frontmatter, html } } }) => { const articleTemplate = ({
data: {
markdownRemark: { frontmatter, html },
},
}) => {
return ( return (
<Layout> <Layout>
<Main> <Main>
@ -31,7 +35,7 @@ const articleTemplate = ({ data: { markdownRemark: { frontmatter, html } } }) =>
export const pageQuery = graphql` export const pageQuery = graphql`
query Article($slug: String!) { query Article($slug: String!) {
markdownRemark(frontmatter: {slug: {eq: $slug}}) { markdownRemark(frontmatter: { slug: { eq: $slug } }) {
html html
frontmatter { frontmatter {
slug slug
@ -54,4 +58,4 @@ export const pageQuery = graphql`
} }
` `
export default articleTemplate export default articleTemplate

View File

@ -1,19 +1,29 @@
import React from "react" import React from "react"
import { Main } from '../ui/ui' import { Main } from "../ui/ui"
import { Grid, Row, Col } from 'react-flexbox-grid' import { Grid, Row, Col } from "react-flexbox-grid"
import { graphql } from 'gatsby' import { graphql } from "gatsby"
import useSiteMetadataQuery from '../hooks/useSiteMetadataQuery' import useSiteMetadataQuery from "../hooks/useSiteMetadataQuery"
import useCategoriesQuery from '../hooks/useCategoriesQuery' import useCategoriesQuery from "../hooks/useCategoriesQuery"
import SEO from '../components/SEO/SEO' import SEO from "../components/SEO/SEO"
import Layout from '../components/Layout/Layout' import Layout from "../components/Layout/Layout"
import Articles from '../components/Articles/Articles' import Articles from "../components/Articles/Articles"
import Categories from '../components/Articles/Categories/Categories' import Categories from "../components/Articles/Categories/Categories"
import CategoryItem from '../components/Articles/Categories/CategoryItem' import CategoryItem from "../components/Articles/Categories/CategoryItem"
import Offers from '../components/Offers/Offers' import Offers from "../components/Offers/Offers"
const CategoryPage = ({ data: { allMarkdownRemark: edges }, pageContext: { title } }) => { const CategoryPage = ({
data: { allMarkdownRemark: edges },
pageContext: { title },
}) => {
const { categories } = useCategoriesQuery() const { categories } = useCategoriesQuery()
const { siteMetadata: { siteUrl, options: { articles: { onPage } } } } = useSiteMetadataQuery() const {
siteMetadata: {
siteUrl,
options: {
articles: { onPage },
},
},
} = useSiteMetadataQuery()
let [limit, setLimit] = React.useState(onPage) let [limit, setLimit] = React.useState(onPage)
@ -26,23 +36,29 @@ const CategoryPage = ({ data: { allMarkdownRemark: edges }, pageContext: { title
<Col lg={9} xs={12}> <Col lg={9} xs={12}>
<div className="articles"> <div className="articles">
<div className="articles-heading"> <div className="articles-heading">
<h1>Категория: <u>{title}</u></h1> <h1>
Категория: <u>{title}</u>
</h1>
</div> </div>
<Categories> <Categories>
{categories.map(({ node }, i) => <CategoryItem key={i} title={node.frontmatter.title} />)} {categories.map(({ node }, i) => (
<CategoryItem key={i} title={node.frontmatter.title} />
))}
</Categories> </Categories>
<div className="articles-info"> <div className="articles-info">
<p>Найдено {edges.edges.length} из категории "{title}"</p> <p>
Найдено {edges.edges.length} из категории "{title}"
</p>
</div> </div>
</div> </div>
</Col> </Col>
</Row> </Row>
<Row> <Row>
<Col lg={9} xs={12}> <Col lg={9} xs={12}>
<Articles data={edges} limit={limit} setLimit={setLimit} /> <Articles data={edges} limit={limit} setLimit={setLimit} />
</Col> </Col>
<Col lg={3} xs={12}> <Col lg={3} xs={12}>
<Offers /> <Offers />
</Col> </Col>
</Row> </Row>
</Grid> </Grid>
@ -53,7 +69,14 @@ const CategoryPage = ({ data: { allMarkdownRemark: edges }, pageContext: { title
export const pageQuery = graphql` export const pageQuery = graphql`
query articlesByCategory($title: String!) { query articlesByCategory($title: String!) {
allMarkdownRemark(filter: {frontmatter: {category: {eq: $title}, templateKey: {eq: "article"}}}) { allMarkdownRemark(
filter: {
frontmatter: {
category: { eq: $title }
templateKey: { eq: "article" }
}
}
) {
edges { edges {
node { node {
frontmatter { frontmatter {

View File

@ -1,11 +1,15 @@
import React from 'react' import React from "react"
import { Main } from '../ui/ui' import { Main } from "../ui/ui"
import { Grid, Row, Col } from 'react-flexbox-grid' import { Grid, Row, Col } from "react-flexbox-grid"
import Snippet from '../components/Snippet/Snippet' import Snippet from "../components/Snippet/Snippet"
import Layout from '../components/Layout/Layout' import Layout from "../components/Layout/Layout"
import { graphql } from "gatsby" import { graphql } from "gatsby"
const snippetTemplate = ({ data: { markdownRemark: { frontmatter, html } } }) => { const snippetTemplate = ({
data: {
markdownRemark: { frontmatter, html },
},
}) => {
return ( return (
<Layout> <Layout>
<Main> <Main>
@ -23,7 +27,9 @@ const snippetTemplate = ({ data: { markdownRemark: { frontmatter, html } } }) =>
export const pageQuery = graphql` export const pageQuery = graphql`
query Snippet($slug: String!) { query Snippet($slug: String!) {
markdownRemark(frontmatter: {slug: {eq: $slug}, templateKey: {eq: "snippet"}}) { markdownRemark(
frontmatter: { slug: { eq: $slug }, templateKey: { eq: "snippet" } }
) {
html html
frontmatter { frontmatter {
slug slug
@ -36,4 +42,4 @@ export const pageQuery = graphql`
} }
` `
export default snippetTemplate export default snippetTemplate

View File

@ -1,20 +1,30 @@
import React from "react" import React from "react"
import { Main } from '../ui/ui' import { Main } from "../ui/ui"
import { Grid, Row, Col } from 'react-flexbox-grid' import { Grid, Row, Col } from "react-flexbox-grid"
import { graphql } from 'gatsby' import { graphql } from "gatsby"
import useSiteMetadataQuery from '../hooks/useSiteMetadataQuery' import useSiteMetadataQuery from "../hooks/useSiteMetadataQuery"
import useCategoriesQuery from '../hooks/useCategoriesQuery' import useCategoriesQuery from "../hooks/useCategoriesQuery"
import SEO from '../components/SEO/SEO' import SEO from "../components/SEO/SEO"
import Layout from '../components/Layout/Layout' import Layout from "../components/Layout/Layout"
import Articles from '../components/Articles/Articles' import Articles from "../components/Articles/Articles"
import Categories from '../components/Articles/Categories/Categories' import Categories from "../components/Articles/Categories/Categories"
import CategoryItem from '../components/Articles/Categories/CategoryItem' import CategoryItem from "../components/Articles/Categories/CategoryItem"
import Offers from '../components/Offers/Offers' import Offers from "../components/Offers/Offers"
const TagPage = ({ data: { allMarkdownRemark: edges }, pageContext: { title } }) => { const TagPage = ({
data: { allMarkdownRemark: edges },
pageContext: { title },
}) => {
const { categories } = useCategoriesQuery() const { categories } = useCategoriesQuery()
const { siteMetadata: { siteUrl, options: { articles: { onPage } } } } = useSiteMetadataQuery() const {
siteMetadata: {
siteUrl,
options: {
articles: { onPage },
},
},
} = useSiteMetadataQuery()
let [limit, setLimit] = React.useState(onPage) let [limit, setLimit] = React.useState(onPage)
return ( return (
@ -26,23 +36,29 @@ const TagPage = ({ data: { allMarkdownRemark: edges }, pageContext: { title } })
<Col lg={9} xs={12}> <Col lg={9} xs={12}>
<div className="articles"> <div className="articles">
<div className="articles-heading"> <div className="articles-heading">
<h1>Тэг: <u>{title}</u></h1> <h1>
Тэг: <u>{title}</u>
</h1>
</div> </div>
<Categories> <Categories>
{categories.map(({ node }, i) => <CategoryItem key={i} title={node.frontmatter.title} />)} {categories.map(({ node }, i) => (
<CategoryItem key={i} title={node.frontmatter.title} />
))}
</Categories> </Categories>
<div className="articles-info"> <div className="articles-info">
<p>Найдено {edges.edges.length} по тегу "{title}"</p> <p>
Найдено {edges.edges.length} по тегу "{title}"
</p>
</div> </div>
</div> </div>
</Col> </Col>
</Row> </Row>
<Row> <Row>
<Col lg={9} xs={12}> <Col lg={9} xs={12}>
<Articles data={edges} limit={limit} setLimit={setLimit} /> <Articles data={edges} limit={limit} setLimit={setLimit} />
</Col> </Col>
<Col lg={3} xs={12}> <Col lg={3} xs={12}>
<Offers /> <Offers />
</Col> </Col>
</Row> </Row>
</Grid> </Grid>
@ -53,7 +69,11 @@ const TagPage = ({ data: { allMarkdownRemark: edges }, pageContext: { title } })
export const pageQuery = graphql` export const pageQuery = graphql`
query articlesByTag($title: [String!]) { query articlesByTag($title: [String!]) {
allMarkdownRemark(filter: {frontmatter: {tags: {in: $title}, templateKey: {eq: "article"}}}) { allMarkdownRemark(
filter: {
frontmatter: { tags: { in: $title }, templateKey: { eq: "article" } }
}
) {
edges { edges {
node { node {
frontmatter { frontmatter {

View File

@ -1,12 +1,7 @@
import React from 'react'; import React from "react"
const Main = ({ children, ...props }) => { const Main = ({ children, ...props }) => {
return ( return <main {...props}>{children}</main>
<main {...props}>
{children}
</main>
)
} }
export { Main }
export { Main }