├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── pull_request_template.md
├── .vscode
├── launch.json
└── settings.json
├── LICENSE
├── README.md
├── banner.png
├── day-01
├── README.md
├── index.html
├── main.js
├── preview
│ └── preview.jpg
└── style.css
├── day-02
├── README.md
├── app.js
├── index.html
├── preview
│ └── preview.jpg
└── style.css
├── day-03
├── README.md
├── app.js
├── index.html
├── preview
│ └── preview.jpg
└── style.css
├── day-04
├── README.md
├── app.js
├── index.html
├── preview
│ └── preview.jpg
└── style.css
├── day-05
├── README.md
├── app.js
├── index.html
├── preview
│ └── preview.jpg
└── style.css
├── day-06
├── README.md
├── index.html
├── preview
│ └── preview.jpg
└── style.css
├── day-07
├── README.md
├── img
│ ├── img-1-min.jpg
│ ├── img-2-min.jpg
│ ├── img-3-min.jpg
│ ├── img-4-min.jpg
│ ├── img-5-min.jpg
│ └── img-6-min.jpg
├── index.html
├── preview
│ └── preview.jpg
└── style.css
├── day-08
├── README.md
├── index.html
├── main.js
├── preview
│ └── preview.jpg
└── style.css
├── day-09
├── README.md
├── index.html
├── main.js
├── preview
│ └── preview.png
└── style.css
├── day-10
├── README.md
├── arrow.svg
├── index.html
├── main.js
├── preview
│ └── preview.png
└── style.css
├── day-11
├── README.md
├── index.html
├── main.js
├── preview
│ └── preview.png
└── style.css
├── day-12
├── img
│ ├── img-1.jpg
│ ├── img-2.jpg
│ ├── img-3.jpg
│ └── img-4.jpg
├── index.html
└── style.css
├── day-13
├── img
│ └── clock-bg.png
├── index.html
├── main.js
└── style.css
├── day-14
├── bg-color-change
│ ├── index.html
│ ├── main.js
│ └── style.css
└── password-generator
│ ├── index.html
│ ├── main.js
│ └── styles.css
├── day-15
├── index.html
├── main.js
└── style.css
├── day-16
├── index.html
└── style.css
├── day-17
├── index.html
└── style.css
├── day-18
├── img-1.jpg
├── img-2.jpg
├── img-3.jpg
├── index.html
├── main.js
└── style.css
├── day-19
├── index.html
├── main.js
└── style.css
├── day-20
├── index.html
├── main.js
└── style.css
├── day-21
├── CSS-loading-animation
│ ├── index.html
│ └── style.css
└── OTP-UI
│ ├── index.html
│ ├── main.js
│ └── styles.css
├── day-22
├── img-1.jpg
├── index.html
├── main.js
└── style.css
├── day-23
├── index.html
└── style.css
├── day-24
├── index.html
├── main.js
└── style.css
├── day-25
├── img
│ ├── img-1.jpg
│ ├── img-2.jpg
│ ├── img-3.jpg
│ └── img-4.jpg
├── index.html
├── main.js
├── oop.js
└── style.css
├── day-26
├── canvas.js
├── dvd.svg
├── index.html
├── main.js
└── style.css
├── day-27
├── index.html
├── main.js
├── placeholder.png
└── style.css
├── day-28
├── index.html
├── main.js
└── style.css
├── day-29
├── bg.jpg
├── index.html
├── mian.js
└── style.css
└── day-30
├── index.html
└── style.css
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug, invalid
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
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 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | # Related Issue
2 | - issue goes here
3 |
4 | # Proposed Changes
5 | - your changes here
6 |
7 | # Additional Info
8 | - Any additional info will go here
9 |
10 | # Screenshots
11 | Original | Updated
12 | :---------------: | :-----------------:
13 | ** Original Screenshot ** | ** Updated Screenshot **
14 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 |
8 |
9 | {
10 | "type": "pwa-chrome",
11 | "request": "launch",
12 | "name": "Launch Chrome against localhost",
13 | "url": "http://localhost:8080",
14 | "webRoot": "${workspaceFolder}"
15 | }
16 | ]
17 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "liveServer.settings.port": 5501
3 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Shaif Arfan
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # 30days30submits
4 |
5 | ## This challenge is started on July 21, 2020 📅
6 |
7 | ### In this challenge, I submitted 30 little to medium size projects. Sometimes I did a little website component or sometimes some javaScript app as a submit. I did it to boost my HTML, CSS & JS skills. Down here you will find all the live previews and youTube videos (how I made it). Also here is the full playlist for this #30days30submits challenge => [playlist](https://www.youtube.com/playlist?list=PLRv_Gd5w9e7m7wokXmB9fGtGYw100UKc0).
8 |
9 | | day | Project Name | source Code/preview | YouTube Video |
10 | | :----- | :----------------------------: | --------------------------------------------------------------: | ---------------------------: |
11 | | day-1 | Custom Cursor | https://codepen.io/Web_Cifar/pen/OJMrzaB | https://youtu.be/de4W0EHMuUs |
12 | | day-2 | Theme Switcher | https://codepen.io/Web_Cifar/pen/OJMrdbq | https://youtu.be/D1yg4T37qYo |
13 | | day-3 | Random Dad Jokes Generator | https://codepen.io/Web_Cifar/pen/XWXOZWX | https://youtu.be/UDIfuvLEkjU |
14 | | day-4 | Numbers API | https://codepen.io/Web_Cifar/pen/PoZLpoG | https://youtu.be/s3LFCErzmHI |
15 | | day-5 | Countdown Timer | https://codepen.io/Web_Cifar/pen/OJMGPbb | https://youtu.be/_a4XCarxwr8 |
16 | | day-6 | Featured Section | https://codepen.io/Web_Cifar/pen/WNrWxYG | https://youtu.be/L4k3_elYm2U |
17 | | day-7 | Photo gallery p-1 | https://codepen.io/Web_Cifar/pen/wvMbwdj | https://youtu.be/URymtcPO11A |
18 | | day-8 | Photo gallery p-2 [Pexels API] | https://github.com/ShaifArfan/30days30submits/tree/master/day-8 | https://youtu.be/gGBpmzLN1Hw |
19 | | day-9 | Read More Button | https://codepen.io/Web_Cifar/pen/OJMeVxx | https://youtu.be/TvVY8c1uvG8 |
20 | | day-10 | key Code Generator App | https://codepen.io/Web_Cifar/pen/eYJwvKV | https://youtu.be/jOLwRV6xSwA |
21 | | day-11 | CSS animated Menu | https://codepen.io/Web_Cifar/pen/eYJqdxy | https://youtu.be/q8vmz-R_3Ck |
22 | | day-12 | CSS Flex Gallery | https://codepen.io/Web_Cifar/pen/wvMVmZN | https://youtu.be/Z6IZ2NOEzmw |
23 | | day-13 | Analog Clock | https://codepen.io/Web_Cifar/pen/LYNYmpb | https://youtu.be/6xEQ_jA5V2Y |
24 | | day-14 | Digital Clock | https://codepen.io/Web_Cifar/pen/MWyYaBP | https://youtu.be/gmNhRyxAPpw |
25 | | day-14 | Password Generator App | https://codepen.io/Web_Cifar/pen/wvMVYVP | https://youtu.be/zmLxhLOVB1M |
26 | | day-15 | BG Color Changer | https://codepen.io/Web_Cifar/pen/dyMPmwY | https://youtu.be/Yem8T8azZko |
27 | | day-16 | Basic Tooltips | https://codepen.io/Web_Cifar/pen/PoNqwNJ | https://youtu.be/MXRxahbJX3A |
28 | | day-17 | Scroll Down Button | https://codepen.io/Web_Cifar/pen/WNwvOaE | https://youtu.be/LY1jeQGUiAI |
29 | | day-18 | Advance Tooltips | https://codepen.io/Web_Cifar/pen/yLOYoPR | https://youtu.be/e_jEquJo7y8 |
30 | | day-19 | Full Functional Html Form | https://codepen.io/Web_Cifar/pen/gOrrPpO | https://youtu.be/vc9rgFHr098 |
31 | | day-20 | Multi Step Form | https://codepen.io/Web_Cifar/pen/PoNNEYY | https://youtu.be/cKTgIDkRsGc |
32 | | day-21 | CSS Loading animation | https://codepen.io/Web_Cifar/pen/jOqqRPM | https://youtu.be/E_jOrp4t0N4 |
33 | | day-21 | OTP UI | https://codepen.io/Web_Cifar/pen/BarOKgO | https://youtu.be/ZVV2UM4hzIE |
34 | | day-22 | Food Recipe App | https://codepen.io/Web_Cifar/pen/oNxLYRY | https://youtu.be/x8EY0BlhPGk |
35 | | day-23 | Neon Light Effect | https://codepen.io/Web_Cifar/pen/MWyJENV | https://youtu.be/NLtUycloTnc |
36 | | day-24 | Speech Recognition App | https://codepen.io/Web_Cifar/pen/jOqBEjE | https://youtu.be/-k-PgvbktX4 |
37 | | day-25 | Custom Slider | https://codepen.io/Web_Cifar/pen/bGpRwEr | https://youtu.be/V9TCxMMpGhI |
38 | | day-26 | Bouncing DVD logo | https://codepen.io/Web_Cifar/pen/JjXrLRJ | https://youtu.be/wMIARRCox9k |
39 | | day-27 | Quiz APP | https://codepen.io/Web_Cifar/pen/dyMZxNg | https://youtu.be/qXXM9nVxLWk |
40 | | day-28 | Simple Calculator | https://codepen.io/Web_Cifar/pen/XWdVgXr | https://youtu.be/0Vg4EiYPCUc |
41 | | day-29 | Weather APP | https://codepen.io/Web_Cifar/pen/gOrvMpR | https://youtu.be/y0iCeKUsYMk |
42 | | day-30 | CSS Dot Loaders | https://codepen.io/Web_Cifar/pen/rNevXPx | https://youtu.be/ENa4y_-fJAs |
43 |
44 | ---
45 |
46 | ### Made with ❤️ by [Shaif Arfan](https://www.instagram.com/shaifarfan08/)
47 |
48 | Like my works and want to support me?
49 |
50 |
51 |
52 | ---
53 |
54 | ## Other projects
55 |
56 | 📚 [All Web Cifar Project Tutorials](https://github.com/ShaifArfan/wc-project-tutorials)
57 |
--------------------------------------------------------------------------------
/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/banner.png
--------------------------------------------------------------------------------
/day-01/README.md:
--------------------------------------------------------------------------------
1 | ## Submit Name : Custom Cursor
2 |
3 | ### Submit Preview ⬇:
4 |
5 | 
--------------------------------------------------------------------------------
/day-01/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 | Hi there, How are you?
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/day-01/main.js:
--------------------------------------------------------------------------------
1 | const cursor = document.querySelector('.cursor');
2 |
3 | window.addEventListener('mousemove', (e) => {
4 | cursor.style.left = e.pageX + 'px';
5 | cursor.style.top = e.pageY + 'px';
6 | cursor.setAttribute('data-fromTop', (cursor.offsetTop - scrollY));
7 | // console.log(e)
8 | });
9 | window.addEventListener('scroll', () => {
10 | const fromTop = cursor.getAttribute('data-fromTop');
11 | cursor.style.top = scrollY + parseInt(fromTop) + 'px';
12 | console.log(scrollY);
13 | });
14 | window.addEventListener('click', () => {
15 | if (cursor.classList.contains('click')) {
16 | cursor.classList.remove("click");
17 | void cursor.offsetWidth; // trigger a DOM reflow
18 | cursor.classList.add("click");
19 | } else {
20 | cursor.classList.add("click");
21 | }
22 | });
--------------------------------------------------------------------------------
/day-01/preview/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-01/preview/preview.jpg
--------------------------------------------------------------------------------
/day-01/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | *{
7 | cursor: none;
8 | }
9 | body{
10 | overflow-x: hidden;
11 | }
12 | section{
13 | min-height: 100vh;
14 | background-color: rgb(41, 42, 46);
15 | width: 100%;
16 | display: flex;
17 | align-items: center;
18 | justify-content: center;
19 | color: white;
20 | }
21 | .cursor{
22 | position: absolute;
23 | top: 0;
24 | left: 0;
25 | /* border: 2px solid white; */
26 | /* background-color: rgba(255, 255, 255, 0.356); */
27 | height: 30px;
28 | width: 30px;
29 | border-radius: 50px;
30 | transform: translate(-50%, -50%);
31 | pointer-events: none;
32 | }
33 | .cursor::after,.cursor::before{
34 | content: '';
35 | position: absolute;
36 | top: 50%;
37 | left: 50%;
38 | transform: translate(-50%, -50%);
39 | background-color: white;
40 | height: 10px;
41 | width: 10px;
42 | border-radius: 50px;
43 | }
44 | .cursor::before{
45 | background-color: rgb(255, 255, 255);
46 | }
47 | .cursor.click::before{
48 | animation: click 1s ease forwards;
49 | background-color: rgb(255, 255, 255);
50 | }
51 | @keyframes click{
52 | 0%{
53 | opacity: 1;
54 | transform:translate(-50%, -50%) scale(1);
55 | }
56 | 100%{
57 | opacity: 0;
58 | transform: translate(-50%, -50%) scale(7);
59 | }
60 | }
--------------------------------------------------------------------------------
/day-02/README.md:
--------------------------------------------------------------------------------
1 | ## Submit Name: CSS Theme Switcher
2 |
3 | ### preview 👇
4 |
5 | 
--------------------------------------------------------------------------------
/day-02/app.js:
--------------------------------------------------------------------------------
1 | const input = document.querySelector('.theme-switcher input');
2 |
3 | input.addEventListener('change', (e) => {
4 | if (e.target.checked) {
5 | document.body.setAttribute('data-theme', 'dark');
6 | } else {
7 | document.body.setAttribute('data-theme', 'light');
8 | }
9 | })
--------------------------------------------------------------------------------
/day-02/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
14 |
This is a title
15 |
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quos maiores atque dolorum voluptatum laudantium id
16 | adipisci quisquam ea laborum sed ipsam quam aspernatur ratione architecto numquam, aperiam recusandae ducimus
17 | aliquid ut enim culpa quis minus! Autem id, recusandae incidunt maiores non saepe dolor ullam perspiciatis!
18 | Nulla nemo sequi vero et.
19 |
Hello!
20 |
21 |
22 |
23 |
24 | switch
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/day-02/preview/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-02/preview/preview.jpg
--------------------------------------------------------------------------------
/day-02/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | body{
7 | font-family: 'Montserrat';
8 | color: var(--color-4);
9 | }
10 | body[data-theme="light"]{
11 | --color-1:rgb(196, 220, 241);
12 | --color-2: white;
13 | --color-3: white;
14 | --color-4: rgb(80, 82, 110);
15 | }
16 | body[data-theme="dark"]{
17 | --color-1:#1E1F26;
18 | --color-2: #292c33;
19 | --color-3: rgb(39, 40, 42);
20 | --color-4: rgb(186, 186, 202);
21 | }
22 |
23 | section{
24 | background-color: var(--color-1);
25 | min-height: 100vh;
26 | width: 100%;
27 | display: flex;
28 | justify-content: center;
29 | align-items: center;
30 | }
31 | .container{
32 | width: 90%;
33 | margin: 0 auto;
34 | background-color: var(--color-2);
35 | border-radius: 8px;
36 | padding: 20px;
37 | max-width: 500px;
38 | }
39 | h1{
40 | font-size: 30px;
41 | font-weight: 500;
42 | text-transform: uppercase;
43 | }
44 | p{
45 | margin-top: 10px;
46 | font-size: 16px;
47 | font-weight: 500;
48 | letter-spacing: 1px;
49 | line-height: 25px;
50 | }
51 | button{
52 | background-color: var(--color-4);
53 | padding: 10px 30px;
54 | border: none;
55 | font-size: 24px;
56 | text-transform: uppercase;
57 | color: var(--color-3);
58 | border-radius:4px ;
59 | margin-top: 20px;
60 | cursor: pointer;
61 | }
62 | .theme-switcher{
63 | position: absolute;
64 | right: 30px;
65 | top: 10px;
66 | }
67 | input{
68 | width: 0;
69 | height: 0;
70 | display: none;
71 | visibility: hidden;
72 | }
73 | label{
74 | cursor: pointer;
75 | display: block;
76 | text-indent: -9999px;
77 | height: 30px;
78 | width: 60px;
79 | border-radius: 50px;
80 | background-color: rgb(255, 255, 255);
81 | transition: .5s ease background-color;
82 | }
83 | label::after{
84 | position: absolute;
85 | content: '';
86 | width: 20px;
87 | height: 20px;
88 | border-radius: 50px;
89 | top: 50%;
90 | left: 5px;
91 | transform: translateY( -50%);
92 | background-color: rgb(46, 42, 68);
93 | transition: .5s ease;
94 | }
95 | input:checked + label::after{
96 | /* left: calc(100% - 2.5px); */
97 | left: calc(100% - 25px);
98 | background-color: aliceblue;
99 | }
100 | input:checked + label{
101 | background-color: rgb(25, 26, 37);
102 | border: 2px solid whitesmoke;
103 | }
--------------------------------------------------------------------------------
/day-03/README.md:
--------------------------------------------------------------------------------
1 | ## Submit Name: Dad Jokes Generator
2 |
3 | ### preview 👇
4 |
5 | 
--------------------------------------------------------------------------------
/day-03/app.js:
--------------------------------------------------------------------------------
1 | const button = document.querySelector('.container button');
2 | const jokeDiv = document.querySelector('.container .joke p');
3 |
4 | document.addEventListener('DOMContentLoaded', getJoke)
5 |
6 | button.addEventListener('click', getJoke);
7 |
8 | function getJoke(){
9 | fetch('https://icanhazdadjoke.com/', {
10 | headers: {
11 | 'Accept': 'application/json'
12 | }})
13 | .then(data => data.json())
14 | .then(obj => jokeDiv.innerHTML = obj.joke);
15 | }
16 |
17 | // async function getJoke(){
18 | // const jokeData = await fetch('https://icanhazdadjoke.com/', {
19 | // headers:{
20 | // 'Accept': 'application/json'
21 | // }
22 | // });
23 | // const jokeObj = await jokeData.json();
24 | // jokeDiv.innerHTML = jokeObj.joke;
25 | // console.log(jokeData);
26 | // }
--------------------------------------------------------------------------------
/day-03/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Random Dad Jocks
7 |
8 |
9 |
10 |
11 | Random Dad Jokes Generator
12 |
13 |
14 |
Get a Dad Joke
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/day-03/preview/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-03/preview/preview.jpg
--------------------------------------------------------------------------------
/day-03/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;700&display=swap');
2 | *{
3 | padding: 0;
4 | margin: 0;
5 | box-sizing: border-box;
6 | }
7 | html{
8 | font-family: 'Montserrat';
9 | font-size: 10px;
10 | }
11 | body{
12 | background-color: rgb(37, 38, 39);
13 | color: white;
14 | }
15 | section{
16 | min-height: 100vh;
17 | width: 100%;
18 | padding: 100px 0;
19 | display: flex;
20 | align-items: center;
21 | justify-content: center;
22 | }
23 | .title{
24 | position: absolute;
25 | top: 50px;
26 | font-size: 3rem;
27 | font-weight: 700;
28 | text-align: center;
29 | }
30 | .container{
31 | width: 90%;
32 | max-width: 500px;
33 | margin: 0 auto;
34 | background-color: rgb(51, 55, 59);
35 | border-radius: 8px;
36 | padding: 3rem;
37 | display: flex;
38 | flex-direction: column
39 | }
40 | .container p{
41 | font-size: 2rem;
42 | font-weight: 300;
43 | line-height: 3rem;
44 | text-align: justify;
45 | }
46 | button{
47 | margin-top: 40px;
48 | width: fit-content;
49 | padding: 2rem;
50 | font-size: 2rem;
51 | background-color: rgb(25, 28, 29);
52 | color: white;
53 | border: none;
54 | border-radius: 4px;
55 | cursor: pointer;
56 | align-self: flex-end;
57 | }
--------------------------------------------------------------------------------
/day-04/README.md:
--------------------------------------------------------------------------------
1 | ## Submit Name: Number Api
2 |
3 | API URL: http://numbersapi.com/
4 |
5 | ### preview 👇
6 |
7 | 
--------------------------------------------------------------------------------
/day-04/app.js:
--------------------------------------------------------------------------------
1 | const form = document.querySelector('form');
2 | const factDiv = document.querySelector('.number-fact');
3 |
4 | form.addEventListener('submit', (e) => {
5 | e.preventDefault();
6 | const loadText ="wait a little bit ⌛";
7 | factDiv.innerHTML = loadText;
8 | const baseURL = "https://cors-anywhere.herokuapp.com/http://numbersapi.com/";
9 | const number = e.target.querySelector('input[type="number"]').value;
10 | fetch(baseURL + number,{
11 | headers:{
12 | 'x-requested-with': 'text/plain'
13 | }})
14 | .then(response => response.text())
15 | .then(text => factDiv.innerHTML = text)
16 | .catch(e=>console.log(e));
17 | })
--------------------------------------------------------------------------------
/day-04/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NumbersAPI
7 |
8 |
9 |
10 |
11 |
12 |
16 |
Give a number and i will tell you a interesting fact 😎.
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/day-04/preview/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-04/preview/preview.jpg
--------------------------------------------------------------------------------
/day-04/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Nunito&display=swap');
2 | *{
3 | padding: 0;
4 | margin: 0;
5 | box-sizing: border-box;
6 | }
7 | html{
8 | font-size: 10px;
9 | font-family: 'Nunito', sans-serif;
10 | }
11 | body{
12 | background-color: rgb(28, 27, 34);
13 | color: white;
14 | min-height: 100vh;
15 | display: flex;
16 | align-items: center;
17 | justify-content: center;
18 | }
19 | section{
20 | width: 100%;
21 | }
22 | .container{
23 | width: 90%;
24 | max-width: 450px;
25 | margin: 0 auto;
26 | }
27 | form,.number-fact{
28 | width: 100%;
29 | background-color: rgb(42, 41, 42);
30 | padding: 20px;
31 | border-radius: 8px;
32 | }
33 | input[type="number"]{
34 | width: 70%;
35 | height: 40px;
36 | border-radius: 4px;
37 | outline: none;
38 | border: none;
39 | background-color: #3a3a3b;
40 | font-size: 24px;
41 | color: aliceblue;
42 | padding-left: 10px;
43 | }
44 | input[type="number"]::placeholder{
45 | font-size: 24px;
46 | font-family: "Nunito";
47 | font-weight: 400;
48 | }
49 | button{
50 | display: inline-block;
51 | width: 25%;
52 | font-size: 24px;
53 | height: 40px;
54 | background-color:#3a3a3b;
55 | color: aliceblue;
56 | border: none;
57 | outline: none;
58 | cursor: pointer;
59 | margin-left: 10px;
60 | border-radius: 4px;
61 | }
62 | .number-fact{
63 | margin-top: 20px;
64 | height: auto;
65 | font-size: 20px;
66 | }
67 | @media only screen and (max-width: 678px){
68 | form button{
69 | font-size: 18px;
70 | }
71 | }
--------------------------------------------------------------------------------
/day-05/README.md:
--------------------------------------------------------------------------------
1 | ## Submit Name: Countdown Timer
2 |
3 | ### preview 👇
4 |
5 | 
--------------------------------------------------------------------------------
/day-05/app.js:
--------------------------------------------------------------------------------
1 | let timeSecond = 5;
2 | const timeH = document.querySelector('h1');
3 |
4 | displayTime(5);
5 |
6 | const countDown = setInterval(()=>{
7 | timeSecond--;
8 | displayTime(timeSecond);
9 | if(timeSecond == 0 || timeSecond < 1){
10 | endCount();
11 | clearInterval(countDown);
12 | }
13 | }, 1000);
14 |
15 | function displayTime(second){
16 | const min = Math.floor(second / 60);
17 | const sec = Math.floor(second % 60);
18 | timeH.innerHTML = `
19 | ${(min < 10) ? '0' : ''}${min}:${(sec < 10) ? '0' : ''}${sec}
20 | `;
21 | }
22 |
23 | function endCount(){
24 | timeH.innerHTML = 'Time out';
25 | }
--------------------------------------------------------------------------------
/day-05/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
12 |
00:00
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/day-05/preview/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-05/preview/preview.jpg
--------------------------------------------------------------------------------
/day-05/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | margin: 0;
3 | padding: 0;
4 | box-sizing: border-box;
5 | }
6 |
7 | section{
8 | height: 100vh;
9 | width: 100%;
10 | display: flex;
11 | align-items: center;
12 | justify-content: center;
13 | }
14 | h1{
15 | font-family: 'Montserrat';
16 | font-size: 90px;
17 | }
--------------------------------------------------------------------------------
/day-06/README.md:
--------------------------------------------------------------------------------
1 | ## Submit Name : Featured Section
2 |
3 | Sketch Link : https://uidesigndaily.com/posts/sketch-links-navigation-card-cards-day-1128
4 |
5 | ### preview 👇
6 |
7 | 
--------------------------------------------------------------------------------
/day-06/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Feature Section
7 |
8 |
9 |
10 |
11 |
12 |
Programmatically or manually monitor, protect, and report your data
13 |
14 |
15 |
16 |
17 |
collections
18 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam quas officia ducimus. Dicta, culpa iure.
19 |
20 |
21 |
22 |
Items
23 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam quas officia ducimus. Dicta, culpa iure.
24 |
25 |
26 |
27 |
collections
28 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam quas officia ducimus. Dicta, culpa iure.
29 |
30 |
31 |
32 |
collections
33 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam quas officia ducimus. Dicta, culpa iure.
34 |
35 |
36 |
37 |
From our blog
38 |
39 |
Expanding support for JCB payments
40 |
Jane Wagner
41 |
42 |
43 |
Expanding support for JCB payments
44 |
Jane Wagner
45 |
46 |
47 |
Expanding support for JCB payments
48 |
Jane Wagner
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/day-06/preview/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-06/preview/preview.jpg
--------------------------------------------------------------------------------
/day-06/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;900&display=swap');
2 |
3 | *{
4 | padding: 0;
5 | margin: 0;
6 | box-sizing: border-box;
7 | }
8 | /* colors */
9 | body{
10 | --color-1: #2F3144;
11 | --color-2: white;
12 | --color-3:#FFBC00;
13 | --color-4:#DA8F00;
14 | --color-5: #E7E8EC;
15 | --color-6:#F1F2F7;
16 | }
17 | html{
18 | font-family: 'Nunito', sans-serif;
19 | font-size: 10px;
20 | }
21 | section{
22 | min-height: 100vh;
23 | width: 100%;
24 | background-color: var(--color-2);
25 | display: flex;
26 | align-items: center;
27 | justify-content: center;
28 | }
29 | .container{
30 | padding: 100px 30px;
31 | width: 100%;
32 | max-width: 1200px;
33 | }
34 | .container .head h1{
35 | font-size: 24px;
36 | font-weight: 700;
37 | line-height: 25px;
38 | color: var(--color-1);
39 | margin-bottom: 50px;
40 | max-width: 700px;
41 | }
42 | .container .main{
43 | display: flex;
44 | flex-direction: column;
45 | }
46 | .left .card{
47 | width: 100%;
48 | padding: 40px 20px;
49 | border-radius: 10px;
50 | transition: .3s ease background-color;
51 | margin-bottom: 20px;
52 | }
53 | .left .card ion-icon{
54 | padding: 15px;
55 | background-color: var(--color-3);
56 | border-radius: 50%;
57 | font-size: 25px;
58 | color: white;
59 | }
60 | .left .card h2{
61 | font-size: 20px;
62 | font-weight: 700;
63 | text-transform: capitalize;
64 | color: var(--color-1);
65 | margin: 10px 0;
66 | }
67 | .left .card p{
68 | font-size: 16px;
69 | font-weight: 400;
70 | }
71 | .left .card:hover{
72 | background-color: var(--color-3);
73 | }
74 | .left .card:hover ion-icon{
75 | color: var(--color-1);
76 | background-color: var(--color-2);
77 | }
78 |
79 | .right{
80 | border: 1px solid var(--color-5);
81 | border-radius: 10px;
82 | padding: 20px;
83 | }
84 | .right h1{
85 | font-size: 22px;
86 | font-weight: 700;
87 | padding-left: 20px;
88 | }
89 | .right .blog-item{
90 | padding: 10px 20px;
91 | margin-top: 20px;
92 | cursor: pointer;
93 | }
94 | .right h3{
95 | font-size: 18px;
96 | font-weight: 700;
97 | }
98 | .right p{
99 | color: var(--color-4);
100 | font-size: 16px;
101 | font-weight: 400;
102 | }
103 | .right .blog-item:hover{
104 | background-color: var(--color-5);
105 | border-radius: 8px;
106 | }
107 | @media only screen and (min-width: 700px){
108 | .container .main{
109 | flex-direction: row;
110 | }
111 | .container .left{
112 | flex: .7;
113 | display: grid;
114 | grid-template:1fr 1fr / 1fr 1fr ;
115 | grid-gap: 20px;
116 | }
117 | .container .right{
118 | flex: .3;
119 | margin: 30px;
120 | }
121 | .container .main .card{
122 | width: 100%;
123 | }
124 | .container .head h1{
125 | font-size: 34px;
126 | font-weight: 900;
127 | line-height: 50px;
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/day-07/README.md:
--------------------------------------------------------------------------------
1 | ## Submit Name: Photo Gallery Part-1
2 |
3 | Sketch Design: https://uidesigndaily.com/posts/sketch-stock-photos-page-website-mockup-list-image-day-1132
4 |
5 | 
--------------------------------------------------------------------------------
/day-07/img/img-1-min.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-07/img/img-1-min.jpg
--------------------------------------------------------------------------------
/day-07/img/img-2-min.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-07/img/img-2-min.jpg
--------------------------------------------------------------------------------
/day-07/img/img-3-min.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-07/img/img-3-min.jpg
--------------------------------------------------------------------------------
/day-07/img/img-4-min.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-07/img/img-4-min.jpg
--------------------------------------------------------------------------------
/day-07/img/img-5-min.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-07/img/img-5-min.jpg
--------------------------------------------------------------------------------
/day-07/img/img-6-min.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-07/img/img-6-min.jpg
--------------------------------------------------------------------------------
/day-07/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Photo gallery UI
7 |
8 |
9 |
10 |
11 |
12 |
19 |
20 |
26 |
32 |
38 |
44 |
50 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/day-07/preview/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-07/preview/preview.jpg
--------------------------------------------------------------------------------
/day-07/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;900&display=swap');
2 | *{
3 | margin: 0;
4 | padding: 0;
5 | box-sizing: border-box;
6 | }
7 | html{
8 | font-family: 'Montserrat', sans-serif;
9 | font-size: 100%;
10 | }
11 | body{
12 | background-color: #DBE2E9;
13 | }
14 | img{
15 | width: 100%;
16 | height: 100%;
17 | object-fit: cover;
18 | }
19 | section{
20 | min-height:100vh;
21 | width: 100%;
22 | display: flex;
23 | align-items: center;
24 | justify-content: center;
25 | margin: 100px 0;
26 | }
27 | .container{
28 | background-color: white;
29 | width: 90%;
30 | max-width: 900px;
31 | margin: 0 auto;
32 | box-shadow: 0px 0px 61px 7px #5e849c40;
33 | padding: 50px 20px;
34 | border-radius: 20px;
35 | }
36 | .header{
37 | display: flex;
38 | flex-direction: column;
39 | align-items: center;
40 | }
41 | .header h1{
42 | font-size: 40px;
43 | font-weight: 900;
44 | letter-spacing: -2px;
45 | }
46 | form{
47 | margin-top: 30px;
48 | width: 80%;
49 | max-width: 300px;
50 | position: relative;
51 | }
52 | input{
53 | border: none;
54 | border-bottom: 2px solid rgba(128, 128, 128, 0.479);
55 | font-size: 20px;
56 | width: 100%;
57 | outline: none;
58 | color: gray;
59 | background-color: transparent;
60 | }
61 | input::placeholder{
62 | opacity: .5;
63 | color: gray;
64 | font-family: 'Montserrat';
65 | }
66 | form ion-icon{
67 | position: absolute;
68 | right: 0;
69 | font-size: 20px;
70 | opacity: .5;
71 | color: gray;
72 | }
73 | .gallery{
74 | width: 100%;
75 | display: grid;
76 | grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) ;
77 | margin-top: 50px;
78 | grid-gap: 20px;
79 | }
80 | .item{
81 | width: 100%;
82 | height: 300px;
83 | position: relative;
84 | overflow: hidden;
85 | border-radius:8px;
86 | transition: .3s ease box-shadow;
87 | }
88 |
89 | .item:hover{
90 | box-shadow: 0px 0px 20px 3px #00000042;
91 | }
92 | .item:nth-last-child(1){
93 | margin-bottom: 0;
94 | }
95 | .item h3{
96 | width: 100%;
97 | padding: 20px;
98 | position: absolute;
99 | background-color: #00000040;
100 | color: aliceblue;
101 | bottom: -70px;
102 | font-weight: 300;
103 | transition: .5s ease-in-out bottom;
104 | }
105 | .item:hover h3{
106 | bottom: 0;
107 | }
108 | @media only screen and (min-width: 900px){
109 | .container{
110 | max-width: 1160px;
111 | padding: 100px;
112 | }
113 | .header{
114 | flex-direction: row;
115 | justify-content: space-between;
116 | }
117 | .header h1{
118 | font-size: 50px;
119 | }
120 | .header input{
121 | font-size: 24px;
122 | }
123 | .header ion-icon{
124 | font-size: 24px;
125 | }
126 | .gallery{
127 | grid-gap: 30px;
128 | }
129 |
130 | }
--------------------------------------------------------------------------------
/day-08/README.md:
--------------------------------------------------------------------------------
1 | ## Submit Name: Photo Gallery Part-2 [pixels API]
2 |
3 | Sketch Design: https://uidesigndaily.com/posts/sketch-stock-photos-page-website-mockup-list-image-day-1132
4 |
5 | 
--------------------------------------------------------------------------------
/day-08/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Photo gallery UI
7 |
8 |
9 |
10 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/day-08/main.js:
--------------------------------------------------------------------------------
1 | class PhotoGallery{
2 | constructor(){
3 | this.API_KEY = 'YOUR_API_KEY';
4 | this.galleryDIv = document.querySelector('.gallery');
5 | this.searchForm = document.querySelector('.header form');
6 | this.loadMore = document.querySelector('.load-more');
7 | this.logo = document.querySelector('.logo')
8 | this.pageIndex = 1;
9 | this.searchValueGlobal = '';
10 | this.eventHandle();
11 | }
12 | eventHandle(){
13 | document.addEventListener('DOMContentLoaded',()=>{
14 | this.getImg(1);
15 | });
16 | this.searchForm.addEventListener('submit', (e)=>{
17 | this.pageIndex = 1;
18 | this.getSearchedImages(e);
19 | });
20 | this.loadMore.addEventListener('click', (e)=>{
21 | this.loadMoreImages(e);
22 | })
23 | this.logo.addEventListener('click',()=>{
24 | this.pageIndex = 1;
25 | this.galleryDIv.innerHTML = '';
26 | this.getImg(this.pageIndex);
27 | })
28 | }
29 | async getImg(index){
30 | this.loadMore.setAttribute('data-img', 'curated');
31 | const baseURL = `https://api.pexels.com/v1/curated?page=${index}&per_page=12`;
32 | const data = await this.fetchImages(baseURL);
33 | this.GenerateHTML(data.photos)
34 | console.log(data)
35 | }
36 | async fetchImages(baseURL){
37 | const response = await fetch(baseURL, {
38 | method: 'GET',
39 | headers: {
40 | Accept: 'application/json',
41 | Authorization: this.API_KEY
42 | }
43 | });
44 | const data = await response.json();
45 | // console.log(data);
46 | return data;
47 | }
48 | GenerateHTML(photos){
49 | photos.forEach(photo=>{
50 | const item= document.createElement('div');
51 | item.classList.add('item');
52 | item.innerHTML = `
53 |
54 |
55 | ${photo.photographer}
56 |
57 | `;
58 | this.galleryDIv.appendChild(item)
59 | })
60 | }
61 | async getSearchedImages(e){
62 | this.loadMore.setAttribute('data-img', 'search');
63 | e.preventDefault();
64 | this.galleryDIv.innerHTML='';
65 | const searchValue = e.target.querySelector('input').value;
66 | this.searchValueGlobal = searchValue;
67 | const baseURL = `https://api.pexels.com/v1/search?query=${searchValue}&page=1&per_page=12`
68 | const data = await this.fetchImages(baseURL);
69 | this.GenerateHTML(data.photos);
70 | e.target.reset();
71 | }
72 | async getMoreSearchedImages(index){
73 | // console.log(searchValue)
74 | const baseURL = `https://api.pexels.com/v1/search?query=${this.searchValueGlobal}&page=${index}&per_page=12`
75 | const data = await this.fetchImages(baseURL);
76 | console.log(data)
77 | this.GenerateHTML(data.photos);
78 | }
79 | loadMoreImages(e){
80 | let index = ++this.pageIndex;
81 | const loadMoreData = e.target.getAttribute('data-img');
82 | if(loadMoreData === 'curated'){
83 | // load next page for curated]
84 | this.getImg(index)
85 | }else{
86 | // load next page for search
87 | this.getMoreSearchedImages(index);
88 | }
89 | }
90 | }
91 |
92 | const gallery = new PhotoGallery;
--------------------------------------------------------------------------------
/day-08/preview/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-08/preview/preview.jpg
--------------------------------------------------------------------------------
/day-08/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;500;900&display=swap');
2 | *{
3 | margin: 0;
4 | padding: 0;
5 | box-sizing: border-box;
6 | }
7 | html{
8 | font-family: 'Montserrat', sans-serif;
9 | font-size: 100%;
10 | }
11 | body{
12 | background-color: #DBE2E9;
13 | }
14 | img{
15 | width: 100%;
16 | height: 100%;
17 | object-fit: cover;
18 | }
19 | section{
20 | min-height:100vh;
21 | width: 100%;
22 | display: flex;
23 | align-items: center;
24 | justify-content: center;
25 | margin: 100px 0;
26 | }
27 | .container{
28 | background-color: white;
29 | width: 90%;
30 | max-width: 900px;
31 | margin: 0 auto;
32 | box-shadow: 0px 0px 61px 7px #5e849c40;
33 | padding: 50px 20px;
34 | border-radius: 20px;
35 | text-align: center;
36 | }
37 | .header{
38 | display: flex;
39 | flex-direction: column;
40 | align-items: center;
41 | }
42 | .header h1{
43 | cursor: pointer;
44 | font-size: 40px;
45 | font-weight: 900;
46 | letter-spacing: -2px;
47 | }
48 | form{
49 | margin-top: 30px;
50 | width: 80%;
51 | max-width: 300px;
52 | position: relative;
53 | }
54 | input{
55 | border: none;
56 | border-bottom: 2px solid rgba(128, 128, 128, 0.479);
57 | font-size: 20px;
58 | width: 100%;
59 | outline: none;
60 | color: gray;
61 | background-color: transparent;
62 | }
63 | input::placeholder{
64 | opacity: .5;
65 | color: gray;
66 | font-family: 'Montserrat';
67 | }
68 | form ion-icon{
69 | position: absolute;
70 | right: 0;
71 | font-size: 20px;
72 | opacity: .5;
73 | color: gray;
74 | }
75 | .gallery{
76 | width: 100%;
77 | display: grid;
78 | grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) ;
79 | margin-top: 50px;
80 | grid-gap: 20px;
81 | }
82 | .item{
83 | width: 100%;
84 | height: 300px;
85 | position: relative;
86 | overflow: hidden;
87 | border-radius:8px;
88 | transition: .3s ease box-shadow;
89 | }
90 |
91 | .item:hover{
92 | box-shadow: 0px 0px 20px 3px #00000042;
93 | }
94 | .item:nth-last-child(1){
95 | margin-bottom: 0;
96 | }
97 | .item h3{
98 | width: 100%;
99 | padding: 20px;
100 | position: absolute;
101 | background-color: #00000040;
102 | color: aliceblue;
103 | bottom: -70px;
104 | font-weight: 300;
105 | transition: .5s ease-in-out bottom;
106 | }
107 | .item:hover h3{
108 | bottom: 0;
109 | }
110 | .load-more{
111 | display: inline-block;
112 | margin-top:30px;
113 | padding: 20px 50px;
114 | background-color: black;
115 | text-decoration: none;
116 | text-transform: uppercase;
117 | color: azure;
118 | font-weight: 500;
119 | cursor: pointer;
120 | }
121 | @media only screen and (min-width: 900px){
122 | .container{
123 | max-width: 1160px;
124 | padding: 100px;
125 | }
126 | .header{
127 | flex-direction: row;
128 | justify-content: space-between;
129 | }
130 | .header h1{
131 | font-size: 50px;
132 | }
133 | .header input{
134 | font-size: 24px;
135 | }
136 | .header ion-icon{
137 | font-size: 24px;
138 | }
139 | .gallery{
140 | grid-gap: 30px;
141 | }
142 |
143 | }
--------------------------------------------------------------------------------
/day-09/README.md:
--------------------------------------------------------------------------------
1 | ## Submit Name: Read More Button
2 |
3 | ### preview ⬇
4 | 
--------------------------------------------------------------------------------
/day-09/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 | Hello world
11 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nesciunt quod, doloremque consequuntur soluta corrupti illo quidem odit dolores voluptates enim minus aperiam repellendus porro. Asperiores ab voluptate architecto recusandae ... ea iusto natus totam sunt voluptas, veniam fugit quibusdam, eum sint, reiciendis alias tempora odit ratione non porro tempore nostrum? Totam unde quam ipsa ratione voluptatibus deleniti quis dicta voluptas ipsum, doloribus aperiam accusamus aspernatur aut velit libero est minus minima repellat recusandae? Provident deleniti doloremque corporis ullam a aperiam cumque illo consequuntur placeat consequatur voluptates, perspiciatis alias magnam iste? Maiores, excepturi. Quisquam adipisci facilis optio veniam delectus sint, ullam excepturi!
12 | Read More
13 |
14 |
15 |
--------------------------------------------------------------------------------
/day-09/main.js:
--------------------------------------------------------------------------------
1 | const readMoreBtn = document.querySelector('.readMoreBtn');
2 | const text = document.querySelector('.text');
3 |
4 | readMoreBtn.addEventListener('click',(e)=>{
5 | text.classList.toggle('show-more');
6 | if(readMoreBtn.innerText === 'Read More'){
7 | readMoreBtn.innerText = 'Read Less';
8 | }else{
9 | readMoreBtn.innerText = 'Read More';
10 | }
11 | })
--------------------------------------------------------------------------------
/day-09/preview/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-09/preview/preview.png
--------------------------------------------------------------------------------
/day-09/style.css:
--------------------------------------------------------------------------------
1 | body{
2 | font-family: 'Montserrat';
3 | text-align: justify;
4 | max-width: 600px;
5 | margin: 0 auto;
6 | background-color: rgb(18, 23, 27);
7 | color: aliceblue;
8 | }
9 | .text{
10 | font-size: 24px;
11 | }
12 | .moreText{
13 | display: none;
14 | }
15 | .text.show-more .moreText{
16 | display: inline;
17 | }
18 | .readMoreBtn{
19 | padding: 15px 60px;
20 | background-color: rgb(149, 170, 197);
21 | color:rgb(53, 49, 49);
22 | border: none;
23 | outline: none;
24 | border-radius: 8px;
25 | font-size: 24px;
26 | cursor: pointer;
27 | }
28 | .dots{
29 | display: inline-block;
30 | }
31 | .text.show-more .dots{
32 | display: none;
33 | }
--------------------------------------------------------------------------------
/day-10/README.md:
--------------------------------------------------------------------------------
1 | ## Submit Name: Key Code Generator JS App
2 |
3 | ### preview ⬇
4 | 
--------------------------------------------------------------------------------
/day-10/arrow.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
9 |
13 |
14 |
17 |
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 |
--------------------------------------------------------------------------------
/day-10/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Key Code App
7 |
8 |
9 |
10 |
11 |
12 |
13 |
Key Pressed
14 | G
15 |
16 |
17 |
18 |
Key Code
19 |
56
20 |
Click to Copy
21 |
22 |
23 |
24 |
25 |
Press Any Key To Start
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/day-10/main.js:
--------------------------------------------------------------------------------
1 | const displayKey = document.querySelector('.key h2');
2 | const displayKeyCode = document.querySelector('.keyCode h2');
3 | const keyCodeDiv = document.querySelector('.keyCode');
4 | const overlay = document.querySelector('.overlay');
5 |
6 | window.addEventListener('keydown',(e)=>{
7 | overlay.classList.add('hide');
8 | displayKey.innerHTML = e.key;
9 | displayKeyCode.innerHTML = e.keyCode;
10 | if(e.keyCode === 32){
11 | displayKey.innerHTML = `'space'`
12 | }
13 | });
14 |
15 | keyCodeDiv.addEventListener('click',(e)=>{
16 | const textArea = document.createElement('textarea');
17 | textArea.setAttribute('readonly', '');
18 | textArea.style.position = 'absolute';
19 | textArea.value = displayKeyCode.innerText;
20 | document.body.appendChild(textArea);
21 | textArea.select()
22 | document.execCommand('copy');
23 | document.body.removeChild(textArea);
24 | keyCodeDiv.querySelector('p').innerText = 'Copied'
25 | setTimeout(()=>{
26 | keyCodeDiv.querySelector('p').innerText = 'Click to Copy'
27 | },2000)
28 | })
--------------------------------------------------------------------------------
/day-10/preview/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-10/preview/preview.png
--------------------------------------------------------------------------------
/day-10/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | body{
7 | font-family: 'Montserrat';
8 | font-size: 20px;
9 | background-color: aliceblue;
10 | }
11 | section{
12 | min-height: 100vh;
13 | width: 100%;
14 | padding: 100px 0;
15 | display: flex;
16 | align-items: center;
17 | justify-content: center;
18 | }
19 | .container{
20 | width: 100%;
21 | height: fit-content;
22 | display: flex;
23 | align-items: center;
24 | justify-content: center;
25 | width: 90%;
26 | max-width: 1000px;
27 | }
28 | .container div{
29 | background-color: white;
30 | display: flex;
31 | align-items: center;
32 | justify-content: center;
33 | flex-direction: column;
34 | padding: 30px;
35 | border-radius: 10px;
36 | box-shadow: 0px 0px 10px 0px #0000001c;
37 | transition: .3s ease box-shadow;
38 | }
39 | .container div:hover{
40 | box-shadow: 0px 0px 60px 0px #0000001f;
41 | }
42 | .container h2{
43 | font-size: 60px;
44 | margin: 20px 0;
45 | }
46 | .arrow{
47 | box-shadow: none!important;
48 | background-color: transparent!important;
49 | padding: 0 100px!important;
50 | }
51 | .arrow img{
52 | height: 80px;
53 | }
54 | .keyCode{
55 | cursor: pointer;
56 | }
57 | .overlay{
58 | position: fixed;
59 | top: 0;
60 | left: 0;
61 | height: 100%;
62 | width: 100%;
63 | background-color: aliceblue;
64 | display: flex;
65 | align-items: center;
66 | justify-content: center;
67 | }
68 | .overlay.hide{
69 | display: none;
70 | }
71 | @media only screen and (max-width: 1000px){
72 | .container{
73 | flex-direction: column;
74 | }
75 | .arrow{
76 | padding: 30px 0!important;
77 | transform: rotate(90deg);
78 | }
79 | }
--------------------------------------------------------------------------------
/day-11/README.md:
--------------------------------------------------------------------------------
1 | ## Submit Name: CSS animated Nav Menu
2 |
3 | ### preview ⬇
4 | 
--------------------------------------------------------------------------------
/day-11/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/day-11/main.js:
--------------------------------------------------------------------------------
1 | const icon = document.querySelector('.icon');
2 | const nav = document.querySelector('nav');
3 |
4 | icon.addEventListener('click', () => {
5 | icon.classList.toggle('close');
6 | nav.classList.toggle('show');
7 | })
--------------------------------------------------------------------------------
/day-11/preview/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-11/preview/preview.png
--------------------------------------------------------------------------------
/day-11/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | body{
7 | background-color: aliceblue;
8 | height: 100vh;
9 | width: 100%;
10 | display: flex;
11 | justify-content: center;
12 | align-items: center;
13 | font-family: 'Montserrat';
14 | font-size: 18px;
15 | }
16 | ul{
17 | background-color: white;
18 | border-radius: 4px;
19 | list-style: none;
20 | display: flex;
21 | align-items: center;
22 | justify-content: center;
23 | box-shadow: -7px 9px 17px 0px #00000017;
24 | }
25 | li a{
26 | display: inline-block;
27 | padding: 10px 20px;
28 | text-decoration: none;
29 | color: black;
30 | }
31 | li:hover a{
32 | color: crimson;
33 | }
34 | nav{
35 | position: relative;
36 | }
37 | .icon{
38 | position: absolute;
39 | top: 50%;
40 | transform: translateY(-50%);
41 | right: -80px;
42 | height: 60px;
43 | width: 60px;
44 | border-radius: 50%;
45 | background-color: rgb(255, 255, 255);
46 | background-image: url(https://image.flaticon.com/icons/svg/545/545705.svg);
47 | background-position: center;
48 | background-repeat: no-repeat;
49 | background-size: 50%;
50 | cursor: pointer;
51 | box-shadow: 0px 0px 17px 0px #00000017;
52 | transition: .5s ease transform;
53 | }
54 | .icon.close{
55 | transform:translateY(-50%) rotate(360deg);
56 | background-image: url(https://image.flaticon.com/icons/svg/748/748122.svg);
57 | }
58 | ul{
59 | width: 0px;
60 | overflow: hidden;
61 | transform: translateX(50px);
62 | opacity: 0;
63 | pointer-events: none;
64 | transition: .5s ease;
65 | padding: 20px;
66 | }
67 | nav.show ul{
68 | width: 450px;
69 | transform: translate(0px);
70 | opacity: 1;
71 | pointer-events: all;
72 | }
73 | nav{
74 | position: absolute;
75 | top: 10px;
76 | right: 100px;
77 | }
78 |
79 | @media only screen and (max-width: 768px){
80 | body{
81 | font-size: 14px;
82 | }
83 | li a{
84 | padding: 5px 10px;
85 | }
86 | nav ul{
87 | padding: 15px;
88 | }
89 | nav.show ul{
90 | width: 260px;
91 | }
92 | .icon{
93 | width: 45px;
94 | height: 45px;
95 | right: -50px;
96 | }
97 | nav{
98 | top: 10px;
99 | right: 60px;
100 | }
101 | }
--------------------------------------------------------------------------------
/day-12/img/img-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-12/img/img-1.jpg
--------------------------------------------------------------------------------
/day-12/img/img-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-12/img/img-2.jpg
--------------------------------------------------------------------------------
/day-12/img/img-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-12/img/img-3.jpg
--------------------------------------------------------------------------------
/day-12/img/img-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-12/img/img-4.jpg
--------------------------------------------------------------------------------
/day-12/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
Beauty Lorem ipsum dolor sit amet.
15 |
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nisi amet assumenda cupiditate eaque ex in dolores corrupti tempore rem, autem qui possimus rerum deserunt aliquam sequi quibusdam recusandae tempora doloremque voluptatem adipisci, dolore quae! Tempore magnam minima mollitia tempora esse!
16 |
17 |
18 |
19 |
20 |
21 |
31 |
32 |
--------------------------------------------------------------------------------
/day-12/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | body{
7 | font-size: 18px;
8 | font-family: 'Montserrat';
9 | }
10 | img{
11 | width: 100%;
12 | height: 100%;
13 | object-fit: cover;
14 | }
15 | section{
16 | height: 100vh;
17 | width: 100%;
18 | display: flex;
19 | align-items: center;
20 | justify-content: center;
21 | }
22 | .item{
23 | height: 100%;
24 | width: 100%;
25 | flex: 1;
26 | transition: .3s ease flex;
27 | position: relative;
28 | cursor: pointer;
29 | overflow: hidden;
30 | }
31 | .caption{
32 | position: absolute;
33 | left: 0px;
34 | bottom: 50px;
35 | color: black;
36 | opacity: 0;
37 | transition: .3s ease opacity;
38 | background-color: rgba(255, 255, 255, 0.404);
39 | padding: 30px;
40 | margin: 20px;
41 | border-radius: 8px;
42 | }
43 | .item.show{
44 | flex: 8;
45 | }
46 | .item.show .caption{
47 | opacity: 1;
48 | }
49 | @media only screen and (max-width: 768px){
50 | section{
51 | flex-direction: column;
52 | }
53 | .item{
54 | flex: 1;
55 | height: 100px;
56 | }
57 | .item.show{
58 | flex: 10;
59 | }
60 | body{
61 | font-size: 14px;
62 | }
63 | }
--------------------------------------------------------------------------------
/day-13/img/clock-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-13/img/clock-bg.png
--------------------------------------------------------------------------------
/day-13/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Analog Clock
7 |
8 |
9 |
10 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/day-13/main.js:
--------------------------------------------------------------------------------
1 | const minEl = document.querySelector('.min');
2 | const secEl = document.querySelector('.sec');
3 | const hourEl = document.querySelector('.hour');
4 |
5 |
6 |
7 | setInterval(()=>{
8 | const date = new Date;
9 | const secDeg = date.getSeconds()/60 * 360 -90;
10 | const minDeg = date.getMinutes() / 60 * 360 -90;
11 | const hourDeg = date.getHours() / 12 * 360 -90;
12 | secEl.style.transform = `rotate(${secDeg}deg)`;
13 | minEl.style.transform = `rotate(${minDeg}deg)`;
14 | hourEl.style.transform = `rotate(${hourDeg}deg)`;
15 | // console.log(date.getSeconds())
16 | // console.log(date.getMinutes())
17 | },1000)
18 |
--------------------------------------------------------------------------------
/day-13/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | section{
7 | height: 100Vh;
8 | width: 100%;
9 | display: flex;
10 | align-items: center;
11 | justify-content: center;
12 | }
13 | .container{
14 | width: 100%;
15 | height: 100%;
16 | }
17 | .clock{
18 | height: 500px;
19 | width: 90%;
20 | max-width: 500px;
21 | margin: 0 auto;
22 | background-color: transparent;
23 | border-radius: 50%;
24 | /* border: 5px solid gray; */
25 | position: relative;
26 | background-image: url(./img/clock-bg.png);
27 | background-position: center;
28 | background-size: contain;
29 | background-repeat: no-repeat;
30 |
31 | }
32 | .min ,
33 | .sec,
34 | .hour{
35 | position: absolute;
36 | top: 50%;
37 | left: 50%;
38 | width: 30%;
39 | height: 5px;
40 | background-color: rgb(0, 0, 0);
41 | transform-origin: left;
42 | border-radius: 50%;
43 | }
44 | .min ,
45 | .sec,
46 | .hour{
47 | transform: rotate(-90deg);
48 | }
--------------------------------------------------------------------------------
/day-14/bg-color-change/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
12 |
00 : 00 : 00 AM
13 |
14 |
15 |
Format
16 | 12hours
17 | 24hours
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/day-14/bg-color-change/main.js:
--------------------------------------------------------------------------------
1 | const clockEl = document.querySelector('.clock');
2 | const buttons = document.querySelectorAll('.format button')
3 | const intervalID = setInterval( generateTime, 1000)
4 |
5 | // console.log(date)
6 | function generateTime (){
7 | const format = clockEl.getAttribute('data-format');
8 | const date = new Date;
9 | let hour = date.getHours();
10 | let timeStatus = '';
11 | const min = date.getMinutes();
12 | const sec = date.getSeconds();
13 | if (format === '12') {
14 | timeStatus = (hour >= 12) ? 'PM' : 'AM';
15 | hour = (hour > 12) ? hour % 12 : hour;
16 | }
17 | clockEl.innerHTML = `${hour} : ${min} : ${sec} ${timeStatus} `
18 | }
19 |
20 | buttons.forEach((button)=>{
21 | button.addEventListener('click', ()=>{
22 | const format = button.getAttribute('data-format');
23 | clockEl.setAttribute('data-format', format);
24 | generateTime();
25 | })
26 | })
--------------------------------------------------------------------------------
/day-14/bg-color-change/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500&display=swap');
2 | *{
3 | padding: 0;
4 | margin: 0;
5 | box-sizing: border-box;
6 | }
7 | html{
8 | font-family: 'Orbitron', sans-serif;
9 | font-size: 30px;
10 | }
11 | section{
12 | height: 100vh;
13 | width: 100%;
14 | display: flex;
15 | align-items: center;
16 | justify-content: center;
17 | background-color: rgb(2, 15, 32);
18 | flex-direction: column;
19 | text-align: center;
20 | }
21 | section .clock {
22 | border-radius: 8px;
23 | color: cyan;
24 | }
25 |
26 | .format{
27 | color: aquamarine;
28 | font-size: 20px;
29 | margin: 30px 0;
30 | }
31 | .format button{
32 | display: inline-block;
33 | border: none;
34 | outline: none;
35 | font-size: 18px;
36 | padding: 10px 20px;
37 | font-family: 'Orbitron';
38 | border-radius: 4px;
39 | cursor: pointer;
40 | margin: 10px;
41 | }
--------------------------------------------------------------------------------
/day-14/password-generator/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/day-14/password-generator/main.js:
--------------------------------------------------------------------------------
1 | const resultElement = document.querySelector("#result");
2 | const lengthElement = document.querySelector("#length");
3 | const capitalElement = document.querySelector("#capital");
4 | const smallElement = document.querySelector("#small");
5 | const numberElement = document.querySelector("#number");
6 | const specialElement = document.querySelector("#symbol");
7 | const form = document.querySelector("#pg-form");
8 | const clipBoard = document.querySelector(".clipboard");
9 |
10 | const fieldsArray = [
11 | {
12 | field: capitalElement,
13 | getChar: getCapitalLetter,
14 | },
15 | {
16 | field: smallElement,
17 | getChar: getSmallLetter,
18 | },
19 | {
20 | field: numberElement,
21 | getChar: getNumber,
22 | },
23 | {
24 | field: specialElement,
25 | getChar: getSpecialChar,
26 | },
27 | ];
28 |
29 | form.addEventListener("submit", (e) => {
30 | e.preventDefault();
31 | const length = lengthElement.value;
32 | let generatePassword = "";
33 | const typeArray = fieldsArray.filter(({ field }) => field.checked);
34 |
35 | for (i = 0; i < length; i++) {
36 | const index = Math.floor(Math.random() * typeArray.length);
37 | const letter = typeArray[index].getChar();
38 | generatePassword += letter;
39 | }
40 | resultElement.value = generatePassword;
41 | });
42 |
43 | function getRandomChar(min, max) {
44 | const limit = max - min + 1;
45 | return String.fromCharCode(Math.floor(Math.random() * limit) + min);
46 | }
47 |
48 | function getCapitalLetter() {
49 | return getRandomChar(65, 90);
50 | }
51 |
52 | function getSmallLetter() {
53 | return getRandomChar(97, 122);
54 | }
55 |
56 | function getNumber() {
57 | return getRandomChar(48, 57);
58 | }
59 |
60 | function getSpecialChar() {
61 | const specialChar = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~'";
62 | return specialChar[Math.floor(Math.random() * specialChar.length)];
63 | }
64 |
65 | clipBoard.addEventListener("click", async () => {
66 | const text = resultElement.value;
67 | if (text) {
68 | await navigator.clipboard.writeText(text);
69 | alert("Copied to clipboard");
70 | } else {
71 | alert("No password to copy");
72 | }
73 | });
74 |
--------------------------------------------------------------------------------
/day-14/password-generator/styles.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Inter&display=swap");
2 | * {
3 | padding: 0;
4 | margin: 0;
5 | box-sizing: border-box;
6 | font-family: Inter;
7 | }
8 |
9 | body {
10 | background-color: rgb(22, 25, 27);
11 | font-size: 18px;
12 | font-family: "Montserrat";
13 | color: rgb(212, 212, 212);
14 | }
15 | section {
16 | min-height: 100vh;
17 | width: 100%;
18 | display: flex;
19 | align-items: center;
20 | justify-content: center;
21 | padding: 100px 0;
22 | }
23 | .container {
24 | padding: 30px;
25 | background-color: #303538;
26 | border-radius: 8px;
27 | box-shadow: 0px 0px 20px #00000011;
28 | width: 90%;
29 | max-width: 400px;
30 | }
31 | form {
32 | width: 100%;
33 | font-size: 20px;
34 | }
35 | .result {
36 | background-color: rgb(220, 233, 243);
37 | position: relative;
38 | margin-bottom: 30px;
39 | border-radius: 6px;
40 | overflow: hidden;
41 | }
42 | .result #result {
43 | width: 85%;
44 | height: 100%;
45 | border: none;
46 | outline: none;
47 | background-color: transparent;
48 | font-size: 20px;
49 | padding: 10px;
50 | }
51 | .result .clipboard {
52 | width: 15%;
53 | height: 100%;
54 | position: absolute;
55 | right: 0;
56 | top: 50%;
57 | transform: translateY(-50%);
58 | font-size: 25px;
59 | cursor: pointer;
60 | background-color: royalblue;
61 | color: white;
62 | display: flex;
63 | align-items: center;
64 | justify-content: center;
65 | }
66 | .field input[type="number"] {
67 | width: 50px;
68 | height: 40px;
69 | outline: none;
70 | border: none;
71 | padding: 10px;
72 | padding-right: 0px;
73 | font-size: 16px;
74 | background-color: rgb(241, 241, 241);
75 | border-radius: 4px;
76 | }
77 | .field {
78 | height: 40px;
79 | margin-top: 5px;
80 | border-radius: 4px;
81 | display: flex;
82 | justify-content: space-between;
83 | align-items: center;
84 | align-items: center;
85 | padding-right: 10px;
86 | transition: 0.3s ease background-color;
87 | }
88 | .field:first-of-type {
89 | padding-right: 0;
90 | }
91 | .field:hover {
92 | background-color: rgb(26, 29, 31);
93 | }
94 | .field label {
95 | width: 100%;
96 | padding: 10px;
97 | cursor: pointer;
98 | }
99 | .field input {
100 | cursor: pointer;
101 | }
102 |
103 | button[type="submit"] {
104 | display: inline-block;
105 | width: 100%;
106 | border: none;
107 | outline: none;
108 | height: 50px;
109 | background-color: royalblue;
110 | color: white;
111 | font-size: 18px;
112 | cursor: pointer;
113 | margin-top: 30px;
114 | border-radius: 6px;
115 | }
116 |
117 | @media only screen and (max-width: 678px) {
118 | .field {
119 | font-size: 16px;
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/day-15/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 | Change BG Color
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/day-15/main.js:
--------------------------------------------------------------------------------
1 | const button = document.querySelector('button');
2 | const h2El = document.querySelector('h2');
3 | const bgEl = document.querySelector('section');
4 | // const hexColorEl = [1,2,3,4,5,6,7,8,9,'A','B','c','D','E','F'];
5 |
6 | button.addEventListener('click', () => {
7 | let color = '#';
8 | color += Math.random().toString(16).slice(2, 8).toUpperCase();
9 | // for(i=0; i<6; i++){
10 | // const number = Math.floor(Math.random()*hexColorEl.length);
11 | // color += hexColorEl[number];
12 | // }
13 | // console.log(color)
14 | bgEl.style.backgroundColor = color;
15 | h2El.innerText = color
16 | });
17 |
--------------------------------------------------------------------------------
/day-15/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | section{
7 | height:100vh;
8 | width: 100%;
9 | display: flex;
10 | align-items: center;
11 | justify-content: center;
12 | flex-direction: column;
13 | }
14 | button{
15 | border: none;
16 | outline: none;
17 | background-color:aquamarine;
18 | font-size: 24px;
19 | font-family: 'Montserrat';
20 | padding: 20px;
21 | cursor: pointer;
22 | }
23 | h2{
24 | font-family: 'Montserrat';
25 | font-size: 30px;
26 | margin-top: 30px;
27 | }
--------------------------------------------------------------------------------
/day-16/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
12 |
13 |
This is Demo title 1
14 |
15 |
16 |
This is Demo title 2
17 |
18 |
19 |
This is Demo title 3
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/day-16/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | body{
7 | overflow: hidden;
8 | }
9 | html{
10 | font-family: 'Montserrat';
11 | font-size: 18px;
12 | }
13 |
14 | section{
15 | height: 100vh;
16 | width: 100%;
17 | display: flex;
18 | align-items: center;
19 | justify-content: center;
20 | background-color: aliceblue;
21 | }
22 | .demo-1,
23 | .demo-2,
24 | .demo-3{
25 | background-color: white;
26 | padding: 30px;
27 | margin: 80px 0;
28 | box-shadow: 0px 0px 20px #00000010;
29 | border-radius: 8px;
30 | }
31 | .tooltip{
32 | position: relative;
33 | }
34 | .tooltip::after,
35 | .tooltip::before{
36 | content: '';
37 | position: absolute;
38 | background-color: black;
39 | height: auto;
40 | width:auto;
41 | top: 0;
42 | left: 50%;
43 | transform: translate(-50%, -100%);
44 | transition: .2s ease-in-out transform;
45 | }
46 |
47 | .tooltip::before{
48 | font-size: 14px;
49 | line-height: 20px;
50 | content: attr(data-tooltip);
51 | color: white;
52 | padding: 10px;
53 | border-radius: 4px;
54 | top: -10px;
55 | transform: translate(-50%, -100%)scale(0);
56 | transform-origin: bottom;
57 | }
58 | .tooltip::after{
59 | height: 10px;
60 | width: 10px;
61 | transform: translate(-50%, -150%) rotate(45deg)scale(0);
62 | transform-origin: top center;
63 | }
64 | .tooltip:hover::before{
65 | transform: translate(-50%, -100%) scale(1);
66 | }
67 | .tooltip:hover::after{
68 | transform: translate(-50%, -150%) rotate(45deg)scale(1);
69 | }
70 | .icon{
71 | display: inline-block;
72 | color: rgb(62, 86, 221);
73 | }
74 | .icon ion-icon{
75 | margin-bottom: -5px;
76 | }
--------------------------------------------------------------------------------
/day-17/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
18 |
19 |
20 |
This is Sec 2
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/day-17/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | html{
7 | font-size: 40px;
8 | font-family: 'Montserrat';
9 | scroll-behavior: smooth;
10 | }
11 | section{
12 | min-height: 100vh;
13 | width: 100%;
14 | display: flex;
15 | align-items: center;
16 | justify-content: center;
17 | }
18 | #sec-1{
19 | background-color: rgb(214, 228, 92);
20 | }
21 | #sec-2{
22 | background-color: aliceblue;
23 | }
24 | .scroll-down{
25 | height: 50px;
26 | width: 30px;
27 | border: 2px solid black;
28 | position: absolute;
29 | left: 50%;
30 | bottom: 20px;
31 | border-radius: 50px;
32 | cursor: pointer;
33 | }
34 | .scroll-down::before,
35 | .scroll-down::after{
36 | content: '';
37 | position: absolute;
38 | top: 20%;
39 | left: 50%;
40 | height: 10px;
41 | width: 10px;
42 | transform:translate(-50%, -100%) rotate(45deg);
43 | border: 2px solid black;
44 | border-top: transparent;
45 | border-left: transparent;
46 | animation: scroll-down 1s ease-in-out infinite;
47 | }
48 | .scroll-down::before{
49 | top: 30%;
50 | animation-delay: .3s;
51 | /* animation: scroll-down 1s ease-in-out infinite; */
52 | }
53 |
54 | @keyframes scroll-down{
55 | 0%{
56 | /* top:20%; */
57 | opacity: 0;
58 | }
59 | 30%{
60 | opacity: 1;
61 | }
62 | 60%{
63 | opacity: 1;
64 | }
65 | 100%{
66 | top:90%;
67 | opacity:0;
68 | }
69 | }
--------------------------------------------------------------------------------
/day-18/img-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-18/img-1.jpg
--------------------------------------------------------------------------------
/day-18/img-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-18/img-2.jpg
--------------------------------------------------------------------------------
/day-18/img-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-18/img-3.jpg
--------------------------------------------------------------------------------
/day-18/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
12 |
13 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/day-18/main.js:
--------------------------------------------------------------------------------
1 | const tooltips = document.querySelectorAll('.all-tooltip .tooltip');
2 | const fullDiv = document.querySelector('section');
3 | const container = document.querySelector('.container')
4 | let timeoutId;
5 | window.addEventListener('resize', contentPosition);
6 | window.addEventListener('DOMContentLoaded', contentPosition);
7 |
8 | function contentPosition(){
9 | tooltips.forEach(tooltip => {
10 | const pin = tooltip.querySelector('.pin');
11 | const content = tooltip.querySelector('.tooltip-content')
12 | const arrow = tooltip.querySelector('.arrow');
13 | // const pinLeft = pin.offsetLeft;
14 | if (pin.offsetLeft + content.offsetWidth / 2 > fullDiv.offsetWidth) {
15 | const extraLeft = fullDiv.offsetWidth - (pin.offsetLeft + content.offsetWidth / 2);
16 | // console.log('right-conflict', tooltip)
17 | content.style.left = pin.offsetLeft - content.offsetWidth / 2 + extraLeft - 30+ 'px';
18 | content.style.top = pin.offsetTop + 30 + 'px';
19 | } else if (pin.offsetLeft + container.offsetLeft < content.offsetWidth / 2 ){
20 | // console.log('left conflict', pin.offsetLeft)
21 | content.style.left = - container.offsetLeft +'px';
22 | content.style.top = pin.offsetTop + 30 + 'px';
23 | } else {
24 | content.style.left = pin.offsetLeft - content.offsetWidth / 2 + 'px';
25 | content.style.top = pin.offsetTop + 30 + 'px';
26 | }
27 | arrow.style.left = pin.offsetLeft - content.offsetLeft + pin.offsetWidth/2 + 'px';
28 | })
29 | }
30 | tooltips.forEach(tooltip => {
31 | const pin = tooltip.querySelector('.pin');
32 | const content = tooltip.querySelector('.tooltip-content');
33 | pin.addEventListener('mousemove', () => {
34 | tooltip.classList.add('active');
35 | })
36 | pin.addEventListener('mouseleave', () => {
37 | timeoutId = setTimeout( () => {
38 | tooltip.classList.remove('active')
39 | },1000)
40 | })
41 | content.addEventListener('mouseover', () => {
42 | clearTimeout(timeoutId)
43 | tooltip.classList.add('active');
44 | })
45 | content.addEventListener('mouseleave', () => {
46 | timeoutId = setTimeout(() => {
47 | tooltip.classList.remove('active')
48 | }, 1000)
49 | })
50 | })
51 |
--------------------------------------------------------------------------------
/day-18/style.css:
--------------------------------------------------------------------------------
1 |
2 | *{
3 | margin: 0;
4 | padding: 0;
5 | box-sizing: border-box;
6 | }
7 | html{
8 | font-size: 16px;
9 | font-family: 'Montserrat';
10 | }
11 | body{
12 | background-color: azure;
13 | width: 100%;
14 | }
15 |
16 | section{
17 | height: 100vh;
18 | width: 100%;
19 | display: flex;
20 | align-items: center;
21 | justify-content: center;
22 | overflow-x: hidden;
23 | }
24 | .container{
25 | width: 90%;
26 | max-width: 1200px;
27 | margin: 0 auto;
28 | position: relative;
29 | }
30 | .container img{
31 | height: 100%;
32 | width: 100%;
33 | }
34 | .all-tooltip{
35 | position: absolute;
36 | height: 100%;
37 | width: 100%;
38 | left: 0;
39 | top: 0;
40 | }
41 |
42 | .tooltip-content{
43 | position: absolute;
44 | background-color: rgb(255, 255, 255);
45 | box-shadow: 0px 0px 20px #00000020;
46 | padding: 30px;
47 | border-radius:8px;
48 | width: 90vw;
49 | max-width: 300px;
50 | opacity: 0;
51 | pointer-events: none;
52 | /* left: -50%; */
53 | z-index: 2;
54 | }
55 | .tooltip-content .arrow{
56 | position: absolute;
57 | width: 10px;
58 | height: 10px;
59 | border: 10px solid transparent;
60 | border-bottom-color: rgb(255, 255, 255);
61 | top: 0px;
62 | left: 50%;
63 | transform:translate(-50%, -100%) rotate(0deg);
64 | }
65 | .pin{
66 | position: absolute;
67 | content: '';
68 | top: 50%;
69 | left: 80%;
70 | height: 25px;
71 | width: 25px;
72 | background-color: rgb(255, 255, 255);
73 | border-radius: 50%;
74 | cursor: pointer;
75 | }
76 | .pin:after{
77 | content: '';
78 | position: absolute;
79 | top: 0;
80 | left: 0;
81 | height: 100%;
82 | width: 100%;
83 | background-color: rgb(255, 255, 255);
84 | border-radius: 50%;
85 | animation: puls-effect 1s ease infinite;
86 | }
87 | .tooltip.active .tooltip-content{
88 | opacity: 1;
89 | pointer-events: all;
90 | display: block;
91 | }
92 |
93 | /* Custom Style for tooltip-1 */
94 |
95 | .tooltip-1 .pin{
96 | top: 40%;
97 | left: 82%;
98 | height: 15px;
99 | width: 15px;
100 | background-color: rgb(255, 255, 255);
101 | }
102 | .tooltip-1 .tooltip-content{
103 | display: flex;
104 | max-width: 500px;
105 | align-items: stretch;
106 | justify-content: center;
107 | padding: 0;
108 | background-color: aliceblue;
109 | }
110 | .tooltip-1.active .tooltip-content{
111 | display: flex;
112 | }
113 | .tooltip-1 .tooltip-content .img{
114 | width: 50%;
115 | object-fit: cover;
116 | }
117 | .tooltip-1 .tooltip-content .content{
118 | width: 50%;
119 | padding: 20px;
120 | }
121 | .tooltip-1 .tooltip-content .content h1{
122 | font-size: 24px;
123 | }
124 | .tooltip-1 .tooltip-content .content p{
125 | font-size: 14px;
126 | }
127 | .tooltip-1 .tooltip-content .content button{
128 | font-family: 'Montserrat';
129 | font-size: 18px;
130 | font-weight: 400;
131 | border: none;
132 | outline: none;
133 | background-color: white;
134 | color: black;
135 | padding: 10px;
136 | cursor: pointer;
137 | margin-top: 20px;
138 | border-radius: 4px;
139 | box-shadow: 0px 0px 20px #00000020;
140 | }
141 |
142 | /* custom style for tooltip-2 */
143 |
144 | .tooltip-2 .pin{
145 | top: 80%;
146 | left: 35%;
147 | height: 15px;
148 | width: 15px;
149 | }
150 | .tooltip-2 .tooltip-content .content h1{
151 | margin: 20px 0;
152 | }
153 | .tooltip-2 .tooltip-content{
154 | background-color: aliceblue;
155 | }
156 | .tooltip-2 .tooltip-content button{
157 | font-family: 'Montserrat';
158 | font-size: 18px;
159 | font-weight: 400;
160 | border: none;
161 | outline: none;
162 | background-color: white;
163 | color: black;
164 | padding: 10px;
165 | cursor: pointer;
166 | margin-top: 20px;
167 | border-radius: 4px;
168 | box-shadow: 0px 0px 20px #00000020;
169 | }
170 |
171 | /* Custom style for tooltip-3 */
172 |
173 | .tooltip-3 .pin{
174 | top: 20%;
175 | left: 5%;
176 | height: 15px;
177 | width: 15px;
178 | }
179 | /* Custom style for tooltip-4 */
180 |
181 | .tooltip-4 .pin{
182 | top: 80%;
183 | left: 5%;
184 | height: 15px;
185 | width: 15px;
186 | }
187 |
188 | /* Puls Effect For Pins */
189 |
190 | @keyframes puls-effect{
191 | 0%{
192 | transform: scale(1);
193 | opacity: 1;
194 | }
195 | 100%{
196 | transform: scale(3);
197 | opacity: 0;
198 | }
199 | }
200 |
201 | /* Media Query */
202 |
203 | @media (max-width: 768px){
204 | .tooltip-1 .tooltip-content{
205 | flex-direction: column;
206 | max-width: 300px;
207 | }
208 | .tooltip-1 .tooltip-content .content,
209 | .tooltip-1 .tooltip-content .img{
210 | width: 100%;
211 | }
212 | }
--------------------------------------------------------------------------------
/day-19/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Full Functional Form
7 |
8 |
9 |
10 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/day-19/main.js:
--------------------------------------------------------------------------------
1 | window.addEventListener("DOMContentLoaded", function () {
2 |
3 | // get the form elements defined in your form HTML above
4 |
5 | var form = document.getElementById("test-form");
6 | var button = document.getElementById("test-form-submit");
7 | var status = document.getElementById("status");
8 |
9 | // Success and Error functions for after the form is submitted
10 |
11 | function success() {
12 | form.reset();
13 | status.classList.add('success');
14 | status.innerHTML = "Thanks!";
15 | }
16 |
17 | function error() {
18 | status.classList.add('error');
19 | status.innerHTML = "Oops! There was a problem.";
20 | }
21 |
22 | // handle the form submission event
23 |
24 | form.addEventListener("submit", function (ev) {
25 | ev.preventDefault();
26 | var data = new FormData(form);
27 | ajax(form.method, form.action, data, success, error);
28 | });
29 | });
30 |
31 | // helper function for sending an AJAX request
32 |
33 | function ajax(method, url, data, success, error) {
34 | var xhr = new XMLHttpRequest();
35 | xhr.open(method, url);
36 | xhr.setRequestHeader("Accept", "application/json");
37 | xhr.onreadystatechange = function () {
38 | if (xhr.readyState !== XMLHttpRequest.DONE) return;
39 | if (xhr.status === 200) {
40 | success(xhr.response, xhr.responseType);
41 | } else {
42 | error(xhr.status, xhr.response, xhr.responseType);
43 | }
44 | };
45 | xhr.send(data);
46 | }
--------------------------------------------------------------------------------
/day-19/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | body{
7 | font-family: montserrat;
8 | }
9 | section{
10 | height: 100vh;
11 | width: 100%;
12 | background-color: aliceblue;
13 | display: flex;
14 | align-items: center;
15 | justify-content: center;
16 | flex-direction: column;
17 | }
18 | .container{
19 | width: 90%;
20 | max-width: 500px;
21 | margin:0 auto;
22 | padding: 20px;
23 | box-shadow: 0px 0px 20px #00000010;
24 | background-color: white;
25 | border-radius: 8px;
26 | margin-bottom: 20px;
27 | }
28 | .form-group{
29 | width: 100%;
30 | margin-top: 20px;
31 | font-size: 20px;
32 | }
33 | .form-group input,
34 | .form-group textarea{
35 | width: 100%;
36 | padding: 10px;
37 | border: 1px solid rgba(128, 128, 128, 0.199);
38 | margin-top: 5px;
39 | }
40 | textarea{
41 | resize: vertical;
42 | }
43 | button[type="submit"]{
44 | width: 100%;
45 | border: none;
46 | outline: none;
47 | padding: 20px;
48 | font-size: 24px;
49 | border-radius: 8px;
50 | font-family: 'Montserrat';
51 | color: rgb(27, 166, 247);
52 | background-color: rgb(227, 233, 238);
53 | text-align: center;
54 | cursor: pointer;
55 | transition: .3s ease background-color;
56 | margin-top: 10px;
57 | }
58 | button[type="submit"]:hover{
59 | background-color: rgb(214, 226, 236);
60 | }
61 | #status{
62 | width: 90%;
63 | max-width: 500px;
64 | text-align: center;
65 | padding: 10px;
66 | border-radius: 8px;
67 | opacity: 0;
68 | pointer-events: none;
69 | }
70 | #status.success{
71 | background-color: rgb(211, 250, 153);
72 | color: green;
73 | animation: status 4s ease forwards;
74 | }
75 | #status.error{
76 | background-color: rgb(250, 129, 92);
77 | color: rgb(252, 252, 252);
78 | animation: status 4s ease forwards;
79 | }
80 |
81 | @keyframes status{
82 | 0%{
83 | opacity: 1;
84 | pointer-events: all;
85 | }
86 | 90%{
87 | opacity: 1;
88 | pointer-events: all;
89 | }
90 | 100%{
91 | opacity: 0;
92 | pointer-events: none;
93 | }
94 | }
--------------------------------------------------------------------------------
/day-20/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Multi Step Forms
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
29 |
30 |
31 |
32 | Email
33 |
34 |
35 |
36 | Phone
37 |
38 |
39 |
Prev
40 |
Next
41 |
42 |
43 |
44 |
45 | country
46 |
47 |
48 |
49 | City
50 |
51 |
52 |
53 | Post Code
54 |
55 |
56 |
Prev
57 |
Submit
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/day-20/main.js:
--------------------------------------------------------------------------------
1 | const steps = Array.from(document.querySelectorAll('form .step'));
2 | const nextBtn = document.querySelectorAll('form .next-btn');
3 | const prevBtn = document.querySelectorAll('form .previous-btn');
4 | const form = document.querySelector('form' );
5 |
6 | nextBtn.forEach(button => {
7 | button.addEventListener('click', () => {
8 | changeStep('next');
9 | })
10 | });
11 | prevBtn.forEach( button => {
12 | button.addEventListener('click', () => {
13 | changeStep('prev');
14 | })
15 | })
16 |
17 | form.addEventListener('submit', (e) => {
18 | e.preventDefault();
19 | const inputs = [];
20 | form.querySelectorAll('input').forEach(input => {
21 | const { name, value } = input;
22 | inputs.push({name , value})
23 | });
24 | console.log(inputs)
25 | form.reset();
26 | let index = 0;
27 | const active = document.querySelector('.active');
28 | index = steps.indexOf(active);
29 | steps[index].classList.remove('active');
30 | steps[0].classList.add('active');
31 | })
32 |
33 |
34 | function changeStep(btn){
35 | let index = 0;
36 | const active = document.querySelector('.active');
37 | index = steps.indexOf(active);
38 | steps[index].classList.remove('active');
39 | if(btn === 'next'){
40 | index++;
41 | }else if(btn === 'prev'){
42 | index --;
43 | }
44 | steps[index].classList.add('active');
45 | }
--------------------------------------------------------------------------------
/day-20/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | body{
7 | font-family: "Montserrat";
8 | }
9 | section{
10 | min-height: 100vh;
11 | width: 100%;
12 | display: flex;
13 | align-items:center;
14 | justify-content: center;
15 | background-color: aliceblue;
16 | }
17 | .container{
18 | max-width: 400px;
19 | width: 90%;
20 | padding: 20px;
21 | box-shadow: 0px 0px 20px #00000020;
22 | border-radius: 8px;
23 | background-color: white;
24 | }
25 | .step{
26 | display: none;
27 | }
28 | .step.active{
29 | display: block;
30 | }
31 | .form-group{
32 | width: 100%;
33 | margin-top:20px;
34 | }
35 | .form-group input{
36 | width: 100%;
37 | border: 1.5px solid rgba(128, 128, 128, 0.418);
38 | padding: 5px;
39 | font-size: 18px;
40 | margin-top: 5px ;
41 | border-radius: 4px;
42 | }
43 |
44 | button.next-btn,
45 | button.previous-btn,
46 | button.submit-btn{
47 | float: right;
48 | margin-top: 20px;
49 | padding: 10px 30px;
50 | border: none;
51 | outline: none;
52 | background-color:rgb(180, 220, 255);
53 | font-family: 'Montserrat';
54 | font-size: 18px;
55 | cursor: pointer;
56 | /* text-align: right; */
57 | }
58 | button.previous-btn{
59 | float: left;
60 | }
61 | button.submit-btn{
62 | background-color: aquamarine;
63 | }
64 |
--------------------------------------------------------------------------------
/day-21/CSS-loading-animation/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
12 |
Loading...
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/day-21/CSS-loading-animation/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | body{
7 | font-family: 'Montserrat';
8 | }
9 | section{
10 | min-height: 100vh;
11 | width: 100%;
12 | display: flex;
13 | align-items: center;
14 | justify-content: center;
15 | background-color: aliceblue;
16 | }
17 | .container{
18 | padding: 20px 40px;
19 | border: 2px solid black;
20 | letter-spacing: 10px;
21 | position: relative;
22 | text-transform: uppercase;
23 | font-size: 24px;
24 | }
25 | .container::after{
26 | content: '';
27 | position: absolute;
28 | height: 100%;
29 | width: 0%;
30 | left: 0;
31 | top: 0;
32 | background-color: rgb(255, 255, 255);
33 | mix-blend-mode: difference;
34 | animation: loader_bg 3s linear infinite alternate;
35 | }
36 | @keyframes loader_bg {
37 | 0%{
38 | width: 0;
39 | }
40 | 100%{
41 | width: 100%;
42 | }
43 | }
--------------------------------------------------------------------------------
/day-21/OTP-UI/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | OTP-UI
9 |
10 |
11 |
12 |
13 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/day-21/OTP-UI/main.js:
--------------------------------------------------------------------------------
1 | const form = document.querySelector("#otp-form");
2 | const inputs = document.querySelectorAll(".otp-input");
3 | const verifyBtn = document.querySelector("#verify-btn");
4 |
5 | const isAllInputFilled = () => {
6 | return Array.from(inputs).every((item) => item.value);
7 | };
8 |
9 | const getOtpText = () => {
10 | let text = "";
11 | inputs.forEach((input) => {
12 | text += input.value;
13 | });
14 | return text;
15 | };
16 |
17 | const verifyOTP = () => {
18 | if (isAllInputFilled()) {
19 | const text = getOtpText();
20 | alert(`Your OTP is "${text}". OTP is correct`);
21 | }
22 | };
23 |
24 | const toggleFilledClass = (field) => {
25 | if (field.value) {
26 | field.classList.add("filled");
27 | } else {
28 | field.classList.remove("filled");
29 | }
30 | };
31 |
32 | form.addEventListener("input", (e) => {
33 | const target = e.target;
34 | const value = target.value;
35 | console.log({ target, value });
36 | toggleFilledClass(target);
37 | if (target.nextElementSibling) {
38 | target.nextElementSibling.focus();
39 | }
40 | verifyOTP();
41 | });
42 |
43 | inputs.forEach((input, currentIndex) => {
44 | // fill check
45 | toggleFilledClass(input);
46 |
47 | // paste event
48 | input.addEventListener("paste", (e) => {
49 | e.preventDefault();
50 | const text = e.clipboardData.getData("text");
51 | console.log(text);
52 | inputs.forEach((item, index) => {
53 | if (index >= currentIndex && text[index - currentIndex]) {
54 | item.focus();
55 | item.value = text[index - currentIndex] || "";
56 | toggleFilledClass(item);
57 | verifyOTP();
58 | }
59 | });
60 | });
61 |
62 | // backspace event
63 | input.addEventListener("keydown", (e) => {
64 | if (e.keyCode === 8) {
65 | e.preventDefault();
66 | input.value = "";
67 | // console.log(input.value);
68 | toggleFilledClass(input);
69 | if (input.previousElementSibling) {
70 | input.previousElementSibling.focus();
71 | }
72 | } else {
73 | if (input.value && input.nextElementSibling) {
74 | input.nextElementSibling.focus();
75 | }
76 | }
77 | });
78 | });
79 |
80 | verifyBtn.addEventListener("click", () => {
81 | verifyOTP();
82 | });
83 |
--------------------------------------------------------------------------------
/day-21/OTP-UI/styles.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Inter&display=swap");
2 | * {
3 | padding: 0;
4 | margin: 0;
5 | box-sizing: border-box;
6 | font-family: Inter;
7 | }
8 | body {
9 | width: 100%;
10 | background: #1a2226;
11 | color: white;
12 | }
13 | section {
14 | width: 100%;
15 | min-height: 100vh;
16 | display: flex;
17 | align-items: center;
18 | justify-content: center;
19 | flex-direction: column;
20 | }
21 | .container {
22 | border-radius: 12px;
23 | background-color: rgb(19, 25, 28);
24 | width: 90%;
25 | max-width: 500px;
26 | padding: 50px 20px;
27 | text-align: center;
28 | }
29 | .title {
30 | font-size: 25px;
31 | margin-bottom: 30px;
32 | }
33 | #otp-form {
34 | width: 100%;
35 | display: flex;
36 | gap: 20px;
37 | align-items: center;
38 | justify-content: center;
39 | }
40 | #otp-form input {
41 | border: none;
42 | background-color: #121517;
43 | color: white;
44 | font-size: 32px;
45 | text-align: center;
46 | padding: 10px;
47 | width: 100%;
48 | max-width: 70px;
49 | height: 70px;
50 | border-radius: 4px;
51 | outline: 2px solid rgb(66, 66, 66);
52 | }
53 | #otp-form input:focus-visible {
54 | outline: 2px solid royalblue;
55 | }
56 | #otp-form input.filled {
57 | outline: 2px solid rgb(7, 192, 99);
58 | }
59 | #verify-btn {
60 | cursor: pointer;
61 | display: inline-block;
62 | margin-top: 30px;
63 | background: royalblue;
64 | color: white;
65 | padding: 7px 10px;
66 | border-radius: 4px;
67 | font-size: 16px;
68 | border: none;
69 | }
70 |
--------------------------------------------------------------------------------
/day-22/img-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-22/img-1.jpg
--------------------------------------------------------------------------------
/day-22/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
12 |
Recipe App
13 |
14 |
15 |
16 |
17 |
18 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/day-22/main.js:
--------------------------------------------------------------------------------
1 | const searchForm = document.querySelector('form');
2 | const searchResultDiv = document.querySelector('.search-result');
3 | const container = document.querySelector('.container');
4 | let searchQuery = '';
5 | const APP_ID = "Use Your Own App ID Here";
6 | const APP_key = "Use Your Own App Key Here";
7 | // console.log(container)
8 | searchForm.addEventListener('submit', (e) => {
9 | e.preventDefault();
10 | searchQuery = e.target.querySelector('input').value;
11 | fetchAPI();
12 | })
13 |
14 | async function fetchAPI(){
15 | const baseURL = `https://api.edamam.com/search?q=${searchQuery}&app_id=${APP_ID}&app_key=${APP_key}&from=0&to=20`;
16 | const response = await fetch(baseURL);
17 | const data = await response.json();
18 | generateHTML(data.hits)
19 | console.log(data);
20 | }
21 |
22 | function generateHTML(results){
23 | container.classList.remove('initial');
24 | let generatedHTML= '';
25 | results.map(result => {
26 | generatedHTML += `
27 |
28 |
29 |
33 |
Calories: ${result.recipe.calories.toFixed(2)}
34 |
Diet label: ${result.recipe.dietLabels.length > 0 ? result.recipe.dietLabels : 'No Data Found'}
35 |
Health labels: ${result.recipe.healthLabels}
36 |
37 | `
38 | })
39 | searchResultDiv.innerHTML = generatedHTML;
40 | }
41 |
--------------------------------------------------------------------------------
/day-22/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;600&display=swap');
2 | *{
3 | padding: 0;
4 | margin: 0;
5 | box-sizing: border-box;
6 | }
7 | img{
8 | width: 100%;
9 | height: 100%;
10 | object-fit: cover;
11 | }
12 | html{
13 | font-family: 'Nunito';
14 | font-size: 12px;
15 | }
16 |
17 | section{
18 | min-height: 100vh;
19 | width: 100%;
20 | display: flex;
21 | align-items: center;
22 | justify-content: center;
23 | padding: 100px 0;
24 | background-color: rgb(26, 26, 27);
25 | }
26 | .container{
27 | width: 100%;
28 | height: 90%;
29 | max-width: 1200px;
30 | margin: 0 auto;
31 | padding: 20px;
32 | }
33 | .brand{
34 | text-align: center;
35 | font-size: 4rem;
36 | color: whitesmoke;
37 | margin-bottom: 30px;
38 | }
39 | form{
40 | width: 90%;
41 | max-width: 400px;
42 | margin: 20px auto;
43 | background-color: rgb(223, 223, 223);
44 | }
45 | input{
46 | width: 90%;
47 | padding: 10px;
48 | border-radius: 4px;
49 | border: none;
50 | outline: none;
51 | font-size: 2rem;
52 | background-color: rgb(223, 223, 223);
53 | display: inline-block;
54 | }
55 | form ion-icon{
56 | width: 8%;
57 | font-size: 3rem;
58 | margin-bottom: -8px;
59 | color: rgb(75, 75, 75) ;
60 | display: inline-block;
61 | }
62 | .search-result{
63 | margin-top: 50px;
64 | width: 100%;
65 | display: grid;
66 | grid-gap: 25px;
67 | grid-template: auto / repeat(auto-fit, minmax(300px, 1fr));
68 | }
69 | .item{
70 | width: 100%;
71 | border-radius: 8px;
72 | background-color: rgb(37, 37, 37);
73 | padding: 15px;
74 | overflow: hidden;
75 | }
76 | .item img{
77 | width: 100%;
78 | height: 300px;
79 | border-radius: 4px ;
80 | }
81 | .flex-container{
82 | display: flex;
83 | align-items: center;
84 | justify-content: space-between;
85 | }
86 | .search-result .title{
87 | color: whitesmoke;
88 | margin: 20px 10px 0 0;
89 | font-size: 1.8rem;
90 | font-weight: 400;
91 | }
92 | .view-btn{
93 | text-decoration: none;
94 | text-align: center;
95 | width: 130px;
96 | padding: 10px 0;
97 | background-color: #404041;
98 | color: whitesmoke;
99 | font-size: 1.4rem;
100 | font-weight: 600;
101 | margin-top: 20px;
102 | border-radius: 4px;
103 | align-self:flex-start;
104 | }
105 | .item-data{
106 | color: whitesmoke;
107 | display: block;
108 | margin-top: 10px ;
109 | font-size: 1.4rem;
110 | letter-spacing: .05rem;
111 | line-height: 2rem;
112 | }
113 | .container.initial .brand{
114 | font-size: 7rem;
115 | }
116 | .container.initial form {
117 | max-width: 800px;
118 | }
119 | .container.initial form input{
120 | padding: 20px;
121 | font-size: 3rem;
122 | }
123 |
124 | @media (max-width: 768px){
125 | .search-result{
126 | grid-gap:10px
127 | }
128 | .container.initial .brand{
129 | font-size: 4rem;
130 | }
131 | .container.initial form {
132 | max-width: 500px;
133 | }
134 | .container.initial form input{
135 | padding: 10px;
136 | font-size: 2rem;
137 | }
138 | }
--------------------------------------------------------------------------------
/day-23/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/day-23/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;600&display=swap');
2 | *{
3 | padding: 0;
4 | margin: 0;
5 | box-sizing: border-box;
6 | }
7 | html{
8 | font-family: 'Nunito'
9 | }
10 | :root{
11 | --var-color: rgb(255, 255, 255);
12 | }
13 | section{
14 | height: 100vh;
15 | width: 100%;
16 | display: flex;
17 | align-items: center;
18 | justify-content: center;
19 | background-color: #09111b;
20 | }
21 | .container h1{
22 | font-size: 20vw;
23 | color: var(--var-color);
24 | position: relative;
25 | }
26 | .container h1::before{
27 | position: absolute;
28 | content: attr(data-text);
29 | text-shadow: 0px 0px 20px var(--var-color);
30 | filter: blur(10px) brightness(0);
31 | animation: flicker 2s linear forwards;
32 | animation-delay: 1s;
33 | }
34 | @keyframes flicker{
35 | 0% {filter: blur(5px) brightness(1)}
36 | 3% {filter: blur(5px) brightness(0)}
37 | 6% {filter: blur(5px) brightness(0)}
38 | 7% {filter: blur(5px) brightness(1)}
39 | 8% {filter: blur(5px) brightness(0)}
40 | 9% {filter: blur(5px) brightness(1)}
41 | 10% {filter: blur(5px) brightness(0)}
42 | 20%{filter: blur(5px) brightness(1)}
43 | 50%{filter: blur(5px) brightness(1)}
44 | 99% {filter: blur(5px) brightness(0)}
45 | 100% {filter: blur(5px) brightness(1)}
46 | }
--------------------------------------------------------------------------------
/day-24/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Speech Recognition
7 |
8 |
9 |
10 |
11 | Speech Recognition
12 | Available In Chrome😎 Only
13 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/day-24/main.js:
--------------------------------------------------------------------------------
1 | const texts = document.querySelector('.texts');
2 |
3 | window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
4 |
5 | const recognition = new SpeechRecognition();
6 | recognition.interimResults = true;
7 |
8 | let p = document.createElement('p');
9 |
10 | recognition.addEventListener('result', (e)=>{
11 | texts.appendChild(p);
12 | const text = Array.from(e.results)
13 | .map(result => result[0])
14 | .map(result => result.transcript)
15 | .join('');
16 |
17 | p.innerText = text;
18 | if(e.results[0].isFinal){
19 | if (text.includes('how are you')) {
20 | p = document.createElement('p');
21 | p.classList.add('replay');
22 | p.innerText = 'I am fine';
23 | texts.appendChild(p)
24 | }
25 | if (text.includes("what's your name") || text.includes('what is your name')) {
26 | p = document.createElement('p');
27 | p.classList.add('replay');
28 | p.innerText = 'My Name is Cifar';
29 | texts.appendChild(p)
30 | }
31 | if (text.includes('open my YouTube')) {
32 | p = document.createElement('p');
33 | p.classList.add('replay');
34 | p.innerText = 'opening youtube channel';
35 | texts.appendChild(p)
36 | console.log('opening youtube')
37 | window.open('https://www.youtube.com/channel/UCdxaLo9ALJgXgOUDURRPGiQ')
38 | }
39 | p = document.createElement('p');
40 | }
41 | });
42 |
43 |
44 | recognition.addEventListener('end', ()=>{
45 | recognition.start();
46 | })
47 |
48 | recognition.start();
--------------------------------------------------------------------------------
/day-24/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | html {
7 | font-family: "Montserrat";
8 | font-size: 20px;
9 | }
10 | section {
11 | min-height: 100vh;
12 | width: 100%;
13 | display: flex;
14 | align-items: flex-start;
15 | background-color: rgb(37, 37, 37);
16 | flex-direction: column;
17 | padding: 50px 0;
18 | }
19 | section h1 {
20 | color: rgba(255, 255, 255, 0.322);
21 | text-align: center;
22 | width: 100%;
23 | font-size: 50px;
24 | margin-bottom: 10px;
25 | }
26 | section p {
27 | text-align: center;
28 | color: rgba(255, 255, 255, 0.322);
29 | width: 100%;
30 | margin-bottom: 40px;
31 | }
32 | .container {
33 | width: 90%;
34 | max-width: 500px;
35 | margin: 0 auto;
36 | justify-content: center;
37 | }
38 | .texts p {
39 | color: black;
40 | text-align: left;
41 | width: 100%;
42 | background-color: white;
43 | padding: 10px;
44 | border-radius: 8px;
45 | margin-bottom: 10px;
46 | }
47 | .texts p.replay {
48 | text-align: right;
49 | }
50 |
--------------------------------------------------------------------------------
/day-25/img/img-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-25/img/img-1.jpg
--------------------------------------------------------------------------------
/day-25/img/img-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-25/img/img-2.jpg
--------------------------------------------------------------------------------
/day-25/img/img-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-25/img/img-3.jpg
--------------------------------------------------------------------------------
/day-25/img/img-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-25/img/img-4.jpg
--------------------------------------------------------------------------------
/day-25/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | JS Slider
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
Hello, Slide-1
15 |
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quaerat culpa dolor accusamus quo laudantium? Ipsum aut
16 | magnam, autem aliquid saepe quis labore animi facilis. Dicta inventore a reprehenderit illum! Temporibus!
17 |
Hello
18 |
19 |
20 |
21 |
Hello, Slide-2
22 |
23 |
24 |
Hello, Slide-3
25 |
26 |
27 |
Hello, Slide-4
28 |
29 |
30 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/day-25/main.js:
--------------------------------------------------------------------------------
1 | const slides = Array.from(document.querySelectorAll('.slide'));
2 | const slider = document.querySelectorAll('.slider');
3 | const buttons = document.querySelectorAll('.buttons div');
4 | const dotsEl = document.querySelector('.dots');
5 | let timeoutId ;
6 |
7 | function getNextPrev() {
8 | const activeSlide = document.querySelector('.slide.active');
9 | const activeIndex = slides.indexOf(activeSlide);
10 | let next, prev;
11 | if (activeIndex === slides.length - 1) {
12 | next = slides[0];
13 | } else {
14 | next = slides[activeIndex + 1];
15 | }
16 | if (activeIndex === 0) {
17 | prev = slides[slides.length - 1]
18 | } else {
19 | prev = slides[activeIndex - 1];
20 | }
21 | return [next, prev];
22 | }
23 | function getPosition() {
24 | const activeSlide = document.querySelector('.slide.active');
25 | const activeIndex = slides.indexOf(activeSlide);
26 | const [next, prev] = getNextPrev();
27 | slides.forEach((slide, index) => {
28 | if(index === activeIndex){
29 | slide.style.transform = 'translateX(0)';
30 | }else if(slide === prev){
31 | slide.style.transform = 'translateX(-100%)';
32 | }else if(slide === next){
33 | slide.style.transform = 'translateX(100%)';
34 | }else{
35 | slide.style.transform = 'translateX(100%)'
36 | }
37 | slide.addEventListener('transitionend', ()=>{
38 | slide.classList.remove('top');
39 | })
40 | });
41 | }
42 | buttons.forEach(button => {
43 | button.addEventListener('click', () => {
44 | if (button.classList.contains('next')) getNextSlide()
45 | else if (button.classList.contains('prev')) getPrevSlide();
46 | })
47 | })
48 | function getNextSlide(){
49 | clearInterval(timeoutId);
50 | const current = document.querySelector('.slide.active');
51 | const [next, prev] = getNextPrev();
52 | if(current.classList.contains('top')) {
53 | return;
54 | };
55 | current.classList.add('top');
56 | next.classList.add('top');
57 | current.style.transform = 'translate(-100%)';
58 | current.classList.remove('active');
59 | next.style.transform = 'translateX(0)';
60 | next.classList.add('active');
61 | getPosition();
62 | getActiveDot();
63 | autoLoop();
64 | }
65 | function getPrevSlide(){
66 | clearInterval(timeoutId);
67 | const current = document.querySelector('.active');
68 | const [next, prev] = getNextPrev();
69 | current.classList.add('top');
70 | prev.classList.add('top');
71 | current.style.transform = 'translate(100%)';
72 | current.classList.remove('active');
73 | prev.style.transform = 'translateX(0)';
74 | prev.classList.add('active');
75 | getPosition();
76 | getActiveDot();
77 | autoLoop();
78 | }
79 | getPosition();
80 |
81 | // dots
82 | slides.forEach(slide => {
83 | const dot = document.createElement('div');
84 | dot.classList.add('dot');
85 | dotsEl.appendChild(dot)
86 | });
87 | function getActiveDot(){
88 | const allDots = document.querySelectorAll('.dots .dot');
89 | allDots.forEach(dot => {
90 | dot.classList.remove('active');
91 | })
92 | const activeSlide = document.querySelector('.slide.active');
93 | const activeIndex = slides.indexOf(activeSlide);
94 | allDots[activeIndex].classList.add('active');
95 | }
96 | function functionalDots(){
97 | const allDots = document.querySelectorAll('.dots .dot');
98 | allDots.forEach((dot, index) => {
99 | dot.addEventListener('click', () => {
100 | getDotSlide(index);
101 | })
102 | })
103 | }
104 | function getDotSlide(index){
105 | clearTimeout(timeoutId);
106 | slides.forEach(slide => {
107 | slide.classList.remove('active');
108 | })
109 | const current = slides[index];
110 | current.classList.add('active')
111 | getPosition();
112 | getActiveDot();
113 | autoLoop();
114 | }
115 |
116 | function autoLoop() {
117 | timeoutId = setTimeout(() => {
118 | getNextSlide();
119 | },5000)
120 | }
121 | getActiveDot();
122 | functionalDots();
123 | autoLoop();
--------------------------------------------------------------------------------
/day-25/oop.js:
--------------------------------------------------------------------------------
1 | class SliderClass {
2 | constructor(){
3 | this.slides = Array.from(document.querySelectorAll('.slide'));
4 | this.slider = document.querySelectorAll('.slider');
5 | this.buttons = document.querySelectorAll('.buttons div');
6 | this.dots = document.querySelector('.dots');
7 | this.timeoutId;
8 | this.autoLoop();
9 | this.getPosition();
10 | this.eventHandler();
11 | this.createDots();
12 | this.getActiveDot();
13 | }
14 | eventHandler(){
15 | this.buttons.forEach(button => {
16 | button.addEventListener('click', () => {
17 | if (button.classList.contains('next')) this.getNextSlide()
18 | else if (button.classList.contains('prev')) this.getPrevSlide();
19 | })
20 | })
21 | }
22 | getNextPrev() {
23 | const activeSlide = document.querySelector('.slide.active');
24 | const activeIndex = this.slides.indexOf(activeSlide);
25 | let next, prev;
26 | if (activeIndex === this.slides.length - 1) {
27 | next = this.slides[0];
28 | } else {
29 | next = this.slides[activeIndex + 1];
30 | }
31 | if (activeIndex === 0) {
32 | prev = this.slides[this.slides.length - 1]
33 | } else {
34 | prev = this.slides[activeIndex - 1];
35 | }
36 | return [next, prev];
37 | }
38 | getPosition() {
39 | const activeSlide = document.querySelector('.slide.active');
40 | const activeIndex = this.slides.indexOf(activeSlide);
41 | const [next, prev] = this.getNextPrev();
42 | this.slides.forEach((slide, index) => {
43 | if (index === activeIndex) {
44 | slide.style.transform = 'translateX(0)';
45 | } else if (slide === prev) {
46 | slide.style.transform = 'translateX(-100%)';
47 | } else if (slide === next) {
48 | slide.style.transform = 'translateX(100%)';
49 | }
50 | next.addEventListener('transitionend', () => {
51 | slide.classList.remove('top');
52 | })
53 | });
54 | }
55 | getNextSlide() {
56 | clearInterval(this.timeoutId);
57 | const current = document.querySelector('.slide.active');
58 | const [next, prev] = this.getNextPrev();
59 | if (current.classList.contains('top')) {
60 | return;
61 | };
62 | current.classList.add('top');
63 | next.classList.add('top');
64 | current.style.transform = 'translate(-100%)';
65 | current.classList.remove('active');
66 | next.style.transform = 'translateX(0)';
67 | next.classList.add('active');
68 | this.getPosition();
69 | this.getActiveDot();
70 | this.autoLoop();
71 | }
72 | getPrevSlide() {
73 | clearInterval(this.timeoutId);
74 | const current = document.querySelector('.active');
75 | const [next, prev] = this.getNextPrev();
76 | current.classList.add('top');
77 | prev.classList.add('top');
78 | current.style.transform = 'translate(100%)';
79 | current.classList.remove('active');
80 | prev.style.transform = 'translateX(0)';
81 | prev.classList.add('active');
82 | this.getPosition();
83 | this.getActiveDot();
84 | this.autoLoop();
85 | }
86 | createDots(){
87 | this.slides.forEach(slide => {
88 | const dot = document.createElement('div');
89 | dot.classList.add('dot');
90 | this.dots.appendChild(dot)
91 | this.functionalDots();
92 | });
93 | }
94 | functionalDots(){
95 | // Dots Click Event
96 | const allDots = document.querySelectorAll('.dots .dot');
97 | allDots.forEach((dot, index) => {
98 | dot.addEventListener('click', () => {
99 | this.getDotSlide(index);
100 | })
101 | })
102 | }
103 | getActiveDot() {
104 | const allDots = document.querySelectorAll('.dots .dot');
105 | allDots.forEach(dot => {
106 | dot.classList.remove('active');
107 | })
108 | const activeSlide = document.querySelector('.slide.active');
109 | const activeIndex = this.slides.indexOf(activeSlide);
110 | allDots[activeIndex].classList.add('active');
111 | }
112 | getDotSlide(index) {
113 | clearTimeout(this.timeoutId);
114 | this.slides.forEach(slide => {
115 | slide.classList.remove('active');
116 | })
117 | const current = this.slides[index];
118 | current.classList.add('active')
119 | this.getPosition();
120 | this.getActiveDot();
121 | this.autoLoop();
122 | }
123 | autoLoop() {
124 | this.timeoutId = setTimeout(() => {
125 | this.getNextSlide();
126 | }, 5000)
127 | }
128 | }
129 | const slider = new SliderClass()
--------------------------------------------------------------------------------
/day-25/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | margin: 0;
3 | padding: 0;
4 | box-sizing: border-box;
5 | }
6 | html{
7 | font-family: 'Montserrat', sans-serif;
8 | font-size: 20px;
9 | color: white;
10 | }
11 | section{
12 | height: 100vh;
13 | width: 100%;
14 | position: relative;
15 | overflow-x: hidden;
16 | }
17 | .slider{
18 | width: 100%;
19 | height: 100%;
20 | }
21 | .slide{
22 | width: 100%;
23 | height: 100%;
24 | display: flex;
25 | align-items: center;
26 | justify-content: center;
27 | position: absolute;
28 | z-index: -1;
29 | background-size: cover;
30 | }
31 | .slide::after{
32 | content: '';
33 | position: absolute;
34 | top: 0;
35 | left: 0;
36 | height: 100%;
37 | width: 100%;
38 | background-color: rgba(0, 0, 0, 0.685);
39 | z-index: -1;
40 | }
41 | .top{
42 | z-index: 3;
43 | transition: .3s ease transform;
44 | }
45 | .slide.active{
46 | transform: translateX(0);
47 | z-index: 3;
48 | }
49 | .slide-1{
50 | background-image: url(./img/img-1.jpg);
51 | }
52 | .slide-2{
53 | background-image: url(./img/img-2.jpg);
54 | }
55 | .slide-3{
56 | background-image: url(./img/img-3.jpg);
57 | }
58 | .slide-4{
59 | background-image: url(./img/img-4.jpg);
60 | }
61 | /* buttons */
62 | .buttons div{
63 | cursor: pointer;
64 | pointer-events: all;
65 | padding: 15px;
66 | background-color: rgba(255, 255, 255, 0.582);
67 | }
68 | .buttons div:hover{
69 | background-color: gray;
70 | }
71 | .buttons{
72 | position: absolute;
73 | z-index: 5;
74 | bottom: 0;
75 | right: 0;
76 | height: auto;
77 | color: black;
78 | display: flex;
79 | flex-direction: row-reverse;
80 | width: auto;
81 | font-size: 50px;
82 | }
83 | /* Dots */
84 | .dots{
85 | z-index: 5;
86 | position: absolute;
87 | bottom: 0;
88 | left: 50%;
89 | transform: translateX(-50%);
90 | }
91 | .dots .dot{
92 | display: inline-block;
93 | height: 10px;
94 | width: 10px;
95 | background-color: rgba(255, 255, 255, 0.185);
96 | border-radius: 10px;
97 | margin: 10px;
98 | transition: .3s ease width;
99 | cursor: pointer;
100 | }
101 | .dots .dot.active{
102 | background-color: white;
103 | width: 40px;
104 | }
105 | /* custom style */
106 | .slide-1{
107 | flex-direction: column;
108 | text-align: left;
109 | align-items: flex-start;
110 | }
111 | .slide-1 .content{
112 | width: 90%;
113 | max-width: 500px;
114 | position: absolute;
115 | left: 20%;
116 | }
117 | .slide-1 h1{
118 | font-size: 50px;
119 | }
120 | .slide-1 p{
121 | font-size: 18px;
122 | margin-top: 20px;
123 | }
124 | .slide-1 button{
125 | display: inline-block;
126 | padding: 15px 50px;
127 | font-size: 24px;
128 | outline: none;
129 | border: none;
130 | background-color: white;
131 | margin-top: 20px;
132 | }
133 | @media (max-width: 768px){
134 | .slide-1 .content{
135 | left: 20px;
136 | }
137 | .dots{
138 | left: 0;
139 | transform: translateX(0);
140 | }
141 | }
--------------------------------------------------------------------------------
/day-26/canvas.js:
--------------------------------------------------------------------------------
1 | const canvas = document.querySelector('canvas');
2 | const logo = document.querySelector('.logo');
3 |
4 | canvas.height = window.innerHeight;
5 | canvas.width = window.innerWidth;
6 |
7 | const logoWidth = 200;
8 | const logoHeight = 118;
9 |
10 | let xSpeed = 2;
11 | let ySpeed = 2;
12 | let xPosition = 100;
13 | let yPosition = 100;
14 |
15 |
16 | const ctx = canvas.getContext('2d');
17 | ctx.clearRect(0, 0, canvas.width, canvas.height);
18 | function draw(){
19 | ctx.fillStyle = 'f00';
20 | ctx.drawImage(logo, xPosition, yPosition, logoWidth, logoHeight)
21 | }
22 |
23 | function updateLogo(){
24 | if (xPosition + logoWidth >= window.innerWidth || xPosition <= 0) {
25 | xSpeed = -xSpeed;
26 | colorImage(logo, 'f00')
27 | }
28 | if (yPosition + logoHeight >= window.innerHeight || yPosition <= 0) {
29 | ySpeed = -ySpeed;
30 | }
31 |
32 | xPosition += xSpeed;
33 | yPosition += ySpeed;
34 |
35 | ctx.clearRect(0, 0, canvas.width, canvas.height);
36 |
37 | draw();
38 | requestAnimationFrame(updateLogo);
39 | }
40 | requestAnimationFrame(updateLogo);
41 | window.addEventListener('resize', () => {
42 | location.reload();
43 | })
44 |
--------------------------------------------------------------------------------
/day-26/dvd.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/day-26/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Bouncing DVD logo
7 |
8 |
9 |
10 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/day-26/main.js:
--------------------------------------------------------------------------------
1 | const section = document.querySelector('section');
2 | const logo = document.querySelector('.logo')
3 | const FPS = 60;
4 | section.style.height = window.innerHeight+'px';
5 | section.style.width = window.innerWidth+'px';
6 |
7 | // Logo moving velocity Variables
8 | let xPosition = 10;
9 | let yPosition = 10;
10 | let xSpeed = 4;
11 | let ySpeed = 4;
12 | function update(){
13 | logo.style.left = xPosition+ 'px';
14 | logo.style.top = yPosition+ 'px';
15 | }
16 |
17 | setInterval( () => {
18 | if(xPosition + logo.clientWidth >= window.innerWidth || xPosition <= 0){
19 | xSpeed = -xSpeed;
20 | logo.style.fill = randomColor();
21 | }
22 | if(yPosition + logo.clientHeight >= window.innerHeight || yPosition <= 0){
23 | ySpeed = -ySpeed;
24 | logo.style.fill = randomColor();
25 | }
26 |
27 | xPosition += xSpeed;
28 | yPosition += ySpeed;
29 | update();
30 |
31 | },1000/FPS)
32 | function randomColor(){
33 | let color = '#';
34 | color += Math.random().toString(16).slice(2, 8).toUpperCase();
35 |
36 | return color;
37 | }
38 | console.log(randomColor())
39 |
40 | window.addEventListener('resize', ()=> {
41 | xPosition = 10;
42 | yPosition = 10;
43 |
44 | section.style.height = window.innerHeight+'px';
45 | section.style.width = window.innerWidth+'px';
46 | })
47 |
48 |
--------------------------------------------------------------------------------
/day-26/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | body{
7 | overflow: hidden;
8 | }
9 | section{
10 | background-color: black;
11 | position: relative;
12 | }
13 | svg{
14 | position: absolute;
15 | width: 200px;
16 | fill: rgb(0, 81, 255);
17 | }
18 | @media (max-width: 768px){
19 | svg{
20 | width: 150px;
21 | }
22 | }
--------------------------------------------------------------------------------
/day-27/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Quiz App
7 |
8 |
9 |
10 |
11 |
12 |
0 /0
13 |
14 | Q: This is a QusThis is a Qus?
15 |
16 |
20 |
21 |
22 | Submit
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/day-27/main.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | const baseURL = 'https://opentdb.com/api.php?amount=1';
3 | const containerEl = document.querySelector('.container');
4 | const form = document.querySelector('#quiz_form');
5 | const qusEl = document.querySelector('.qus');
6 | const optionsEl = document.querySelector('.all_options');
7 | const buttonsEl = document.querySelector('.buttons');
8 | const scoreEl = document.querySelector('.scoreBoard .score-num');
9 | const answeredEl = document.querySelector('.scoreBoard .answered-num');
10 |
11 | let question, answer;
12 | let options = [];
13 | let score = 0;
14 | let answeredQus = 0;
15 |
16 | window.addEventListener('DOMContentLoaded', quizApp)
17 |
18 | async function quizApp() {
19 | updateScoreBoard();
20 | addPlaceholder();
21 | const data = await fetchQuiz();
22 | question = data[0].question;
23 | options = [];
24 | answer = data[0].correct_answer;
25 | data[0].incorrect_answers.map(item => options.push(item));
26 | options.splice(Math.floor(Math.random() * options.length + 1), 0, answer)
27 | // console.log(answer)
28 | generateTemplate(question, options, answer);
29 | }
30 |
31 | form.addEventListener('submit', (e) => {
32 | e.preventDefault();
33 |
34 | if (e.target.quiz.value) {
35 | checkQuiz(e.target.quiz.value);
36 | e.target.querySelector('button').style.display = 'none';
37 | generateButtons();
38 | }else{
39 | return;
40 | }
41 | });
42 |
43 | async function fetchQuiz() {
44 | const response = await fetch(baseURL);
45 | const data = await response.json();
46 | // console.log(data.results)
47 | return data.results;
48 | }
49 |
50 | function generateTemplate(question, options, answer) {
51 | removePlaceHolder();
52 | optionsEl.innerHTML = '';
53 | qusEl.innerText = question;
54 | options.map((option, index) => {
55 | const item = document.createElement('div');
56 | item.classList.add('option');
57 | item.innerHTML = `
58 |
59 | ${option}
60 | `
61 | optionsEl.appendChild(item);
62 | })
63 | }
64 |
65 | function checkQuiz(selected) {
66 | // console.log(selected, answer)
67 | answeredQus++;
68 | if (selected === answer) {
69 | score++;
70 | }
71 | updateScoreBoard();
72 | form.quiz.forEach(input => {
73 | if (input.value === answer) {
74 | input.parentElement.classList.add('correct')
75 | // console.log(input)
76 | }
77 | })
78 | }
79 |
80 | function generateButtons() {
81 | const finishBtn = document.createElement('button');
82 | finishBtn.innerText = 'Finish';
83 | finishBtn.setAttribute('type', 'button')
84 | finishBtn.classList.add('finish-btn')
85 | buttonsEl.appendChild(finishBtn)
86 |
87 | const nextBtn = document.createElement('button');
88 | nextBtn.innerText = 'Next Qus';
89 | nextBtn.setAttribute('type', 'button')
90 | nextBtn.classList.add('next-btn')
91 | buttonsEl.appendChild(nextBtn)
92 |
93 | nextBtn.addEventListener('click', getNextQuiz);
94 | finishBtn.addEventListener('click', finishQuiz);
95 | }
96 |
97 | function getNextQuiz() {
98 | const nextBtn = document.querySelector('.next-btn');
99 | const finishBtn = document.querySelector('.finish-btn');
100 |
101 | buttonsEl.removeChild(nextBtn);
102 | buttonsEl.removeChild(finishBtn);
103 |
104 | buttonsEl.querySelector('button[type="submit"]').style.display = 'block';
105 | quizApp();
106 |
107 | }
108 |
109 | function finishQuiz() {
110 |
111 | const nextBtn = document.querySelector('.next-btn');
112 | const finishBtn = document.querySelector('.finish-btn');
113 |
114 | buttonsEl.removeChild(nextBtn);
115 | buttonsEl.removeChild(finishBtn);
116 |
117 | buttonsEl.querySelector('button[type="submit"]').style.display = 'block';
118 |
119 | const overlay = document.createElement('div');
120 | overlay.classList.add('result-overlay');
121 | overlay.innerHTML = `
122 | ${score}/${answeredQus}
123 | Play Again
124 | `
125 | containerEl.appendChild(overlay);
126 | document.querySelector('.result-overlay button')
127 | .addEventListener('click', () => {
128 | containerEl.removeChild(overlay);
129 | playAgain();
130 | })
131 | console.log(score)
132 | }
133 |
134 | function updateScoreBoard() {
135 | scoreEl.innerText = score;
136 | answeredEl.innerText = answeredQus;
137 | }
138 |
139 | function playAgain() {
140 | score = 0;
141 | answeredQus = 0;
142 |
143 | quizApp();
144 | }
145 | function addPlaceholder(){
146 | const placeholder = document.createElement('div');
147 | placeholder.classList.add('placeholder')
148 | containerEl.appendChild(placeholder);
149 | }
150 |
151 | function removePlaceHolder(){
152 | const placeholderEl = document.querySelector('.container .placeholder')
153 | containerEl.removeChild(placeholderEl);
154 | }
155 | })();
--------------------------------------------------------------------------------
/day-27/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-27/placeholder.png
--------------------------------------------------------------------------------
/day-27/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Nunito:wght@600&display=swap');
2 | *{
3 | padding: 0;
4 | margin: 0;
5 | box-sizing: border-box;
6 | }
7 | html{
8 | font-family: 'Nunito', sans-serif;
9 | font-size: 20px;
10 | }
11 |
12 | section{
13 | min-height: 100vh;
14 | width: 100%;
15 | background-color: rgb(25, 25, 26);
16 | display: flex;
17 | align-items: center;
18 | justify-content: center;
19 | }
20 |
21 | .container{
22 | background-color: rgb(40, 40, 44);
23 | padding: 50px 30px 30px 30px;
24 | width: 90%;
25 | max-width: 600px;
26 | min-height: 500px;
27 | border-radius: 8px;
28 | color: aliceblue;
29 | position: relative;
30 | overflow: hidden;
31 | }
32 | .container .scoreBoard{
33 | position: absolute;
34 | top: 20px;
35 | right: 20px;
36 | }
37 | form h1{
38 | font-size: 1.4rem;
39 | line-height: 2rem;
40 | margin-bottom: 2rem;
41 | }
42 |
43 | form .option{
44 | font-size: 1.2rem;
45 | margin: 10px 0 0 10px;
46 | padding: 10px;
47 | transition: .3s ease background-color;
48 | border-radius: 4px;
49 | width: 100%;
50 | display: flex;
51 | align-items: center;
52 | justify-content: stretch;
53 | }
54 | form .option label{
55 | width: 100%;
56 | margin-left: 10px ;
57 | cursor: pointer;
58 | justify-self: stretch;
59 | }
60 | form .option:hover{
61 | background-color: rgb(23, 23, 24);
62 | }
63 | form .option input[type="radio"]:checked + label{
64 | color: rgb(0, 238, 255);
65 | }
66 | form .option.correct{
67 | background-color: green;
68 | }
69 | form button,
70 | .container .result-overlay button{
71 | width: 100%;
72 | margin-top: 20px;
73 | padding: 10px;
74 | font-size: 1.3rem;
75 | font-family: 'Montserrat';
76 | background-color: rgb(98, 100, 105);
77 | border: none;
78 | outline: none;
79 | color: rgb(20, 20, 20);
80 | cursor: pointer;
81 | transition: .3s ease background-color;
82 | }
83 | button:hover,
84 | .container .result-overlay button:hover{
85 | background-color: rgb(145, 148, 155);
86 | }
87 | .finish-btn, .next-btn{
88 | width: 50%;
89 | display: inline-block;
90 | }
91 | .finish-btn{
92 | border-right: 1px solid black;
93 | }
94 | .next-btn{
95 | border-left: 1px solid black;
96 | }
97 |
98 | .container .result-overlay{
99 | position: absolute;
100 | top: 0;
101 | left: 0;
102 | height: 100%;
103 | width: 100%;
104 | background-color: rgb(40, 40, 44);
105 | text-align: center;
106 | display: flex;
107 | align-items:center ;
108 | justify-content: center;
109 | flex-direction: column;
110 | }
111 | .container .result-overlay .final-result{
112 | font-size: 5rem;
113 | }
114 | .container .placeholder{
115 | position: absolute;
116 | top: 0;
117 | left: 0;
118 | height: 100%;
119 | width: 100%;
120 | background-image: url(./placeholder.png);
121 | background-color: rgb(40, 40, 44);
122 | background-position: center;
123 | background-size: 90%;
124 | background-repeat: no-repeat;
125 | }
126 |
127 | @media (max-width: 768px){
128 | html{
129 | font-size: 17px;
130 | }
131 | .container form h1{
132 | font-size: 1.5rem;
133 | }
134 | }
--------------------------------------------------------------------------------
/day-28/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Calculator
7 |
8 |
9 |
10 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/day-28/main.js:
--------------------------------------------------------------------------------
1 | const display1El = document.querySelector('.display-1');
2 | const display2El = document.querySelector('.display-2');
3 | const tempResultEl = document.querySelector('.temp-result');
4 | const numbersEl = document.querySelectorAll('.number');
5 | const operationEl = document.querySelectorAll('.operation');
6 | const equalEl = document.querySelector('.equal');
7 | const clearAllEl = document.querySelector('.all-clear');
8 | const clearLastEl = document.querySelector('.last-entity-clear');
9 | let dis1Num = '';
10 | let dis2Num = '';
11 | let result = null;
12 | let lastOperation = '';
13 | let haveDot = false;
14 |
15 | numbersEl.forEach( number => {
16 | number.addEventListener('click', (e)=>{
17 | if(e.target.innerText === '.' && !haveDot){
18 | haveDot = true;
19 | } else if (e.target.innerText === '.' && haveDot){
20 | return;
21 | }
22 | dis2Num += e.target.innerText;
23 | display2El.innerText = dis2Num;
24 | // console.log();
25 | })
26 | })
27 |
28 | operationEl.forEach( operation => {
29 | operation.addEventListener('click', (e)=> {
30 | if (!dis2Num) return;
31 | haveDot = false;
32 | const operationName = e.target.innerText;
33 | if (dis1Num && dis2Num && lastOperation){
34 | mathOperation();
35 |
36 | }else{
37 | result = parseFloat(dis2Num);
38 | }
39 | clearVar(operationName);
40 | lastOperation = operationName;
41 | console.log(result)
42 | })
43 | });
44 | function clearVar(name = ''){
45 | dis1Num += dis2Num + ' ' + name + ' ';
46 | display1El.innerText = dis1Num;
47 | display2El.innerText = '';
48 | dis2Num = '';
49 | tempResultEl.innerText = result;
50 | }
51 |
52 | function mathOperation() {
53 | if (lastOperation === 'x') {
54 | result = parseFloat(result) * parseFloat(dis2Num);
55 | } else if (lastOperation === '+') {
56 | result = parseFloat(result) + parseFloat(dis2Num);
57 | } else if (lastOperation === '-') {
58 | result = parseFloat(result) - parseFloat(dis2Num);
59 | } else if (lastOperation === '/') {
60 | result = parseFloat(result) / parseFloat(dis2Num);
61 | }else if( lastOperation === '%'){
62 | result = parseFloat(result) % parseFloat(dis2Num);
63 | }
64 | }
65 | // operation();
66 |
67 | equalEl.addEventListener('click', ()=> {
68 | if (!dis2Num || !dis1Num) return;
69 | haveDot = false;
70 | mathOperation();
71 | clearVar();
72 | display2El.innerText = result;
73 | tempResultEl.innerText = '';
74 | dis2Num = result;
75 | dis1Num = '';
76 | })
77 |
78 | clearAllEl.addEventListener('click', ()=>{
79 | dis1Num = '';
80 | dis2Num = '';
81 | display1El.innerText ='';
82 | display2El.innerText ='';
83 | result = '';
84 | tempResultEl.innerText = '';
85 | });
86 |
87 | clearLastEl.addEventListener('click', () => {
88 | display2El.innerText = '';
89 | dis2Num= '';
90 | });
91 |
92 | window.addEventListener('keydown', (e)=>{
93 | if(
94 | e.key === '0' ||
95 | e.key === '1' ||
96 | e.key === '2' ||
97 | e.key === '3' ||
98 | e.key === '4' ||
99 | e.key === '5' ||
100 | e.key === '6' ||
101 | e.key === '7' ||
102 | e.key === '8' ||
103 | e.key === '9' ||
104 | e.key === '.'
105 | ){
106 | clickButtonEl(e.key)
107 | // console.log(e.key)
108 | }else if(
109 | e.key === '+' ||
110 | e.key === '-' ||
111 | e.key === '/' ||
112 | e.key === '%'
113 | ){
114 | clickOperation(e.key);
115 | }
116 | else if(e.key === '*'){
117 | clickOperation('x')
118 | // console.log(e.key)
119 | } else if( e.key == "Enter" || e.key === '='){
120 | clickEqual();
121 | }
122 | // console.log(e.key)
123 | })
124 | function clickButtonEl(key) {
125 | numbersEl.forEach(button => {
126 | if (button.innerText === key) {
127 | button.click();
128 | }
129 | })
130 | }
131 | function clickOperation(key){
132 | operationEl.forEach( operation => {
133 | if(operation.innerText === key){
134 | operation.click()
135 | }
136 | })
137 | }
138 | function clickEqual(){
139 | equalEl.click();
140 | }
--------------------------------------------------------------------------------
/day-28/style.css:
--------------------------------------------------------------------------------
1 | *{
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | html{
7 | font-family: 'Montserrat', sans-serif;
8 | }
9 | section{
10 | background-color: rgb(18, 26, 31);
11 | min-height: 100vh;
12 | width: 100%;
13 | display: flex;
14 | align-items: center;
15 | justify-content: center;
16 | }
17 | .container{
18 | width: 90%;
19 | max-width: 400px;
20 | background-color: rgb(39, 55, 59);
21 | border-radius: 8px;
22 | overflow: hidden;
23 | }
24 | .display{
25 | background-color: rgb(182, 182, 182);
26 | height: 100px;
27 | width: 100%;
28 | text-align: right;
29 | padding: 20px;
30 | font-size: 30px;
31 | position: relative;
32 | }
33 | .display-1{
34 | opacity: .4;
35 | font-size: 20px;
36 | height: 20px;
37 | overflow: hidden;
38 | }
39 | .temp-result{
40 | position: absolute;
41 | bottom: 0;
42 | left: 10;
43 | font-size: 20px;
44 | opacity: .4;
45 | }
46 | .all_button{
47 | color: whitesmoke;
48 | display: grid;
49 | grid-template:repeat(4, 1fr) / repeat(4, 1fr) ;
50 | }
51 | .button{
52 | border: .5px solid rgba(92, 92, 92, 0.137);
53 | height: 100px;
54 | width: 100%;
55 | display: flex;
56 | align-items: center;
57 | justify-content: center;
58 | font-size: 30px;
59 | cursor: pointer;
60 | }
61 | .button:hover{
62 | background-color: rgb(30, 43, 46);
63 | }
64 | .btn-0{
65 | grid-column: 1/3;
66 | }
--------------------------------------------------------------------------------
/day-29/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShaifArfan/30days30submits/4d3d2ca44e7e71747fc4462530d30c63ce242672/day-29/bg.jpg
--------------------------------------------------------------------------------
/day-29/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
Welcome & Search By Location
16 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/day-29/mian.js:
--------------------------------------------------------------------------------
1 | const key = '6a73ed993fb67076477df40767903d8a';
2 | const formEl = document.querySelector('form');
3 | const details = document.querySelector('.details')
4 |
5 | formEl.addEventListener('submit', (e)=> {
6 | e.preventDefault();
7 | details.innerHTML = 'Loading... ';
8 | const location = e.target.location.value;
9 | weatherApp(location);
10 | formEl.reset();
11 | })
12 | async function weatherApp(location){
13 | const result = await fetchAPI(location);
14 | generateHTML(result);
15 |
16 | }
17 | async function fetchAPI(location){
18 | const baseURL = `https://cors-anywhere.herokuapp.com/http://api.weatherstack.com/current?access_key=${key}&query=${location}`;
19 |
20 | // Use this if you get any error with cors-anywhere
21 | // {headers: {
22 | // 'x-requested-with': 'text/plain'
23 | // }}
24 |
25 | const res = await fetch(baseURL, {
26 | headers: {
27 | 'x-requested-with': 'text/plain'
28 | }});
29 | const data = await res.json();
30 | console.log(data);
31 | return data;
32 | }
33 |
34 | function generateHTML(data){
35 | const html = `
36 | ${data.current.temperature}°c
37 | ${data.current.weather_descriptions.map(item => item).join(' ')}
38 |
39 |
Humidity- ${data.current.humidity}%
40 |
Wind Speed- ${data.current.wind_speed}km/h
41 |
Wind Dir- ${data.current.wind_dir}
42 |
Pressure- ${data.current.pressure}MB
43 |
44 | ${data.request.query}
45 | `;
46 | details.innerHTML = html;
47 | }
--------------------------------------------------------------------------------
/day-29/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@500&display=swap');
2 | *{
3 | padding: 0;
4 | margin: 0;
5 | box-sizing: border-box;
6 | }
7 | html{
8 | font-family: 'Montserrat';
9 | font-weight: 500;
10 | }
11 | section{
12 | min-height: 100vh;
13 | width: 100%;
14 | display: flex;
15 | align-items: center;
16 | background-color: rgb(34, 34, 34);
17 | padding: 100px 0;
18 | }
19 | .container{
20 | width: 90%;
21 | max-width: 400px;
22 | background-color: #00919F;
23 | margin: 0 auto;
24 | height: 600px;
25 | position: relative;
26 | display: flex;
27 | align-items: center;
28 | justify-content: center;
29 | overflow: hidden;
30 | z-index: 1;
31 | }
32 | .container::after{
33 | position: absolute;
34 | content: '';
35 | top: 50%;
36 | left: 50%;
37 | transform: translate(-50%, -50%);
38 | height: 120%;
39 | width: 120%;
40 | background:linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)), url(./bg.jpg);
41 | background-position: center;
42 | background-size: cover;
43 | filter: blur(3px);
44 | z-index: -1;
45 | }
46 | form{
47 | position: absolute;
48 | bottom: 0;
49 | left: 0;
50 | width: 100%;
51 | height: 50px;
52 | display: flex;
53 | align-items: center;
54 | justify-content: center;
55 | }
56 | form input{
57 | width: 100%;
58 | height: 100%;
59 | outline: none;
60 | border: none;
61 | background-color: #3a3a3a;
62 | font-size: 25px;
63 | padding: 10px;
64 | color: white;
65 | }
66 | form button[type="submit"]{
67 | width: 100px;
68 | height: 100%;
69 | outline: none;
70 | border: none;
71 | cursor: pointer;
72 | background-color: #676767;
73 | color: white;
74 | font-size: 30px;
75 | }
76 | form button ion-icon{
77 | margin-bottom: -6px;
78 | }
79 | form input::placeholder{
80 | font-family: 'Montserrat';
81 | letter-spacing: 1.2px;
82 | font-size: 22px;
83 | }
84 | .container .details{
85 | width: 80%;
86 | margin: 0 auto;
87 | background-color: #dfbebe94;
88 | text-align: center;
89 | padding: 30px 10px;
90 | border-radius: 8px;
91 | }
92 | .temp{
93 | font-size: 30px;
94 | }
95 | .status{
96 | margin: 10px 0 30px 0;
97 | }
98 | .more-info p{
99 | margin: 10px 0;
100 | font-size: 20px;
101 | }
102 |
103 | .query{
104 | margin-top: 20px;
105 | }
--------------------------------------------------------------------------------
/day-30/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Dot loading
7 |
8 |
9 |
10 |
22 |
23 |
--------------------------------------------------------------------------------
/day-30/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | padding: 0;
3 | margin: 0;
4 | box-sizing: border-box;
5 | }
6 | section {
7 | min-height: 100vh;
8 | width: 100%;
9 | background-color: rgb(22, 22, 22);
10 | display: flex;
11 | align-items: center;
12 | justify-content: center;
13 | }
14 | .container {
15 | margin: 0 50px;
16 | width: fit-content;
17 | height: auto;
18 | }
19 | .container .dot {
20 | height: 12px;
21 | width: 12px;
22 | background-color: whitesmoke;
23 | display: inline-block;
24 | margin: 0 5px;
25 | border-radius: 50px;
26 | }
27 | .container:nth-child(1) .dot {
28 | animation: dotLoaders 0.9s linear infinite forwards;
29 | }
30 | .container:nth-child(2) .dot {
31 | animation: dotLoaders2 1.5s linear infinite forwards;
32 | }
33 | .container .dot.dot-1 {
34 | animation-delay: 0.25s;
35 | }
36 | .container .dot.dot-2 {
37 | animation-delay: 0.5s;
38 | }
39 | .container .dot.dot-3 {
40 | animation-delay: 0.75s;
41 | }
42 | @keyframes dotLoaders {
43 | 0% {
44 | transform: translateY(0px);
45 | }
46 | 50% {
47 | transform: translateY(-20px);
48 | }
49 | 100% {
50 | transform: translateY(0px);
51 | }
52 | }
53 | @keyframes dotLoaders2 {
54 | 0% {
55 | background-color: rgba(255, 255, 255, 0.137);
56 | transform: scale(0.8);
57 | }
58 | 50% {
59 | background-color: rgb(255, 255, 255);
60 | transform: scale(1.5);
61 | }
62 | 100% {
63 | background-color: rgba(255, 255, 255, 0.137);
64 | transform: scale(0.8);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------