├── .all-contributorsrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── new_docs_section.md └── workflows │ ├── playwright.yml │ └── vitest.yml ├── .gitignore ├── .stylelintrc.json ├── .vscode ├── extensions.json ├── launch.json └── settings.json ├── E2E ├── Articles.test.ts ├── DocsButton.test.ts └── StarButton.test.ts ├── LICENSE ├── README.md ├── astro.config.mjs ├── package-lock.json ├── package.json ├── playwright.config.ts ├── postcss.config.cjs ├── prettier.config.ts ├── public ├── favicon.ico ├── fonts │ ├── Inter-Regular.woff2 │ ├── Nunito-Italic-VariableFont_wght.woff2 │ ├── Nunito-VariableFont_wght.woff2 │ ├── Poppins-Black.ttf │ ├── Poppins-BlackItalic.ttf │ ├── Poppins-Bold.ttf │ ├── Poppins-BoldItalic.ttf │ ├── Poppins-ExtraBold.ttf │ ├── Poppins-ExtraBoldItalic.ttf │ ├── Poppins-ExtraLight.ttf │ ├── Poppins-ExtraLightItalic.ttf │ ├── Poppins-Italic.ttf │ ├── Poppins-Light.ttf │ ├── Poppins-LightItalic.ttf │ ├── Poppins-Medium.ttf │ ├── Poppins-MediumItalic.ttf │ ├── Poppins-Regular.ttf │ ├── Poppins-SemiBold.ttf │ ├── Poppins-SemiBoldItalic.ttf │ ├── Poppins-Thin.ttf │ └── Poppins-ThinItalic.ttf ├── icons │ ├── hourglass.svg │ ├── savings.svg │ └── school_hat.svg ├── images │ ├── css │ │ ├── components.webp │ │ ├── css_exercises_1_3.webp │ │ ├── css_exercises_2_3.webp │ │ ├── css_exercises_3_3.webp │ │ ├── flex_basis_grow_shrink.webp │ │ ├── flex_shorthand.webp │ │ ├── tailwind_ally1.png │ │ ├── tailwind_ally2.png │ │ ├── tailwind_typesafe.png │ │ ├── tailwind_variants.png │ │ └── unsprinkle.webp │ ├── logo.svg │ ├── misc │ │ ├── pl_hr_response.webp │ │ ├── projekt.webp │ │ └── puzzle.webp │ ├── nukp-logo.webp │ ├── promo │ │ ├── about-us.svg │ │ └── wavy-edu.svg │ ├── react │ │ ├── react-fetching-1_3.webp │ │ ├── react-fetching-2_3.webp │ │ └── react-fetching-3_3.webp │ └── starButton │ │ └── star-icon.svg ├── make-scrollable-code-focusable.js ├── metaimage.png └── metaimages │ ├── css.png │ ├── git.png │ ├── html.png │ ├── javascript.png │ ├── nextjs.png │ ├── nodejs.png │ ├── react.png │ ├── redux.png │ ├── testing.png │ └── typescript.png ├── src ├── components │ ├── DonationModal │ │ ├── DonationButton.tsx │ │ └── DonationModal.tsx │ ├── GitHubStarLink │ │ └── GitHubStarLink.astro │ ├── HeadCommon.astro │ ├── HeadSEO.astro │ ├── Header │ │ ├── GithubStars.tsx │ │ ├── Header.astro │ │ ├── Logo.astro │ │ ├── Search.css │ │ ├── Search.tsx │ │ ├── SidebarToggle.tsx │ │ └── SkipToContent.astro │ ├── LandingPage │ │ ├── LandingSEO.astro │ │ └── VideoEmbed │ │ │ ├── VideoEmbed.astro │ │ │ └── helpers.ts │ ├── LeftSidebar │ │ ├── LeftSidebar.astro │ │ └── SidebarItem.astro │ ├── PageContent │ │ └── PageContent.astro │ ├── RecommendedSections │ │ └── RecommendedSections.astro │ ├── Redesign │ │ ├── ComparisonCard.astro │ │ ├── LandingElements │ │ │ └── DocsButton.astro │ │ ├── LandingPage.astro │ │ ├── LandingSection.astro │ │ └── LandingSections │ │ │ ├── AboutUs.astro │ │ │ ├── Accordion.tsx │ │ │ ├── Advantages.astro │ │ │ ├── FAQ.astro │ │ │ ├── Footer │ │ │ ├── BottomFooterSection.astro │ │ │ ├── Footer.astro │ │ │ ├── ImageAttribution.astro │ │ │ ├── LinkGroup.astro │ │ │ ├── SocialLink.astro │ │ │ ├── Socials.astro │ │ │ └── TopFooterSection.astro │ │ │ └── Hero.astro │ ├── RightSidebar │ │ ├── MoreMenu.astro │ │ ├── RightSidebar.astro │ │ ├── TableOfContents.module.scss │ │ ├── TableOfContents.tsx │ │ └── ThemeToggleButton.tsx │ ├── common │ │ └── GlowText.astro │ └── utility │ │ ├── CopyCodeToClipboard │ │ ├── CopyCodeToClipboard.astro │ │ └── helpers.ts │ │ └── HeadingLinksCopyToClipboard │ │ ├── HeadingLinksCopyToClipboard.astro │ │ ├── copyIconSVG.ts │ │ └── helpers.ts ├── config.ts ├── data │ └── vscode.data.ts ├── env.d.ts ├── hooks │ ├── usePersistedState.ts │ └── usePrefersReducedMotion.ts ├── layouts │ └── MainLayout.astro ├── pages │ ├── 404.astro │ ├── README.md │ ├── common │ │ ├── english.md │ │ ├── hr_recruitment_resources.md │ │ ├── job_boards.md │ │ ├── learning_to_learn.md │ │ ├── productivity.md │ │ └── programmer_pov.md │ ├── docs │ │ └── assets │ │ │ ├── css │ │ │ ├── components.webp │ │ │ ├── css_exercises_1_3.webp │ │ │ ├── css_exercises_2_3.webp │ │ │ ├── css_exercises_3_3.webp │ │ │ ├── flex_basis_grow_shrink.webp │ │ │ ├── flex_shorthand.webp │ │ │ └── unsprinkle.webp │ │ │ ├── misc │ │ │ ├── pl_hr_response.png │ │ │ └── projekt.png │ │ │ └── react │ │ │ ├── react-fetching-1_3.png │ │ │ ├── react-fetching-2_3.png │ │ │ └── react-fetching-3_3.png │ ├── index.astro │ ├── introduction.md │ ├── principles │ │ ├── clean_code.md │ │ ├── design_patterns.md │ │ ├── design_ui_ux.md │ │ ├── frontend.md │ │ ├── how_web_works.md │ │ └── testing.md │ ├── resources │ │ ├── _exercises │ │ │ ├── css4js.md │ │ │ ├── frontend_platforms.md │ │ │ └── practice_css_problems.md │ │ ├── _questions │ │ │ ├── advanced_questions.md │ │ │ ├── css.md │ │ │ ├── javascript.md │ │ │ ├── react.md │ │ │ ├── recruitment_tasks.md │ │ │ └── typescript.md │ │ ├── build_your_project.md │ │ ├── complete_project.md │ │ ├── content_creators.md │ │ ├── other_resources.md │ │ └── test_your_skills.mdx │ ├── software │ │ ├── development_setup.md │ │ ├── other_tools.md │ │ ├── repository_tools.md │ │ ├── vim.md │ │ └── vscode.mdx │ └── technologies │ │ ├── css.md │ │ ├── git.md │ │ ├── html.md │ │ ├── javascript.md │ │ ├── nextjs.md │ │ ├── nodejs.md │ │ ├── react.md │ │ ├── redux.md │ │ └── typescript.md ├── styles │ ├── docs.scss │ └── themes │ │ └── tailwind.css └── utils │ ├── addPluralFormEnding.ts │ ├── filePath.mjs │ ├── getDateTimeComponents.ts │ ├── millisecondsToSeconds.ts │ ├── millisecondsToTimeUnits.ts │ ├── modifiedTime.mjs │ ├── timeSince.test.ts │ ├── timeSince.ts │ └── unknownToError.ts ├── static └── .nojekyll ├── tailwind.config.ts ├── tsconfig.json ├── vercel.json └── vitest.config.ts /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "contributors": [ 8 | { 9 | "login": "goodideagiver", 10 | "name": "prplblck", 11 | "avatar_url": "https://avatars.githubusercontent.com/u/55458485?v=4", 12 | "profile": "https://purpleblack.dev/", 13 | "contributions": [ 14 | "doc", 15 | "maintenance" 16 | ] 17 | }, 18 | { 19 | "login": "Willaiem", 20 | "name": "Damian Żygadło", 21 | "avatar_url": "https://avatars.githubusercontent.com/u/25301582?v=4", 22 | "profile": "https://github.com/Willaiem", 23 | "contributions": [ 24 | "code", 25 | "doc", 26 | "infra" 27 | ] 28 | }, 29 | { 30 | "login": "Aksa12", 31 | "name": "Aksa12", 32 | "avatar_url": "https://avatars.githubusercontent.com/u/41188167?v=4", 33 | "profile": "https://github.com/Aksa12", 34 | "contributions": [ 35 | "maintenance" 36 | ] 37 | }, 38 | { 39 | "login": "skoczy01", 40 | "name": "Filip", 41 | "avatar_url": "https://avatars.githubusercontent.com/u/82238474?v=4", 42 | "profile": "https://github.com/skoczy01", 43 | "contributions": [ 44 | "maintenance" 45 | ] 46 | }, 47 | { 48 | "login": "martindustry", 49 | "name": "Marcin Niemczyk", 50 | "avatar_url": "https://avatars.githubusercontent.com/u/82864230?v=4", 51 | "profile": "https://github.com/martindustry", 52 | "contributions": [ 53 | "doc" 54 | ] 55 | }, 56 | { 57 | "login": "grzegorzpokorski", 58 | "name": "Grzegorz Pokorski", 59 | "avatar_url": "https://avatars.githubusercontent.com/u/27455716?v=4", 60 | "profile": "http://grzegorzpokorski.pl", 61 | "contributions": [ 62 | "a11y" 63 | ] 64 | }, 65 | { 66 | "login": "getlaurekt", 67 | "name": "Muszkowy Potworek", 68 | "avatar_url": "https://avatars.githubusercontent.com/u/58201840?v=4", 69 | "profile": "https://github.com/getlaurekt", 70 | "contributions": [ 71 | "doc" 72 | ] 73 | } 74 | ], 75 | "contributorsPerLine": 7, 76 | "projectName": "webdev-learning-materials", 77 | "projectOwner": "NowYouKnowProgramming", 78 | "repoType": "github", 79 | "repoHost": "https://github.com", 80 | "skipCi": true, 81 | "commitConvention": "angular", 82 | "commitType": "docs" 83 | } 84 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | 28 | - OS: [e.g. iOS] 29 | - Browser [e.g. chrome, safari] 30 | - Version [e.g. 22] 31 | 32 | **Smartphone (please complete the following information):** 33 | 34 | - Device: [e.g. iPhone6] 35 | - OS: [e.g. iOS8.1] 36 | - Browser [e.g. stock browser, safari] 37 | - Version [e.g. 22] 38 | 39 | **Additional context** 40 | Add any other context about the problem here. 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/new_docs_section.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: New docs 3 | about: Suggest new materials to be added to the docs. Check first if there is an issue for your topic already. 4 | title: '' 5 | labels: ['new docs'] 6 | assignees: '' 7 | --- 8 | 9 | # What you want to add to the docs 10 | 11 | > [e.g. MDN docs *here is a link*] 12 | 13 | ## Why it should be added 14 | 15 | > I used it and it's up to date and helped me grow in the web dev field 16 | > 17 | > List of arguments why: ... ... ... 18 | 19 | ## Additional information 20 | -------------------------------------------------------------------------------- /.github/workflows/playwright.yml: -------------------------------------------------------------------------------- 1 | name: E2E Tests 2 | on: 3 | push: 4 | branches: [ main, master ] 5 | workflow_dispatch: 6 | 7 | jobs: 8 | test: 9 | timeout-minutes: 10 10 | runs-on: ubuntu-20.04 11 | strategy: 12 | matrix: 13 | node-version: [16] 14 | steps: 15 | - uses: actions/checkout@v3 16 | - uses: pnpm/action-setup@v2.2.4 17 | with: 18 | version: 7 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v3 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | cache: 'pnpm' 24 | - name: Install dependencies 25 | run: pnpm install 26 | - name: Install Playwright Browsers 27 | run: npx playwright install --with-deps 28 | - name : Build app 29 | run: pnpm build 30 | - name: Launch app 31 | run: pnpm preview & sleep 10 && curl http://localhost:3000 && npx playwright test 32 | - uses: actions/upload-artifact@v3 33 | if: always() 34 | with: 35 | name: playwright-report 36 | path: playwright-report/ 37 | retention-days: 30 38 | -------------------------------------------------------------------------------- /.github/workflows/vitest.yml: -------------------------------------------------------------------------------- 1 | name: Unit and Integration Tests 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-20.04 12 | strategy: 13 | matrix: 14 | node-version: [20] 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: Use Node.js ${{ matrix.node-version }} 18 | uses: actions/setup-node@v3 19 | with: 20 | node-version: ${{ matrix.node-version }} 21 | - name: Install dependencies 22 | run: npm install 23 | - name: Run Vitest 24 | run: npm run test 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # dependencies 5 | node_modules/ 6 | 7 | # logs 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | pnpm-debug.log* 12 | 13 | 14 | # environment variables 15 | .env 16 | .env.production 17 | 18 | # macOS-specific files 19 | .DS_Store 20 | /test-results/ 21 | /playwright-report/ 22 | /playwright/.cache/ 23 | .temp* 24 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["stylelint-config-standard"] 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "astro-build.astro-vscode", 4 | "rioukkevin.vscode-git-commit", 5 | "esbenp.prettier-vscode", 6 | "bradlc.vscode-tailwindcss", 7 | "streetsidesoftware.code-spell-checker" 8 | ], 9 | "unwantedRecommendations": [] 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "command": "./node_modules/.bin/astro dev", 6 | "name": "Development server", 7 | "request": "launch", 8 | "type": "node-terminal" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "vscodeGitCommit.template": [ 3 | "{type}: {action}{what_was_done}\n\n{why_it_was_done}{breaking}" 4 | ], 5 | "vscodeGitCommit.variables": { 6 | "prefix": "keke", 7 | "action": [ 8 | { 9 | "label": "", 10 | "detail": "❌ no action to describe" 11 | }, 12 | { 13 | "label": "add ", 14 | "detail": "🆕 a new feature is introduced with the changes" 15 | }, 16 | { 17 | "label": "remove ", 18 | "detail": "🗑️ removing code or files" 19 | }, 20 | { 21 | "label": "update ", 22 | "detail": "🔧 an existing feature is updated with the changes" 23 | }, 24 | { 25 | "label": "move ", 26 | "detail": "🚚 moving files, folders or code" 27 | }, 28 | { 29 | "label": "fix ", 30 | "detail": "🐛 something was not correct and now it is" 31 | }, 32 | { 33 | "label": "change ", 34 | "detail": "🔧 changing code or files without adding or removing" 35 | }, 36 | { 37 | "label": "improve ", 38 | "detail": "🏁 performance improvements" 39 | }, 40 | { 41 | "label": "setup ", 42 | "detail": "🔧 setting up the project or dependencies" 43 | }, 44 | { 45 | "label": "update dependencies ", 46 | "detail": "🔧 updating dependencies" 47 | } 48 | ], 49 | "breaking": [ 50 | { 51 | "label": "", 52 | "detail": "❌ no breaking change to describe" 53 | }, 54 | { 55 | "label": "\n\nBREAKING CHANGE", 56 | "detail": "💥 a breaking change: a feature that was previously available will now behave differently" 57 | } 58 | ], 59 | "type": [ 60 | { 61 | "label": "Feat", 62 | "detail": "🆕 a new feature is introduced with the changes" 63 | }, 64 | { 65 | "label": "Fix", 66 | "detail": "🔴 a bug fix has occurred" 67 | }, 68 | { 69 | "label": "Refactor", 70 | "detail": "🔧 not bugfix, not feature, but code changes, works the same" 71 | }, 72 | { 73 | "label": "Chore", 74 | "detail": "🧹 update dependency / changes to build tools or scripts / code doesn't change" 75 | }, 76 | { 77 | "label": "Perf", 78 | "detail": "🏁 performance improvements" 79 | }, 80 | { 81 | "label": "Docs", 82 | "detail": "🗄️ updates to documentation such as a the README or other markdown files" 83 | }, 84 | { 85 | "label": "Style", 86 | "detail": "✨ changes to code formatting, like spaces or semicolons" 87 | }, 88 | { 89 | "label": "Test", 90 | "detail": "🤖 including new or correcting previous tests" 91 | }, 92 | { 93 | "label": "Build", 94 | "detail": "👷 changes that affect the build system or external dependencies " 95 | }, 96 | { 97 | "label": "CI", 98 | "detail": "👾 continuous integration related" 99 | }, 100 | { 101 | "label": "Revert", 102 | "detail": "🤕 reverts a previous commit" 103 | }, 104 | { 105 | "label": "WIP", 106 | "detail": "🚧 work in progress" 107 | } 108 | ] 109 | }, 110 | } 111 | -------------------------------------------------------------------------------- /E2E/Articles.test.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@playwright/test' 2 | 3 | test.beforeEach(async ({ page }) => { 4 | await page.goto('http://localhost:3000/') 5 | 6 | const docsButton = page.getByText(/Start learning/).first() 7 | 8 | await docsButton.click() 9 | 10 | await expect(page).toHaveURL(/.*introduction/) 11 | }) 12 | 13 | test('JavaScript article is possible to reach', async ({ page }) => { 14 | const javascriptArticleLink = page.getByText(/JavaScript/).first() 15 | 16 | await javascriptArticleLink.click() 17 | 18 | await expect(page).toHaveURL(/.*javascript/) 19 | }) 20 | 21 | test('React article is possible to reach', async ({ page }) => { 22 | const reactArticleLink = page.getByText(/React/).first() 23 | 24 | await reactArticleLink.click() 25 | 26 | await expect(page).toHaveURL(/.*react/) 27 | }) 28 | -------------------------------------------------------------------------------- /E2E/DocsButton.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from '@playwright/test' 2 | 3 | test('homepage has title and links to intro page', async ({ page }) => { 4 | await page.goto('http://localhost:3000/') 5 | 6 | // Expect a title "to contain" a substring. 7 | await expect(page).toHaveTitle(/The best way to learn web/) 8 | 9 | // create a locator 10 | const getStarted = page.getByText(/Start learning/).first() 11 | 12 | // Click the get started link. 13 | await getStarted.click() 14 | 15 | // Expects the URL to contain intro. 16 | await expect(page).toHaveURL(/.*introduction/) 17 | }) 18 | -------------------------------------------------------------------------------- /E2E/StarButton.test.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@playwright/test' 2 | 3 | const githubRepoLink = 4 | 'https://github.com/NowYouKnowProgramming/webdev-learning-materials' 5 | 6 | test.beforeEach(async ({ page }) => { 7 | await page.goto('http://localhost:3000/') 8 | }) 9 | 10 | test('Button that is a CTA to star project is in the docs page', async ({ 11 | page, 12 | }) => { 13 | const docsButton = page.getByText(/Start learning/).first() 14 | 15 | await docsButton.click() 16 | 17 | await expect(page).toHaveURL(/.*introduction/) 18 | 19 | const starButton = page.getByRole('link', { name: /Star/ }).first() 20 | 21 | await expect(starButton).toBeVisible() 22 | await expect(starButton).toHaveAttribute('href', githubRepoLink) 23 | }) 24 | 25 | test('CTA button to star project is visible on the landing page', async ({ 26 | page, 27 | }) => { 28 | const starButtonLink = page.getByRole('link', { name: /Star \w*/ }) 29 | 30 | await expect(starButtonLink).toBeVisible() 31 | await expect(starButtonLink).toHaveAttribute('href', githubRepoLink) 32 | }) 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2023, bewebdev.tech 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚧🚧🚧🚧🚧 2 | # THIS PROJECT WAS MOVED TO [NEW REPOSITORY](https://github.com/goodideagiver/webdev-learning-materials-1) 3 | # 🚧🚧🚧🚧🚧 4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | # bewebdev.tech (Web Development Learning Materials) 13 | 14 | A list of learning materials for Web Development. 15 | 16 | ## Check the website here! 17 | 18 | [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/J3J4761UB) 19 | 20 | ### Contributing 21 | 22 | If you found something interesting, but it's not in the list, please open an issue or, even better, a pull request. 23 | 24 |

😊 We will be happy to check it out and add it.

25 | 26 | ### Website 27 | 28 | This website is built using [Astro](https://astro.build/), a modern static website generator. 29 | 30 | #### Installation 31 | 32 | ``` 33 | npm i 34 | ``` 35 | 36 | #### Local Development 37 | 38 | ``` 39 | npm dev 40 | ``` 41 | 42 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 43 | 44 | #### Build 45 | 46 | ``` 47 | npm build 48 | ``` 49 | 50 | This command generates static content into the `dist` directory and can be served using any static contents hosting service. 51 | 52 | ## Contributors ✨ 53 | 54 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
prplblck
prplblck

📖 🚧
Damian Żygadło
Damian Żygadło

💻 📖 🚇
Aksa12
Aksa12

🚧
Filip
Filip

🚧
Marcin Niemczyk
Marcin Niemczyk

📖
Grzegorz Pokorski
Grzegorz Pokorski

️️️️♿️
Muszkowy Potworek
Muszkowy Potworek

📖
72 | 73 | 74 | 75 | 76 | 77 | 78 | ### [How to add the contributor to the list](https://allcontributors.org/docs/en/bot/usage) 79 | 80 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! 81 | 82 | ## Special thanks 83 | 84 | 85 | This project is tested with [BrowserStack](https://www.browserstack.com/). 86 | 87 | ## License 88 | 89 | This project is licensed under **BSD-3-Clause**, see the 90 | [LICENSE](LICENSE) file for more details. 91 | -------------------------------------------------------------------------------- /astro.config.mjs: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | import mdx from '@astrojs/mdx' 4 | import preact from '@astrojs/preact' 5 | import react from '@astrojs/react' 6 | import compress from 'astro-compress' 7 | import { defineConfig } from 'astro/config' 8 | import sitemap from '@astrojs/sitemap' 9 | import tailwind from '@astrojs/tailwind' 10 | import { modifiedTime } from './src/utils/modifiedTime.mjs' 11 | import { filePath } from './src/utils/filePath.mjs' 12 | 13 | // https://astro.build/config 14 | export default defineConfig({ 15 | integrations: [ 16 | preact({ 17 | include: ['**/preact/*'], 18 | }), 19 | react({ 20 | include: ['**/react/*'], 21 | }), 22 | mdx(), 23 | compress(), 24 | sitemap(), 25 | tailwind(), 26 | ], 27 | markdown: { 28 | remarkPlugins: [modifiedTime, filePath], 29 | }, 30 | site: `https://bewebdev.tech/`, 31 | }) 32 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webdev-learning-materials-page", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "private": true, 6 | "scripts": { 7 | "dev": "astro dev", 8 | "start": "astro dev", 9 | "check": "astro check && tsc", 10 | "build": "astro build", 11 | "preview": "astro preview", 12 | "astro": "astro", 13 | "test": "vitest", 14 | "e2e": "playwright test" 15 | }, 16 | "dependencies": { 17 | "@algolia/client-search": "^4.19.1", 18 | "@astrojs/check": "^0.2.0", 19 | "@astrojs/mdx": "^1.0.3", 20 | "@astrojs/preact": "^3.0.0", 21 | "@astrojs/react": "^3.0.2", 22 | "@astrojs/sitemap": "^3.0.0", 23 | "@astrojs/tailwind": "^5.0.0", 24 | "@docsearch/css": "^3.5.2", 25 | "@docsearch/react": "^3.5.2", 26 | "@radix-ui/react-accordion": "^1.1.2", 27 | "@radix-ui/react-dialog": "^1.0.4", 28 | "@radix-ui/react-icons": "^1.3.0", 29 | "@types/node": "^20.6.0", 30 | "@types/react": "^18.2.21", 31 | "@types/react-dom": "^18.2.7", 32 | "astro": "^3.0.12", 33 | "astro-compress": "2.0.15", 34 | "autoprefixer": "^10.4.15", 35 | "body-scroll-lock": "4.0.0-beta.0", 36 | "clsx": "^2.0.0", 37 | "framer-motion": "^10.16.4", 38 | "postcss": "^8.4.29", 39 | "preact": "^10.17.1", 40 | "react": "^18.2.0", 41 | "react-dom": "^18.2.0", 42 | "react-just-parallax": "^3.1.16", 43 | "react-use-observer": "^2.2.4", 44 | "rollup": "^3.29.0", 45 | "swr": "^2.2.2", 46 | "tailwindcss": "^3.3.3" 47 | }, 48 | "devDependencies": { 49 | "@playwright/test": "^1.37.1", 50 | "@types/body-scroll-lock": "^3.1.0", 51 | "@types/gtag.js": "^0.0.13", 52 | "prettier": "3.0.3", 53 | "prettier-plugin-astro": "^0.12.0", 54 | "prettier-plugin-tailwindcss": "^0.5.4", 55 | "sass": "^1.66.1", 56 | "stylelint": "^15.10.3", 57 | "stylelint-config-standard": "^34.0.0", 58 | "typescript": "^5.2.2", 59 | "vitest": "^0.34.4" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /playwright.config.ts: -------------------------------------------------------------------------------- 1 | import type { PlaywrightTestConfig } from '@playwright/test'; 2 | import { devices } from '@playwright/test'; 3 | 4 | /** 5 | * Read environment variables from file. 6 | * https://github.com/motdotla/dotenv 7 | */ 8 | // require('dotenv').config(); 9 | 10 | /** 11 | * See https://playwright.dev/docs/test-configuration. 12 | */ 13 | const config: PlaywrightTestConfig = { 14 | testDir: './E2E', 15 | /* Maximum time one test can run for. */ 16 | timeout: 30 * 1000, 17 | expect: { 18 | /** 19 | * Maximum time expect() should wait for the condition to be met. 20 | * For example in `await expect(locator).toHaveText();` 21 | */ 22 | timeout: 5000 23 | }, 24 | /* Run tests in files in parallel */ 25 | fullyParallel: true, 26 | /* Fail the build on CI if you accidentally left test.only in the source code. */ 27 | forbidOnly: !!process.env.CI, 28 | /* Retry on CI only */ 29 | retries: process.env.CI ? 2 : 0, 30 | /* Opt out of parallel tests on CI. */ 31 | workers: process.env.CI ? 1 : undefined, 32 | /* Reporter to use. See https://playwright.dev/docs/test-reporters */ 33 | reporter: 'html', 34 | /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ 35 | use: { 36 | /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ 37 | actionTimeout: 0, 38 | /* Base URL to use in actions like `await page.goto('/')`. */ 39 | // baseURL: 'http://localhost:3000', 40 | 41 | /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ 42 | trace: 'on-first-retry', 43 | }, 44 | 45 | /* Configure projects for major browsers */ 46 | projects: [ 47 | { 48 | name: 'chromium', 49 | use: { 50 | ...devices['Desktop Chrome'], 51 | }, 52 | }, 53 | 54 | { 55 | name: 'firefox', 56 | use: { 57 | ...devices['Desktop Firefox'], 58 | }, 59 | }, 60 | 61 | { 62 | name: 'webkit', 63 | use: { 64 | ...devices['Desktop Safari'], 65 | }, 66 | }, 67 | 68 | /* Test against mobile viewports. */ 69 | // { 70 | // name: 'Mobile Chrome', 71 | // use: { 72 | // ...devices['Pixel 5'], 73 | // }, 74 | // }, 75 | // { 76 | // name: 'Mobile Safari', 77 | // use: { 78 | // ...devices['iPhone 12'], 79 | // }, 80 | // }, 81 | 82 | /* Test against branded browsers. */ 83 | // { 84 | // name: 'Microsoft Edge', 85 | // use: { 86 | // channel: 'msedge', 87 | // }, 88 | // }, 89 | // { 90 | // name: 'Google Chrome', 91 | // use: { 92 | // channel: 'chrome', 93 | // }, 94 | // }, 95 | ], 96 | 97 | /* Folder for test artifacts such as screenshots, videos, traces, etc. */ 98 | // outputDir: 'test-results/', 99 | 100 | /* Run your local dev server before starting the tests */ 101 | // webServer: { 102 | // command: 'npm run start', 103 | // port: 3000, 104 | // }, 105 | }; 106 | 107 | export default config; 108 | -------------------------------------------------------------------------------- /postcss.config.cjs: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | module.exports = { 4 | plugins: { 5 | autoprefixer: {}, 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /prettier.config.ts: -------------------------------------------------------------------------------- 1 | /** @type {import("prettier").Config} */ 2 | 3 | import { type Config } from 'prettier' 4 | 5 | module.exports = { 6 | tabWidth: 2, 7 | semi: false, 8 | singleQuote: true, 9 | jsxSingleQuote: true, 10 | overrides: [ 11 | { 12 | files: '*.astro', 13 | options: { 14 | parser: 'astro', 15 | }, 16 | }, 17 | ], 18 | plugins: ['prettier-plugin-astro', 'prettier-plugin-tailwindcss'], 19 | } satisfies Config 20 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/favicon.ico -------------------------------------------------------------------------------- /public/fonts/Inter-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Inter-Regular.woff2 -------------------------------------------------------------------------------- /public/fonts/Nunito-Italic-VariableFont_wght.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Nunito-Italic-VariableFont_wght.woff2 -------------------------------------------------------------------------------- /public/fonts/Nunito-VariableFont_wght.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Nunito-VariableFont_wght.woff2 -------------------------------------------------------------------------------- /public/fonts/Poppins-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-Black.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-BlackItalic.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-Bold.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-BoldItalic.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-ExtraBold.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-ExtraLight.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-Italic.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-Light.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-LightItalic.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-Medium.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-MediumItalic.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-Regular.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-SemiBold.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-Thin.ttf -------------------------------------------------------------------------------- /public/fonts/Poppins-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/fonts/Poppins-ThinItalic.ttf -------------------------------------------------------------------------------- /public/icons/hourglass.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/icons/savings.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/icons/school_hat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/images/css/components.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/css/components.webp -------------------------------------------------------------------------------- /public/images/css/css_exercises_1_3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/css/css_exercises_1_3.webp -------------------------------------------------------------------------------- /public/images/css/css_exercises_2_3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/css/css_exercises_2_3.webp -------------------------------------------------------------------------------- /public/images/css/css_exercises_3_3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/css/css_exercises_3_3.webp -------------------------------------------------------------------------------- /public/images/css/flex_basis_grow_shrink.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/css/flex_basis_grow_shrink.webp -------------------------------------------------------------------------------- /public/images/css/flex_shorthand.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/css/flex_shorthand.webp -------------------------------------------------------------------------------- /public/images/css/tailwind_ally1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/css/tailwind_ally1.png -------------------------------------------------------------------------------- /public/images/css/tailwind_ally2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/css/tailwind_ally2.png -------------------------------------------------------------------------------- /public/images/css/tailwind_typesafe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/css/tailwind_typesafe.png -------------------------------------------------------------------------------- /public/images/css/tailwind_variants.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/css/tailwind_variants.png -------------------------------------------------------------------------------- /public/images/css/unsprinkle.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/css/unsprinkle.webp -------------------------------------------------------------------------------- /public/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /public/images/misc/pl_hr_response.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/misc/pl_hr_response.webp -------------------------------------------------------------------------------- /public/images/misc/projekt.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/misc/projekt.webp -------------------------------------------------------------------------------- /public/images/misc/puzzle.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/misc/puzzle.webp -------------------------------------------------------------------------------- /public/images/nukp-logo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/nukp-logo.webp -------------------------------------------------------------------------------- /public/images/react/react-fetching-1_3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/react/react-fetching-1_3.webp -------------------------------------------------------------------------------- /public/images/react/react-fetching-2_3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/react/react-fetching-2_3.webp -------------------------------------------------------------------------------- /public/images/react/react-fetching-3_3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/images/react/react-fetching-3_3.webp -------------------------------------------------------------------------------- /public/images/starButton/star-icon.svg: -------------------------------------------------------------------------------- 1 | star-symbol -------------------------------------------------------------------------------- /public/make-scrollable-code-focusable.js: -------------------------------------------------------------------------------- 1 | Array.from(document.getElementsByTagName('pre')).forEach((element) => { 2 | element.setAttribute('tabindex', '0') 3 | }) 4 | -------------------------------------------------------------------------------- /public/metaimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/metaimage.png -------------------------------------------------------------------------------- /public/metaimages/css.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/metaimages/css.png -------------------------------------------------------------------------------- /public/metaimages/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/metaimages/git.png -------------------------------------------------------------------------------- /public/metaimages/html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/metaimages/html.png -------------------------------------------------------------------------------- /public/metaimages/javascript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/metaimages/javascript.png -------------------------------------------------------------------------------- /public/metaimages/nextjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/metaimages/nextjs.png -------------------------------------------------------------------------------- /public/metaimages/nodejs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/metaimages/nodejs.png -------------------------------------------------------------------------------- /public/metaimages/react.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/metaimages/react.png -------------------------------------------------------------------------------- /public/metaimages/redux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/metaimages/redux.png -------------------------------------------------------------------------------- /public/metaimages/testing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/metaimages/testing.png -------------------------------------------------------------------------------- /public/metaimages/typescript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NowYouKnowProgramming/webdev-learning-materials/0dab258dcc81f4f7f5a173df91f3a99e80bb8e46/public/metaimages/typescript.png -------------------------------------------------------------------------------- /src/components/DonationModal/DonationButton.tsx: -------------------------------------------------------------------------------- 1 | import { HeartFilledIcon } from '@radix-ui/react-icons' 2 | 3 | const GradientGlow = () => ( 4 |
5 | ) 6 | 7 | type Props = { 8 | onClick: () => void 9 | } 10 | 11 | export const DonationButton = ({ onClick }: Props) => { 12 | return ( 13 | 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /src/components/GitHubStarLink/GitHubStarLink.astro: -------------------------------------------------------------------------------- 1 | Star on GitHub 6 | -------------------------------------------------------------------------------- /src/components/HeadCommon.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { ViewTransitions } from 'astro:transitions' 3 | import '../styles/themes/tailwind.css' 4 | 5 | const experimentalOptions = { importance: 'high' } 6 | 7 | const poppinsVariants = [ 8 | 'Black', 9 | 'BlackItalic', 10 | 'Bold', 11 | 'BoldItalic', 12 | 'ExtraBold', 13 | 'ExtraBoldItalic', 14 | 'ExtraLight', 15 | 'ExtraLightItalic', 16 | 'Italic', 17 | 'Light', 18 | 'LightItalic', 19 | 'Medium', 20 | 'MediumItalic', 21 | 'Regular', 22 | 'SemiBold', 23 | 'SemiBoldItalic', 24 | 'Thin', 25 | 'ThinItalic', 26 | ] 27 | 28 | --- 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | { 43 | poppinsVariants.map((font) => ( 44 | 51 | )) 52 | } 53 | 54 | 62 | 63 | 64 | 65 | 66 | 67 | 96 | 97 | 98 | 100 | 108 | -------------------------------------------------------------------------------- /src/components/HeadSEO.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { SITE, OPEN_GRAPH, type Frontmatter } from '../config' 3 | 4 | export interface Props { 5 | frontmatter: Frontmatter 6 | canonicalUrl: URL 7 | } 8 | 9 | const { frontmatter, canonicalUrl } = Astro.props as Props 10 | const formattedContentTitle = `${frontmatter.title} 👨‍💻 ${SITE.title}` 11 | const imageAlt = frontmatter.image?.alt ?? '' 12 | 13 | const META_IMG_URL = 14 | Astro.url.origin + (frontmatter.image?.src ?? '/metaimage.png') 15 | 16 | const DESCRIPTION = frontmatter.description ?? SITE.description 17 | --- 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 51 | -------------------------------------------------------------------------------- /src/components/Header/GithubStars.tsx: -------------------------------------------------------------------------------- 1 | /** @jsxImportSource react */ 2 | 3 | import { StarIcon } from '@radix-ui/react-icons' 4 | import useSWR, { type Fetcher } from 'swr' 5 | 6 | type Response = { 7 | stargazers_count: number 8 | } 9 | 10 | const fetcher: Fetcher = (...args) => 11 | fetch(...args).then((res) => res.json()) 12 | 13 | const ONE_MINUTE_IN_MILLISECONDS = 60000 14 | 15 | export const GithubStars = () => { 16 | const { data, error } = useSWR( 17 | `https://api.github.com/repos/nowyouknowprogramming/webdev-learning-materials`, 18 | fetcher, 19 | { 20 | revalidateOnFocus: true, 21 | refreshInterval: ONE_MINUTE_IN_MILLISECONDS * 5, 22 | shouldRetryOnError: true, 23 | errorRetryCount: 3, 24 | errorRetryInterval: ONE_MINUTE_IN_MILLISECONDS * 2, 25 | }, 26 | ) 27 | 28 | const canDisplayStars = !error && data?.stargazers_count !== undefined 29 | 30 | return ( 31 | 37 | 38 | Star 39 | {canDisplayStars && ( 40 | 41 | {data?.stargazers_count} 42 | 43 | )} 44 | 45 | ) 46 | } 47 | 48 | export default GithubStars 49 | -------------------------------------------------------------------------------- /src/components/Header/Header.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import * as CONFIG from '../../config' 3 | import ThemeToggle from '../RightSidebar/ThemeToggleButton' 4 | import AstroLogo from './Logo.astro' 5 | import Search from './Search' 6 | import SidebarToggle from './SidebarToggle' 7 | import SkipToContent from './SkipToContent.astro' 8 | import DonationModal from '../DonationModal/DonationModal' 9 | 10 | type Props = { 11 | currentPage: string 12 | } 13 | 14 | const { currentPage } = Astro.props as Props 15 | 16 | const currentPageIsRoot = currentPage === '/' 17 | 18 | const { ALGOLIA } = CONFIG 19 | const { apiKey, appId, indexName } = ALGOLIA 20 | 21 | import GithubStars from './GithubStars' 22 | 23 | const algoliaIsSetUp = indexName && appId && apiKey 24 | --- 25 | 26 |
30 | 31 | 69 |
70 | 71 | 72 | 86 | 87 | 118 | 119 | 124 | -------------------------------------------------------------------------------- /src/components/Header/Logo.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const { size = 50 } = Astro.props as { size?: number } 3 | --- 4 | 5 | bewebdev logo - computer backlit with pink color 12 | -------------------------------------------------------------------------------- /src/components/Header/Search.css: -------------------------------------------------------------------------------- 1 | in 2 | 3 | /** Style Algolia */ 4 | :root { 5 | --docsearch-primary-color: var(--theme-accent); 6 | --docsearch-logo-color: var(--theme-text); 7 | } 8 | 9 | .search-input { 10 | flex-grow: 1; 11 | box-sizing: border-box; 12 | width: 100%; 13 | margin: 0; 14 | padding: 0.33em 0.5em; 15 | overflow: visible; 16 | font-weight: 500; 17 | font-size: 1rem; 18 | font-family: inherit; 19 | line-height: inherit; 20 | background-color: var(--theme-divider); 21 | border-color: var(--theme-divider); 22 | color: var(--theme-text-light); 23 | border-style: solid; 24 | border-width: 1px; 25 | border-radius: 0.25rem; 26 | outline: 0; 27 | cursor: pointer; 28 | transition-timing-function: ease-out; 29 | transition-duration: 0.2s; 30 | transition-property: border-color, color; 31 | -webkit-font-smoothing: antialiased; 32 | } 33 | 34 | .search-input:hover, 35 | .search-input:focus { 36 | color: var(--theme-text); 37 | border-color: var(--theme-text-light); 38 | } 39 | 40 | .search-input:hover::placeholder, 41 | .search-input:focus::placeholder { 42 | color: var(--theme-text-light); 43 | } 44 | 45 | .search-input::placeholder { 46 | color: var(--theme-text-light); 47 | } 48 | 49 | .search-hint { 50 | margin-left: auto; 51 | padding: 3px 5px; 52 | display: none; 53 | align-items: center; 54 | justify-content: center; 55 | letter-spacing: 0.125em; 56 | font-size: 13px; 57 | font-family: var(--font-mono); 58 | pointer-events: none; 59 | border-color: rgba(var(--color-text-muted), 20%); 60 | color: var(--theme-text-light); 61 | border-style: solid; 62 | border-width: 0px; 63 | border-radius: 0.25rem; 64 | line-height: 14px; 65 | box-shadow: 66 | rgba(128, 128, 128, 0.308) 0 0 0 1px, 67 | rgba(0, 0, 0, 0.1) 0 2px 2px; 68 | } 69 | 70 | @media (min-width: 50em) { 71 | .search-hint { 72 | display: flex; 73 | } 74 | } 75 | 76 | /* ------------------------------------------------------------ *\ 77 | DocSearch (Algolia) 78 | \* ------------------------------------------------------------ */ 79 | 80 | .DocSearch-Modal .DocSearch-Hit a { 81 | box-shadow: none; 82 | border: 1px solid rgba(var(--color-text-muted), 30%); 83 | } 84 | 85 | .DocSearch-Hit[aria-selected='true'] a { 86 | box-shadow: 0 0 15px 150px rgba(var(--color-text-muted), 30%) inset; 87 | background-color: transparent !important; 88 | } 89 | 90 | .DocSearch-Modal { 91 | --docsearch-searchbox-focus-background: rgba(var(--color-bg-base), 30%); 92 | --docsearch-muted-color: rgb(var(--color-text-muted)); 93 | --docsearch-searchbox-shadow: 0 0 0 2px rgb(var(--color-text-muted), 10%) 94 | inset; 95 | --docsearch-footer-background: rgb(var(--color-bg-base)); 96 | --docsearch-modal-background: rgb(var(--color-bg-base)); 97 | --docsearch-hit-active-color: rgb(var(--color-text-base)); 98 | --docsearch-text-color: rgb(var(--color-text-base)); 99 | --docsearch-hit-color: rgba(var(--color-text-muted), 50%); 100 | --docsearch-hit-background: rgb(var(--color-bg-base)); 101 | --docsearch-footer-shadow: 0 -1px 0 0 rgba(var(--color-text-muted), 50%); 102 | 103 | border-radius: 4px; 104 | overflow: hidden; 105 | box-shadow: rgb(0 0 0 / 65%) 0 7px 29px 0; 106 | } 107 | 108 | .DocSearch-Footer { 109 | box-shadow: none; 110 | border-radius: 0; 111 | } 112 | 113 | .DocSearch-Form:focus-within { 114 | box-shadow: inset rgb(var(--color-text-muted)) 0 0 0 2px; 115 | } 116 | 117 | .DocSearch-Modal input:focus-visible { 118 | outline: none; 119 | } 120 | 121 | .DocSearch-Container { 122 | z-index: 99999 !important; 123 | } 124 | 125 | .DocSearch-SearchBar { 126 | padding: var(--docsearch-spacing) var(--docsearch-spacing); 127 | } 128 | -------------------------------------------------------------------------------- /src/components/Header/Search.tsx: -------------------------------------------------------------------------------- 1 | /** @jsxImportSource react */ 2 | import { useState, useCallback, useRef } from 'react' 3 | import { ALGOLIA } from '../../config' 4 | import '@docsearch/css' 5 | import './Search.css' 6 | 7 | import { createPortal } from 'react-dom' 8 | import * as docSearchReact from '@docsearch/react' 9 | 10 | /** FIXME: This is still kinda nasty, but DocSearch is not ESM ready. */ 11 | const DocSearchModal = 12 | docSearchReact.DocSearchModal || 13 | (docSearchReact as any).default.DocSearchModal 14 | const useDocSearchKeyboardEvents = 15 | docSearchReact.useDocSearchKeyboardEvents || 16 | (docSearchReact as any).default.useDocSearchKeyboardEvents 17 | 18 | export default function Search() { 19 | const [isOpen, setIsOpen] = useState(false) 20 | const searchButtonRef = useRef(null) 21 | const [initialQuery, setInitialQuery] = useState('') 22 | 23 | const onOpen = useCallback(() => { 24 | setIsOpen(true) 25 | }, [setIsOpen]) 26 | 27 | const onClose = useCallback(() => { 28 | setIsOpen(false) 29 | }, [setIsOpen]) 30 | 31 | const onInput = useCallback( 32 | (e: any) => { 33 | setIsOpen(true) 34 | setInitialQuery(e.key) 35 | }, 36 | [setIsOpen, setInitialQuery], 37 | ) 38 | 39 | useDocSearchKeyboardEvents({ 40 | isOpen, 41 | onOpen, 42 | onClose, 43 | onInput, 44 | searchButtonRef, 45 | }) 46 | 47 | return ( 48 | <> 49 | 75 | 76 | {isOpen && 77 | createPortal( 78 | { 86 | return items.map((item) => { 87 | // We transform the absolute URL into a relative URL to 88 | // work better on localhost, preview URLS. 89 | const a = document.createElement('a') 90 | a.href = item.url 91 | const hash = a.hash === '#overview' ? '' : a.hash 92 | return { 93 | ...item, 94 | url: `${a.pathname}${hash}`, 95 | } 96 | }) 97 | }} 98 | />, 99 | document.body, 100 | )} 101 | 102 | ) 103 | } 104 | -------------------------------------------------------------------------------- /src/components/Header/SidebarToggle.tsx: -------------------------------------------------------------------------------- 1 | /** @jsxImportSource preact */ 2 | import type { FunctionalComponent } from 'preact' 3 | import { useState, useEffect } from 'preact/hooks' 4 | import { disableBodyScroll, enableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock'; 5 | 6 | 7 | const MenuToggle: FunctionalComponent = () => { 8 | const [sidebarShown, setSidebarShown] = useState(false) 9 | 10 | useEffect(() => { 11 | const sidebarElement = document.querySelector('#toggleable-sidebar')! 12 | const sidebarScrollElement = document.querySelector('#toggleable-sidebar-overflow')! 13 | if (sidebarShown) { 14 | sidebarElement.setAttribute('data-sidebar-shown', 'true') 15 | disableBodyScroll(sidebarScrollElement) 16 | } else { 17 | sidebarElement.setAttribute('data-sidebar-shown', 'false') 18 | enableBodyScroll(sidebarScrollElement) 19 | } 20 | return () => { 21 | clearAllBodyScrollLocks() 22 | } 23 | }, [sidebarShown]) 24 | 25 | return ( 26 | 50 | ) 51 | } 52 | 53 | export default MenuToggle 54 | -------------------------------------------------------------------------------- /src/components/Header/SkipToContent.astro: -------------------------------------------------------------------------------- 1 | --- 2 | type Props = {} 3 | --- 4 | 5 | 8 | 9 | 29 | -------------------------------------------------------------------------------- /src/components/LandingPage/LandingSEO.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const META_IMG_URL = 'https://bewebdev.tech/metaimage.png' 3 | const URL = 'https://bewebdev.tech/' 4 | const DESCRIPTION = 5 | 'We’ve done the work for you. We’ve collected the best resources and put them in one place.' 6 | const TITLE = 'bewebdev.tech - The best way to learn web development' 7 | --- 8 | 9 | {TITLE} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/components/LandingPage/VideoEmbed/VideoEmbed.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import DocsButton from '../../Redesign/LandingElements/DocsButton.astro' 3 | const YOUTUBE_CHANNEL_ID = 'UUww1wSWy6LvZjyEEHr7ypLA' 4 | 5 | const LATEST_VIDEO_COUNT = 3 6 | 7 | const CHANNEL_SUBSCRIBE_LINK = 8 | 'https://www.youtube.com/@bewebdev?sub_confirmation=1' 9 | 10 | const getLatestVideoLink = (index: number) => { 11 | return `https://www.youtube.com/embed?listType=playlist&list=${YOUTUBE_CHANNEL_ID}&index=${ 12 | index + 1 13 | }` 14 | } 15 | --- 16 | 17 | 59 | 60 |
61 |
62 | 63 |
64 |
65 |

66 | We record code reviews 67 |

68 |

69 | We believe that code review can be the best way to learn best practices 70 | and new ways to write code for both parties - code reviewer and code 71 | writer 72 |

73 | 74 | Visit our YouTube channel 75 | 76 |
77 |
78 |
79 | { 80 | Array.from({ length: LATEST_VIDEO_COUNT }).map((_, index) => { 81 | const embedSource = getLatestVideoLink(index + 1) 82 | return