From eec51d896d2c13f45d5c5f0eef15edf3db8068f9 Mon Sep 17 00:00:00 2001 From: CodeDead Date: Fri, 14 Feb 2025 19:56:42 +0100 Subject: [PATCH 01/22] feat: building blocks for v2 --- .eslintignore | 6 - .eslintrc.json | 30 - .github/workflows/npm_test.yml | 27 + .gitignore | 98 +- .nvmrc | 1 + .prettierrc.mjs | 35 + .storybook/main.ts | 16 + .storybook/preview.tsx | 33 + .stylelintignore | 2 + .stylelintrc.json | 28 + README.md | 8 +- app/robots.txt | 3 + .../ColorSchemeToggle/ColorSchemeToggle.tsx | 13 + components/Dots/index.jsx | 118 + components/FeatureCard/index.jsx | 19 + components/FeatureCard/index.module.css | 39 + components/Footer/index.jsx | 45 + components/Footer/index.module.css | 12 + components/NavBar/index.jsx | 121 + components/NavBar/navbar.module.css | 55 + components/TopBar/index.jsx | 135 + components/TopBar/index.module.css | 35 + .../MainContextProvider/index.jsx | 10 - eslint.config.mjs | 4 + gatsby-browser.js | 8 - gatsby-config.js | 72 - gatsby-node.js | 31 - gatsby-ssr.js | 8 - lib/posts.js | 95 + next-env.d.ts | 6 + next.config.mjs | 13 + package.json | 100 +- pages/_app.jsx | 42 + pages/_document.jsx | 18 + pages/about.jsx | 163 + pages/blog/[year]/[month]/[day]/[id].jsx | 87 + pages/blog/index.jsx | 136 + pages/blog/posts/[id].jsx | 161 + pages/contact.jsx | 106 + pages/donate.jsx | 249 + pages/index.jsx | 226 + pages/privacy.jsx | 192 + pages/software/deadhash/index.jsx | 228 + pages/software/index.jsx | 373 + postcss.config.cjs | 14 + .../blog => posts}/2014/12/14/hello-world.md | 0 .../blog => posts}/2014/12/29/deadhash-1.1.md | 2 +- .../blog => posts}/2015/03/05/deadhash-1.2.md | 0 .../2015/03/06/deadpix-1.0.md | 0 .../blog => posts}/2015/06/20/deadpix-1.1.md | 0 .../blog => posts}/2015/07/04/deadhash-1.3.md | 0 .../2015/08/24/5-software-project-ideas.md | 4 +- .../2015/09/22/advanced-passgen-release.md | 0 .../2015/10/26/deadlock-release.md | 0 .../2015/10/27/advanced-passgen-1.1.md | 0 .../blog => posts}/2015/11/06/deadlock-1.1.md | 0 .../blog => posts}/2015/11/27/deadlock-1.2.md | 0 .../2015/12/01/deadlock-1.2.1.md | 0 .../2015/12/07/deadlock-1.2.2.md | 0 .../blog => posts}/2016/01/12/deadlock-1.3.md | 0 .../2016/01/14/deadlock-1.3.1.md | 0 .../2016/01/20/deadlock-1.3.2.md | 0 .../2016/02/10/deadlock-1.3.3.md | 0 .../2016/03/13/deadlock-1.3.4.md | 4 +- .../blog => posts}/2016/09/07/deadlock-1.4.md | 0 .../2016/09/11/advanced-passgen-1.2.md | 0 .../2016/09/12/advanced-passgen-1.3.md | 0 .../2017/01/17/advanced-portchecker.md | 0 .../blog => posts}/2017/01/27/aniview.md | 0 .../blog => posts}/2017/01/31/aniview-1.1.md | 0 .../blog => posts}/2017/02/11/pk-finder.md | 0 .../2017/03/10/pk-finder-1.1.md | 0 .../2017/04/18/advanced-portchecker-1.1.md | 0 .../blog => posts}/2017/04/19/aniview-1.2.md | 0 .../2017/05/05/deadhash-android.md | 0 .../blog => posts}/2017/06/22/aniview-1.3.md | 0 .../2017/06/28/advanced-passgen-1.4.md | 0 .../2017/06/28/advanced-portchecker-1.2.md | 0 .../2017/07/03/aniview-1.3.1.md | 0 .../2017/08/28/aniview-1.3.2.md | 0 .../2017/08/28/pk-finder-1.2.md | 0 .../2017/09/02/pk-finder-1.3.md | 0 .../2017/09/08/advanced-passgen-1.5.md | 0 .../2017/09/12/advanced-passgen-1.5.1.md | 0 .../2018/01/01/pk-finder-1.4.md | 0 .../2018/01/04/advanced-portchecker-1.3.md | 0 .../2018/01/04/pk-finder-1.4.1.md | 0 .../2018/01/07/advanced-passgen-1.6.md | 0 .../2018/01/07/what-tools-do-we-use.md | 0 .../blog => posts}/2018/01/27/aniview-1.4.md | 0 .../2018/02/01/aniview-1.4.1.md | 0 .../blog => posts}/2018/02/26/memplus.md | 0 .../2018/03/05/aniview-1.4.2.md | 0 .../blog => posts}/2018/03/06/memplus-1.1.md | 0 .../blog => posts}/2018/03/13/memplus-1.2.md | 0 .../blog => posts}/2018/03/20/memplus-1.3.md | 0 .../2018/03/25/pk-finder-1.4.2.md | 0 .../blog => posts}/2018/04/02/aniview-1.5.md | 0 .../2018/04/04/memplus-1.3.1.md | 0 .../2018/05/01/memplus-1.3.2.md | 0 .../2018/05/02/memplus-translations-wanted.md | 0 .../2018/09/02/pk-finder-1.5.md | 0 .../2018/09/04/advanced-portchecker-1.4.md | 0 .../2019/03/17/pk-finder-1.5.1.md | 0 .../2019/03/19/aniview-1.5.1.md | 0 .../2019/03/29/aniview-1.5.2.md | 0 .../2019/05/07/advanced-portchecker-1.5.md | 0 .../2019/05/09/pk-finder-1.6.md | 0 .../2019/05/11/advanced-passgen-1.7.md | 0 .../2019/05/18/aniview-1.5.3.md | 0 .../blog => posts}/2019/05/21/deadpix-1.2.md | 0 .../2019/08/03/advanced-passgen-1.7.1.md | 0 .../blog => posts}/2020/01/01/deadhash-2.0.md | 0 .../2020/01/23/deadhash-2.0.1.md | 0 .../2020/02/20/javascript-array-traversal.md | 0 .../2020/04/06/deadhash-2.0.2.md | 0 .../2020/06/07/deadhash-2.0.3.md | 0 .../2020/11/10/deadhash-2.0.4.md | 0 .../blog => posts}/2020/11/11/aniview-1.6.md | 0 .../blog => posts}/2021/02/02/new-layout.md | 0 .../2021/02/03/deadhash-2.1.md | 0 .../2021/02/05/deadhash-2.1.1.md | 0 .../2021/02/11/deadhash-2.1.2.md | 0 .../2021/03/23/egld-price-calculator.md | 0 .../2021/06/07/deadhash-2.1.3.md | 0 .../2021/10/01/deadhash-2.2.0.md | 0 .../blog => posts}/2021/10/03/opal-1.0.md | 0 .../blog => posts}/2021/11/22/opal-1.0.1.md | 0 .../2022/01/04/deadhash-2.2.1.md | 0 .../blog => posts}/2022/04/04/opal-1.0.2.md | 0 .../2022/05/08/deadhash-2.2.2.md | 0 .../blog => posts}/2022/06/17/opal-1.0.3.md | 0 .../2022/07/23/deadhash-2.2.3.md | 0 .../2022/07/26/pk-finder-2.0.md | 0 .../2022/10/17/advanced-passgen-2.0.md | 0 .../2022/11/03/advanced-passgen-2.1.0.md | 0 .../2022/12/15/advanced-passgen-2.2.0.md | 0 .../2022/12/16/advanced-passgen-2.2.1.md | 0 .../2023/01/08/advanced-passgen-2.3.0.md | 0 .../2023/03/05/advanced-passgen-2.4.0.md | 0 .../blog => posts}/2023/04/02/opal-1.1.0.md | 0 .../2023/05/04/advanced-passgen-2.4.1.md | 0 .../blog => posts}/2023/07/11/opal-1.2.0.md | 0 .../2023/07/20/advanced-passgen-2.4.2.md | 0 .../2023/10/08/advanced-passgen-2.4.3.md | 0 .../blog => posts}/2023/10/25/opal-1.3.0.md | 0 .../2023/12/18/advanced-passgen-2.5.0.md | 0 .../2024/01/30/advanced-portchecker-2.0.0.md | 0 .../2024/03/21/advanced-portchecker-2.0.1.md | 0 .../blog => posts}/2024/03/28/opal-1.3.1.md | 0 .../2024/05/12/advanced-passgen-2.5.1.md | 0 .../blog => posts}/2024/07/16/opal-1.4.0.md | 0 .../2024/09/30/advanced-passgen-2.5.2.md | 0 .../2024/10/20/advanced-portchecker-2.1.0.md | 0 .../blog => posts}/2025/01/19/opal-1.5.0.md | 0 public/DeadHash.webp | Bin 0 -> 6594 bytes public/advanced passgen.webp | Bin 0 -> 11384 bytes public/advanced portchecker.webp | Bin 0 -> 14042 bytes public/aniview.webp | Bin 0 -> 3780 bytes public/compressr.webp | Bin 0 -> 42152 bytes public/deadhash/deadhash_result.webp | Bin 0 -> 13408 bytes public/deadhash/deadhash_text.webp | Bin 0 -> 5914 bytes public/deadlock.webp | Bin 0 -> 4102 bytes public/deadpix.webp | Bin 0 -> 6764 bytes public/egld.webp | Bin 0 -> 46522 bytes public/favicon.svg | 1 + public/memplus.webp | Bin 0 -> 8878 bytes public/opal.webp | Bin 0 -> 6044 bytes public/pkfinder.webp | Bin 0 -> 2250 bytes public/title.module.css | 10 + .../MainReducer/Actions/actionTypes.js | 2 - .../MainReducer/Actions/index.js | 12 - .../MainReducer/index.jsx | 13 - src/components/AlertDialog/index.jsx | 67 - src/components/Application/index.jsx | 49 - src/components/BackButton/index.jsx | 25 - src/components/BlogList/index.jsx | 23 - src/components/BlogPost/index.jsx | 24 - src/components/DefaultAppBar/index.jsx | 75 - src/components/DonationAlert/index.jsx | 24 - src/components/FacebookIcon/index.jsx | 12 - src/components/Footer/index.jsx | 66 - src/components/GithubIcon/index.jsx | 12 - src/components/Layout/index.css | 16 - src/components/Layout/index.jsx | 102 - src/components/LinkedInIcon/index.jsx | 12 - src/components/LoadingBar/index.jsx | 14 - src/components/MastodonIcon/index.jsx | 12 - src/components/NavigationDrawer/index.jsx | 127 - src/components/PageHeader/index.jsx | 35 - src/components/SEO/index.jsx | 73 - src/images/Advanced PassGen/ap.png | Bin 38008 -> 0 bytes .../Advanced PassGen/ap_advanced_settings.png | Bin 38518 -> 0 bytes .../Advanced PassGen/ap_theme_settings.png | Bin 48095 -> 0 bytes src/images/Advanced PortChecker/ap.png | Bin 52298 -> 0 bytes src/images/Advanced PortChecker/ap_about.png | Bin 48376 -> 0 bytes .../ap_general_settings.png | Bin 63412 -> 0 bytes src/images/AniView/aniview.png | Bin 4591 -> 0 bytes src/images/AniView/av_settings_image.png | Bin 4950 -> 0 bytes src/images/AniView/settings.png | Bin 5538 -> 0 bytes src/images/Compressr/compressr.png | Bin 105963 -> 0 bytes src/images/DeadHash/DeadHash.png | Bin 25667 -> 0 bytes src/images/DeadHash/deadhash_result.png | Bin 47371 -> 0 bytes src/images/DeadHash/deadhash_text.png | Bin 24341 -> 0 bytes src/images/DeadLock/about.png | Bin 4499 -> 0 bytes src/images/DeadLock/deadlock.png | Bin 3298 -> 0 bytes src/images/DeadLock/settings.png | Bin 4919 -> 0 bytes src/images/DeadPix/deadpix.png | Bin 13414 -> 0 bytes src/images/DeadPix/settings.png | Bin 10410 -> 0 bytes src/images/Elrond/egld.png | Bin 129935 -> 0 bytes src/images/MemPlus/memplus.png | Bin 10685 -> 0 bytes src/images/MemPlus/memplus_analyzer.png | Bin 7042 -> 0 bytes .../MemPlus/memplus_settings_monitor.png | Bin 7833 -> 0 bytes src/images/Opal/Opal.png | Bin 30851 -> 0 bytes src/images/Opal/opal_settings.png | Bin 37959 -> 0 bytes src/images/Opal/opal_timer.png | Bin 20514 -> 0 bytes src/images/PK Finder/pkfinder.png | Bin 2898 -> 0 bytes src/images/PK Finder/pkgeneral.png | Bin 6988 -> 0 bytes src/images/PK Finder/pktheme.png | Bin 6348 -> 0 bytes src/pages/404/index.jsx | 44 - src/pages/about/index.jsx | 190 - src/pages/blog/index.jsx | 158 - src/pages/contact/index.jsx | 111 - src/pages/donate/index.jsx | 256 - src/pages/index.jsx | 222 - src/pages/privacy/index.jsx | 201 - src/pages/software/advanced-passgen/index.jsx | 327 - .../advanced-passgen/requirements/index.jsx | 143 - .../software/advanced-portchecker/index.jsx | 338 - .../requirements/index.jsx | 143 - src/pages/software/aniview/index.jsx | 311 - .../software/aniview/requirements/index.jsx | 134 - src/pages/software/deadhash/index.jsx | 344 - .../software/deadhash/requirements/index.jsx | 134 - src/pages/software/deadlock/index.jsx | 293 - .../software/deadlock/requirements/index.jsx | 121 - src/pages/software/deadpix/index.jsx | 303 - .../software/deadpix/requirements/index.jsx | 135 - .../software/egld-price-calculator/index.jsx | 253 - src/pages/software/index.jsx | 382 - src/pages/software/memplus/index.jsx | 301 - .../software/memplus/requirements/index.jsx | 134 - src/pages/software/opal/index.jsx | 340 - .../software/opal/requirements/index.jsx | 144 - src/pages/software/pk-finder/index.jsx | 297 - .../software/pk-finder/requirements/index.jsx | 120 - src/templates/BlogTemplate/index.css | 4 - src/templates/BlogTemplate/index.jsx | 63 - src/utils/ThemeSelector/index.js | 35 - static/favicon.ico | Bin 105563 -> 0 bytes test-utils/index.ts | 5 + test-utils/render.tsx | 11 + theme.js | 5 + tsconfig.json | 46 + yarn.lock | 14145 ++++++---------- 255 files changed, 8563 insertions(+), 15667 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc.json create mode 100644 .github/workflows/npm_test.yml create mode 100644 .nvmrc create mode 100644 .prettierrc.mjs create mode 100644 .storybook/main.ts create mode 100644 .storybook/preview.tsx create mode 100644 .stylelintignore create mode 100644 .stylelintrc.json create mode 100644 app/robots.txt create mode 100644 components/ColorSchemeToggle/ColorSchemeToggle.tsx create mode 100644 components/Dots/index.jsx create mode 100644 components/FeatureCard/index.jsx create mode 100644 components/FeatureCard/index.module.css create mode 100644 components/Footer/index.jsx create mode 100644 components/Footer/index.module.css create mode 100644 components/NavBar/index.jsx create mode 100644 components/NavBar/navbar.module.css create mode 100644 components/TopBar/index.jsx create mode 100644 components/TopBar/index.module.css rename {src/contexts => contexts}/MainContextProvider/index.jsx (67%) create mode 100644 eslint.config.mjs delete mode 100644 gatsby-browser.js delete mode 100644 gatsby-config.js delete mode 100644 gatsby-node.js delete mode 100644 gatsby-ssr.js create mode 100644 lib/posts.js create mode 100644 next-env.d.ts create mode 100644 next.config.mjs create mode 100644 pages/_app.jsx create mode 100644 pages/_document.jsx create mode 100644 pages/about.jsx create mode 100644 pages/blog/[year]/[month]/[day]/[id].jsx create mode 100644 pages/blog/index.jsx create mode 100644 pages/blog/posts/[id].jsx create mode 100644 pages/contact.jsx create mode 100644 pages/donate.jsx create mode 100644 pages/index.jsx create mode 100644 pages/privacy.jsx create mode 100644 pages/software/deadhash/index.jsx create mode 100644 pages/software/index.jsx create mode 100644 postcss.config.cjs rename {src/markdown/blog => posts}/2014/12/14/hello-world.md (100%) rename {src/markdown/blog => posts}/2014/12/29/deadhash-1.1.md (97%) rename {src/markdown/blog => posts}/2015/03/05/deadhash-1.2.md (100%) rename src/markdown/blog/2015/03/06/deadpix.md => posts/2015/03/06/deadpix-1.0.md (100%) rename {src/markdown/blog => posts}/2015/06/20/deadpix-1.1.md (100%) rename {src/markdown/blog => posts}/2015/07/04/deadhash-1.3.md (100%) rename src/markdown/blog/2015/08/24/5-project-ideas.md => posts/2015/08/24/5-software-project-ideas.md (92%) rename src/markdown/blog/2015/09/22/advanced-passgen.md => posts/2015/09/22/advanced-passgen-release.md (100%) rename {src/markdown/blog => posts}/2015/10/26/deadlock-release.md (100%) rename {src/markdown/blog => posts}/2015/10/27/advanced-passgen-1.1.md (100%) rename {src/markdown/blog => posts}/2015/11/06/deadlock-1.1.md (100%) rename {src/markdown/blog => posts}/2015/11/27/deadlock-1.2.md (100%) rename {src/markdown/blog => posts}/2015/12/01/deadlock-1.2.1.md (100%) rename {src/markdown/blog => posts}/2015/12/07/deadlock-1.2.2.md (100%) rename {src/markdown/blog => posts}/2016/01/12/deadlock-1.3.md (100%) rename {src/markdown/blog => posts}/2016/01/14/deadlock-1.3.1.md (100%) rename {src/markdown/blog => posts}/2016/01/20/deadlock-1.3.2.md (100%) rename {src/markdown/blog => posts}/2016/02/10/deadlock-1.3.3.md (100%) rename {src/markdown/blog => posts}/2016/03/13/deadlock-1.3.4.md (95%) rename {src/markdown/blog => posts}/2016/09/07/deadlock-1.4.md (100%) rename {src/markdown/blog => posts}/2016/09/11/advanced-passgen-1.2.md (100%) rename {src/markdown/blog => posts}/2016/09/12/advanced-passgen-1.3.md (100%) rename {src/markdown/blog => posts}/2017/01/17/advanced-portchecker.md (100%) rename {src/markdown/blog => posts}/2017/01/27/aniview.md (100%) rename {src/markdown/blog => posts}/2017/01/31/aniview-1.1.md (100%) rename {src/markdown/blog => posts}/2017/02/11/pk-finder.md (100%) rename {src/markdown/blog => posts}/2017/03/10/pk-finder-1.1.md (100%) rename {src/markdown/blog => posts}/2017/04/18/advanced-portchecker-1.1.md (100%) rename {src/markdown/blog => posts}/2017/04/19/aniview-1.2.md (100%) rename {src/markdown/blog => posts}/2017/05/05/deadhash-android.md (100%) rename {src/markdown/blog => posts}/2017/06/22/aniview-1.3.md (100%) rename {src/markdown/blog => posts}/2017/06/28/advanced-passgen-1.4.md (100%) rename {src/markdown/blog => posts}/2017/06/28/advanced-portchecker-1.2.md (100%) rename {src/markdown/blog => posts}/2017/07/03/aniview-1.3.1.md (100%) rename {src/markdown/blog => posts}/2017/08/28/aniview-1.3.2.md (100%) rename {src/markdown/blog => posts}/2017/08/28/pk-finder-1.2.md (100%) rename {src/markdown/blog => posts}/2017/09/02/pk-finder-1.3.md (100%) rename {src/markdown/blog => posts}/2017/09/08/advanced-passgen-1.5.md (100%) rename {src/markdown/blog => posts}/2017/09/12/advanced-passgen-1.5.1.md (100%) rename {src/markdown/blog => posts}/2018/01/01/pk-finder-1.4.md (100%) rename {src/markdown/blog => posts}/2018/01/04/advanced-portchecker-1.3.md (100%) rename {src/markdown/blog => posts}/2018/01/04/pk-finder-1.4.1.md (100%) rename {src/markdown/blog => posts}/2018/01/07/advanced-passgen-1.6.md (100%) rename src/markdown/blog/2018/01/07/our-tools.md => posts/2018/01/07/what-tools-do-we-use.md (100%) rename {src/markdown/blog => posts}/2018/01/27/aniview-1.4.md (100%) rename {src/markdown/blog => posts}/2018/02/01/aniview-1.4.1.md (100%) rename {src/markdown/blog => posts}/2018/02/26/memplus.md (100%) rename {src/markdown/blog => posts}/2018/03/05/aniview-1.4.2.md (100%) rename {src/markdown/blog => posts}/2018/03/06/memplus-1.1.md (100%) rename {src/markdown/blog => posts}/2018/03/13/memplus-1.2.md (100%) rename {src/markdown/blog => posts}/2018/03/20/memplus-1.3.md (100%) rename {src/markdown/blog => posts}/2018/03/25/pk-finder-1.4.2.md (100%) rename {src/markdown/blog => posts}/2018/04/02/aniview-1.5.md (100%) rename {src/markdown/blog => posts}/2018/04/04/memplus-1.3.1.md (100%) rename {src/markdown/blog => posts}/2018/05/01/memplus-1.3.2.md (100%) rename src/markdown/blog/2018/05/02/memplus-translations.md => posts/2018/05/02/memplus-translations-wanted.md (100%) rename {src/markdown/blog => posts}/2018/09/02/pk-finder-1.5.md (100%) rename {src/markdown/blog => posts}/2018/09/04/advanced-portchecker-1.4.md (100%) rename {src/markdown/blog => posts}/2019/03/17/pk-finder-1.5.1.md (100%) rename {src/markdown/blog => posts}/2019/03/19/aniview-1.5.1.md (100%) rename {src/markdown/blog => posts}/2019/03/29/aniview-1.5.2.md (100%) rename {src/markdown/blog => posts}/2019/05/07/advanced-portchecker-1.5.md (100%) rename {src/markdown/blog => posts}/2019/05/09/pk-finder-1.6.md (100%) rename {src/markdown/blog => posts}/2019/05/11/advanced-passgen-1.7.md (100%) rename {src/markdown/blog => posts}/2019/05/18/aniview-1.5.3.md (100%) rename {src/markdown/blog => posts}/2019/05/21/deadpix-1.2.md (100%) rename {src/markdown/blog => posts}/2019/08/03/advanced-passgen-1.7.1.md (100%) rename {src/markdown/blog => posts}/2020/01/01/deadhash-2.0.md (100%) rename {src/markdown/blog => posts}/2020/01/23/deadhash-2.0.1.md (100%) rename src/markdown/blog/2020/02/20/array-traversal-javascript.md => posts/2020/02/20/javascript-array-traversal.md (100%) rename {src/markdown/blog => posts}/2020/04/06/deadhash-2.0.2.md (100%) rename {src/markdown/blog => posts}/2020/06/07/deadhash-2.0.3.md (100%) rename {src/markdown/blog => posts}/2020/11/10/deadhash-2.0.4.md (100%) rename {src/markdown/blog => posts}/2020/11/11/aniview-1.6.md (100%) rename {src/markdown/blog => posts}/2021/02/02/new-layout.md (100%) rename src/markdown/blog/2021/02/03/deadhash-2.1.0.md => posts/2021/02/03/deadhash-2.1.md (100%) rename {src/markdown/blog => posts}/2021/02/05/deadhash-2.1.1.md (100%) rename {src/markdown/blog => posts}/2021/02/11/deadhash-2.1.2.md (100%) rename {src/markdown/blog => posts}/2021/03/23/egld-price-calculator.md (100%) rename {src/markdown/blog => posts}/2021/06/07/deadhash-2.1.3.md (100%) rename {src/markdown/blog => posts}/2021/10/01/deadhash-2.2.0.md (100%) rename {src/markdown/blog => posts}/2021/10/03/opal-1.0.md (100%) rename {src/markdown/blog => posts}/2021/11/22/opal-1.0.1.md (100%) rename {src/markdown/blog => posts}/2022/01/04/deadhash-2.2.1.md (100%) rename {src/markdown/blog => posts}/2022/04/04/opal-1.0.2.md (100%) rename {src/markdown/blog => posts}/2022/05/08/deadhash-2.2.2.md (100%) rename {src/markdown/blog => posts}/2022/06/17/opal-1.0.3.md (100%) rename {src/markdown/blog => posts}/2022/07/23/deadhash-2.2.3.md (100%) rename {src/markdown/blog => posts}/2022/07/26/pk-finder-2.0.md (100%) rename {src/markdown/blog => posts}/2022/10/17/advanced-passgen-2.0.md (100%) rename {src/markdown/blog => posts}/2022/11/03/advanced-passgen-2.1.0.md (100%) rename {src/markdown/blog => posts}/2022/12/15/advanced-passgen-2.2.0.md (100%) rename {src/markdown/blog => posts}/2022/12/16/advanced-passgen-2.2.1.md (100%) rename {src/markdown/blog => posts}/2023/01/08/advanced-passgen-2.3.0.md (100%) rename {src/markdown/blog => posts}/2023/03/05/advanced-passgen-2.4.0.md (100%) rename {src/markdown/blog => posts}/2023/04/02/opal-1.1.0.md (100%) rename {src/markdown/blog => posts}/2023/05/04/advanced-passgen-2.4.1.md (100%) rename {src/markdown/blog => posts}/2023/07/11/opal-1.2.0.md (100%) rename {src/markdown/blog => posts}/2023/07/20/advanced-passgen-2.4.2.md (100%) rename {src/markdown/blog => posts}/2023/10/08/advanced-passgen-2.4.3.md (100%) rename {src/markdown/blog => posts}/2023/10/25/opal-1.3.0.md (100%) rename {src/markdown/blog => posts}/2023/12/18/advanced-passgen-2.5.0.md (100%) rename {src/markdown/blog => posts}/2024/01/30/advanced-portchecker-2.0.0.md (100%) rename {src/markdown/blog => posts}/2024/03/21/advanced-portchecker-2.0.1.md (100%) rename {src/markdown/blog => posts}/2024/03/28/opal-1.3.1.md (100%) rename {src/markdown/blog => posts}/2024/05/12/advanced-passgen-2.5.1.md (100%) rename {src/markdown/blog => posts}/2024/07/16/opal-1.4.0.md (100%) rename {src/markdown/blog => posts}/2024/09/30/advanced-passgen-2.5.2.md (100%) rename {src/markdown/blog => posts}/2024/10/20/advanced-portchecker-2.1.0.md (100%) rename {src/markdown/blog => posts}/2025/01/19/opal-1.5.0.md (100%) create mode 100644 public/DeadHash.webp create mode 100644 public/advanced passgen.webp create mode 100644 public/advanced portchecker.webp create mode 100644 public/aniview.webp create mode 100644 public/compressr.webp create mode 100644 public/deadhash/deadhash_result.webp create mode 100644 public/deadhash/deadhash_text.webp create mode 100644 public/deadlock.webp create mode 100644 public/deadpix.webp create mode 100644 public/egld.webp create mode 100644 public/favicon.svg create mode 100644 public/memplus.webp create mode 100644 public/opal.webp create mode 100644 public/pkfinder.webp create mode 100644 public/title.module.css rename {src/reducers => reducers}/MainReducer/Actions/actionTypes.js (55%) rename {src/reducers => reducers}/MainReducer/Actions/index.js (58%) rename {src/reducers => reducers}/MainReducer/index.jsx (64%) delete mode 100644 src/components/AlertDialog/index.jsx delete mode 100644 src/components/Application/index.jsx delete mode 100644 src/components/BackButton/index.jsx delete mode 100644 src/components/BlogList/index.jsx delete mode 100644 src/components/BlogPost/index.jsx delete mode 100644 src/components/DefaultAppBar/index.jsx delete mode 100644 src/components/DonationAlert/index.jsx delete mode 100644 src/components/FacebookIcon/index.jsx delete mode 100644 src/components/Footer/index.jsx delete mode 100644 src/components/GithubIcon/index.jsx delete mode 100644 src/components/Layout/index.css delete mode 100644 src/components/Layout/index.jsx delete mode 100644 src/components/LinkedInIcon/index.jsx delete mode 100644 src/components/LoadingBar/index.jsx delete mode 100644 src/components/MastodonIcon/index.jsx delete mode 100644 src/components/NavigationDrawer/index.jsx delete mode 100644 src/components/PageHeader/index.jsx delete mode 100644 src/components/SEO/index.jsx delete mode 100644 src/images/Advanced PassGen/ap.png delete mode 100644 src/images/Advanced PassGen/ap_advanced_settings.png delete mode 100644 src/images/Advanced PassGen/ap_theme_settings.png delete mode 100644 src/images/Advanced PortChecker/ap.png delete mode 100644 src/images/Advanced PortChecker/ap_about.png delete mode 100644 src/images/Advanced PortChecker/ap_general_settings.png delete mode 100644 src/images/AniView/aniview.png delete mode 100644 src/images/AniView/av_settings_image.png delete mode 100644 src/images/AniView/settings.png delete mode 100644 src/images/Compressr/compressr.png delete mode 100644 src/images/DeadHash/DeadHash.png delete mode 100644 src/images/DeadHash/deadhash_result.png delete mode 100644 src/images/DeadHash/deadhash_text.png delete mode 100644 src/images/DeadLock/about.png delete mode 100644 src/images/DeadLock/deadlock.png delete mode 100644 src/images/DeadLock/settings.png delete mode 100644 src/images/DeadPix/deadpix.png delete mode 100644 src/images/DeadPix/settings.png delete mode 100644 src/images/Elrond/egld.png delete mode 100644 src/images/MemPlus/memplus.png delete mode 100644 src/images/MemPlus/memplus_analyzer.png delete mode 100644 src/images/MemPlus/memplus_settings_monitor.png delete mode 100644 src/images/Opal/Opal.png delete mode 100644 src/images/Opal/opal_settings.png delete mode 100644 src/images/Opal/opal_timer.png delete mode 100644 src/images/PK Finder/pkfinder.png delete mode 100644 src/images/PK Finder/pkgeneral.png delete mode 100644 src/images/PK Finder/pktheme.png delete mode 100644 src/pages/404/index.jsx delete mode 100644 src/pages/about/index.jsx delete mode 100644 src/pages/blog/index.jsx delete mode 100644 src/pages/contact/index.jsx delete mode 100644 src/pages/donate/index.jsx delete mode 100644 src/pages/index.jsx delete mode 100644 src/pages/privacy/index.jsx delete mode 100644 src/pages/software/advanced-passgen/index.jsx delete mode 100644 src/pages/software/advanced-passgen/requirements/index.jsx delete mode 100644 src/pages/software/advanced-portchecker/index.jsx delete mode 100644 src/pages/software/advanced-portchecker/requirements/index.jsx delete mode 100644 src/pages/software/aniview/index.jsx delete mode 100644 src/pages/software/aniview/requirements/index.jsx delete mode 100644 src/pages/software/deadhash/index.jsx delete mode 100644 src/pages/software/deadhash/requirements/index.jsx delete mode 100644 src/pages/software/deadlock/index.jsx delete mode 100644 src/pages/software/deadlock/requirements/index.jsx delete mode 100644 src/pages/software/deadpix/index.jsx delete mode 100644 src/pages/software/deadpix/requirements/index.jsx delete mode 100644 src/pages/software/egld-price-calculator/index.jsx delete mode 100644 src/pages/software/index.jsx delete mode 100644 src/pages/software/memplus/index.jsx delete mode 100644 src/pages/software/memplus/requirements/index.jsx delete mode 100644 src/pages/software/opal/index.jsx delete mode 100644 src/pages/software/opal/requirements/index.jsx delete mode 100644 src/pages/software/pk-finder/index.jsx delete mode 100644 src/pages/software/pk-finder/requirements/index.jsx delete mode 100644 src/templates/BlogTemplate/index.css delete mode 100644 src/templates/BlogTemplate/index.jsx delete mode 100644 src/utils/ThemeSelector/index.js delete mode 100644 static/favicon.ico create mode 100644 test-utils/index.ts create mode 100644 test-utils/render.tsx create mode 100644 theme.js create mode 100644 tsconfig.json diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index d9dbc72..0000000 --- a/.eslintignore +++ /dev/null @@ -1,6 +0,0 @@ -.yarn -.cache -public -gatsby-browser.js -gatsby-ssr.js -yarn.lock diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index ee3adff..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "env": { - "browser": true, - "es2021": true - }, - "extends": [ - "plugin:react/recommended", - "airbnb" - ], - "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": "latest", - "sourceType": "module" - }, - "plugins": [ - "react" - ], - "rules": { - "react/function-component-definition": [ - 2, - { - "namedComponents": "arrow-function", - "unnamedComponents": "arrow-function" - } - ], - "react/prop-types": 0 - } -} diff --git a/.github/workflows/npm_test.yml b/.github/workflows/npm_test.yml new file mode 100644 index 0000000..ab5e842 --- /dev/null +++ b/.github/workflows/npm_test.yml @@ -0,0 +1,27 @@ +name: npm test + +on: + pull_request: + branches: + - '**' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.number || github.sha }} + cancel-in-progress: true + +jobs: + test_pull_request: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version-file: '.nvmrc' + cache: 'yarn' + cache-dependency-path: '**/yarn.lock' + - name: Install dependencies + run: yarn + - name: Run build + run: npm run build + - name: Run tests + run: npm test diff --git a/.gitignore b/.gitignore index e390758..dcfd385 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,11 @@ logs npm-debug.log* yarn-debug.log* yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json # Runtime data pids @@ -16,11 +21,12 @@ lib-cov # Coverage directory used by tools like istanbul coverage +*.lcov # nyc test coverage .nyc_output -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) .grunt # Bower dependency directory (https://bower.io/) @@ -29,15 +35,18 @@ bower_components # node-waf configuration .lock-wscript -# Compiled binary addons (http://nodejs.org/api/addons.html) +# Compiled binary addons (https://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules/ jspm_packages/ -# Typescript v1 declaration files -typings/ +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo # Optional npm cache directory .npm @@ -45,28 +54,83 @@ typings/ # Optional eslint cache .eslintcache +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + # Optional REPL history .node_repl_history # Output of 'npm pack' *.tgz +# Yarn Integrity file +.yarn-integrity + # dotenv environment variable files -.env* +.env +.env.development.local +.env.test.local +.env.production.local +.env.local -# gatsby files +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files .cache/ -public +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public -# Mac files -.DS_Store +# vuepress build output +.vuepress/dist -# Yarn -.yarn-integrity -.idea/* -.yarn/* -!.yarn/releases -!.yarn/plugins -!.yarn/sdks -!.yarn/versions +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz .pnp.* + +.DS_Store + +# IDE +.idea/ +.vscode/ diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..bb8c76c --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v22.11.0 diff --git a/.prettierrc.mjs b/.prettierrc.mjs new file mode 100644 index 0000000..31e43b8 --- /dev/null +++ b/.prettierrc.mjs @@ -0,0 +1,35 @@ +/** @type {import("@ianvs/prettier-plugin-sort-imports").PrettierConfig} */ +const config = { + printWidth: 100, + singleQuote: true, + trailingComma: 'es5', + plugins: ['@ianvs/prettier-plugin-sort-imports'], + importOrder: [ + '.*styles.css$', + '', + 'dayjs', + '^react$', + '^next$', + '^next/.*$', + '', + '', + '^@mantine/(.*)$', + '^@mantinex/(.*)$', + '^@mantine-tests/(.*)$', + '^@docs/(.*)$', + '^@/.*$', + '^../(?!.*.css$).*$', + '^./(?!.*.css$).*$', + '\\.css$', + ], + overrides: [ + { + files: '*.mdx', + options: { + printWidth: 70, + }, + }, + ], +}; + +export default config; \ No newline at end of file diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 0000000..dc5c706 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,16 @@ +import type { StorybookConfig } from '@storybook/nextjs'; + +const config: StorybookConfig = { + core: { + disableWhatsNewNotifications: true, + disableTelemetry: true, + enableCrashReports: false, + }, + stories: ['../components/**/*.(stories|story).@(js|jsx|ts|tsx)'], + addons: ['storybook-dark-mode'], + framework: { + name: '@storybook/nextjs', + options: {}, + }, +}; +export default config; diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx new file mode 100644 index 0000000..522af1a --- /dev/null +++ b/.storybook/preview.tsx @@ -0,0 +1,33 @@ +import '@mantine/core/styles.css'; + +import React, { useEffect } from 'react'; +import { addons } from '@storybook/preview-api'; +import { DARK_MODE_EVENT_NAME } from 'storybook-dark-mode'; +import { MantineProvider, useMantineColorScheme } from '@mantine/core'; +import { theme } from '../theme'; + +export const parameters = { + layout: 'fullscreen', + options: { + showPanel: false, + }, +}; + +const channel = addons.getChannel(); + +function ColorSchemeWrapper({ children }: { children: React.ReactNode }) { + const { setColorScheme } = useMantineColorScheme(); + const handleColorScheme = (value: boolean) => setColorScheme(value ? 'dark' : 'light'); + + useEffect(() => { + channel.on(DARK_MODE_EVENT_NAME, handleColorScheme); + return () => channel.off(DARK_MODE_EVENT_NAME, handleColorScheme); + }, [channel]); + + return <>{children}; +} + +export const decorators = [ + (renderStory: any) => {renderStory()}, + (renderStory: any) => {renderStory()}, +]; diff --git a/.stylelintignore b/.stylelintignore new file mode 100644 index 0000000..2b3533c --- /dev/null +++ b/.stylelintignore @@ -0,0 +1,2 @@ +.next +out diff --git a/.stylelintrc.json b/.stylelintrc.json new file mode 100644 index 0000000..4ea6506 --- /dev/null +++ b/.stylelintrc.json @@ -0,0 +1,28 @@ +{ + "extends": ["stylelint-config-standard-scss"], + "rules": { + "custom-property-pattern": null, + "selector-class-pattern": null, + "scss/no-duplicate-mixins": null, + "declaration-empty-line-before": null, + "declaration-block-no-redundant-longhand-properties": null, + "alpha-value-notation": null, + "custom-property-empty-line-before": null, + "property-no-vendor-prefix": null, + "color-function-notation": null, + "length-zero-no-unit": null, + "selector-not-notation": null, + "no-descending-specificity": null, + "comment-empty-line-before": null, + "scss/at-mixin-pattern": null, + "scss/at-rule-no-unknown": null, + "value-keyword-case": null, + "media-feature-range-notation": null, + "selector-pseudo-class-no-unknown": [ + true, + { + "ignorePseudoClasses": ["global"] + } + ] + } +} diff --git a/README.md b/README.md index a32bb05..25e9116 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,25 @@ # CodeDead.com This is the source code behind the CodeDead website. -The project was realized with the help of Gatsby, React, Material-UI and various other packages! +The project was realized with the help of Next, React, Mantine and various other packages! ## Usage In order to run a development build of the website, run: ```Bash -yarn start +yarn dev ``` A development server will be executed and you can then view the website in your browser using the following url: -`http://localhost:8000` +`http://localhost:3000` In order to build a production-ready version of the website, run: ```Bash yarn build ``` -`Gatsby` will then generate a static website that can be deployed on a server in seconds. +`Next` will then generate a static website that can be deployed on a server in seconds. ## About diff --git a/app/robots.txt b/app/robots.txt new file mode 100644 index 0000000..be46f29 --- /dev/null +++ b/app/robots.txt @@ -0,0 +1,3 @@ +User-Agent: * +Allow: / +Host: https://codedead.com diff --git a/components/ColorSchemeToggle/ColorSchemeToggle.tsx b/components/ColorSchemeToggle/ColorSchemeToggle.tsx new file mode 100644 index 0000000..18e2bb7 --- /dev/null +++ b/components/ColorSchemeToggle/ColorSchemeToggle.tsx @@ -0,0 +1,13 @@ +import { Button, Group, useMantineColorScheme } from '@mantine/core'; + +export function ColorSchemeToggle() { + const { setColorScheme } = useMantineColorScheme(); + + return ( + + + + + + ); +} diff --git a/components/Dots/index.jsx b/components/Dots/index.jsx new file mode 100644 index 0000000..fe63668 --- /dev/null +++ b/components/Dots/index.jsx @@ -0,0 +1,118 @@ +import React from 'react'; + +const Dots = ({ size = 185, radius = 2.5, ...others }) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default Dots; diff --git a/components/FeatureCard/index.jsx b/components/FeatureCard/index.jsx new file mode 100644 index 0000000..1376a5c --- /dev/null +++ b/components/FeatureCard/index.jsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Card, Text } from '@mantine/core'; +import classes from './index.module.css'; + +const FeatureCard = ({ icon, title, description }) => { + return ( + + {icon} + + {title} + + + {description} + + + ); +}; + +export default FeatureCard; diff --git a/components/FeatureCard/index.module.css b/components/FeatureCard/index.module.css new file mode 100644 index 0000000..076d7ef --- /dev/null +++ b/components/FeatureCard/index.module.css @@ -0,0 +1,39 @@ +.title { + font-size: 34px; + font-weight: 900; + + @media (max-width: $mantine-breakpoint-sm) { + font-size: 24px; + } +} + +.description { + max-width: 600px; + margin: auto; + + &::after { + content: ''; + display: block; + background-color: var(--mantine-color-blue-filled); + width: 45px; + height: 2px; + margin-top: var(--mantine-spacing-sm); + margin-left: auto; + margin-right: auto; + } +} + +.card { + border: 1px solid light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-5)); +} + +.cardTitle { + &::after { + content: ''; + display: block; + background-color: var(--mantine-color-blue-filled); + width: 45px; + height: 2px; + margin-top: var(--mantine-spacing-sm); + } +} diff --git a/components/Footer/index.jsx b/components/Footer/index.jsx new file mode 100644 index 0000000..c4cb4a0 --- /dev/null +++ b/components/Footer/index.jsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { IconBrandBluesky, IconBrandGithub, IconBrandReddit } from '@tabler/icons-react'; +import { ActionIcon, Container, Group } from '@mantine/core'; +import classes from './index.module.css'; + +const Footer = () => { + return ( +
+ + Copyright © 2025 CodeDead + + window.open('https://bsky.app/profile/codedead.com', '_blank')} + > + + + window.open('https://www.reddit.com/r/CodeDead/', '_blank')} + > + + + window.open('https://github.com/CodeDead', '_blank')} + > + + + + +
+ ); +}; + +export default Footer; diff --git a/components/Footer/index.module.css b/components/Footer/index.module.css new file mode 100644 index 0000000..52c384e --- /dev/null +++ b/components/Footer/index.module.css @@ -0,0 +1,12 @@ +.footer { + border-top: 1px solid + light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5)); +} + +.inner { + display: flex; + justify-content: space-between; + align-items: center; + padding-top: var(--mantine-spacing-xl); + padding-bottom: var(--mantine-spacing-xl); +} diff --git a/components/NavBar/index.jsx b/components/NavBar/index.jsx new file mode 100644 index 0000000..7dd1943 --- /dev/null +++ b/components/NavBar/index.jsx @@ -0,0 +1,121 @@ +import React, { useContext } from 'react'; +import { useRouter } from 'next/navigation'; +import { + IconArticle, + IconCoin, + IconHome, + IconInfoCircle, + IconLockSquare, + IconMail, + IconTool, +} from '@tabler/icons-react'; +import { Divider, ScrollArea } from '@mantine/core'; +import { MainContext } from '../../contexts/MainContextProvider'; +import classes from './navbar.module.css'; + +const NavBar = () => { + const router = useRouter(); + const [state, d1] = useContext(MainContext); + const { pageIndex } = state; + + return ( + + + + ); +}; + +export default NavBar; diff --git a/components/NavBar/navbar.module.css b/components/NavBar/navbar.module.css new file mode 100644 index 0000000..09083cf --- /dev/null +++ b/components/NavBar/navbar.module.css @@ -0,0 +1,55 @@ +.navbar { + background-color: var(--mantine-color-body); + padding: var(--mantine-spacing-md); + display: flex; + flex-direction: column; + border-right: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4)); +} + +.navbarMain { + flex: 1; +} + +.title { + text-transform: uppercase; + letter-spacing: -0.25px; +} + +.link { + display: flex; + align-items: center; + text-decoration: none; + font-size: var(--mantine-font-size-sm); + color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1)); + padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm); + border-radius: var(--mantine-radius-sm); + font-weight: 500; + + &:hover { + background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6)); + color: light-dark(var(--mantine-color-black), var(--mantine-color-white)); + + & .linkIcon { + color: light-dark(var(--mantine-color-black), var(--mantine-color-white)); + } + } + + &[data-active] { + &, + &:hover { + background-color: var(--mantine-color-blue-light); + color: var(--mantine-color-blue-light-color); + + & .linkIcon { + color: var(--mantine-color-blue-light-color); + } + } + } +} + +.linkIcon { + color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2)); + margin-right: var(--mantine-spacing-sm); + width: 25px; + height: 25px; +} diff --git a/components/TopBar/index.jsx b/components/TopBar/index.jsx new file mode 100644 index 0000000..60da718 --- /dev/null +++ b/components/TopBar/index.jsx @@ -0,0 +1,135 @@ +import React from 'react'; +import { useRouter } from 'next/navigation'; +import { IconSun, IconSunOff } from '@tabler/icons-react'; +import { + ActionIcon, + Burger, + Container, + Divider, + Drawer, + Group, + rem, + ScrollArea, + Title, + Tooltip, + useMantineColorScheme, +} from '@mantine/core'; +import classes from './index.module.css'; + +const TopBar = ({ opened, toggle }) => { + const router = useRouter(); + const { colorScheme, setColorScheme } = useMantineColorScheme(); + + /** + * Change the color scheme + */ + const changeTheme = () => { + const newTheme = colorScheme === 'dark' ? 'light' : 'dark'; + setColorScheme(newTheme); + }; + + /** + * Click the scroll link + * @param event The event argument + * @param link The link to navigate to + */ + const clickScrollLink = (event, link) => { + event.preventDefault(); + + toggle(); + router.push(link); + }; + + return ( +
+ + + { + e.preventDefault(); + router.push('/'); + }} + > + CodeDead + + + + + + + {colorScheme === 'dark' ? ( + + ) : ( + + )} + + + + + + toggle()} + size="100%" + padding="md" + title="Navigation" + hiddenFrom="sm" + zIndex={1000000} + > + + + clickScrollLink(e, '/')}> + Home + + clickScrollLink(e, '/software')} + > + Software + + clickScrollLink(e, '/blog')}> + Blog + + + clickScrollLink(e, '/donate')} + > + Donate + + clickScrollLink(e, '/about')}> + About + + + clickScrollLink(e, '/privacy')} + > + Privacy + + clickScrollLink(e, '/contact')} + > + Contact + + + + +
+ ); +}; + +export default TopBar; diff --git a/components/TopBar/index.module.css b/components/TopBar/index.module.css new file mode 100644 index 0000000..e67759c --- /dev/null +++ b/components/TopBar/index.module.css @@ -0,0 +1,35 @@ +.header { + height: 56px; + margin-bottom: 120px; + background-color: var(--mantine-color-body); +} + +.inner { + max-width: 100%; + height: 56px; + display: flex; + align-items: center; +} + +.link { + display: block; + line-height: 1; + padding: 8px 12px; + border-radius: var(--mantine-radius-sm); + text-decoration: none; + color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0)); + font-size: var(--mantine-font-size-md); + font-weight: 500; + + @mixin hover { + background-color: light-dark( + var(--mantine-color-gray-0), + var(--mantine-color-dark-6) + ); + } + + [data-mantine-color-scheme] &[data-active] { + background-color: var(--mantine-color-blue-filled); + color: var(--mantine-color-white); + } +} diff --git a/src/contexts/MainContextProvider/index.jsx b/contexts/MainContextProvider/index.jsx similarity index 67% rename from src/contexts/MainContextProvider/index.jsx rename to contexts/MainContextProvider/index.jsx index c0bc7c1..0896954 100644 --- a/src/contexts/MainContextProvider/index.jsx +++ b/contexts/MainContextProvider/index.jsx @@ -1,20 +1,10 @@ import React, { useReducer, createContext } from 'react'; import MainReducer from '../../reducers/MainReducer'; -const themeIndex = typeof window !== 'undefined' && localStorage.themeIndex ? parseFloat(localStorage.themeIndex) : 0; -const themeColorIndex = typeof window !== 'undefined' && localStorage.themeColorIndex - ? parseFloat(localStorage.themeColorIndex) - : 6; const hasAcceptedCookieNotice = typeof window !== 'undefined' && localStorage.hasAcceptedCookieNotice ? localStorage.hasAcceptedCookieNotice === 'true' : false; const initState = { pageIndex: 0, - themeIndex, - themeColorIndex, - themes: { - defaultColor: '#1c2661', - }, - blogLimit: 0, hasAcceptedCookieNotice, }; diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..a905b4c --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,4 @@ +import mantine from 'eslint-config-mantine'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config(...mantine, { ignores: ['**/*.{mjs,cjs,js,d.ts,d.mts}'] }); diff --git a/gatsby-browser.js b/gatsby-browser.js deleted file mode 100644 index 390edd4..0000000 --- a/gatsby-browser.js +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react'; -import MainContextProvider from './src/contexts/MainContextProvider'; - -export const wrapRootElement = ({ element }) => ( - - {element} - -); diff --git a/gatsby-config.js b/gatsby-config.js deleted file mode 100644 index 89eb7ef..0000000 --- a/gatsby-config.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Configure your Gatsby site with this file. - * - * See: https://www.gatsbyjs.org/docs/gatsby-config/ - */ -const path = require('path'); - -module.exports = { - polyfill: false, - trailingSlash: 'ignore', - siteMetadata: { - title: 'CodeDead', - description: 'Solving problems using code', - siteUrl: 'https://codedead.com', - author: 'CodeDead', - github: 'https://github.com/CodeDead', - mastodon: 'https://mstdn.social/@CodeDead', - facebook: 'https://facebook.com/deadlinecodedead', - }, - plugins: [ - 'gatsby-theme-material-ui', - { - resolve: 'gatsby-source-filesystem', - options: { - name: 'images', - path: path.join(__dirname, 'src', 'images'), - }, - }, - { - resolve: 'gatsby-source-filesystem', - options: { - name: 'blog', - path: `${__dirname}/src/markdown/blog`, - }, - }, - { - resolve: 'gatsby-transformer-remark', - options: { - footnotes: true, - gfm: true, - plugins: [ - { - resolve: 'gatsby-remark-images', - options: { - maxWidth: 590, - }, - }, - ], - }, - }, - { - resolve: 'gatsby-plugin-google-gtag', - options: { - trackingIds: [ - 'G-5BW4G4STJ8', - ], - pluginConfig: { - head: true, - respectDNT: true, - }, - }, - }, - 'gatsby-plugin-catch-links', - 'gatsby-plugin-react-helmet', - 'gatsby-transformer-remark', - 'gatsby-plugin-sitemap', - 'gatsby-plugin-robots-txt', - 'gatsby-plugin-image', - 'gatsby-plugin-sharp', - 'gatsby-transformer-sharp', - ], -}; diff --git a/gatsby-node.js b/gatsby-node.js deleted file mode 100644 index 28ee22e..0000000 --- a/gatsby-node.js +++ /dev/null @@ -1,31 +0,0 @@ -const path = require('path'); - -exports.createPages = async ({ actions, graphql, reporter }) => { - const { createPage } = actions; - const BlogTemplate = path.resolve('./src/templates/BlogTemplate/index.jsx'); - - const result = await graphql(`{ - allMarkdownRemark { - edges { - node { - frontmatter { - path - } - } - } - } - }`); - - if (result.errors) { - reporter.panicOnBuild('Error while running GraphQL query!'); - return; - } - - result.data.allMarkdownRemark.edges.forEach(({ node }) => { - createPage({ - path: node.frontmatter.path, - component: BlogTemplate, - context: {}, - }); - }); -}; diff --git a/gatsby-ssr.js b/gatsby-ssr.js deleted file mode 100644 index 4149f5e..0000000 --- a/gatsby-ssr.js +++ /dev/null @@ -1,8 +0,0 @@ -const React = require('react'); -const MainContextProvider = require('./src/contexts/MainContextProvider').default; - -exports.wrapRootElement = ({ element }) => ( - - {element} - -); diff --git a/lib/posts.js b/lib/posts.js new file mode 100644 index 0000000..655b854 --- /dev/null +++ b/lib/posts.js @@ -0,0 +1,95 @@ +import fs from 'fs'; +import path from 'path'; +import matter from 'gray-matter'; + +const postsDirectory = path.join(process.cwd(), 'posts'); + +export function* readAllFiles(dir) { + const files = fs.readdirSync(dir, { withFileTypes: true }); + + for (const file of files) { + if (file.isDirectory()) { + yield* readAllFiles(path.join(dir, file.name)); + } else { + yield path.join(dir, file.name); + } + } +} + +export const getSortedPostsData = () => { + // Get file names under /posts + const fileNames = readAllFiles(postsDirectory); + const allPostsData = []; + + fileNames.forEach((fileName) => { + // Remove ".md" from file name to get id + const id = fileName.replace(/\.md$/, ''); + + // Read markdown file as string + const fileContents = fs.readFileSync(fileName, 'utf8'); + + // Use gray-matter to parse the post metadata section + const matterResult = matter(fileContents); + + // Combine the data with the id + allPostsData.push({ + id, + ...matterResult.data, + }); + }); + + // Sort posts by date + return allPostsData.sort((a, b) => { + if (a.date < b.date) { + return 1; + } else { + return -1; + } + }); +}; + +export const getAllPosts = () => { + // Get file names under /posts + const fileNames = readAllFiles(postsDirectory); + const allPostsData = []; + + fileNames.forEach((fileName) => { + const day = path.basename(path.dirname(fileName)); + const month = path.basename(path.dirname(path.dirname(fileName))); + const year = path.basename(path.dirname(path.dirname(path.dirname(fileName)))); + const id = path.parse(fileName).name; + + // Combine the data with the id + allPostsData.push({ + params: { + id: id, + year: year, + month: month, + day: day, + }, + }); + }); + + // Sort posts by date + return allPostsData; +}; + +export const getPostData = (year, month, day, id) => { + const fullPath = path.join(postsDirectory, year, month, day, `${id}.md`); + const fileContents = fs.readFileSync(fullPath, 'utf8'); + + // Use gray-matter to parse the post metadata section + const matterResult = matter(fileContents); + + // Combine the data with the id + return { + id, + content: matterResult.content, + ...matterResult.data, + }; +}; + +export const getLastPosts = (limit) => { + const allPostsData = getSortedPostsData(); + return allPostsData.slice(0, limit); +}; diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..3cd7048 --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,6 @@ +/// +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/next.config.mjs b/next.config.mjs new file mode 100644 index 0000000..21dac5f --- /dev/null +++ b/next.config.mjs @@ -0,0 +1,13 @@ +import bundleAnalyzer from '@next/bundle-analyzer'; + +const withBundleAnalyzer = bundleAnalyzer({ + enabled: process.env.ANALYZE === 'true', +}); + +export default withBundleAnalyzer({ + reactStrictMode: false, + eslint: { + ignoreDuringBuilds: true, + }, + output: "export", +}); diff --git a/package.json b/package.json index 0870315..6c76dbf 100644 --- a/package.json +++ b/package.json @@ -1,57 +1,69 @@ { "name": "codedead.com", + "version": "1.0.0", "private": true, - "description": "CodeDead Website", - "version": "1.0.4", - "license": "0BSD", "scripts": { - "build": "gatsby build", - "develop": "gatsby develop", - "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"", - "lint": "eslint .", - "start": "yarn run develop", - "serve": "gatsby serve", - "clean": "gatsby clean", - "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1" + "dev": "next dev", + "build": "next build", + "analyze": "ANALYZE=true next build", + "start": "next start", + "export": "next build && next export", + "lint": "npm run eslint && npm run stylelint", + "eslint": "next lint", + "stylelint": "stylelint '**/*.css' --cache", + "jest": "jest", + "jest:watch": "jest --watch", + "prettier:check": "prettier --check \"**/*.{ts,tsx}\"", + "prettier:write": "prettier --write \"**/*.{ts,tsx}\"", + "test": "npm run prettier:check && npm run lint && npm run typecheck && npm run jest", + "storybook": "storybook dev -p 6006", + "storybook:build": "storybook build" }, "dependencies": { - "@emotion/react": "^11.14.0", - "@emotion/styled": "^11.14.0", - "@fontsource/roboto": "^5.1.1", - "@mui/icons-material": "^6.4.0", - "@mui/material": "^6.4.0", - "axios": "^1.7.9", - "gatsby": "^5.14.1", - "gatsby-plugin-catch-links": "^5.14.0", - "gatsby-plugin-google-gtag": "^5.14.0", - "gatsby-plugin-image": "^3.14.0", - "gatsby-plugin-react-helmet": "^6.14.0", - "gatsby-plugin-robots-txt": "^1.8.0", - "gatsby-plugin-sharp": "^5.14.0", - "gatsby-plugin-sitemap": "^6.14.0", - "gatsby-remark-images": "^7.14.0", - "gatsby-source-filesystem": "^5.14.0", - "gatsby-theme-material-ui": "^5.3.0", - "gatsby-transformer-remark": "^6.14.0", - "gatsby-transformer-sharp": "^5.14.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-helmet": "^6.1.0" + "@mantine/carousel": "^7.16.3", + "@mantine/core": "^7.16.3", + "@mantine/hooks": "^7.16.3", + "@next/bundle-analyzer": "^15.1.6", + "@tabler/icons-react": "^3.30.0", + "embla-carousel-react": "^7.1.0", + "gray-matter": "^4.0.3", + "next": "^15.1.6", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-markdown": "^9.0.3" }, "devDependencies": { - "eslint": "^9.18.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-plugin-import": "^2.31.0", + "@babel/core": "^7.26.8", + "@eslint/js": "^9.20.0", + "@ianvs/prettier-plugin-sort-imports": "^4.4.1", + "@storybook/nextjs": "^8.5.3", + "@storybook/react": "^8.5.3", + "@testing-library/dom": "^10.4.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.2.0", + "@testing-library/user-event": "^14.6.1", + "@types/eslint-plugin-jsx-a11y": "^6.10.0", + "@types/jest": "^29.5.14", + "@types/node": "^22.13.1", + "@types/react": "19.0.8", + "babel-loader": "^9.2.1", + "eslint": "^9.20.0", + "eslint-config-mantine": "^4.0.3", "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-react": "^7.37.4", - "eslint-plugin-react-hooks": "^5.1.0" - }, - "repository": { - "type": "git", - "url": "https://github.com/CodeDead/codedead.com" - }, - "bugs": { - "url": "https://github.com/CodeDead/codedead.com/issues" + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "postcss": "^8.5.1", + "postcss-preset-mantine": "1.17.0", + "postcss-simple-vars": "^7.0.1", + "prettier": "^3.5.0", + "storybook": "^8.5.3", + "storybook-dark-mode": "^4.0.2", + "stylelint": "^16.14.1", + "stylelint-config-standard-scss": "^14.0.0", + "ts-jest": "^29.2.5", + "typescript": "5.7.3", + "typescript-eslint": "^8.24.0" }, "packageManager": "yarn@4.6.0" } diff --git a/pages/_app.jsx b/pages/_app.jsx new file mode 100644 index 0000000..b6283fc --- /dev/null +++ b/pages/_app.jsx @@ -0,0 +1,42 @@ +import '@mantine/core/styles.css'; +import '@mantine/carousel/styles.css'; + +import { AppShell, MantineProvider } from '@mantine/core'; +import { useDisclosure } from '@mantine/hooks'; +import Footer from '../components/Footer'; +import NavBar from '../components/NavBar'; +import TopBar from '../components/TopBar'; +import MainContextProvider from '../contexts/MainContextProvider'; +import { theme } from '../theme'; + +const App = ({ Component, pageProps }) => { + const [opened, { toggle }] = useDisclosure(false); + + return ( + + + + + + + + + + + + + +