diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c78a4b0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,60 @@ +### Node ### +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages +.idea + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + + +# Build Files +public/ +.cache/ + +# Gatsby context +.gatsby-context.js + +# Bundle stats +bundle-stats.json \ No newline at end of file diff --git a/.huskyrc b/.huskyrc new file mode 100644 index 0000000..15665a1 --- /dev/null +++ b/.huskyrc @@ -0,0 +1,5 @@ +{ + "hooks": { + "pre-commit": ["lint-staged"] + } +} \ No newline at end of file diff --git a/.lintstagedrc b/.lintstagedrc new file mode 100644 index 0000000..d80b4a3 --- /dev/null +++ b/.lintstagedrc @@ -0,0 +1,4 @@ +{ + "*.{ts,tsx}": ["npm run lint:fix", "git add"], + "{*.{scss,json,md}}": ["npm run fix", "git add"] +} \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..07bd1f2 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "semi": false, + "tabWidth": 2, + "printWidth": 120, + "singleQuote": true, + "trailingComma": "all" +} diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 0000000..aba49c1 --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,11 @@ +{ + "plugins": [ + "stylelint-scss" + ], + "rules": { + "scss/dollar-variable-pattern": null, + "scss/selector-no-redundant-nesting-selector": true, + "scss/at-rule-no-unknown": true, + "at-rule-no-unknown": null + } +} \ No newline at end of file diff --git a/CNAME b/CNAME deleted file mode 100644 index 273b1fa..0000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -medson.me diff --git a/README.md b/README.md new file mode 100644 index 0000000..bb77a94 --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +## Gatsby 2 Power blog starter with Typescript +More features are coming, stay tuned! + +## Success Stories: +- I am using this template for my website https://www.majidhajian.com + +### Description +This is a standard starter with Typescript, TSLint, StyleLint, Prettier, Lint-Staged(Husky), Sass, StyleComponent, PWA + +#### Desktop + + +#### Mobile + + +### new project +``` +gatsby new my_blog https://github.com/mhadaily/gatsby-starter-typescript-power-blog +``` + +### Keywords + - PWA + - Blog + - Personal website + - TypeScript + - TSLint + - Progressive web app + - StyleLint + - Prettier + - Lint-Staged + - Styling:SCSS + - Prisim.js + - Style Components + - Markdown + - Pagination + +### Features + - Mobile-First approach in development. + - TSLint & Prettier + - Offline support + - Category and Tag for post + - Type Safe by TypeScript + - Format Safe by TSLint, StyleLint and Prettier with Lint-Staged(Husky) + - Blog page + - Syntax highlighting in code blocks. + - Pagination Ready + - Ready to deploy to Github pages + - Automatic RSS generation. + - Automatic Sitemap generation. + - Automatic support for Google Tag Manager diff --git a/asset-manifest.json b/asset-manifest.json deleted file mode 100644 index 639b3b9..0000000 --- a/asset-manifest.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "main.css": "/static/css/main.40bdc170.chunk.css", - "main.js": "/static/js/main.2babfbe2.chunk.js", - "main.js.map": "/static/js/main.2babfbe2.chunk.js.map", - "static/js/1.9fac4be2.chunk.js": "/static/js/1.9fac4be2.chunk.js", - "static/js/1.9fac4be2.chunk.js.map": "/static/js/1.9fac4be2.chunk.js.map", - "runtime~main.js": "/static/js/runtime~main.229c360f.js", - "runtime~main.js.map": "/static/js/runtime~main.229c360f.js.map", - "static/media/profile_picture.jpg": "/static/media/profile_picture.a2320353.jpg", - "static/css/main.40bdc170.chunk.css.map": "/static/css/main.40bdc170.chunk.css.map", - "index.html": "/index.html", - "precache-manifest.bf0a8db339bdfd08998693f3110f440e.js": "/precache-manifest.bf0a8db339bdfd08998693f3110f440e.js", - "service-worker.js": "/service-worker.js" -} \ No newline at end of file diff --git a/blog/2018-10-01/index.md b/blog/2018-10-01/index.md new file mode 100644 index 0000000..1c5822a --- /dev/null +++ b/blog/2018-10-01/index.md @@ -0,0 +1,208 @@ +--- +date: "2018-01-01" +title: "Test Title For This is a paragraph" +category: "General" +tags: ['gatsby', 'react', 'typescript', 'graphql'] +--- + +[View raw (TEST.md)](https://raw.github.com/adamschwartz/github-markdown-kitchen-sink/master/README.md) + +This is a paragraph. + + This is a paragraph. + + + +Header 1 +======== + +Header 2 +-------- + + Header 1 + ======== + + Header 2 + -------- + + + +# Header 1 +## Header 2 +### Header 3 +#### Header 4 +##### Header 5 +###### Header 6 + + # Header 1 + ## Header 2 + ### Header 3 + #### Header 4 + ##### Header 5 + ###### Header 6 + + + +# Header 1 # +## Header 2 ## +### Header 3 ### +#### Header 4 #### +##### Header 5 ##### +###### Header 6 ###### + + # Header 1 # + ## Header 2 ## + ### Header 3 ### + #### Header 4 #### + ##### Header 5 ##### + ###### Header 6 ###### + + + +> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. + + > Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. + + + +> ## This is a header. +> 1. This is the first list item. +> 2. This is the second list item. +> +> Here's some example code: +> +> Markdown.generate(); + + > ## This is a header. + > 1. This is the first list item. + > 2. This is the second list item. + > + > Here's some example code: + > + > Markdown.generate(); + + + + +- Red +- Green +- Blue + + ++ Red ++ Green ++ Blue + + +* Red +* Green +* Blue + + +```markdown +- Red +- Green +- Blue + ++ Red ++ Green ++ Blue + +* Red +* Green +* Blue +``` + + + +1. Buy flour and salt +1. Mix together with water +1. Bake + +```markdown +1. Buy flour and salt +1. Mix together with water +1. Bake +``` + + + +Paragraph: + + Code + + + + Paragraph: + + Code + + + +* * * + +*** + +***** + +- - - + +--------------------------------------- + + * * * + + *** + + ***** + + - - - + + --------------------------------------- + + + +This is [an example](http://example.com "Example") link. + +[This link](http://example.com) has no title attr. + +This is [an example] [id] reference-style link. + +[id]: http://example.com "Optional Title" + + This is [an example](http://example.com "Example") link. + + [This link](http://example.com) has no title attr. + + This is [an example] [id] reference-style link. + + [id]: http://example.com "Optional Title" + + + +*single asterisks* + +_single underscores_ + +**double asterisks** + +__double underscores__ + + *single asterisks* + + _single underscores_ + + **double asterisks** + + __double underscores__ + + + +This paragraph has some `code` in it. + + This paragraph has some `code` in it. + + + +![Alt Text](https://placehold.it/200x50 "Image Title") + + ![Alt Text](https://placehold.it/200x50 "Image Title") diff --git a/blog/2018-10-02/index.md b/blog/2018-10-02/index.md new file mode 100644 index 0000000..48206e8 --- /dev/null +++ b/blog/2018-10-02/index.md @@ -0,0 +1,23 @@ +--- +date: "2018-01-02" +title: "Alper Musig Clare is a create author" +category: "Technology" +tags: ['Author', 'Book'] +banner: "/assets/bg/1.jpg" +--- + +# Heading 1 + +Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. + +Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. + +## Zwei flinke Boxer + +Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. + +> "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. + +### Heading 3 + +Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. diff --git a/blog/2018-10-03/index.md b/blog/2018-10-03/index.md new file mode 100644 index 0000000..1d93b6b --- /dev/null +++ b/blog/2018-10-03/index.md @@ -0,0 +1,19 @@ +--- +date: "2018-01-03" +title: "A title must be meaningful" +category: "Coding" +tags: ['Technology', 'graphql'] +banner: "/assets/bg/2.jpg" +--- + +Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. + +Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. + +## Zwei flinke Boxer + +Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. + +> "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. + +Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. diff --git a/blog/2018-10-04/index.md b/blog/2018-10-04/index.md new file mode 100644 index 0000000..6c908f1 --- /dev/null +++ b/blog/2018-10-04/index.md @@ -0,0 +1,23 @@ +--- +date: "2018-01-04" +title: "Listen to music to enjoy coding" +category: "Music" +tags: ['Music', 'coding'] +banner: "/assets/bg/3.jpg" +--- + +Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. + +Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. + +## Zwei flinke Boxer + +Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. + +> "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. + +Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. + +Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. + +Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. diff --git a/blog/2018-10-05/index.md b/blog/2018-10-05/index.md new file mode 100644 index 0000000..f33b5fb --- /dev/null +++ b/blog/2018-10-05/index.md @@ -0,0 +1,62 @@ +--- +date: "2018-01-05" +title: "Coding is fun, isn't it?" +category: "Coding" +tags: ['Technology', 'Coding'] +banner: "/assets/bg/4.jpg" +--- + +Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. Sylvia wagt quick den Jux bei Pforzheim. Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. "Fix, Schwyz! " quäkt Jürgen blöd vom Paß. Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich. Falsches Üben von Xylophonmusik quält jeden größeren Zwerg. Heizölrückstoßabdämpfung. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. Zwölf Boxkämpfer jagen Viktor quer über den großen Sylter Deich. Vogel Quax zwickt Johnys Pferd Bim. + +```js +(function() { + +var cache = {}; +var form = $('form'); +var minified = true; + +var dependencies = {}; + +var treeURL = 'https://api.github.com/repos/PrismJS/prism/git/trees/gh-pages?recursive=1'; +var treePromise = new Promise(function(resolve) { + $u.xhr({ + url: treeURL, + callback: function(xhr) { + if (xhr.status < 400) { + resolve(JSON.parse(xhr.responseText).tree); + } + } + }); +}); +``` + +Zwei flinke Boxer jagen die quir + +```md +# asdfasdfads +- auesufuaus +``` + +```css +code[class*="language-"], +pre[class*="language-"] { + color: black; + background: none; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} +``` \ No newline at end of file diff --git a/blog/config/SiteConfig.ts b/blog/config/SiteConfig.ts new file mode 100644 index 0000000..3bdaf09 --- /dev/null +++ b/blog/config/SiteConfig.ts @@ -0,0 +1,34 @@ +export default { + pathPrefix: '/', // Prefix for all links. If you deploy your site to example.com/portfolio your pathPrefix should be "portfolio" + + siteTitle: 'Medson.dev', // Navigation and Site Title + siteTitleAlt: 'Medson.dev', // Alternative Site title for SEO + siteUrl: 'https://medson10.github.io', // Domain of your site. No trailing slash! + siteLanguage: 'en', // Language Tag on element + siteBanner: '/assets/banner.jpg', // Your image for og:image tag. You can find it in the /static folder + defaultBg: '/assets/bg.png', // default post background header + favicon: 'src/favicon.png', // Your image for favicons. You can find it in the /src folder + siteDescription: 'Blog about web development and others subject of my interest', // Your site description + author: 'Medson Oliveira', // Author for schemaORGJSONLD + siteLogo: '/assets/logo.png', // Image for schemaORGJSONLD + + // siteFBAppID: '123456789', // Facebook App ID - Optional + userTwitter: '@o_medson', // Twitter Username - Optional + + // Manifest and Progress color + // See: https://developers.google.com/web/fundamentals/web-app-manifest/ + themeColor: '#000', + backgroundColor: '#000', + + // Settings for typography.ts + headerFontFamily: 'Bitter', + bodyFontFamily: 'Open Sans', + baseFontSize: '18px', + + // Social media + siteFBAppID: '', + + // + Google_Tag_Manager_ID: 'GTM-XXXXXXX', + POST_PER_PAGE: 4, +}; diff --git a/blog/config/Theme.ts b/blog/config/Theme.ts new file mode 100644 index 0000000..06e6adf --- /dev/null +++ b/blog/config/Theme.ts @@ -0,0 +1,26 @@ +const colors = { + primary: '#000', // Color for buttons or links + bg: '#fff', // Background color + white: '#fff', + grey: { + dark: 'rgba(0, 0, 0, 0.9)', + default: 'rgba(0, 0, 0, 0.7)', + light: 'rgba(0, 0, 0, 0.5)', + ultraLight: 'rgba(0, 0, 0, 0.25)', + }, +}; + +const transitions = { + normal: '0.5s', +}; + +const fontSize = { + small: '0.9rem', + big: '2.9rem', +}; + +export default { + colors, + transitions, + fontSize, +}; diff --git a/blog/desktop.png b/blog/desktop.png new file mode 100644 index 0000000..c2c3189 Binary files /dev/null and b/blog/desktop.png differ diff --git a/config/SiteConfig.ts b/config/SiteConfig.ts new file mode 100644 index 0000000..3bdaf09 --- /dev/null +++ b/config/SiteConfig.ts @@ -0,0 +1,34 @@ +export default { + pathPrefix: '/', // Prefix for all links. If you deploy your site to example.com/portfolio your pathPrefix should be "portfolio" + + siteTitle: 'Medson.dev', // Navigation and Site Title + siteTitleAlt: 'Medson.dev', // Alternative Site title for SEO + siteUrl: 'https://medson10.github.io', // Domain of your site. No trailing slash! + siteLanguage: 'en', // Language Tag on element + siteBanner: '/assets/banner.jpg', // Your image for og:image tag. You can find it in the /static folder + defaultBg: '/assets/bg.png', // default post background header + favicon: 'src/favicon.png', // Your image for favicons. You can find it in the /src folder + siteDescription: 'Blog about web development and others subject of my interest', // Your site description + author: 'Medson Oliveira', // Author for schemaORGJSONLD + siteLogo: '/assets/logo.png', // Image for schemaORGJSONLD + + // siteFBAppID: '123456789', // Facebook App ID - Optional + userTwitter: '@o_medson', // Twitter Username - Optional + + // Manifest and Progress color + // See: https://developers.google.com/web/fundamentals/web-app-manifest/ + themeColor: '#000', + backgroundColor: '#000', + + // Settings for typography.ts + headerFontFamily: 'Bitter', + bodyFontFamily: 'Open Sans', + baseFontSize: '18px', + + // Social media + siteFBAppID: '', + + // + Google_Tag_Manager_ID: 'GTM-XXXXXXX', + POST_PER_PAGE: 4, +}; diff --git a/config/Theme.ts b/config/Theme.ts new file mode 100644 index 0000000..06e6adf --- /dev/null +++ b/config/Theme.ts @@ -0,0 +1,26 @@ +const colors = { + primary: '#000', // Color for buttons or links + bg: '#fff', // Background color + white: '#fff', + grey: { + dark: 'rgba(0, 0, 0, 0.9)', + default: 'rgba(0, 0, 0, 0.7)', + light: 'rgba(0, 0, 0, 0.5)', + ultraLight: 'rgba(0, 0, 0, 0.25)', + }, +}; + +const transitions = { + normal: '0.5s', +}; + +const fontSize = { + small: '0.9rem', + big: '2.9rem', +}; + +export default { + colors, + transitions, + fontSize, +}; diff --git a/desktop.png b/desktop.png new file mode 100644 index 0000000..c2c3189 Binary files /dev/null and b/desktop.png differ diff --git a/favicon.ico b/favicon.ico deleted file mode 100644 index a11777c..0000000 Binary files a/favicon.ico and /dev/null differ diff --git a/gatsby-config.js b/gatsby-config.js new file mode 100644 index 0000000..8add28a --- /dev/null +++ b/gatsby-config.js @@ -0,0 +1,79 @@ +require('source-map-support').install(); +require('ts-node').register({ + compilerOptions: { + module: 'commonjs', + target: 'es2017', + }, +}); + +const config = require('./config/SiteConfig').default; +const pathPrefix = config.pathPrefix === '/' ? '' : config.pathPrefix; + +module.exports = { + pathPrefix: config.pathPrefix, + siteMetadata: { + siteUrl: config.siteUrl + pathPrefix, + }, + plugins: [ + 'gatsby-plugin-react-helmet', + 'gatsby-plugin-styled-components', + 'gatsby-plugin-offline', + 'gatsby-plugin-typescript', + 'gatsby-plugin-sass', + 'gatsby-plugin-manifest', + 'gatsby-plugin-catch-links', + 'gatsby-plugin-sitemap', + 'gatsby-plugin-lodash', + { + resolve: 'gatsby-source-filesystem', + options: { + name: 'post', + path: `${__dirname}/blog`, + }, + }, + { + resolve: `gatsby-plugin-google-tagmanager`, + options: { + id: config.Google_Tag_Manager_ID, + // Include GTM in development. + // Defaults to false meaning GTM will only be loaded in production. + includeInDevelopment: false, + }, + }, + { + resolve: 'gatsby-transformer-remark', + options: { + plugins: [ + { + resolve: 'gatsby-remark-external-links', + options: { + target: '_blank', + rel: 'nofollow noopener noreferrer', + }, + }, + 'gatsby-remark-prismjs', + 'gatsby-remark-autolink-headers', + ], + }, + }, + { + resolve: 'gatsby-plugin-typography', + options: { + pathToConfigModule: 'src/utils/typography.ts', + }, + }, + { + resolve: 'gatsby-plugin-manifest', + options: { + name: config.siteTitle, + short_name: config.siteTitleAlt, + description: config.siteDescription, + start_url: config.pathPrefix, + background_color: config.backgroundColor, + theme_color: config.themeColor, + display: 'standalone', + icon: config.favicon, + }, + }, + ] +}; diff --git a/gatsby-node.js b/gatsby-node.js new file mode 100644 index 0000000..945038b --- /dev/null +++ b/gatsby-node.js @@ -0,0 +1,162 @@ +const path = require('path'); +const _ = require('lodash'); +const config = require('./config/SiteConfig').default; + +exports.onCreateNode = ({ node, actions }) => { + const { createNodeField } = actions; + if (node.internal.type === 'MarkdownRemark' && _.has(node, 'frontmatter') && _.has(node.frontmatter, 'title')) { + const slug = `${_.kebabCase(node.frontmatter.title)}`; + createNodeField({ node, name: 'slug', value: slug }); + } +}; + +const getPostsByType = (posts, classificationType) => { + const postsByType = {}; + posts.forEach(({ node }) => { + const nodeClassificationType = node.frontmatter[classificationType]; + if (nodeClassificationType) { + if (_.isArray(nodeClassificationType)) { + nodeClassificationType.forEach(name => { + if (!_.has(postsByType, name)) { + postsByType[name] = []; + } + postsByType[name].push(node); + }); + } + else { + const name = nodeClassificationType; + if (!postsByType[name]) { + postsByType[name] = []; + } + postsByType[name].push(node); + } + } + }); + return postsByType; +}; + +const createClassificationPages = ({ createPage, posts, postsPerPage, numPages }) => { + const classifications = [ + { + singularName: 'category', + pluralName: 'categories', + template: { + part: path.resolve(`src/templates/Category.tsx`), + all: path.resolve(`src/templates/AllCategory.tsx`), + }, + postsByClassificationNames: getPostsByType(posts, 'category'), + }, + { + singularName: 'tag', + pluralName: 'tags', + template: { + part: path.resolve(`src/templates/Tag.tsx`), + all: path.resolve(`src/templates/AllTag.tsx`), + }, + postsByClassificationNames: getPostsByType(posts, 'tags'), + }, + ]; + + classifications.forEach(classification => { + const names = Object.keys(classification.postsByClassificationNames); + + createPage({ + path: _.kebabCase(`/${classification.pluralName}`), + component: classification.template.all, + context: { + [`${classification.pluralName}`]: names.sort(), + }, + }); + + names.forEach(name => { + const postsByName = classification.postsByClassificationNames[name]; + createPage({ + path: `/${classification.pluralName}/${_.kebabCase(name)}`, + component: classification.template.part, + context: { + posts: postsByName, + [`${classification.singularName}Name`]: name, + }, + }); + }); + }); +}; + +exports.onCreateWebpackConfig = ({ stage, actions }) => { + actions.setWebpackConfig({ + resolve: { + modules: [path.resolve(__dirname, 'src'), 'node_modules'], + }, + }); +}; + +exports.createPages = ({ actions, graphql }) => { + const { createPage } = actions; + + const postTemplate = path.resolve(`src/templates/Post.tsx`); + + return graphql(`{ + allMarkdownRemark( + sort: { order: DESC, fields: [frontmatter___date] } + limit: 10000 + ) { + edges { + node { + excerpt(pruneLength: 250) + html + id + fields { + slug + } + frontmatter { + date + title + category + tags + banner + } + timeToRead + } + } + } + }`) + .then(result => { + if (result.errors) { + return Promise.reject(result.errors); + } + const posts = result.data.allMarkdownRemark.edges; + const postsPerPage = config.POST_PER_PAGE; + const numPages = Math.ceil(posts.length / postsPerPage); + + Array.from({ length: numPages }) + .forEach((_, i) => { + createPage({ + path: i === 0 ? `/blog` : `/blog/${i + 1}`, + component: path.resolve('./src/templates/Blog.tsx'), + context: { + limit: postsPerPage, + skip: i * postsPerPage, + totalPages: numPages, + currentPage: i + 1 + }, + }); + }); + + createClassificationPages({ createPage, posts, postsPerPage, numPages }); + + posts.forEach(({ node }, index) => { + const next = index === 0 ? null : posts[index - 1].node; + const prev = index === posts.length - 1 ? null : posts[index + 1].node; + + createPage({ + path: `/blog/${_.kebabCase(node.frontmatter.title)}`, + component: postTemplate, + context: { + slug: _.kebabCase(node.frontmatter.title), + prev, + next, + }, + }); + }); + }); +}; diff --git a/index.html b/index.html deleted file mode 100644 index 2cfae11..0000000 --- a/index.html +++ /dev/null @@ -1 +0,0 @@ -Medson Oliveira
\ No newline at end of file diff --git a/manifest.json b/manifest.json deleted file mode 100644 index 1f2f141..0000000 --- a/manifest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/mobile.png b/mobile.png new file mode 100644 index 0000000..4982045 Binary files /dev/null and b/mobile.png differ diff --git a/package.json b/package.json new file mode 100644 index 0000000..d857a9f --- /dev/null +++ b/package.json @@ -0,0 +1,75 @@ +{ + "name": "medson10.github.io", + "description": "gatsyby blog template with typescript and tslint", + "version": "1.0.0", + "author": "Medson Oliveira (medson.oliveira.jr@gmail.com)", + "keywords": [ + "gatsby, typescript", + "blog" + ], + "license": "MIT", + "main": "n/a", + "scripts": { + "build": "gatsby build", + "start": "gatsby develop", + "deploy": "gatsby build --prefix-paths && gh-pages -d public", + "lint": "tslint --project .", + "lint:fix": "tslint --fix --project .", + "fix": "prettier --write 'src/**/*.{ts,tsx,scss,md}' && tslint --fix 'src/**/*.{ts,tsx}' -p tsconfig.json && stylelint --fix 'src/**/*.scss' " + }, + "devDependencies": { + "@types/lodash": "^4.14.117", + "@types/react": "^16.4.18", + "@types/react-dom": "^16.0.9", + "@types/react-helmet": "^5.0.7", + "@types/styled-components": "^4.0.1", + "@types/typography": "^0.16.0", + "babel-plugin-styled-components": "^1.8.0", + "gatsby": "^2.0.25", + "gatsby-plugin-catch-links": "^2.0.5", + "gatsby-plugin-lodash": "^3.0.1", + "gatsby-plugin-manifest": "^2.0.5", + "gatsby-plugin-offline": "^2.0.7", + "gatsby-plugin-react-helmet": "^3.0.0", + "gatsby-plugin-sass": "^2.0.1", + "gatsby-plugin-sitemap": "^2.0.1", + "gatsby-plugin-styled-components": "^3.0.0", + "gatsby-plugin-typescript": "^2.0.0", + "gatsby-plugin-typography": "^2.2.0", + "gatsby-remark-autolink-headers": "^2.0.7", + "gatsby-remark-external-links": "0.0.4", + "gatsby-remark-prismjs": "^3.0.2", + "gatsby-source-filesystem": "^2.0.4", + "gatsby-transformer-remark": "^2.1.7", + "gh-pages": "^2.0.1", + "husky": "^1.1.2", + "lint-staged": "^7.3.0", + "lodash": "^4.17.11", + "node-sass": "^4.9.4", + "polished": "^2.2.0", + "prettier": "^1.14.3", + "prismjs": "^1.15.0", + "react": "^16.5.2", + "react-dom": "^16.5.2", + "react-helmet": "^5.2.0", + "react-typography": "^0.16.13", + "source-map-support": "latest", + "styled-components": "^4.0.0", + "stylelint": "^9.6.0", + "stylelint-config-css-modules": "^1.3.0", + "stylelint-config-prettier": "^4.0.0", + "stylelint-config-recommended-scss": "^3.2.0", + "stylelint-order": "^1.0.0", + "stylelint-scss": "^3.3.1", + "ts-node": "^7.0.1", + "tslint": "^5.11.0", + "tslint-config-blvd": "^1.2.1", + "tslint-config-prettier": "^1.15.0", + "tslint-plugin-prettier": "^2.0.0", + "typescript": "^3.1.3", + "typography": "^0.16.17" + }, + "dependencies": { + "gatsby-plugin-google-tagmanager": "^2.0.5" + } +} diff --git a/precache-manifest.bf0a8db339bdfd08998693f3110f440e.js b/precache-manifest.bf0a8db339bdfd08998693f3110f440e.js deleted file mode 100644 index 8124168..0000000 --- a/precache-manifest.bf0a8db339bdfd08998693f3110f440e.js +++ /dev/null @@ -1,26 +0,0 @@ -self.__precacheManifest = [ - { - "revision": "a2320353eb56f5d9b24d157b1c6a33d0", - "url": "/static/media/profile_picture.a2320353.jpg" - }, - { - "revision": "229c360febb4351a89df", - "url": "/static/js/runtime~main.229c360f.js" - }, - { - "revision": "2babfbe2f2b1fcef8650", - "url": "/static/js/main.2babfbe2.chunk.js" - }, - { - "revision": "9fac4be24baf7918d832", - "url": "/static/js/1.9fac4be2.chunk.js" - }, - { - "revision": "2babfbe2f2b1fcef8650", - "url": "/static/css/main.40bdc170.chunk.css" - }, - { - "revision": "52e109a270a010f78f889ed1743f5a20", - "url": "/index.html" - } -]; \ No newline at end of file diff --git a/service-worker.js b/service-worker.js deleted file mode 100644 index 0bf0dab..0000000 --- a/service-worker.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Welcome to your Workbox-powered service worker! - * - * You'll need to register this file in your web app and you should - * disable HTTP caching for this file too. - * See https://goo.gl/nhQhGp - * - * The rest of the code is auto-generated. Please don't update this file - * directly; instead, make changes to your Workbox build configuration - * and re-run your build process. - * See https://goo.gl/2aRDsh - */ - -importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.6.3/workbox-sw.js"); - -importScripts( - "/precache-manifest.bf0a8db339bdfd08998693f3110f440e.js" -); - -workbox.clientsClaim(); - -/** - * The workboxSW.precacheAndRoute() method efficiently caches and responds to - * requests for URLs in the manifest. - * See https://goo.gl/S9QRab - */ -self.__precacheManifest = [].concat(self.__precacheManifest || []); -workbox.precaching.suppressWarnings(); -workbox.precaching.precacheAndRoute(self.__precacheManifest, {}); - -workbox.routing.registerNavigationRoute("/index.html", { - - blacklist: [/^\/_/,/\/[^\/]+\.[^\/]+$/], -}); diff --git a/src/components/Article.tsx b/src/components/Article.tsx new file mode 100644 index 0000000..dc61333 --- /dev/null +++ b/src/components/Article.tsx @@ -0,0 +1,63 @@ +import React from 'react'; +import styled from 'styled-components'; +import { Link } from 'gatsby'; +import kebabCase from 'lodash/kebabCase'; +import { Subline } from './Subline'; + +const Post = styled.article` + display: flex; + flex-direction: column; + margin-top: 3.5rem; + margin-bottom: 3.5rem; +`; + +const Title = styled.h2` + position: relative; + text-shadow: 0 12px 30px rgba(0, 0, 0, 0.15); + margin-bottom: 0.75rem; +`; + +const Initiale = styled.span` + position: absolute; + font-size: 7rem; + transform: translate(-50%, -50%); + opacity: 0.08; + user-select: none; + z-index: -1; +`; + +const Excerpt = styled.p` + grid-column: -1 / 1; + margin-top: 1rem; + margin-bottom: 1rem; +`; + +interface Props { + title: string; + date: string; + excerpt: string; + slug: string; + timeToRead: number; + category: string; +} + +export class Article extends React.PureComponent { + public render() { + const { title, date, excerpt, slug, timeToRead, category } = this.props; + const firstChar = title.charAt(0); + + return ( + + + <Initiale>{firstChar}</Initiale> + <Link to={`/blog/${slug}`}>{title}</Link> + + + {date} — {timeToRead} Min Read — In + {category} + + {excerpt} + + ); + } +} diff --git a/src/components/Button.tsx b/src/components/Button.tsx new file mode 100644 index 0000000..f95d83a --- /dev/null +++ b/src/components/Button.tsx @@ -0,0 +1,30 @@ +import styled from 'styled-components'; +import curriedDarken from 'polished/lib/color/darken'; + +export const Button: any = styled.button` + background: ${props => props.theme.colors.primary}; + border: none; + display: inline-flex; + align-items: center; + margin: 0 0.5rem; + border-radius: ${(props: any) => (props.big ? '1.5rem' : '1rem')}; + font-size: ${(props: any) => (props.big ? '1.2rem' : '1rem')}; + color: white; + padding: ${(props: any) => (props.big ? '0.35rem 1.6rem' : '0.25rem 1.5rem')}; + transition: all ${(props: any) => props.theme.transitions.normal}; + box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08); + &:hover { + background: ${(props: any) => curriedDarken(0.3, props.theme.colors.primary)}; + cursor: pointer; + transform: translateY(-2px); + } + &:focus { + outline: none; + } + svg { + width: 20px; + height: 20px; + margin-right: 0.75rem; + fill: white; + } +`; diff --git a/src/components/Content.tsx b/src/components/Content.tsx new file mode 100644 index 0000000..4e2e1f7 --- /dev/null +++ b/src/components/Content.tsx @@ -0,0 +1,33 @@ +import styled from 'styled-components'; +import { media } from '../utils/media'; + +export const Content = styled.div` + box-shadow: 0 4px 120px rgba(0, 0, 0, 0.1); + border-radius: 1rem; + padding: 2rem 4rem; + background-color: ${props => props.theme.colors.bg}; + z-index: 9000; + margin-top: -4rem; + form { + p { + label, + input { + display: block; + } + input { + min-width: 275px; + } + textarea { + resize: vertical; + min-height: 150px; + width: 100%; + } + } + } + @media ${media.tablet} { + padding: 3rem 3rem; + } + @media ${media.phone} { + padding: 2rem 1.5rem; + } +`; diff --git a/src/components/Header.tsx b/src/components/Header.tsx new file mode 100644 index 0000000..926e4f9 --- /dev/null +++ b/src/components/Header.tsx @@ -0,0 +1,63 @@ +import React from 'react'; +import styled from 'styled-components'; +import { darken, lighten } from 'polished'; +import rgba from 'polished/lib/color/rgba'; +import { media } from '../utils/media'; +import config from '../../config/SiteConfig'; + +const HeaderWrapper: any = styled.header` + position: relative; + background: linear-gradient( + -185deg, + ${props => rgba(darken(0.1, props.theme.colors.primary), 0.6)}, + ${props => rgba(lighten(0.1, props.theme.colors.grey.dark), 0.8)} + ), + url(${(props: any) => props.banner}) no-repeat; + background-size: cover; + padding: 8rem 2rem 10rem; + text-align: center; + ::after { + background: transparent url(/assets/mask.svg) no-repeat bottom left; + background-size: 101%; + bottom: -2px; + content: ''; + display: block; + height: 100%; + left: 0; + position: absolute; + width: 100%; + } + @media ${media.tablet} { + padding: 4rem 2rem 6rem; + } + @media ${media.phone} { + padding: 1rem 0.5rem 2rem; + } +`; + +const Content = styled.div` + position: relative; + z-index: 999; + a { + color: white; + &:hover { + opacity: 0.85; + color: white; + } + } +`; + +interface Props { + children: any; + banner?: string; +} + +export class Header extends React.PureComponent { + public render() { + return ( + + {this.props.children} + + ); + } +} diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx new file mode 100644 index 0000000..044ca17 --- /dev/null +++ b/src/components/Layout.tsx @@ -0,0 +1,99 @@ +import React from 'react'; +import { StaticQuery, graphql } from 'gatsby'; +import styled, { ThemeProvider, createGlobalStyle } from 'styled-components'; +import theme from '../../config/Theme'; +import { media } from '../utils/media'; +import split from 'lodash/split'; +import './layout.scss'; + +const GlobalStyle = createGlobalStyle` + ::selection { + color: ${theme.colors.bg}; + background: ${theme.colors.primary}; + } + body { + background: ${theme.colors.bg}; + color: ${theme.colors.grey.default}; + @media ${media.phone} { + font-size: 14px; + } + } + a { + color: ${theme.colors.grey.dark}; + text-decoration: none; + transition: all ${theme.transitions.normal}; + } + a:hover { + color: ${theme.colors.primary}; + } + h1, h2, h3, h4 { + color: ${theme.colors.grey.dark}; + } + blockquote { + font-style: italic; + position: relative; + } + + blockquote:before { + content: ""; + position: absolute; + background: ${theme.colors.primary}; + height: 100%; + width: 6px; + margin-left: -1.6rem; + } + label { + margin-bottom: .5rem; + color: ${theme.colors.grey.dark}; + } + input, textarea { + border-radius: .5rem; + border: none; + background: rgba(0, 0, 0, 0.05); + padding: .25rem 1rem; + &:focus { + outline: none; + } + } + .textRight { + text-align:right; + } +`; + +const Footer = styled.footer` + text-align: center; + padding: 3rem 0; + span { + font-size: 0.75rem; + } +`; + +export class Layout extends React.PureComponent<{}> { + public render() { + const { children } = this.props; + + return ( + ( + + + + {children} +
+ © {split(data.site.buildTime, '.')[2]} by Medson Oliveira. All rights reserved.
+ Last update: {data.site.buildTime} +
+
+
+ )} + /> + ); + } +} diff --git a/src/components/Pagination.tsx b/src/components/Pagination.tsx new file mode 100644 index 0000000..3382c91 --- /dev/null +++ b/src/components/Pagination.tsx @@ -0,0 +1,123 @@ +import React from 'react'; +import { Link } from 'gatsby'; +import styled from 'styled-components'; +import { media } from '../utils/media'; +import theme from '../../config/Theme'; +import curriedDarken from 'polished/lib/color/darken'; + +export const PaginationContainer = styled.div` + text-align: center; + margin: 2rem; + } +`; + +export const PaginationContent = styled.div` + display: inline-block; + padding: 0 2.5rem; + border-radius: 3.5rem; + background-color: #eee; + + @media ${media.phone} { + padding: 0 1rem; + } + + .page-numbers { + display: block; + float:left; + transition: 400ms ease; + color: ${theme.colors.grey.light}; + letter-spacing: 0.1em; + padding: 1rem; + + &:hover, + &.current { + background-color: ${curriedDarken(0.2, theme.colors.primary)}; + color: ${theme.colors.white}; + } + + &.prev { + margin-left: -1.5rem; + } + + &.next { + margin-right: -1.5rem; + } + + &.prev:hover, + &.next:hover { + background-color: transparent; + color: ${curriedDarken(0.2, theme.colors.primary)}; + } + + + @media ${media.tablet} { + padding: 0 1.4rem; + display: none; + + &:nth-of-type(2) { + position: relative; + padding-right: 5rem; + + &::after { + content: '...'; + position: absolute; + top: 0; + left: 4.5rem; + } + } + + &:nth-child(-n + 3), + &:nth-last-child(-n + 3) { + display: block; + } + + &:nth-last-child(-n + 4) { + padding-right: 1.4rem; + + &::after { + content: none; + } + } + } + `; + +interface Props { + currentPage: number; + totalPages: number; + url: string; +} + +export class Pagination extends React.PureComponent { + public render() { + const { currentPage, totalPages, url } = this.props; + const isFirst = currentPage === 1; + const isLast = currentPage === totalPages; + const prevPage = currentPage - 1 === 1 ? `/${url}/` : `/${url}/${(currentPage - 1).toString()}`; + const nextPage = `/${url}/${(currentPage + 1).toString()}`; + return totalPages > 1 ? ( + + + {!isFirst && ( + + ← Prev + + )} + {Array.from({ length: totalPages }, (_, i) => ( + + {i + 1} + + ))} + {!isLast && ( + + Next → + + )} + + + ) : null; + } +} diff --git a/src/components/PrevNext.tsx b/src/components/PrevNext.tsx new file mode 100644 index 0000000..3123a91 --- /dev/null +++ b/src/components/PrevNext.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import styled from 'styled-components'; +import { Link } from 'gatsby'; +import kebabCase from 'lodash/kebabCase'; +import Post from '../models/Post'; + +const Wrapper = styled.div` + display: flex; + margin: 6rem auto 0 auto; + a { + color: ${props => props.theme.colors.primary}; + display: flex; + align-items: center; + } + justify-items: center; +`; + +const Prev = styled.div` + span { + text-transform: uppercase; + font-size: 0.8rem; + color: ${props => props.theme.colors.grey.light}; + } +`; + +const Next = styled.div` + margin-left: auto; + text-align: right; + span { + text-transform: uppercase; + font-size: 0.8rem; + color: ${props => props.theme.colors.grey.light}; + } +`; + +interface Props { + next: Post; + prev: Post; +} + +export class PrevNext extends React.PureComponent { + public render() { + const { prev, next } = this.props; + return ( + + {prev && ( + + Previous + {prev.frontmatter.title} + + )} + {next && ( + + Next + {next.frontmatter.title} + + )} + + ); + } +} diff --git a/src/components/SEO.tsx b/src/components/SEO.tsx new file mode 100644 index 0000000..4d4c3c8 --- /dev/null +++ b/src/components/SEO.tsx @@ -0,0 +1,105 @@ +/* eslint-disable react/require-default-props */ +import React from 'react'; +import Helmet from 'react-helmet'; +import config from '../../config/SiteConfig'; +import Post from '../models/Post'; + +interface SEO { + postNode: Post; + postPath: string; + postSEO: boolean; +} + +export const SEO = (props: SEO) => { + const { postNode, postPath, postSEO } = props; + let title; + let description; + let image; + let postURL; + const realPrefix = config.pathPrefix === '/' ? '' : config.pathPrefix; + if (postSEO) { + const postMeta = postNode.frontmatter; + title = postMeta.title; + description = postNode.excerpt; + image = config.siteBanner; + postURL = config.siteUrl + realPrefix + postPath; + } else { + title = config.siteTitle; + description = config.siteDescription; + image = config.siteBanner; + } + image = config.siteUrl + realPrefix + image; + const blogURL = config.siteUrl + config.pathPrefix; + let schemaOrgJSONLD = [ + { + '@context': 'http://schema.org', + '@type': 'WebSite', + '@id': blogURL, + url: blogURL, + name: title, + alternateName: config.siteTitleAlt ? config.siteTitleAlt : '', + }, + ]; + if (postSEO) { + schemaOrgJSONLD = [ + { + '@context': 'http://schema.org', + '@type': 'BlogPosting', + // @ts-ignore + '@id': postURL, + // @ts-ignore + url: postURL, + name: title, + alternateName: config.siteTitleAlt ? config.siteTitleAlt : '', + headline: title, + image: { + '@type': 'ImageObject', + url: image, + }, + description: config.siteDescription, + datePublished: postNode.frontmatter.date, + dateModified: postNode.frontmatter.date, + author: { + '@type': 'Person', + name: config.author, + }, + publisher: { + '@type': 'Organization', + name: config.author, + logo: { + '@type': 'ImageObject', + url: config.siteUrl + realPrefix + config.siteLogo, + }, + }, + isPartOf: blogURL, + mainEntityOfPage: { + '@type': 'WebSite', + '@id': blogURL, + }, + }, + ]; + } + return ( + + + {config.siteTitle} + + + + + + + {postSEO ? : null} + + + + + + + + + + + + ); +}; diff --git a/src/components/SectionTitle.tsx b/src/components/SectionTitle.tsx new file mode 100644 index 0000000..7bf2c0d --- /dev/null +++ b/src/components/SectionTitle.tsx @@ -0,0 +1,21 @@ +import styled from 'styled-components'; + +export const SectionTitle: any = styled.div` + font-size: ${props => props.theme.fontSize.big}; + text-transform: ${(props: any) => (props.uppercase ? 'uppercase' : 'normal')}; + text-align: center; + color: ${props => props.theme.colors.white}; + position: relative; + padding: 2rem 0 0; + margin-bottom: 2rem; + &:after { + content: ''; + height: 1px; + width: 50px; + position: absolute; + bottom: 0; + left: 50%; + margin-left: -25px; + background: ${props => props.theme.colors.white}; + } +`; diff --git a/src/components/Subline.tsx b/src/components/Subline.tsx new file mode 100644 index 0000000..6d7cc5d --- /dev/null +++ b/src/components/Subline.tsx @@ -0,0 +1,25 @@ +import styled from 'styled-components'; +import rgba from 'polished/lib/color/rgba'; + +interface Props { + theme: { + fontSize: { + small: number; + big: number; + }; + colors: { + white: string; + grey: { + light: string; + }; + }; + }; + sectionTitle: string; + light: boolean; +} + +export const Subline: any = styled.div` + font-size: ${(props: Props) => props.theme.fontSize.small}; + ${(props: Props) => props.light && `color: ${rgba(props.theme.colors.white, 0.7)}`}; + ${(props: Props) => props.sectionTitle && 'text-align: center'}; +`; diff --git a/src/components/Title.tsx b/src/components/Title.tsx new file mode 100644 index 0000000..c7589ed --- /dev/null +++ b/src/components/Title.tsx @@ -0,0 +1,7 @@ +import styled from 'styled-components'; + +export const Title = styled.h3` + position: relative; + text-shadow: 0 12px 30px rgba(0, 0, 0, 0.15); + margin-bottom: 0.75rem; +`; diff --git a/src/components/Wrapper.tsx b/src/components/Wrapper.tsx new file mode 100644 index 0000000..a0d4600 --- /dev/null +++ b/src/components/Wrapper.tsx @@ -0,0 +1,16 @@ +import styled from 'styled-components'; +import { media } from '../utils/media'; + +export const Wrapper: any = styled.div` + display: flex; + flex-direction: column; + margin: 0 auto; + max-width: ${(props: any) => (props.fullWidth ? '100%' : '100rem')}; + padding: ${(props: any) => (props.fullWidth ? '0' : '0 6rem')}; + @media ${media.tablet} { + padding: ${(props: any) => (props.fullWidth ? '0' : '0 3rem')}; + } + @media ${media.phone} { + padding: ${(props: any) => (props.fullWidth ? '0' : '0 1rem')}; + } +`; diff --git a/src/components/index.tsx b/src/components/index.tsx new file mode 100644 index 0000000..5a92ae7 --- /dev/null +++ b/src/components/index.tsx @@ -0,0 +1,12 @@ +export * from './Article'; +export * from './Button'; +export * from './Header'; +export * from './Layout'; +export * from './PrevNext'; +export * from './SectionTitle'; +export * from './SEO'; +export * from './Subline'; +export * from './Wrapper'; +export * from './Content'; +export * from './Title'; +export * from './Pagination'; diff --git a/src/components/layout.scss b/src/components/layout.scss new file mode 100644 index 0000000..d6091a4 --- /dev/null +++ b/src/components/layout.scss @@ -0,0 +1,39 @@ +// all scss if you like! +//---------- responsive breakpoints +//------------------------------------------------------------------------------ +@mixin breakpoint($value) { + @if $value == 'phone' { + @media only screen and (min-width: 120px) and (max-width: 767px) { + @content; + } + } @else if $value == 'tablet' { + @media only screen and (min-width: 768px) and (max-width: 1024px) { + @content; + } + } @else if $value == 'touch' { + @media only screen and (min-width: 120px) and (max-width: 1024px) { + @content; + } + } @else if $value == 'desktop' { + @media only screen and (min-width: 1025px) { + @content; + } + } @else { + @media only screen and (max-width: $value) { + @content; + } + } +} + +// Colors +$white: #fff; +$black: #000; +$grey: #595959; +$grey-dark: #2b2b2b; +$grey-light: #eee; +$green: #86c023; +$blue: #017ac7; + +// Transition +$duration: 400ms; +$easing: ease; diff --git a/src/declarations.d.ts b/src/declarations.d.ts new file mode 100644 index 0000000..9f16e4d --- /dev/null +++ b/src/declarations.d.ts @@ -0,0 +1 @@ +declare const graphql: (query: TemplateStringsArray) => void; diff --git a/src/favicon.png b/src/favicon.png new file mode 100644 index 0000000..53654e9 Binary files /dev/null and b/src/favicon.png differ diff --git a/src/models/AllMarkdownRemark.ts b/src/models/AllMarkdownRemark.ts new file mode 100644 index 0000000..e578c4a --- /dev/null +++ b/src/models/AllMarkdownRemark.ts @@ -0,0 +1,8 @@ +import Post from './Post'; + +interface AllMarkdownRemark { + totalCount: number; + edges: { node: Post }[]; +} + +export default AllMarkdownRemark; diff --git a/src/models/Data.ts b/src/models/Data.ts new file mode 100644 index 0000000..d9cbe95 --- /dev/null +++ b/src/models/Data.ts @@ -0,0 +1,7 @@ +import AllMarkdownRemark from './AllMarkdownRemark'; + +interface Data { + allMarkdownRemark: AllMarkdownRemark; +} + +export default Data; diff --git a/src/models/Frontmatter.ts b/src/models/Frontmatter.ts new file mode 100644 index 0000000..dae2b13 --- /dev/null +++ b/src/models/Frontmatter.ts @@ -0,0 +1,9 @@ +interface Frontmatter { + date: string; + title: string; + category: string; + tags: string[]; + banner?: string; +} + +export default Frontmatter; diff --git a/src/models/PageProps.ts b/src/models/PageProps.ts new file mode 100644 index 0000000..18f2625 --- /dev/null +++ b/src/models/PageProps.ts @@ -0,0 +1,12 @@ +import PathContext from './PathContext'; +import PageResources from './PageResources'; +import Data from './Data'; + +interface PageProps { + data: Data; + location: Location; + pageResources?: PageResources; + pathContext: PathContext; +} + +export default PageProps; diff --git a/src/models/PageResources.ts b/src/models/PageResources.ts new file mode 100644 index 0000000..0c6ecb1 --- /dev/null +++ b/src/models/PageResources.ts @@ -0,0 +1,7 @@ +import * as React from 'react'; + +interface PageResources { + component: React.PureComponent; + path: string; +} +export default PageResources; diff --git a/src/models/PathContext.ts b/src/models/PathContext.ts new file mode 100644 index 0000000..72bc4fd --- /dev/null +++ b/src/models/PathContext.ts @@ -0,0 +1,13 @@ +import Post from './Post'; + +interface PathContext { + tags?: string[]; + categories?: string[]; + categoryName: string; + tagName?: string; + posts?: Post[]; + next: any; + prev: any; +} + +export default PathContext; diff --git a/src/models/Post.ts b/src/models/Post.ts new file mode 100644 index 0000000..f04e9e4 --- /dev/null +++ b/src/models/Post.ts @@ -0,0 +1,14 @@ +import Frontmatter from './Frontmatter'; + +interface Post { + id: number; + excerpt: string; + html: string; + frontmatter: Frontmatter; + fields: { + slug: string; + }; + timeToRead: number; +} + +export default Post; diff --git a/src/pages/404.tsx b/src/pages/404.tsx new file mode 100644 index 0000000..227fd8a --- /dev/null +++ b/src/pages/404.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; +import { Content, Header, Layout, Wrapper, SectionTitle } from '../components'; +import Helmet from 'react-helmet'; +import config from '../../config/SiteConfig'; +import { Link } from 'gatsby'; + +export default class NotFoundPage extends React.Component { + public render() { + return ( + + +
+ {config.siteTitle} + NOT FOUND +
+ + +

You just hit a route that doesn't exist... the sadness.

+
+
+
+ ); + } +} diff --git a/src/pages/contact.tsx b/src/pages/contact.tsx new file mode 100644 index 0000000..770220f --- /dev/null +++ b/src/pages/contact.tsx @@ -0,0 +1,50 @@ +import React from 'react'; +import Helmet from 'react-helmet'; +import { Link } from 'gatsby'; +import { Layout, Wrapper, Header, Button, Content, SectionTitle } from '../components'; + +import config from '../../config/SiteConfig'; +import PageProps from '../models/PageProps'; + +export default class ContactPage extends React.Component { + public render() { + return ( + + +
+ {config.siteTitle} + Contact +
+ + +

Super cool intro text to get people contacting me!

+ + + + + + + + + +
+
+
+ ); + } +} diff --git a/src/pages/index.tsx b/src/pages/index.tsx new file mode 100644 index 0000000..cfda39e --- /dev/null +++ b/src/pages/index.tsx @@ -0,0 +1,139 @@ +import React from 'react'; +import { Link, graphql } from 'gatsby'; +import styled from 'styled-components'; +import { Layout, Wrapper, Button, Article } from '../components'; +import PageProps from '../models/PageProps'; +import Helmet from 'react-helmet'; +import config from '../../config/SiteConfig'; +import { media } from '../utils/media'; +import rgba from 'polished/lib/color/rgba'; +import darken from 'polished/lib/color/darken'; +import lighten from 'polished/lib/color/lighten'; + +const Homepage = styled.main` + display: flex; + height: 100vh; + flex-direction: row; + @media ${media.tablet} { + height: 100%; + flex-direction: column; + } + @media ${media.phone} { + height: 100%; + flex-direction: column; + } +`; + +const GridRow: any = styled.div` + flex: 1; + display: flex; + justify-content: center; + align-items: center; + background: ${(props: any) => + props.background + ? `linear-gradient( + -185deg, + ${rgba(darken(0.1, props.theme.colors.primary), 0.7)}, + ${rgba(lighten(0.1, props.theme.colors.grey.dark), 0.9)}), url(/assets/bg.png) no-repeat` + : null}; + background-size: cover; + padding: 2rem 4rem; + color: ${(props: any) => (props.background ? props.theme.colors.white : null)}; + h1 { + color: ${(props: any) => (props.background ? props.theme.colors.white : null)}; + } + @media ${media.tablet} { + padding: 3rem 3rem; + } + @media ${media.phone} { + padding: 2rem 1.5rem; + } +`; + +const HomepageContent: any = styled.div` + max-width: 30rem; + text-align: ${(props: any) => (props.center ? 'center' : 'left')}; +`; + +export default class IndexPage extends React.Component { + public render() { + const { data } = this.props; + const { edges, totalCount } = data.allMarkdownRemark; + return ( + + + + + + + {/* */} +

+ Hi. I am Medson +

+

and I'm just a developer for fun

+ + + + + + +
+
+ + +

Who I am

+

I'm a full-stack developer, enthusiast of new technologies, and challenge seeker

+
+

Latest Blog

+ {edges.map(post => ( +
+ ))} +

+ All articles ({totalCount}) +

+ + + + + + ); + } +} +export const IndexQuery = graphql` + query { + allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }, limit: 1) { + totalCount + edges { + node { + fields { + slug + } + frontmatter { + title + date(formatString: "DD.MM.YYYY") + category + } + timeToRead + } + } + } + } +`; diff --git a/src/templates/AllCategory.tsx b/src/templates/AllCategory.tsx new file mode 100644 index 0000000..07a583e --- /dev/null +++ b/src/templates/AllCategory.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import Helmet from 'react-helmet'; +import { Link } from 'gatsby'; +import kebabCase from 'lodash/kebabCase'; +import { Layout, Wrapper, Header, SectionTitle, Content, Title } from '../components'; + +import config from '../../config/SiteConfig'; +import PageProps from '../models/PageProps'; + +export default class AllCategoryTemplate extends React.PureComponent { + public render() { + const { categories } = this.props.pathContext; + if (categories) { + return ( + + +
+ {config.siteTitle} + Categories +
+ + + {categories.map((category, index: number) => ( + + <Link to={`/categories/${kebabCase(category)}`}>{category}</Link> + + ))} + + +
+ ); + } + } +} diff --git a/src/templates/AllTag.tsx b/src/templates/AllTag.tsx new file mode 100644 index 0000000..985dbcf --- /dev/null +++ b/src/templates/AllTag.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import Helmet from 'react-helmet'; +import { Link } from 'gatsby'; +import kebabCase from 'lodash/kebabCase'; +import { Layout, Wrapper, Header, SectionTitle, Content, Title } from '../components'; + +import config from '../../config/SiteConfig'; +import PageProps from '../models/PageProps'; + +export default class AllTagTemplate extends React.PureComponent { + public render() { + const { tags } = this.props.pathContext; + if (tags) { + return ( + + +
+ {config.siteTitle} + Tags +
+ + + {tags.map((tag, index: number) => ( + + <Link to={`/tags/${kebabCase(tag)}`}>{tag}</Link> + + ))} + + +
+ ); + } + } +} diff --git a/src/templates/Blog.tsx b/src/templates/Blog.tsx new file mode 100644 index 0000000..5ddd0af --- /dev/null +++ b/src/templates/Blog.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import { Link, graphql } from 'gatsby'; +import { Layout, Article, Wrapper, SectionTitle, Header, Content, Pagination } from '../components'; +import Helmet from 'react-helmet'; +import config from '../../config/SiteConfig'; +import Data from '../models/Data'; + +interface Props { + data: Data; + pageContext: { + currentPage: number; + totalPages: number; + }; +} + +export default class BlogPage extends React.Component { + public render() { + const { currentPage, totalPages } = this.props.pageContext; + + const { data } = this.props; + const { edges, totalCount } = data.allMarkdownRemark; + + return ( + + +
+ {config.siteTitle} + Latest stories ({totalCount}) +
+ + + {edges.map(post => ( +
+ ))} + + + + + ); + } +} +export const BlogQuery = graphql` + query($skip: Int!, $limit: Int!) { + allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }, limit: $limit, skip: $skip) { + totalCount + edges { + node { + fields { + slug + } + frontmatter { + title + date(formatString: "DD.MM.YYYY") + category + } + excerpt(pruneLength: 200) + timeToRead + } + } + } + } +`; diff --git a/src/templates/Category.tsx b/src/templates/Category.tsx new file mode 100644 index 0000000..9837041 --- /dev/null +++ b/src/templates/Category.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import Helmet from 'react-helmet'; +import { Link } from 'gatsby'; +import { Layout, Wrapper, Header, Subline, Article, SectionTitle, Content } from '../components'; +import config from '../../config/SiteConfig'; +import kebabCase from 'lodash/kebabCase'; +import PageProps from '../models/PageProps'; + +export default class Category extends React.PureComponent { + public render() { + const { posts, categoryName } = this.props.pathContext; + const totalCount = posts ? posts.length : 0; + const subline = `${totalCount} post${totalCount === 1 ? '' : 's'} tagged with "${categoryName}"`; + + return ( + + +
+ {config.siteTitle} + Category – {categoryName} + + {subline} (See all categories) + +
+ + + {posts + ? posts.map((post: any, index) => ( +
+ )) + : null} + + + + ); + } +} diff --git a/src/templates/Post.tsx b/src/templates/Post.tsx new file mode 100644 index 0000000..b4d8ded --- /dev/null +++ b/src/templates/Post.tsx @@ -0,0 +1,81 @@ +import React from 'react'; +import Helmet from 'react-helmet'; +import { Link, graphql } from 'gatsby'; +import styled from 'styled-components'; +import kebabCase from 'lodash/kebabCase'; +import { Layout, Wrapper, Header, Subline, SEO, PrevNext, SectionTitle, Content } from '../components'; +import config from '../../config/SiteConfig'; +import '../utils/prismjs-theme.css'; +import PathContext from '../models/PathContext'; +import Post from '../models/Post'; + +const PostContent = styled.div` + margin-top: 4rem; +`; + +interface Props { + data: { + markdownRemark: Post; + }; + pathContext: PathContext; +} + +export default class PostPage extends React.PureComponent { + public render() { + const { prev, next } = this.props.pathContext; + const post = this.props.data.markdownRemark; + return ( + + {post ? ( + <> + + +
+ {config.siteTitle} + {post.frontmatter.title} + + {post.frontmatter.date} — {post.timeToRead} Min Read — In{' '} + {post.frontmatter.category} + +
+ + + + {post.frontmatter.tags ? ( + + Tags:   + {post.frontmatter.tags.map((tag, i) => ( + + {tag} {i < post.frontmatter.tags.length - 1 ? `, ` : ``} + + ))} + + ) : null} + + + + + ) : null} +
+ ); + } +} + +export const postQuery = graphql` + query($slug: String!) { + markdownRemark(fields: { slug: { eq: $slug } }) { + html + fields { + slug + } + frontmatter { + title + date(formatString: "DD.MM.YYYY") + category + tags + banner + } + timeToRead + } + } +`; diff --git a/src/templates/Tag.tsx b/src/templates/Tag.tsx new file mode 100644 index 0000000..679e2f4 --- /dev/null +++ b/src/templates/Tag.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import Link from 'gatsby-link'; +import PageProps from '../models/PageProps'; +import { Article, Content, Header, Layout, SectionTitle, Subline, Wrapper } from '../components'; +import Helmet from 'react-helmet'; +import config from '../../config/SiteConfig'; +import kebabCase from 'lodash/kebabCase'; + +export default class TagTemplate extends React.PureComponent { + public render() { + const { posts, tagName } = this.props.pathContext; + const totalCount = posts ? posts.length : 0; + const subline = `${totalCount} post${totalCount === 1 ? '' : 's'} tagged with "${tagName}"`; + + return ( + + +
+ {config.siteTitle} + Tag – {tagName} + + {subline} (See all tags) + +
+ + + {posts + ? posts.map((post: any, index) => ( +
+ )) + : null} + + + + ); + } +} diff --git a/src/utils/media.ts b/src/utils/media.ts new file mode 100644 index 0000000..f0ed863 --- /dev/null +++ b/src/utils/media.ts @@ -0,0 +1,9 @@ +const sizes = { + tablet: '1200px', + phone: '600px', +}; + +export const media = { + tablet: `(max-width: ${sizes.tablet})`, + phone: `(max-width: ${sizes.phone})`, +}; diff --git a/src/utils/prismjs-theme.css b/src/utils/prismjs-theme.css new file mode 100644 index 0000000..23c2ed0 --- /dev/null +++ b/src/utils/prismjs-theme.css @@ -0,0 +1,122 @@ +/** + * okaidia theme for JavaScript, CSS and HTML + * Loosely based on Monokai textmate theme by http://www.monokai.nl/ + * @author ocodia + */ + +code[class*="language-"], +pre[class*="language-"] { + color: #f8f8f2; + background: none; + text-shadow: 0 1px rgba(0, 0, 0, 0.3); + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; + border-radius: 0.3em; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #272822; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #f8f8f2; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.constant, +.token.symbol, +.token.deleted { + color: #f92672; +} + +.token.boolean, +.token.number { + color: #ae81ff; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #a6e22e; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string, +.token.variable { + color: #f8f8f2; +} + +.token.atrule, +.token.attr-value, +.token.function, +.token.class-name { + color: #e6db74; +} + +.token.keyword { + color: #66d9ef; +} + +.token.regex, +.token.important { + color: #fd971f; +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} \ No newline at end of file diff --git a/src/utils/typography.ts b/src/utils/typography.ts new file mode 100644 index 0000000..ff7a3a2 --- /dev/null +++ b/src/utils/typography.ts @@ -0,0 +1,28 @@ +import Typography from 'typography'; +import config from '../../config/SiteConfig'; + +const typography = new Typography({ + baseFontSize: config.baseFontSize, + baseLineHeight: 1.66, + scaleRatio: 3.157, + headerFontFamily: [config.headerFontFamily, 'sans-serif'], + bodyFontFamily: [config.bodyFontFamily, 'sans-serif'], + headerWeight: 700, + googleFonts: [ + { + name: config.headerFontFamily, + styles: ['700'], + }, + { + name: config.bodyFontFamily, + styles: ['400'], + }, + ], +}); + +// Hot reload typography in development. +if (process.env.NODE_ENV !== 'production') { + typography.injectStyles(); +} + +export default typography; diff --git a/static/CNAME b/static/CNAME new file mode 100644 index 0000000..564580e --- /dev/null +++ b/static/CNAME @@ -0,0 +1 @@ +gatsby-starter-typescript-power-blog.majidhajian.com \ No newline at end of file diff --git a/static/assets/bg.png b/static/assets/bg.png new file mode 100644 index 0000000..f3a462f Binary files /dev/null and b/static/assets/bg.png differ diff --git a/static/assets/bg/1.jpg b/static/assets/bg/1.jpg new file mode 100644 index 0000000..b9564ba Binary files /dev/null and b/static/assets/bg/1.jpg differ diff --git a/static/assets/bg/2.jpg b/static/assets/bg/2.jpg new file mode 100644 index 0000000..de58f8c Binary files /dev/null and b/static/assets/bg/2.jpg differ diff --git a/static/assets/bg/3.jpg b/static/assets/bg/3.jpg new file mode 100644 index 0000000..5a9dfb7 Binary files /dev/null and b/static/assets/bg/3.jpg differ diff --git a/static/assets/bg/4.jpg b/static/assets/bg/4.jpg new file mode 100644 index 0000000..03a1782 Binary files /dev/null and b/static/assets/bg/4.jpg differ diff --git a/static/assets/logo.png b/static/assets/logo.png new file mode 100644 index 0000000..e3e3448 Binary files /dev/null and b/static/assets/logo.png differ diff --git a/static/assets/mask.svg b/static/assets/mask.svg new file mode 100644 index 0000000..b829077 --- /dev/null +++ b/static/assets/mask.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/css/main.40bdc170.chunk.css b/static/css/main.40bdc170.chunk.css deleted file mode 100644 index 6bbb99f..0000000 --- a/static/css/main.40bdc170.chunk.css +++ /dev/null @@ -1,2 +0,0 @@ -body{margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace} -/*# sourceMappingURL=main.40bdc170.chunk.css.map */ \ No newline at end of file diff --git a/static/css/main.40bdc170.chunk.css.map b/static/css/main.40bdc170.chunk.css.map deleted file mode 100644 index 165fe3b..0000000 --- a/static/css/main.40bdc170.chunk.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["/Users/medson/Desktop/medson10.github.io/src/index.css"],"names":[],"mappings":"AAAA,KACE,SAAU,AACV,UAAW,AACX,oIAEa,AACb,mCAAoC,AACpC,iCAAmC,CACpC,AAED,KACE,uEACY,CACb","file":"main.40bdc170.chunk.css","sourcesContent":["body {\n margin: 0;\n padding: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\",\n \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\",\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\",\n monospace;\n}\n"]} \ No newline at end of file diff --git a/static/js/1.9fac4be2.chunk.js b/static/js/1.9fac4be2.chunk.js deleted file mode 100644 index fda8f38..0000000 --- a/static/js/1.9fac4be2.chunk.js +++ /dev/null @@ -1,2 +0,0 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[1],[function(e,t,n){"use strict";e.exports=n(13)},function(e,t,n){"use strict";function r(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}n.d(t,"a",function(){return r})},function(e,t,n){"use strict";(function(e,r){var a=n(5),o=n.n(a),i=n(9),l=n.n(i),u=n(0),c=n.n(u),s=n(10),f=n(4),d=n(6),p=(n(23),n(3),n(11)),h=function(e,t){for(var n=[e[0]],r=0,a=t.length;r=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n},w=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!==typeof t&&"function"!==typeof t?e:t},x=function(e){return"object"===("undefined"===typeof e?"undefined":m(e))&&e.constructor===Object},C=Object.freeze([]),T=Object.freeze({});function S(e){return"function"===typeof e}function E(e){return e.displayName||e.name||"Component"}function _(e){return e&&"string"===typeof e.styledComponentId}var P="undefined"!==typeof e&&Object({NODE_ENV:"production",PUBLIC_URL:""}).SC_ATTR||"data-styled",O="undefined"!==typeof window&&"HTMLElement"in window,N="boolean"===typeof SC_DISABLE_SPEEDY&&SC_DISABLE_SPEEDY||!1;var A=function(e){function t(n){y(this,t);for(var r=arguments.length,a=Array(r>1?r-1:0),o=1;o0&&-1!==n.slice(0,t).indexOf($)&&n.slice(t-$.length,t)!==$?"."+z:e};F.use([function(e,t,n){2===e&&n.length&&n[0].lastIndexOf($)>0&&(n[0]=n[0].replace(W,V))},U,L]),j.use([U,L]);function B(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"&",a=e.join("").replace(R,""),o=t&&n?n+" "+t+" { "+a+" }":a;return z=r,$=t,W=new RegExp("\\"+$+"\\b","g"),F(n||!t?"":t,o)}var H=function(){return n.nc},Q=function(e,t,n){n&&((e[t]||(e[t]=Object.create(null)))[n]=!0)},q=function(e,t){e[t]=Object.create(null)},K=function(e){return function(t,n){return void 0!==e[t]&&e[t][n]}},Y=function(e){var t="";for(var n in e)t+=Object.keys(e[n]).join(" ")+" ";return t.trim()},X=function(e){if(e.sheet)return e.sheet;for(var t=document.styleSheets.length,n=0;n"+e()+""}},te=function(e,t){return function(){var n,r=((n={})[P]=Y(t),n["data-styled-version"]="4.1.3",n),a=H();return a&&(r.nonce=a),c.a.createElement("style",g({},r,{dangerouslySetInnerHTML:{__html:e()}}))}},ne=function(e){return function(){return Object.keys(e)}},re=function(e){return document.createTextNode(Z(e))},ae=function e(t,n){var r=void 0===t?Object.create(null):t,a=void 0===n?Object.create(null):n,o=function(e){var t=a[e];return void 0!==t?t:a[e]=[""]},i=function(){var e="";for(var t in a){var n=a[t][0];n&&(e+=Z(t)+n)}return e};return{clone:function(){var t=function(e){var t=Object.create(null);for(var n in e)t[n]=g({},e[n]);return t}(r),n=Object.create(null);for(var o in a)n[o]=[a[o][0]];return e(t,n)},css:i,getIds:ne(a),hasNameForId:K(r),insertMarker:o,insertRules:function(e,t,n){o(e)[0]+=t.join(" "),Q(r,e,n)},removeRules:function(e){var t=a[e];void 0!==t&&(t[0]="",q(r,e))},sealed:!1,styleTag:null,toElement:te(i,r),toHTML:ee(i,r)}},oe=function(e,t,n,r,a){if(O&&!n){var o=function(e,t,n){var r=document.createElement("style");r.setAttribute(P,""),r.setAttribute("data-styled-version","4.1.3");var a=H();if(a&&r.setAttribute("nonce",a),r.appendChild(document.createTextNode("")),e&&!t)e.appendChild(r);else{if(!t||!e||!t.parentNode)throw new A(6);t.parentNode.insertBefore(r,n?t:t.nextSibling)}return r}(e,t,r);return N?function(e,t){var n=Object.create(null),r=Object.create(null),a=void 0!==t,o=!1,i=function(t){var a=r[t];return void 0!==a?a:(r[t]=re(t),e.appendChild(r[t]),n[t]=Object.create(null),r[t])},l=function(){var e="";for(var t in r)e+=r[t].data;return e};return{clone:function(){throw new A(5)},css:l,getIds:ne(r),hasNameForId:K(n),insertMarker:i,insertRules:function(e,r,l){for(var u=i(e),c=[],s=r.length,f=0;f0&&(o=!0,t().insertRules(e+"-import",c))},removeRules:function(i){var l=r[i];if(void 0!==l){var u=re(i);e.replaceChild(u,l),r[i]=u,q(n,i),a&&o&&t().removeRules(i+"-import")}},sealed:!1,styleTag:e,toElement:te(l,n),toHTML:ee(l,n)}}(o,a):function(e,t){var n=Object.create(null),r=Object.create(null),a=[],o=void 0!==t,i=!1,l=function(e){var t=r[e];return void 0!==t?t:(r[e]=a.length,a.push(0),q(n,e),r[e])},u=function(){var t=X(e).cssRules,n="";for(var o in r){n+=Z(o);for(var i=r[o],l=J(a,i),u=l-a[i];u0&&(i=!0,t().insertRules(r+"-import",h)),a[s]+=p,Q(n,r,c)},removeRules:function(l){var u=r[l];if(void 0!==u){var c=a[u];!function(e,t,n){for(var r=t-n,a=t;a>r;a-=1)e.deleteRule(a)}(X(e),J(a,u)-1,c),a[u]=0,q(n,l),o&&i&&t().removeRules(l+"-import")}},sealed:!1,styleTag:e,toElement:te(u,n),toHTML:ee(u,n)}}(o,a)}return ae()},ie=/\s+/,le=void 0;le=O?N?40:1e3:-1;var ue=0,ce=void 0,se=function(){function e(){var t=this,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:O?document.head:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1];y(this,e),this.getImportRuleTag=function(){var e=t.importRuleTag;if(void 0!==e)return e;var n=t.tags[0];return t.importRuleTag=oe(t.target,n?n.styleTag:null,t.forceServer,!0)},ue+=1,this.id=ue,this.forceServer=r,this.target=r?null:n,this.tagMap={},this.deferred={},this.rehydratedNames={},this.ignoreRehydratedNames={},this.tags=[],this.capacity=1,this.clones=[]}return e.prototype.rehydrate=function(){if(!O||this.forceServer)return this;var e=[],t=[],n=!1,r=document.querySelectorAll("style["+P+'][data-styled-version="4.1.3"]'),a=r.length;if(!a)return this;for(var o=0;o0&&void 0!==arguments[0]&&arguments[0];ce=new e(void 0,t).rehydrate()},e.prototype.clone=function(){var t=new e(this.target,this.forceServer);return this.clones.push(t),t.tags=this.tags.map(function(e){for(var n=e.getIds(),r=e.clone(),a=0;a1?t-1:0),r=1;r=4;)t=1540483477*(65535&(t=255&e.charCodeAt(a)|(255&e.charCodeAt(++a))<<8|(255&e.charCodeAt(++a))<<16|(255&e.charCodeAt(++a))<<24))+((1540483477*(t>>>16)&65535)<<16),r=1540483477*(65535&r)+((1540483477*(r>>>16)&65535)<<16)^(t=1540483477*(65535&(t^=t>>>24))+((1540483477*(t>>>16)&65535)<<16)),n-=4,++a;switch(n){case 3:r^=(255&e.charCodeAt(a+2))<<16;case 2:r^=(255&e.charCodeAt(a+1))<<8;case 1:r=1540483477*(65535&(r^=255&e.charCodeAt(a)))+((1540483477*(r>>>16)&65535)<<16)}return((r=1540483477*(65535&(r^=r>>>13))+((1540483477*(r>>>16)&65535)<<16))^r>>>15)>>>0}var be=52,ke=function(e){return String.fromCharCode(e+(e>25?39:97))};function we(e){var t="",n=void 0;for(n=e;n>be;n=Math.floor(n/be))t=ke(n%be)+t;return ke(n%be)+t}function xe(e,t){for(var n=0;n2&&void 0!==arguments[2]?arguments[2]:T,r=!!n&&e.theme===n.theme;return e.theme&&!r?e.theme:t||n.theme},Pe=/[[\].#*$><+~=|^:(),"'`-]+/g,Oe=/(^-|-$)/g;function Ne(e){return e.replace(Pe,"-").replace(Oe,"")}function Ae(e){return"string"===typeof e&&!0}var Ie={childContextTypes:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDerivedStateFromProps:!0,propTypes:!0,type:!0},Me={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},Re=((Ce={})[f.ForwardRef]={$$typeof:!0,render:!0},Ce),je=Object.defineProperty,Fe=Object.getOwnPropertyNames,De=Object.getOwnPropertySymbols,Le=void 0===De?function(){return[]}:De,Ue=Object.getOwnPropertyDescriptor,ze=Object.getPrototypeOf,$e=Object.prototype,We=Array.prototype;function Ve(e,t,n){if("string"!==typeof t){var r=ze(t);r&&r!==$e&&Ve(e,r,n);for(var a=We.concat(Fe(t),Le(t)),o=Re[e.$$typeof]||Ie,i=Re[t.$$typeof]||Ie,l=a.length,u=void 0,c=void 0;l--;)if(c=a[l],!Me[c]&&(!n||!n[c])&&(!i||!i[c])&&(!o||!o[c])&&(u=Ue(t,c)))try{je(e,c,u)}catch(s){}return e}return e}var Be=Object(u.createContext)(),He=Be.Consumer,Qe=(function(e){function t(n){y(this,t);var r=w(this,e.call(this,n));return r.getContext=Object(d.a)(r.getContext.bind(r)),r.renderInner=r.renderInner.bind(r),r}b(t,e),t.prototype.render=function(){return this.props.children?c.a.createElement(Be.Consumer,null,this.renderInner):null},t.prototype.renderInner=function(e){var t=this.getContext(this.props.theme,e);return c.a.createElement(Be.Provider,{value:t},c.a.Children.only(this.props.children))},t.prototype.getTheme=function(e,t){if(S(e))return e(t);if(null===e||Array.isArray(e)||"object"!==("undefined"===typeof e?"undefined":m(e)))throw new A(8);return g({},t,e)},t.prototype.getContext=function(e,t){return this.getTheme(e,t)}}(u.Component),function(){function e(){y(this,e),this.masterSheet=se.master,this.instance=this.masterSheet.clone(),this.sealed=!1}e.prototype.seal=function(){if(!this.sealed){var e=this.masterSheet.clones.indexOf(this.instance);this.masterSheet.clones.splice(e,1),this.sealed=!0}},e.prototype.collectStyles=function(e){if(this.sealed)throw new A(2);return c.a.createElement(Ke,{sheet:this.instance},e)},e.prototype.getStyleTags=function(){return this.seal(),this.instance.toHTML()},e.prototype.getStyleElement=function(){return this.seal(),this.instance.toReactElements()},e.prototype.interleaveWithNodeStream=function(e){throw new A(3)}}(),Object(u.createContext)()),qe=Qe.Consumer,Ke=function(e){function t(n){y(this,t);var r=w(this,e.call(this,n));return r.getContext=Object(d.a)(r.getContext),r}return b(t,e),t.prototype.getContext=function(e,t){if(e)return e;if(t)return new se(t);throw new A(4)},t.prototype.render=function(){var e=this.props,t=e.children,n=e.sheet,r=e.target;return c.a.createElement(Qe.Provider,{value:this.getContext(n,r)},t)},t}(u.Component),Ye=(new Set,{});var Xe=function(e){function t(){y(this,t);var n=w(this,e.call(this));return n.attrs={},n.renderOuter=n.renderOuter.bind(n),n.renderInner=n.renderInner.bind(n),n}return b(t,e),t.prototype.render=function(){return c.a.createElement(qe,null,this.renderOuter)},t.prototype.renderOuter=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:se.master;return this.styleSheet=e,this.props.forwardedComponent.componentStyle.isStatic?this.renderInner():c.a.createElement(He,null,this.renderInner)},t.prototype.renderInner=function(e){var t=this.props.forwardedComponent,n=t.componentStyle,r=t.defaultProps,a=(t.displayName,t.foldedComponentIds),o=t.styledComponentId,i=t.target,l=void 0;l=n.isStatic?this.generateAndInjectStyles(T,this.props):void 0!==e?this.generateAndInjectStyles(_e(this.props,e,r),this.props):this.generateAndInjectStyles(this.props.theme||T,this.props);var c=this.props.as||this.attrs.as||i,s=Ae(c),f={},d=g({},this.attrs,this.props),h=void 0;for(h in d)"forwardedComponent"!==h&&"as"!==h&&("forwardedRef"===h?f.ref=d[h]:s&&!Object(p.a)(h)||(f[h]=d[h]));return this.props.style&&this.attrs.style&&(f.style=g({},this.attrs.style,this.props.style)),f.className=Array.prototype.concat(a,this.props.className,o,this.attrs.className,l).filter(Boolean).join(" "),Object(u.createElement)(c,f)},t.prototype.buildExecutionContext=function(e,t,n){var r=this,a=g({},t,{theme:e});return n.length?(this.attrs={},n.forEach(function(e){var t,n=e,o=!1,i=void 0,l=void 0;for(l in S(n)&&(n=n(a),o=!0),n)i=n[l],o||!S(i)||(t=i)&&t.prototype&&t.prototype.isReactComponent||_(i)||(i=i(a)),r.attrs[l]=i,a[l]=i}),a):a},t.prototype.generateAndInjectStyles=function(e,t){var n=t.forwardedComponent,r=n.attrs,a=n.componentStyle;n.warnTooManyClasses;return a.isStatic&&!r.length?a.generateAndInjectStyles(T,this.styleSheet):a.generateAndInjectStyles(this.buildExecutionContext(e,t,r),this.styleSheet)},t}(u.Component);function Ge(e,t,n){var r=_(e),a=!Ae(e),o=t.displayName,i=void 0===o?function(e){return Ae(e)?"styled."+e:"Styled("+E(e)+")"}(e):o,l=t.componentId,u=void 0===l?function(e,t,n){var r="string"!==typeof t?"sc":Ne(t),a=(Ye[r]||0)+1;Ye[r]=a;var o=r+"-"+e.generateName(r+a);return n?n+"-"+o:o}(Ee,t.displayName,t.parentComponentId):l,s=t.ParentComponent,f=void 0===s?Xe:s,d=t.attrs,p=void 0===d?C:d,h=t.displayName&&t.componentId?Ne(t.displayName)+"-"+t.componentId:t.componentId||u,m=r&&e.attrs?Array.prototype.concat(e.attrs,p).filter(Boolean):p,y=new Ee(r?e.componentStyle.rules.concat(n):n,m,h),v=c.a.forwardRef(function(e,t){return c.a.createElement(f,g({},e,{forwardedComponent:v,forwardedRef:t}))});return v.attrs=m,v.componentStyle=y,v.displayName=i,v.foldedComponentIds=r?Array.prototype.concat(e.foldedComponentIds,e.styledComponentId):C,v.styledComponentId=h,v.target=r?e.target:e,v.withComponent=function(e){var r=t.componentId,a=k(t,["componentId"]),o=r&&r+"-"+(Ae(e)?e:Ne(E(e)));return Ge(e,g({},a,{attrs:m,componentId:o,ParentComponent:f}),n)},v.toString=function(){return"."+v.styledComponentId},a&&Ve(v,e,{attrs:!0,componentStyle:!0,displayName:!0,foldedComponentIds:!0,styledComponentId:!0,target:!0,withComponent:!0}),v}var Ze=function(e){return function e(t,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:T;if(!Object(f.isValidElementType)(n))throw new A(1,String(n));var a=function(){return t(n,r,ve.apply(void 0,arguments))};return a.withConfig=function(a){return e(t,n,g({},r,a))},a.attrs=function(a){return e(t,n,g({},r,{attrs:Array.prototype.concat(r.attrs,a).filter(Boolean)}))},a}(Ge,e)};["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","main","map","mark","marquee","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr","circle","clipPath","defs","ellipse","foreignObject","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","svg","text","tspan"].forEach(function(e){Ze[e]=Ze(e)});!function(){function e(t,n){y(this,e),this.rules=t,this.componentId=n,this.isStatic=xe(t,C),se.master.hasId(n)||se.master.deferredInject(n,[])}e.prototype.createStyles=function(e,t){var n=B(ye(this.rules,e,t),"");t.inject(this.componentId,n)},e.prototype.removeStyles=function(e){var t=this.componentId;e.hasId(t)&&e.remove(t)},e.prototype.renderStyles=function(e,t){this.removeStyles(t),this.createStyles(e,t)}}();O&&(window.scCGSHMRCache={});t.a=Ze}).call(this,n(20),n(21)(e))},function(e,t,n){"use strict";!function e(){if("undefined"!==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"===typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(14)},function(e,t,n){"use strict";e.exports=n(22)},function(e,t,n){e.exports=function e(t){"use strict";var n=/^\0+/g,r=/[\0\r\f]/g,a=/: */g,o=/zoo|gra/,i=/([,: ])(transform)/g,l=/,+\s*(?![^(]*[)])/g,u=/ +\s*(?![^(]*[)])/g,c=/ *[\0] */g,s=/,\r+?/g,f=/([\t\r\n ])*\f?&/g,d=/:global\(((?:[^\(\)\[\]]*|\[.*\]|\([^\(\)]*\))*)\)/g,p=/\W+/g,h=/@(k\w+)\s*(\S*)\s*/,m=/::(place)/g,y=/:(read-only)/g,v=/\s+(?=[{\];=:>])/g,g=/([[}=:>])\s+/g,b=/(\{[^{]+?);(?=\})/g,k=/\s{2,}/g,w=/([^\(])(:+) */g,x=/[svh]\w+-[tblr]{2}/,C=/\(\s*(.*)\s*\)/g,T=/([\s\S]*?);/g,S=/-self|flex-/g,E=/[^]*?(:[rp][el]a[\w-]+)[^]*/,_=/stretch|:\s*\w+\-(?:conte|avail)/,P=/([^-])(image-set\()/,O="-webkit-",N="-moz-",A="-ms-",I=59,M=125,R=123,j=40,F=41,D=91,L=93,U=10,z=13,$=9,W=64,V=32,B=38,H=45,Q=95,q=42,K=44,Y=58,X=39,G=34,Z=47,J=62,ee=43,te=126,ne=0,re=12,ae=11,oe=107,ie=109,le=115,ue=112,ce=111,se=105,fe=99,de=100,pe=112,he=1,me=1,ye=0,ve=1,ge=1,be=1,ke=0,we=0,xe=0,Ce=[],Te=[],Se=0,Ee=null,_e=-2,Pe=-1,Oe=0,Ne=1,Ae=2,Ie=3,Me=0,Re=1,je="",Fe="",De="";function Le(e,t,a,o,i){for(var l,u,s=0,f=0,d=0,p=0,v=0,g=0,b=0,k=0,x=0,T=0,S=0,E=0,_=0,P=0,Q=0,ke=0,Te=0,Ee=0,_e=0,Pe=a.length,ze=Pe-1,Qe="",qe="",Ke="",Ye="",Xe="",Ge="";Q0&&(qe=qe.replace(r,"")),qe.trim().length>0)){switch(b){case V:case $:case I:case z:case U:break;default:qe+=a.charAt(Q)}b=I}if(1===Te)switch(b){case R:case M:case I:case G:case X:case j:case F:case K:Te=0;case $:case z:case U:case V:break;default:for(Te=0,_e=Q,v=b,Q--,b=I;_e0&&(++Q,b=v);case R:_e=Pe}}switch(b){case R:for(v=(qe=qe.trim()).charCodeAt(0),S=1,_e=++Q;Q0&&(qe=qe.replace(r,"")),g=qe.charCodeAt(1)){case de:case ie:case le:case H:l=t;break;default:l=Ce}if(_e=(Ke=Le(t,l,Ke,g,i+1)).length,xe>0&&0===_e&&(_e=qe.length),Se>0&&(l=Ue(Ce,qe,Ee),u=Be(Ie,Ke,l,t,me,he,_e,g,i,o),qe=l.join(""),void 0!==u&&0===(_e=(Ke=u.trim()).length)&&(g=0,Ke="")),_e>0)switch(g){case le:qe=qe.replace(C,Ve);case de:case ie:case H:Ke=qe+"{"+Ke+"}";break;case oe:Ke=(qe=qe.replace(h,"$1 $2"+(Re>0?je:"")))+"{"+Ke+"}",Ke=1===ge||2===ge&&We("@"+Ke,3)?"@"+O+Ke+"@"+Ke:"@"+Ke;break;default:Ke=qe+Ke,o===pe&&(Ye+=Ke,Ke="")}else Ke="";break;default:Ke=Le(t,Ue(t,qe,Ee),Ke,o,i+1)}Xe+=Ke,E=0,Te=0,P=0,ke=0,Ee=0,_=0,qe="",Ke="",b=a.charCodeAt(++Q);break;case M:case I:if((_e=(qe=(ke>0?qe.replace(r,""):qe).trim()).length)>1)switch(0===P&&((v=qe.charCodeAt(0))===H||v>96&&v<123)&&(_e=(qe=qe.replace(" ",":")).length),Se>0&&void 0!==(u=Be(Ne,qe,t,e,me,he,Ye.length,o,i,o))&&0===(_e=(qe=u.trim()).length)&&(qe="\0\0"),v=qe.charCodeAt(0),g=qe.charCodeAt(1),v){case ne:break;case W:if(g===se||g===fe){Ge+=qe+a.charAt(Q);break}default:if(qe.charCodeAt(_e-1)===Y)break;Ye+=$e(qe,v,g,qe.charCodeAt(2))}E=0,Te=0,P=0,ke=0,Ee=0,qe="",b=a.charCodeAt(++Q)}}switch(b){case z:case U:if(f+p+d+s+we===0)switch(T){case F:case X:case G:case W:case te:case J:case q:case ee:case Z:case H:case Y:case K:case I:case R:case M:break;default:P>0&&(Te=1)}f===Z?f=0:ve+E===0&&o!==oe&&qe.length>0&&(ke=1,qe+="\0"),Se*Me>0&&Be(Oe,qe,t,e,me,he,Ye.length,o,i,o),he=1,me++;break;case I:case M:if(f+p+d+s===0){he++;break}default:switch(he++,Qe=a.charAt(Q),b){case $:case V:if(p+s+f===0)switch(k){case K:case Y:case $:case V:Qe="";break;default:b!==V&&(Qe=" ")}break;case ne:Qe="\\0";break;case re:Qe="\\f";break;case ae:Qe="\\v";break;case B:p+f+s===0&&ve>0&&(Ee=1,ke=1,Qe="\f"+Qe);break;case 108:if(p+f+s+ye===0&&P>0)switch(Q-P){case 2:k===ue&&a.charCodeAt(Q-3)===Y&&(ye=k);case 8:x===ce&&(ye=x)}break;case Y:p+f+s===0&&(P=Q);break;case K:f+d+p+s===0&&(ke=1,Qe+="\r");break;case G:case X:0===f&&(p=p===b?0:0===p?b:p);break;case D:p+f+d===0&&s++;break;case L:p+f+d===0&&s--;break;case F:p+f+s===0&&d--;break;case j:if(p+f+s===0){if(0===E)switch(2*k+3*x){case 533:break;default:S=0,E=1}d++}break;case W:f+d+p+s+P+_===0&&(_=1);break;case q:case Z:if(p+s+d>0)break;switch(f){case 0:switch(2*b+3*a.charCodeAt(Q+1)){case 235:f=Z;break;case 220:_e=Q,f=q}break;case q:b===Z&&k===q&&_e+2!==Q&&(33===a.charCodeAt(_e+2)&&(Ye+=a.substring(_e,Q+1)),Qe="",f=0)}}if(0===f){if(ve+p+s+_===0&&o!==oe&&b!==I)switch(b){case K:case te:case J:case ee:case F:case j:if(0===E){switch(k){case $:case V:case U:case z:Qe+="\0";break;default:Qe="\0"+Qe+(b===K?"":"\0")}ke=1}else switch(b){case j:P+7===Q&&108===k&&(P=0),E=++S;break;case F:0==(E=--S)&&(ke=1,Qe+="\0")}break;case $:case V:switch(k){case ne:case R:case M:case I:case K:case re:case $:case V:case U:case z:break;default:0===E&&(ke=1,Qe+="\0")}}qe+=Qe,b!==V&&b!==$&&(T=b)}}x=k,k=b,Q++}if(_e=Ye.length,xe>0&&0===_e&&0===Xe.length&&0===t[0].length==0&&(o!==ie||1===t.length&&(ve>0?Fe:De)===t[0])&&(_e=t.join(",").length+2),_e>0){if(l=0===ve&&o!==oe?function(e){for(var t,n,a=0,o=e.length,i=Array(o);a1)){if(d=u.charCodeAt(u.length-1),p=n.charCodeAt(0),t="",0!==s)switch(d){case q:case te:case J:case ee:case V:case j:break;default:t=" "}switch(p){case B:n=t+Fe;case te:case J:case ee:case V:case F:case j:break;case D:n=t+n+Fe;break;case Y:switch(2*n.charCodeAt(1)+3*n.charCodeAt(2)){case 530:if(be>0){n=t+n.substring(8,f-1);break}default:(s<1||l[s-1].length<1)&&(n=t+Fe+n)}break;case K:t="";default:n=f>1&&n.indexOf(":")>0?t+n.replace(w,"$1"+Fe+"$2"):t+n+Fe}u+=n}i[a]=u.replace(r,"").trim()}return i}(t):t,Se>0&&void 0!==(u=Be(Ae,Ye,l,e,me,he,_e,o,i,o))&&0===(Ye=u).length)return Ge+Ye+Xe;if(Ye=l.join(",")+"{"+Ye+"}",ge*ye!=0){switch(2!==ge||We(Ye,2)||(ye=0),ye){case ce:Ye=Ye.replace(y,":"+N+"$1")+Ye;break;case ue:Ye=Ye.replace(m,"::"+O+"input-$1")+Ye.replace(m,"::"+N+"$1")+Ye.replace(m,":"+A+"input-$1")+Ye}ye=0}}return Ge+Ye+Xe}function Ue(e,t,n){var r=t.trim().split(s),a=r,o=r.length,i=e.length;switch(i){case 0:case 1:for(var l=0,u=0===i?"":e[0]+" ";l0&&ve>0)return a.replace(d,"$1").replace(f,"$1"+De);break;default:return e.trim()+a.replace(f,"$1"+e.trim())}default:if(n*ve>0&&a.indexOf("\f")>0)return a.replace(f,(e.charCodeAt(0)===Y?"":"$1")+e.trim())}return e+a}function $e(e,t,n,r){var c,s=0,f=e+";",d=2*t+3*n+4*r;if(944===d)return function(e){var t=e.length,n=e.indexOf(":",9)+1,r=e.substring(0,n).trim(),a=e.substring(n,t-1).trim();switch(e.charCodeAt(9)*Re){case 0:break;case H:if(110!==e.charCodeAt(10))break;default:for(var o=a.split((a="",l)),i=0,n=0,t=o.length;iW&&f<90||f>96&&f<123||f===Q||f===H&&c.charCodeAt(1)!==H))switch(isNaN(parseFloat(c))+(-1!==c.indexOf("("))){case 1:switch(c){case"infinite":case"alternate":case"backwards":case"running":case"normal":case"forwards":case"both":case"none":case"linear":case"ease":case"ease-in":case"ease-out":case"ease-in-out":case"paused":case"reverse":case"alternate-reverse":case"inherit":case"initial":case"unset":case"step-start":case"step-end":break;default:c+=je}}s[n++]=c}a+=(0===i?"":",")+s.join(" ")}}return a=r+a+";",1===ge||2===ge&&We(a,1)?O+a+a:a}(f);if(0===ge||2===ge&&!We(f,1))return f;switch(d){case 1015:return 97===f.charCodeAt(10)?O+f+f:f;case 951:return 116===f.charCodeAt(3)?O+f+f:f;case 963:return 110===f.charCodeAt(5)?O+f+f:f;case 1009:if(100!==f.charCodeAt(4))break;case 969:case 942:return O+f+f;case 978:return O+f+N+f+f;case 1019:case 983:return O+f+N+f+A+f+f;case 883:return f.charCodeAt(8)===H?O+f+f:f.indexOf("image-set(",11)>0?f.replace(P,"$1"+O+"$2")+f:f;case 932:if(f.charCodeAt(4)===H)switch(f.charCodeAt(5)){case 103:return O+"box-"+f.replace("-grow","")+O+f+A+f.replace("grow","positive")+f;case 115:return O+f+A+f.replace("shrink","negative")+f;case 98:return O+f+A+f.replace("basis","preferred-size")+f}return O+f+A+f+f;case 964:return O+f+A+"flex-"+f+f;case 1023:if(99!==f.charCodeAt(8))break;return c=f.substring(f.indexOf(":",15)).replace("flex-","").replace("space-between","justify"),O+"box-pack"+c+O+f+A+"flex-pack"+c+f;case 1005:return o.test(f)?f.replace(a,":"+O)+f.replace(a,":"+N)+f:f;case 1e3:switch(s=(c=f.substring(13).trim()).indexOf("-")+1,c.charCodeAt(0)+c.charCodeAt(s)){case 226:c=f.replace(x,"tb");break;case 232:c=f.replace(x,"tb-rl");break;case 220:c=f.replace(x,"lr");break;default:return f}return O+f+A+c+f;case 1017:if(-1===f.indexOf("sticky",9))return f;case 975:switch(s=(f=e).length-10,d=(c=(33===f.charCodeAt(s)?f.substring(0,s):f).substring(e.indexOf(":",7)+1).trim()).charCodeAt(0)+(0|c.charCodeAt(7))){case 203:if(c.charCodeAt(8)<111)break;case 115:f=f.replace(c,O+c)+";"+f;break;case 207:case 102:f=f.replace(c,O+(d>102?"inline-":"")+"box")+";"+f.replace(c,O+c)+";"+f.replace(c,A+c+"box")+";"+f}return f+";";case 938:if(f.charCodeAt(5)===H)switch(f.charCodeAt(6)){case 105:return c=f.replace("-items",""),O+f+O+"box-"+c+A+"flex-"+c+f;case 115:return O+f+A+"flex-item-"+f.replace(S,"")+f;default:return O+f+A+"flex-line-pack"+f.replace("align-content","").replace(S,"")+f}break;case 973:case 989:if(f.charCodeAt(3)!==H||122===f.charCodeAt(4))break;case 931:case 953:if(!0===_.test(e))return 115===(c=e.substring(e.indexOf(":")+1)).charCodeAt(0)?$e(e.replace("stretch","fill-available"),t,n,r).replace(":fill-available",":stretch"):f.replace(c,O+c)+f.replace(c,N+c.replace("fill-",""))+f;break;case 962:if(f=O+f+(102===f.charCodeAt(5)?A+f:"")+f,n+r===211&&105===f.charCodeAt(13)&&f.indexOf("transform",10)>0)return f.substring(0,f.indexOf(";",27)+1).replace(i,"$1"+O+"$2")+f}return f}function We(e,t){var n=e.indexOf(1===t?":":"{"),r=e.substring(0,3!==t?n:10),a=e.substring(n+1,e.length-1);return Ee(2!==t?r:r.replace(E,"$1"),a,t)}function Ve(e,t){var n=$e(t,t.charCodeAt(0),t.charCodeAt(1),t.charCodeAt(2));return n!==t+";"?n.replace(T," or ($1)").substring(4):"("+t+")"}function Be(e,t,n,r,a,o,i,l,u,c){for(var s,f=0,d=t;f0&&(je=a.replace(p,o===D?"":"-")),o=1,1===ve?De=a:Fe=a;var i,l=[De];Se>0&&void 0!==(i=Be(Pe,n,l,l,me,he,0,0,0,0))&&"string"==typeof i&&(n=i);var u=Le(Ce,l,n,0,0);return Se>0&&void 0!==(i=Be(_e,u,l,l,me,he,u.length,0,0,0))&&"string"!=typeof(u=i)&&(o=0),je="",De="",Fe="",ye=0,me=1,he=1,ke*o==0?u:u.replace(r,"").replace(v,"").replace(g,"$1").replace(b,"$1").replace(k," ")}return qe.use=function e(t){switch(t){case void 0:case null:Se=Te.length=0;break;default:if("function"==typeof t)Te[Se++]=t;else if("object"==typeof t)for(var n=0,r=t.length;nA.length&&A.push(e)}function R(e,t,n){return null==e?0:function e(t,n,r,a){var l=typeof t;"undefined"!==l&&"boolean"!==l||(t=null);var u=!1;if(null===t)u=!0;else switch(l){case"string":case"number":u=!0;break;case"object":switch(t.$$typeof){case o:case i:u=!0}}if(u)return r(a,t,""===n?"."+j(t,0):n),1;if(u=0,n=""===n?".":n+":",Array.isArray(t))for(var c=0;cthis.eventPool.length&&this.eventPool.push(e)}function fe(e){e.eventPool=[],e.getPooled=ce,e.release=se}a(ue.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!==typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=ie)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!==typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=ie)},persist:function(){this.isPersistent=ie},isPersistent:le,destructor:function(){var e,t=this.constructor.Interface;for(e in t)this[e]=null;this.nativeEvent=this._targetInst=this.dispatchConfig=null,this.isPropagationStopped=this.isDefaultPrevented=le,this._dispatchInstances=this._dispatchListeners=null}}),ue.Interface={type:null,target:null,currentTarget:function(){return null},eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null},ue.extend=function(e){function t(){}function n(){return r.apply(this,arguments)}var r=this;t.prototype=r.prototype;var o=new t;return a(o,n.prototype),n.prototype=o,n.prototype.constructor=n,n.Interface=a({},r.Interface,e),n.extend=r.extend,fe(n),n},fe(ue);var de=ue.extend({data:null}),pe=ue.extend({data:null}),he=[9,13,27,32],me=H&&"CompositionEvent"in window,ye=null;H&&"documentMode"in document&&(ye=document.documentMode);var ve=H&&"TextEvent"in window&&!ye,ge=H&&(!me||ye&&8=ye),be=String.fromCharCode(32),ke={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["compositionend","keypress","textInput","paste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:"blur compositionend keydown keypress keyup mousedown".split(" ")},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:"blur compositionstart keydown keypress keyup mousedown".split(" ")},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:"blur compositionupdate keydown keypress keyup mousedown".split(" ")}},we=!1;function xe(e,t){switch(e){case"keyup":return-1!==he.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"blur":return!0;default:return!1}}function Ce(e){return"object"===typeof(e=e.detail)&&"data"in e?e.data:null}var Te=!1;var Se={eventTypes:ke,extractEvents:function(e,t,n,r){var a=void 0,o=void 0;if(me)e:{switch(e){case"compositionstart":a=ke.compositionStart;break e;case"compositionend":a=ke.compositionEnd;break e;case"compositionupdate":a=ke.compositionUpdate;break e}a=void 0}else Te?xe(e,n)&&(a=ke.compositionEnd):"keydown"===e&&229===n.keyCode&&(a=ke.compositionStart);return a?(ge&&"ko"!==n.locale&&(Te||a!==ke.compositionStart?a===ke.compositionEnd&&Te&&(o=oe()):(re="value"in(ne=r)?ne.value:ne.textContent,Te=!0)),a=de.getPooled(a,t,n,r),o?a.data=o:null!==(o=Ce(n))&&(a.data=o),B(a),o=a):o=null,(e=ve?function(e,t){switch(e){case"compositionend":return Ce(t);case"keypress":return 32!==t.which?null:(we=!0,be);case"textInput":return(e=t.data)===be&&we?null:e;default:return null}}(e,n):function(e,t){if(Te)return"compositionend"===e||!me&&xe(e,t)?(e=oe(),ae=re=ne=null,Te=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1