├── .github ├── CODEOWNERS └── FUNDING.yml ├── public ├── robots.txt ├── favicon.ico ├── js-logo.png ├── 50daysofjavascript.png ├── 50-days-of-javascript.png ├── 50daysofjavascript_logo.png ├── star-3.svg ├── twitter-icon.svg ├── star-2.svg ├── star-btn.svg ├── star-1.svg ├── manifest.json ├── fork-btn.svg ├── moon.svg ├── cube.svg ├── index.html └── bg-gradient-img-1.svg ├── src ├── setupTests.js ├── App.test.js ├── index.css ├── reportWebVitals.js ├── index.js ├── components │ └── GitHubButtons │ │ ├── GithubButtons.css │ │ └── GitHubButtons.js ├── logo.svg ├── App.js └── App.css ├── .gitignore ├── package.json ├── LICENSE ├── _config.yml └── README.md /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @vinitshahdeo 2 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vinitshahdeo/50DaysOfJavaScript/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/js-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vinitshahdeo/50DaysOfJavaScript/HEAD/public/js-logo.png -------------------------------------------------------------------------------- /public/50daysofjavascript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vinitshahdeo/50DaysOfJavaScript/HEAD/public/50daysofjavascript.png -------------------------------------------------------------------------------- /public/50-days-of-javascript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vinitshahdeo/50DaysOfJavaScript/HEAD/public/50-days-of-javascript.png -------------------------------------------------------------------------------- /public/50daysofjavascript_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vinitshahdeo/50DaysOfJavaScript/HEAD/public/50daysofjavascript_logo.png -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /public/star-3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /public/twitter-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /public/star-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/star-btn.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/star-1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | 9 | console.log('Code awesome shit with @vinitshahdeo & friends!'); 10 | 11 | root.render( 12 | 13 | 14 | 15 | ); 16 | 17 | // If you want to start measuring performance in your app, pass a function 18 | // to log results (for example: reportWebVitals(console.log)) 19 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 20 | reportWebVitals(); 21 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "50JS", 3 | "name": "50DaysOfJavaScript", 4 | "description": "Elevate JavaScript skills with daily coding challenges in a global, community-driven initiative.", 5 | "icons": [ 6 | { 7 | "src": "favicon.ico", 8 | "sizes": "64x64 32x32 24x24 16x16", 9 | "type": "image/x-icon" 10 | }, 11 | { 12 | "src": "js-logo.png", 13 | "type": "image/png", 14 | "sizes": "192x192" 15 | }, 16 | { 17 | "src": "js-logo.png", 18 | "type": "image/png", 19 | "sizes": "512x512" 20 | } 21 | ], 22 | "start_url": "/", 23 | "display": "standalone", 24 | "scope": "/", 25 | "orientation": "portrait", 26 | "theme_color": "#933ffe", 27 | "background_color": "#0b0b0f" 28 | } 29 | -------------------------------------------------------------------------------- /public/fork-btn.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [vinitshahdeo] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /src/components/GitHubButtons/GithubButtons.css: -------------------------------------------------------------------------------- 1 | .github_buttons { 2 | margin-top: 2rem; 3 | font-size: 2rem; 4 | display: flex; 5 | justify-items: center; 6 | align-items: center; 7 | column-gap: 12px; 8 | } 9 | 10 | .github_buttons__link { 11 | display: flex; 12 | justify-items: center; 13 | align-items: center; 14 | column-gap: 6px; 15 | 16 | padding-top: 4px; 17 | padding-bottom: 4px; 18 | padding-left: 12px; 19 | padding-right: 12px; 20 | 21 | border-radius: 2.2rem; 22 | background: #1a1b23; 23 | 24 | text-decoration: none; 25 | } 26 | 27 | .github_buttons__icon { 28 | width: 20px; 29 | height: 20px; 30 | } 31 | 32 | .github_buttons__text { 33 | color: white; 34 | font-weight: bold; 35 | text-decoration: none; 36 | } 37 | 38 | @media only screen and (max-width: 720px) { 39 | .github_buttons { 40 | font-size: 1.8rem; 41 | } 42 | 43 | .github_buttons__icon { 44 | width: 18px; 45 | height: 18px; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "50daysofjavascript", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.5", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.2.0", 10 | "react-dom": "^18.2.0", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "author": { 15 | "name": "Vinit Shahdeo", 16 | "url": "https://github.com/vinitshahdeo" 17 | }, 18 | "scripts": { 19 | "start": "react-scripts start", 20 | "build": "react-scripts build", 21 | "test": "react-scripts test", 22 | "eject": "react-scripts eject" 23 | }, 24 | "eslintConfig": { 25 | "extends": [ 26 | "react-app", 27 | "react-app/jest" 28 | ] 29 | }, 30 | "browserslist": { 31 | "production": [ 32 | ">0.2%", 33 | "not dead", 34 | "not op_mini all" 35 | ], 36 | "development": [ 37 | "last 1 chrome version", 38 | "last 1 firefox version", 39 | "last 1 safari version" 40 | ] 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Vinit Shahdeo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /public/moon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/components/GitHubButtons/GitHubButtons.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "./GithubButtons.css"; 3 | 4 | const settings = { 5 | namepsace: "vinitshahdeo", 6 | repo: "50DaysOfJavaScript", 7 | }; 8 | 9 | function GitHubButtons() { 10 | const [forkCount, setForkCount] = React.useState(); 11 | const [starCount, setStarCount] = React.useState(); 12 | 13 | React.useEffect(() => { 14 | function getCount(data, type) { 15 | return data[`${type}_count`]; 16 | } 17 | ajaxGet(getRequestUrl(), (response) => { 18 | setStarCount(getCount(response, "stargazers")); 19 | setForkCount(getCount(response, "forks")); 20 | }); 21 | }, []); 22 | 23 | function getRequestUrl() { 24 | return `//api.github.com/repos/${settings.namepsace}/${settings.repo}`; 25 | } 26 | function getRepoStargazersUrl() { 27 | return `//github.com/${settings.namepsace}/${settings.repo}/stargazers`; 28 | } 29 | function getRepoForkUrl() { 30 | return `//github.com/${settings.namepsace}/${settings.repo}/fork`; 31 | } 32 | 33 | return ( 34 |
35 | 41 | stargazers 46 | {starCount} 47 | 48 | 54 | forks 55 | {forkCount} 56 | 57 |
58 | ); 59 | } 60 | 61 | function ajaxGet(url, callback) { 62 | if (typeof XDomainRequest !== "undefined") { 63 | callback(null); 64 | return null; 65 | } 66 | 67 | const xhr = new XMLHttpRequest(); 68 | xhr.onreadystatechange = () => { 69 | if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { 70 | callback(JSON.parse(xhr.responseText)); 71 | } 72 | }; 73 | xhr.open("GET", url, true); 74 | xhr.send(); 75 | return xhr; 76 | } 77 | 78 | export default GitHubButtons; 79 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | title: 50DaysOfJavaScript — Solve one question daily to ace your next interview! 2 | author: 3 | name: Vinit Shahdeo 4 | email: vinitshahdeo@gmail.com 5 | 6 | # The `>` after `description:` means to ignore line-breaks until next key. 7 | # If you want to omit the line-break after the end of text, use `>-` instead. 8 | description: > 9 | A community-driven open-source initiative by Vinit Shahdeo for elevating JavaScript skills through daily, practical coding challenges tailored to real-world tasks, led by a supportive global community of developers. 10 | 11 | # Build settings 12 | 13 | # If you clone the Minima repo and build locally, use this setting. 14 | theme: minima 15 | 16 | # As of November 2023, GitHub Pages still uses Minima 2.5.1 (https://pages.github.com/versions/). 17 | # If you want to use the latest Minima version on GitHub Pages, use the following setting and 18 | # add a line comment on "theme: minima" above. 19 | #remote_theme: jekyll/minima 20 | 21 | plugins: 22 | - jekyll-feed 23 | - jekyll-seo-tag 24 | 25 | # Theme-specific settings 26 | 27 | # If you want to link only specific pages in your header, use this and add the path to the pages 28 | # in order as they should show up. 29 | # header_pages: 30 | # - OLD_README.md 31 | 32 | # Set to `true` to show excerpts on the homepage. 33 | #show_excerpts: false 34 | 35 | # Minima specific settings, which are only available from Minima 3.0 onward. 36 | minima: 37 | # Minima skin selection. 38 | # Available skins are: 39 | # classic Default, light color scheme. 40 | # dark Dark variant of the classic skin. 41 | # auto Adaptive skin based on the default classic and dark skins. 42 | # solarized-light Light variant of solarized color scheme. 43 | # solarized-dark Dark variant of solarized color scheme. 44 | # solarized Adaptive skin for solarized color scheme skins. 45 | skin: solarized-dark 46 | 47 | # Minima date format. 48 | # The default value is "%b %d, %Y" (e.g. Nov 14, 2023) 49 | # Refer to https://shopify.github.io/liquid/filters/date/ if you want to customize this. 50 | #date_format: "%b-%d-%Y" 51 | 52 | # Generate social links in footer. 53 | social_links: 54 | # - { platform: devto, user_url: "https://dev.to/jekyll" } 55 | # - { platform: dribbble, user_url: "https://dribbble.com/jekyll" } 56 | # - { platform: facebook, user_url: "https://www.facebook.com/jekyll" } 57 | # - { platform: flickr, user_url: "https://www.flickr.com/photos/jekyll" } 58 | - { platform: github, user_url: "https://github.com/vinitshahdeo" } 59 | # - { platform: google_scholar, user_url: "https://scholar.google.com/citations?user=qc6CJjYAAAAJ" } 60 | - { platform: instagram, user_url: "https://www.instagram.com/vinitshahdeo" } 61 | # - { platform: keybase, user_url: "https://keybase.io/jekyll" } 62 | - { platform: linkedin, user_url: "https://www.linkedin.com/in/vinitshahdeo" } 63 | # - { platform: microdotblog, user_url: "https://micro.blog/jekyll" } 64 | # - { platform: pinterest, user_url: "https://www.pinterest.com/jekyll" } 65 | # - { platform: stackoverflow, user_url: "https://stackoverflow.com/users/1234567/jekyll" } 66 | # - { platform: telegram, user_url: "https://t.me/jekyll" } 67 | # - { platform: twitter, user_url: "https://twitter.com/jekyllrb" } 68 | - { platform: x, user_url: "https://x.com/vinit_shahdeo" } 69 | # - { platform: youtube, user_url: "https://www.youtube.com/jekyll" } 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |

#50DaysOfJavaScript

4 | Solve one question daily to ace 🎯 your next interview!
5 | 50daysofjavascript.netlify.app 6 |

7 | 8 | 9 | 10 | 11 |


12 |
13 | 14 | Similar to the [Hactoberfest'21](https://vinitshahdeo.dev/hacktoberfest-2021) initiative, we're planning another community-led open-source initiative to help the community level up their JavaScript coding skills by solving a non-trivial problem daily. None of the questions will be tricks ━ you don’t have to worry about handling big integers or knowing how to balance a red-black tree. Every problem will be based on what you do daily as a JavaScript developer. 15 | 16 | [![#50DaysOfJavaScipt](https://badgen.net/badge/%23/50DaysOfJavaScript?&scale=1.3)](https://50daysofjavascript.netlify.app/) 17 | 18 | [Join `#50DaysOfJavaScript`](https://tinyurl.com/50DaysOfJavaScript) ━ **Solve just a single coding challenge each day to improve your JavaScript skills!** This will tentatively start from **Jan 20, 2024**. Begin any day and stick for the next 50 days to complete the challenge. **More details to follow!** ✨ 19 | 20 | **Learn more**: [50daysofjavascript.netlify.app](https://50daysofjavascript.netlify.app/) 21 | 22 | > [!NOTE] 23 | > This repository hosts the launch website of **`#50DaysOfJavaScript`** challenge which is currently deployed on [Netlify](https://50daysofjavascript.netlify.app/).

24 | > [![Netlify Status](https://api.netlify.com/api/v1/badges/32100f59-fa5f-49a1-89aa-40ecc48f002a/deploy-status)](https://app.netlify.com/sites/50daysofjavascript/deploys) 25 | 26 | ## Quick links 27 | 28 | Calling out **participants**, **mentors**, and **communities** for an open-source initiative—join us to make a difference. 29 | 30 | - ***[🏄 Join as a participant](https://forms.gle/83ZKpF4S5VEqNG6P8)*** 31 | - ***[🍿 Become a mentor](https://forms.gle/zGHWps1t7heYbcrP7)*** 32 | - ***[🚀 Collaborate as a community](https://forms.gle/oQAFMDofBtjeawhp8)*** 33 | 34 | 35 | ```javascript 36 | console.log('#50DaysOfJavaScript ━ Code awesome stuffs with @vinitshahdeo & friends!'); 37 | ``` 38 | 39 | ## Similar initiative 40 | 41 | A community-led initiative to help beginners get started with open-source during Hacktoberfest'21—[learn more](https://vinitshahdeo.dev/hacktoberfest-2021)! 42 | 43 | [![Hacktoberfest'21](https://github-readme-stats.vercel.app/api/pin/?username=vinitshahdeo&repo=Hacktoberfest2021&theme=nord)](https://github.com/vinitshahdeo/Hacktoberfest2021) 44 | 45 | ## Local development 46 | 47 | ```terminal 48 | npm i 49 | npm start 50 | ``` 51 | 52 | This is created using [create-react-app](https://legacy.reactjs.org/docs/create-a-new-react-app.html) and can be run locally in the development mode using the above commands. Open http://localhost:3000 to view it in your browser. 53 | 54 | ## Contributors 55 | 56 | - [@yashvi2001](https://github.com/yashvi2001) 57 | - [@vinitshahdeo](https://github.com/vinitshahdeo) 58 | 59 | 60 | ## Support 61 | 62 | Please help us spread the registration link among your connections—**[tinyurl.com/50DaysOfJavaScript](https://tinyurl.com/50DaysOfJavaScript)**. For any suggestions or feedback, please hit me up on [Twitter](https://twitter.com/Vinit_Shahdeo). 63 | 64 | [![Join #50DaysOfJavaScript](https://img.shields.io/badge/Join-%2350DaysOfJavaScript-EAD54D?logo=javascript&labelColor=31322E)](https://50daysofjavascript.netlify.app/) [![Twitter Follow](https://img.shields.io/twitter/follow/Vinit_Shahdeo?style=social)](https://twitter.com/Vinit_Shahdeo) 65 | -------------------------------------------------------------------------------- /public/cube.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import "./App.css"; 2 | import { useEffect, useMemo, useState } from "react"; 3 | import GitHubButtons from "./components/GitHubButtons/GitHubButtons"; 4 | 5 | const SECOND = 1000; 6 | const MINUTE = SECOND * 60; 7 | const HOUR = MINUTE * 60; 8 | const DAY = HOUR * 24; 9 | 10 | function App() { 11 | return ( 12 | <> 13 |
14 | 15 |

#50DaysOfJavaScript

16 |

17 | A community-driven open-source initiative for elevating JavaScript 18 | skills through daily, practical coding challenges tailored to 19 | real-world tasks, led by a supportive global community of developers. 20 |

21 | 27 | Join Now 28 | 29 | 30 |
31 | 36 | 37 | 38 | 43 | 44 | 45 | 50 | 51 | 52 |
53 |
54 | twitter icon 55 |

56 | Share on{" "} 57 | 62 | Twitter 63 | 64 | 65 | 66 | 67 |

68 |
69 |
70 | moon illustration 71 | cube-js illustration 72 | star-pattern-1 73 | star-pattern-2 74 | star-pattern-3 75 | star-pattern-1 76 | star-pattern-2 77 | 78 | bg-gradient-img 83 | bg-gradient-img 88 | 89 | ); 90 | } 91 | export const Timer = ({ deadline = new Date().toString() }) => { 92 | const parsedDeadline = useMemo(() => Date.parse(deadline), [deadline]); 93 | const [time, setTime] = useState(parsedDeadline - Date.now()); 94 | 95 | useEffect(() => { 96 | const interval = setInterval( 97 | () => setTime(parsedDeadline - Date.now()), 98 | 1000 99 | ); 100 | 101 | return () => clearInterval(interval); 102 | }, [parsedDeadline]); 103 | 104 | return ( 105 |
106 | {Object.entries({ 107 | Days: time / DAY, 108 | Hours: (time / HOUR) % 24, 109 | Minutes: (time / MINUTE) % 60, 110 | Seconds: (time / SECOND) % 60, 111 | }).map(([label, value]) => ( 112 |
113 |

{`${Math.floor(value)}`.padStart(2, "0")}

114 | {label} 115 |
116 | ))} 117 |
118 | ); 119 | }; 120 | 121 | export default App; 122 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600;9..40,700;9..40,800;9..40,900;9..40,1000&display=swap"); 2 | 3 | :root { 4 | --primary: #fff; 5 | --secondary: #0b0b0f; 6 | } 7 | 8 | * { 9 | box-sizing: border-box; 10 | margin: 0; 11 | padding: 0; 12 | } 13 | 14 | html { 15 | font-size: 62.5%; 16 | } 17 | 18 | html, 19 | body { 20 | background: var(--secondary); 21 | color: var(--primary); 22 | font-family: "DM Sans", sans-serif; 23 | width: 100vw; 24 | overflow-x: hidden; 25 | position: relative; 26 | z-index: -1; 27 | } 28 | 29 | .container { 30 | padding: 1.6rem; 31 | height: 100vh; 32 | display: flex; 33 | flex-direction: column; 34 | align-items: center; 35 | } 36 | 37 | .title { 38 | margin-top: 4.2rem; 39 | text-align: center; 40 | font-size: 6.4rem; 41 | font-weight: 900; 42 | } 43 | 44 | .description { 45 | color: #898ca9; 46 | text-align: center; 47 | font-size: 2rem; 48 | font-weight: 400; 49 | line-height: 130%; 50 | margin-top: 2.2rem; 51 | max-width: 80rem; 52 | } 53 | 54 | .join-button:link, 55 | .join-button:visited { 56 | display: flex; 57 | justify-content: center; 58 | align-items: center; 59 | text-decoration: none; 60 | 61 | margin-top: 3.4rem; 62 | padding: 1.4rem 3.3rem; 63 | text-align: center; 64 | font-size: 2rem; 65 | font-weight: 600; 66 | cursor: pointer; 67 | transition: 0.5s; 68 | 69 | border-radius: 1rem; 70 | color: var(--primary); 71 | border: none; 72 | background: linear-gradient(245deg, #18c8ff 8.05%, #933ffe 86.9%); 73 | } 74 | 75 | .join-button:hover, 76 | .join-button:active { 77 | box-shadow: 0px 0px 10px 6px rgba(69, 149, 254, 0.286); 78 | } 79 | 80 | .timer { 81 | display: flex; 82 | align-items: center; 83 | justify-content: center; 84 | gap: 2.6rem; 85 | margin-top: 8.2rem; 86 | } 87 | 88 | .box { 89 | width: 20rem; 90 | height: 20rem; 91 | display: flex; 92 | align-items: center; 93 | justify-content: center; 94 | flex-direction: column; 95 | gap: 2.8rem; 96 | border-radius: 2.2rem; 97 | background: #1a1b23; 98 | } 99 | 100 | .timetext { 101 | color: #fff; 102 | text-align: center; 103 | font-size: 4.8rem; 104 | font-weight: 700; 105 | } 106 | 107 | .text { 108 | text-transform: uppercase; 109 | color: #b982ff; 110 | text-align: center; 111 | font-size: 2rem; 112 | font-weight: 500; 113 | } 114 | 115 | .buttons { 116 | display: flex; 117 | justify-content: space-evenly; 118 | align-items: center; 119 | gap: 3.6rem; 120 | margin-top: 10rem; 121 | } 122 | 123 | .btn { 124 | border-radius: 1rem; 125 | padding: 2rem; 126 | background-image: linear-gradient( 127 | to right, 128 | #982dec, 129 | #da8af8, 130 | #a9c4f3, 131 | #982dec 132 | ); 133 | border: none; 134 | background-size: 200% auto; 135 | color: #fff; 136 | text-align: center; 137 | font-weight: 600; 138 | line-height: 130%; 139 | font-size: 2rem; 140 | 141 | transition: 0.5s; 142 | cursor: pointer; 143 | 144 | background-size: 300% 100%; 145 | 146 | -moz-transition: all 0.4s ease-in-out; 147 | -o-transition: all 0.4s ease-in-out; 148 | -webkit-transition: all 0.4s ease-in-out; 149 | transition: all 0.4s ease-in-out; 150 | } 151 | 152 | .btn:hover { 153 | background-position: 100% 0; 154 | -moz-transition: all 0.4s ease-in-out; 155 | -o-transition: all 0.4s ease-in-out; 156 | -webkit-transition: all 0.4s ease-in-out; 157 | transition: all 0.4s ease-in-out; 158 | } 159 | 160 | .btn:focus { 161 | outline: none; 162 | } 163 | 164 | .footer { 165 | margin-top: 10rem; 166 | display: flex; 167 | align-items: center; 168 | justify-content: center; 169 | gap: 1rem; 170 | } 171 | 172 | .footer p { 173 | color: #fff; 174 | text-align: center; 175 | font-size: 2rem; 176 | font-weight: 400; 177 | line-height: 130%; 178 | } 179 | 180 | .footer p a { 181 | display: inline-block; 182 | position: relative; 183 | text-decoration: none; 184 | color: inherit; 185 | margin: 0 var(--spacing, 0px); 186 | transition: margin 0.25s; 187 | } 188 | 189 | .footer p a svg { 190 | width: 76px; 191 | height: 40px; 192 | position: absolute; 193 | left: 50%; 194 | bottom: 0; 195 | transform: translate(-50%, 7px) translateZ(0); 196 | fill: none; 197 | stroke: var(--stroke, #bbc1e1); 198 | stroke-linecap: round; 199 | stroke-width: 2px; 200 | stroke-dasharray: var(--offset, 69px) 278px; 201 | stroke-dashoffset: 361px; 202 | transition: stroke 0.25s ease var(--stroke-delay, 0s), stroke-dasharray 0.35s; 203 | } 204 | 205 | .footer p a svg:hover { 206 | --spacing: 4px; 207 | --stroke: #7d41e7; 208 | --stroke-delay: 0.1s; 209 | --offset: 180px; 210 | } 211 | 212 | .moon, 213 | .cube, 214 | .star-1, 215 | .star-2, 216 | .star-3, 217 | .star-4, 218 | .star-5, 219 | .bg-gradient-img-1, 220 | .bg-gradient-img-2 { 221 | position: absolute; 222 | } 223 | 224 | .moon, 225 | .cube, 226 | .star-1, 227 | .star-2, 228 | .star-3, 229 | .star-4, 230 | .star-5 { 231 | z-index: -1; 232 | } 233 | 234 | .moon { 235 | top: 30%; 236 | left: 88%; 237 | } 238 | 239 | .cube { 240 | top: 65%; 241 | right: 87%; 242 | } 243 | .star-1, 244 | .star-2, 245 | .star-3, 246 | .star-4, 247 | .star-5 { 248 | animation-timing-function: ease-in-out; 249 | animation-iteration-count: infinite; 250 | animation-duration: 1.5s; 251 | } 252 | 253 | @keyframes scale-star { 254 | 0%, 255 | 100% { 256 | transform: scale(1); 257 | } 258 | 25% { 259 | transform: scale(1.8); 260 | } 261 | 50% { 262 | transform: scale(1); 263 | } 264 | } 265 | 266 | .star-1 { 267 | top: 20%; 268 | right: 85%; 269 | animation-name: scale-star; 270 | animation-delay: 1s; 271 | } 272 | 273 | .star-2 { 274 | top: 10%; 275 | left: 83%; 276 | animation-name: scale-star; 277 | animation-delay: 3s; 278 | } 279 | 280 | .star-3 { 281 | top: 90%; 282 | left: 88%; 283 | animation-name: scale-star; 284 | animation-delay: 5s; 285 | } 286 | 287 | .star-4 { 288 | top: 20%; 289 | left: 90%; 290 | animation-name: scale-star; 291 | animation-delay: 7s; 292 | } 293 | 294 | .star-5 { 295 | top: 30%; 296 | right: 92%; 297 | animation-name: scale-star; 298 | animation-delay: 9s; 299 | } 300 | 301 | .bg-gradient-img-1 { 302 | bottom: 0%; 303 | right: 0%; 304 | z-index: -2; 305 | } 306 | 307 | .bg-gradient-img-2 { 308 | top: 0%; 309 | left: 0%; 310 | z-index: -2; 311 | } 312 | 313 | @media only screen and (max-width: 924px) { 314 | .title { 315 | font-size: 5.2rem; 316 | } 317 | 318 | .description { 319 | font-size: 1.8rem; 320 | } 321 | 322 | .join-button { 323 | font-size: 1.8rem; 324 | } 325 | 326 | .timer { 327 | gap: 2rem; 328 | margin-top: 8.2rem; 329 | } 330 | 331 | .box { 332 | width: 16rem; 333 | height: 16rem; 334 | gap: 2.8rem; 335 | } 336 | 337 | .timetext { 338 | font-size: 3.6rem; 339 | } 340 | 341 | .text { 342 | font-size: 1.8rem; 343 | } 344 | 345 | .buttons { 346 | gap: 2rem; 347 | margin-top: 8rem; 348 | } 349 | 350 | .btn { 351 | font-size: 1.6rem; 352 | padding: 1.8rem; 353 | } 354 | 355 | .footer p { 356 | font-size: 1.6rem; 357 | font-weight: 400; 358 | } 359 | 360 | .footer p a svg { 361 | width: 62px; 362 | height: 40px; 363 | bottom: -10%; 364 | } 365 | 366 | .star-1, 367 | .star-2, 368 | .star-3, 369 | .star-4, 370 | .star-5 { 371 | display: none; 372 | } 373 | 374 | .moon { 375 | left: 83%; 376 | } 377 | } 378 | 379 | @media only screen and (max-width: 720px) { 380 | .title { 381 | font-size: 4.8rem; 382 | } 383 | 384 | .description { 385 | margin-left: 1.6rem; 386 | margin-right: 1.6rem; 387 | font-size: 1.6rem; 388 | } 389 | 390 | .join-button { 391 | font-size: 1.6rem; 392 | } 393 | 394 | .timer { 395 | gap: 1.6rem; 396 | } 397 | 398 | .box { 399 | width: 12rem; 400 | height: 12rem; 401 | gap: 1.6rem; 402 | } 403 | 404 | .timetext { 405 | font-size: 2.6rem; 406 | } 407 | 408 | .text { 409 | font-size: 1.4rem; 410 | } 411 | 412 | .buttons { 413 | flex-direction: column; 414 | gap: 1.8rem; 415 | margin-top: 6rem; 416 | width: fit-content; 417 | align-items: stretch; 418 | } 419 | 420 | .btn { 421 | width: 100%; 422 | } 423 | } 424 | 425 | @media only screen and (max-width: 548px) { 426 | .title { 427 | font-size: 3.2rem; 428 | } 429 | 430 | .box { 431 | width: 10rem; 432 | height: 10rem; 433 | gap: 1.2rem; 434 | } 435 | 436 | .timetext { 437 | font-size: 2rem; 438 | } 439 | 440 | .text { 441 | font-size: 1.2rem; 442 | } 443 | 444 | .buttons { 445 | gap: 1.6rem; 446 | } 447 | 448 | .btn { 449 | font-size: 1.6rem; 450 | padding: 1.6rem; 451 | } 452 | 453 | .star-3, 454 | .moon { 455 | display: none; 456 | } 457 | 458 | .footer { 459 | margin-top: 6rem; 460 | } 461 | } 462 | 463 | @media only screen and (max-width: 458px) { 464 | .timer { 465 | margin-top: 5.6rem; 466 | gap: 1rem; 467 | } 468 | 469 | .box { 470 | width: 9rem; 471 | height: 9rem; 472 | } 473 | 474 | .buttons { 475 | margin-top: 5.4rem; 476 | } 477 | } 478 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 44 | 45 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 62 | 63 | 72 | 50 Days Of JavaScript 73 | 254 | 255 | 256 | 257 |
258 | 268 | 269 | 270 | -------------------------------------------------------------------------------- /public/bg-gradient-img-1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | --------------------------------------------------------------------------------