diff --git a/calculator/cover.png b/calculator/cover.png
new file mode 100644
index 0000000..58b6b36
Binary files /dev/null and b/calculator/cover.png differ
diff --git a/calculator/index.html b/calculator/index.html
new file mode 100644
index 0000000..1661d7e
--- /dev/null
+++ b/calculator/index.html
@@ -0,0 +1,49 @@
+
+
+
+
+ Simple Calculator - Practical JavaScript
+
+
+
+
+
+
+
+
C
+
%
+
x
+
1
+
2
+
3
+
-
+
4
+
5
+
6
+
/
+
7
+
8
+
9
+
+
+
0
+
.
+
=
+
+
+
+
+
+
+
diff --git a/calculator/script-solved.js b/calculator/script-solved.js
new file mode 100644
index 0000000..55120b6
--- /dev/null
+++ b/calculator/script-solved.js
@@ -0,0 +1,78 @@
+// প্রয়োজনীয় সব ইলিমেন্ট সিলেক্ট করে নিন
+const selectKeypad = document.querySelector('.keypad');
+const selectInput = document.querySelector('input[name=input]');
+const selectEqualBtn = document.querySelector('.btn-equal');
+const selectResult = document.querySelector('.result p');
+
+// ইনপুট ডাটা
+let data = '';
+
+// ইনপুট ফিল্ডের চেঞ্জ ইভেন্ট
+selectInput.addEventListener('change', (e) => {
+ // ইনপুট ফিল্ডের ইনপুট ডাটাতে স্টোর করে ফেলা
+ data = e.target.value;
+ // ডাটা অনুযায়ী ইকুয়্যাল বাটনের অবস্থা দেখা
+ equalBtnState(e.target.value);
+})
+
+// ক্যালকুলেটরের কীপ্যাড বাটনের ইভেন্ট, পুরোটা কীপ্যাডের উপ ইভেন্ট লাগানো হয়েছে
+selectKeypad.addEventListener('click', (e) => {
+ // ইলিমেন্ট যদি বাটনই হয় তাহলে অ্যাকশন নেওয়া
+ if(e.target.tagName==='P') {
+ // আমাদের বাটনের কাজ অনুযায়ী ডাটা সেট করা
+ switch (e.target.textContent) {
+ case 'C':
+ // এই কেস হলে ডাটা ক্লিয়ার করা ফেলা
+ data = '';
+ break;
+ case '=':
+ // এই কেস হলে ডাটাতে এটার কোনো ইফেক্ট পড়বে না
+ break;
+ case 'x':
+ // এই কেস হলে এটাকে আসল ম্যাথ অপারেটর * এ কনভার্ট করে ফেলা
+ data += '*';
+ break;
+ case '%':
+ // এই কেস হলে মূল ক্যালকুলেশনের জন্যে তৈরী করে একটা এক্সপ্রেশন তৈরী করা
+ data += '/100*'
+ break;
+ default:
+ // বাই ডিফল্ট বাটনের ভ্যালু ডাটাতে অ্যাড করা
+ data += e.target.textContent;
+ }
+ // ইনপুট ফিল্ডে ডাটা দেখানো
+ selectInput.value = data;
+
+ // ডাটা অনুযায়ী ইকুয়্যাল বাটনের অবস্থা দেখা
+ equalBtnState(selectInput.value);
+ }
+})
+
+// ইকুয়্যাল বাটনের ক্লিক হ্যান্ডেল করা
+selectEqualBtn.addEventListener('click', () => {
+ // আগে শিউর হওয়া ইকুয়্যাল বাটন ডিসাবল না এনাবল
+ if(!selectEqualBtn.classList.contains('disabled')) {
+ // আমাদের ম্যাথমেটিক্যাল এক্সপ্রেশন তৈরী, এখন এটাকে ইভালিউট করা
+ const result = eval(data);
+ // এবার রেসাল্ট ইউজারকে দেখানো
+ selectResult.textContent = result;
+ }
+})
+
+// ইকুয়্যাল বাটনের অবস্থার ফাংশন
+const equalBtnState = (value) => {
+ // ইনপুট ফিল্ডের ডাটা ভ্যালিডেট করা
+ if(validateInput(value)) {
+ // ইকুয়্যাল বাটন একমাত্র ইনপুট ক্যালকুলেট করার মতো হলেই ক্লিক এনাবল করা
+ selectEqualBtn.classList.remove('disabled');
+ } else {
+ // নাইলে বাটন ডিসাবল করে রাখা
+ selectEqualBtn.classList.add('disabled');
+ }
+}
+
+// ইনপুট ভ্যালিডেট করা, ইনপুট ক্যালকুলেশন করার মতো কিনা
+const validateInput = input => {
+ // রেগুলার এক্সপ্রেশন দিয়ে ইনপুট যাচাই
+ return (/^[-+]?[0-9\.]+?([-+*/x%]+[-+]?[0-9\.]+)*$/).test(input);
+}
diff --git a/calculator/script.js b/calculator/script.js
new file mode 100644
index 0000000..bc23d40
--- /dev/null
+++ b/calculator/script.js
@@ -0,0 +1,72 @@
+// Write your code here
+const selectKeypad = document.querySelector('.keypad');
+const selectInput = document.querySelector('input[name=input]');
+const selectEqualBtn = document.querySelector('.btn-equal');
+const selectResult = document.querySelector('.result p');
+
+let data = '';
+
+selectInput.addEventListener('change', (e) => {
+ // ইনপুট ফিল্ডের ইনপুট ডাটাতে স্টোর করে ফেলা
+ data = e.target.value;
+ // ডাটা অনুযায়ী ইকুয়্যাল বাটনের অবস্থা দেখা
+ equalBtnState(e.target.value);
+})
+
+selectKeypad.addEventListener('click', (e) => {
+ // ইলিমেন্ট যদি বাটনই হয়(যেখানে P ট্যাগ হচ্ছে বাটন) তাহলে অ্যাকশন নেওয়া
+ if(e.target.tagName==='P') {
+ // আমাদের বাটনের কাজ অনুযায়ী ডাটা সেট করা
+ switch (e.target.textContent) {
+ case 'C':
+ // এই কেস হলে ডাটা ক্লিয়ার করা ফেলা
+ data = '';
+ break;
+ case '=':
+ // এই কেস হলে ডাটাতে এটার কোনো ইফেক্ট পড়বে না
+ break;
+ case 'x':
+ // এই কেস হলে এটাকে আসল ম্যাথ অপারেটর * এ কনভার্ট করে ফেলা
+ data += '*';
+ break;
+ case '%':
+ // এই কেস হলে মূল ক্যালকুলেশনের জন্যে তৈরী করে একটা এক্সপ্রেশন তৈরী করা
+ data += '/100*'
+ break;
+ default:
+ // উপরের কোনো কেস না মিললে বাটনের ভ্যালু ডাটাতে অ্যাড করা
+ data += e.target.textContent;
+ }
+ // সবশেষে ইনপুট ফিল্ডে সেই ডাটা দেখানো
+ selectInput.value = data;
+
+ // আবার ডাটা অনুযায়ী ডাটা অনুযায়ী ইকুয়্যাল বাটনের অবস্থা দেখা
+ equalBtnState(selectInput.value);
+ }
+})
+
+selectEqualBtn.addEventListener('click', () => {
+ // আগে শিউর হওয়া ইকুয়্যাল বাটন ডিসাবল না এনাবল
+ if(!selectEqualBtn.classList.contains('disabled')) {
+ // আমাদের ম্যাথমেটিক্যাল এক্সপ্রেশন তৈরী, এখন এটাকে ইভালিউট করা
+ const result = eval(data);
+ // এবার রেসাল্ট ইউজারকে দেখানো
+ selectResult.textContent = result;
+ }
+})
+
+const equalBtnState = (value) => {
+ // ইনপুট ফিল্ডের ডাটা ভ্যালিডেট করা
+ if(validateInput(value)) {
+ // ইকুয়্যাল বাটন একমাত্র ইনপুট ক্যালকুলেট করার মতো হলেই ক্লিক এনাবল করা
+ selectEqualBtn.classList.remove('disabled');
+ } else {
+ // নাইলে বাটন ডিসাবল করে রাখা
+ selectEqualBtn.classList.add('disabled');
+ }
+}
+
+const validateInput = (input) => {
+ // রেগুলার এক্সপ্রেশন দিয়ে ইনপুট যাচাই
+ return (/^[-+]?[0-9\.]+?([-+*/x%]+[-+]?[0-9\.]+)*$/).test(input);
+}
diff --git a/calculator/style.css b/calculator/style.css
new file mode 100644
index 0000000..b21de73
--- /dev/null
+++ b/calculator/style.css
@@ -0,0 +1,143 @@
+@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,900');
+
+* {
+ box-sizing: border-box;
+ margin: 0;
+}
+
+html, body {
+ margin: 0;
+ padding: 0;
+ line-height: 1;
+}
+
+body {
+ min-height: 100vh;
+ width: 100%;
+ font-family: 'Roboto', sans-serif;
+ font-weight: 300;
+ text-align: center;
+ display: flex;
+ color: #333;
+ align-items: center;
+ background-image: url(cover.png);
+ background-color: #f2f2f2;
+ background-size: cover;
+ background-position: center;
+}
+
+body>div {
+ flex: 1;
+}
+
+.calculator {
+ width: 320px;
+ margin: 0 auto;
+ background: #fff;
+ border-radius: 4px;
+ box-shadow: 0 0 20px -10px rgba(0, 0, 0, 0.5);
+}
+
+.display {
+ color: #4b4c4c;
+ padding: 30px 25px;
+ font-size: 42px;
+ text-align: right;
+ background-color: #efefef;
+}
+
+.display .result {
+ overflow: hidden;
+}
+
+.display .inputs input {
+ font-size: 22px;
+ font-weight: 900;
+ width: 100%;
+ background: transparent;
+ border: none;
+ text-align: right;
+ color: rgba(0, 0, 0, 0.5);
+ letter-spacing: 3px;
+ font-family: 'Roboto', sans-serif;
+ font-weight: 900;
+}
+
+.keypad {
+ display: flex;
+ flex-wrap: wrap;
+ padding: 20px 10px;
+}
+
+.keypad>p {
+ flex-basis: calc(100% / 4 - 30px);
+ margin: 10px 15px;
+ font-weight: 900;
+ padding: 15px 10px;
+ border-radius: 50px;
+}
+
+.keypad .big {
+ flex: 2;
+ flex-basis: calc(100% / 3)
+}
+
+.keypad .function {
+ background: #efefef;
+ box-shadow: 0 5px 13px -5px rgba(0, 0, 0, 0.5);
+}
+
+.keypad .col-purple {
+ background: #9C27B0;
+ color: #fff;
+}
+
+.keypad .col-orange {
+ background: #FF9800;
+ color: #fff;
+}
+
+.keypad .col-deepgreen {
+ background: #1B5E20;
+ color: #fff;
+}
+
+.keypad .col-red {
+ background-color: #F44336;
+ color: #fff;
+}
+
+.keypad .col-green {
+ background: #4CAF50;
+ color: #fff;
+}
+
+
+.keypad .disabled {
+ cursor: not-allowed;
+ background: #E0E0E0;
+}
+
+.copyright {
+ margin-top: 45px;
+}
+
+.copyright ul {
+ margin: 0;
+ list-style: none;
+ padding: 0;
+}
+
+.copyright ul li {
+ display: inline-block;
+ margin: 0 5px;
+ font-weight: 900;
+ font-size: 13px;
+}
+
+.copyright ul li a {
+ text-decoration: none;
+ padding: 3px 8px;
+ border-radius: 4px;
+ background: #fff;
+}
diff --git a/index.html b/click-game/index.html
similarity index 100%
rename from index.html
rename to click-game/index.html
diff --git a/script-solved.js b/click-game/script-solved.js
similarity index 100%
rename from script-solved.js
rename to click-game/script-solved.js
diff --git a/click-game/script.js b/click-game/script.js
new file mode 100644
index 0000000..69af50b
--- /dev/null
+++ b/click-game/script.js
@@ -0,0 +1,56 @@
+// Write your code here
+const stats = document.querySelector('.stats'); // যেখানে ক্লিকের কাউন্ট দেখাবে
+const btnStart = document.querySelector('button[name=start]'); // স্টার্ট বাটন
+const btnClick = document.querySelector('button[name=click]'); // ক্লিক বাটন
+
+const winScore = 10; // উইন স্কোর
+let count = 0; // কাউন্ট করার ভ্যারিয়েবল
+
+btnStart.addEventListener('click', () => {
+ start();
+});
+
+btnClick.addEventListener('click', () => {
+ // কাউন্ট এক করে বাড়ানো
+ count++;
+ // কাউন্টটা ইউআইতে দেখানো
+ stats.textContent = count;
+});
+
+const start = () => {
+ // কাউন্ট জিরোতে সেট করা
+ count = 0;
+ // এখন এই কাউন্টটাকে ইউআইতে দেখানো
+ stats.textContent = count;
+ // ক্লিক বাটন থেকে ডিসাবল্ড অবস্থা সরিয়ে ফেলা
+ btnClick.removeAttribute('disabled');
+ // কাউন্ট শুরু করা
+ startCounting();
+}
+
+const startCounting = () => {
+ // সেট টাইম আউট ফাংশন ২ সেকেন্ড এর জন্যে অপেক্ষা করবে
+ setTimeout(() => {
+ // উইন হয়েছে দেখবো
+ if(isWin()) {
+ // উইন হলে উইনের টেক্সট দেখাবো
+ stats.textContent = 'You Won!';
+ } else {
+ // উইন না হলে উইন হয়নি সে টেক্সট দেখাবো
+ stats.textContent = 'You Lost!';
+ }
+ // ফলাফল দেখানো হয়ে গেলে ক্লিক বাটন ডিসাবল করে ফেলবো
+ btnClick.setAttribute('disabled', true);
+ }, 2000);
+}
+
+const isWin = () => {
+ // স্কোর চেক করা
+ if(count < winScore) {
+ // কাউন্ট উইনস্কোর থেকে ছোটো হলে উইন হয়নি
+ return false;
+ } else {
+ // কাউন্ট উইনস্কোর থেকে বড় হলে উইন হয়েছে
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/style.css b/click-game/style.css
similarity index 100%
rename from style.css
rename to click-game/style.css
diff --git a/script.js b/script.js
deleted file mode 100644
index b55091c..0000000
--- a/script.js
+++ /dev/null
@@ -1 +0,0 @@
-// Write your code here
diff --git a/tip-calculator/cover.jpg b/tip-calculator/cover.jpg
new file mode 100644
index 0000000..84ef43c
Binary files /dev/null and b/tip-calculator/cover.jpg differ
diff --git a/tip-calculator/index.html b/tip-calculator/index.html
new file mode 100644
index 0000000..0fcb75e
--- /dev/null
+++ b/tip-calculator/index.html
@@ -0,0 +1,50 @@
+
+
+
+
+ Simple Tip Calculator - Practical JavaScript
+
+
+
+
+
+
+
+
+
+
Tip
+
BDT 0.00
+
Per Person
+
+
+
Total
+
BDT 0.00
+
Per Person
+
+
+
+
+
+
+
+
diff --git a/tip-calculator/script-solved.js b/tip-calculator/script-solved.js
new file mode 100644
index 0000000..c5215bc
--- /dev/null
+++ b/tip-calculator/script-solved.js
@@ -0,0 +1,51 @@
+// প্রয়োজনীয় সব ইলিমেন্ট সিলেক্ট করে নিন
+const tipCalculator = document.querySelector('.tip-calculator');
+const selectTotal = document.querySelector('.amount_total span');
+const selectTipPerPerson = document.querySelector('.tip_per_person span');
+
+// ডাটা স্ট্রাকচার, ইনপুট ফিল্ডের নামের সাথে মিল রেখে
+const data = {
+ bill: 0,
+ tip: 0,
+ person: 1
+}
+
+// ইনপুট ভ্যালিডেট করা, ইনপুট আসলেই নাম্বার কিনা
+const validateInput = input => {
+ return (/^\d+$/).test(input);
+}
+
+// ফর্মের ইনপুট ফিল্ডে কোনোরকম পরিবর্তন আসলেই আমরা অ্যাকশন নিবো
+tipCalculator.addEventListener('change', (e) => {
+ // ফর্মের ইনপুট ঠিক আছে কি নেই সেটার উপর ভিত্তি করে এখানে অ্যাকশন নিবো
+ if(validateInput(e.target.value)) {
+ // ইনপুট ঠিক থাকলে আমরা আমাদের এরর ক্লাসটা সরিয়ে নিবো ইনপুট থেকে
+ e.target.classList.remove('err');
+
+ // এখন আমরা আমাদের টার্গেগেটেড ইলিমেন্টটার ভ্যালু অ্যাসাইন করবো(এজন্যেই ডাটা স্ট্রাকচারের কীগুলোর নাম ইনপুট ফিল্ডের নামের সাথে মিল রেখেছি), আর সেই ভ্যালো যাতে ফ্লোট নাম্বার হয় সেটাও খেয়াল রাখবো
+ data[e.target.name] = parseFloat(e.target.value);
+
+ // টোটাল টিপ কতো আসে সেটা হিসেব করা
+ const tip = (data.bill * data.tip) / 100;
+
+ // টোটাল হিসেব করবো
+ let total = data.bill + tip;
+ // পার পার্সন হিসেব করা
+ total = total / data.person;
+ // টোটালটার দশমিককে ফিক্সড করে দেওয়া
+ total = total.toFixed(2);
+ // টোটালটা আমাদের ডকুমেন্ট এ শো করাবো
+ selectTotal.textContent = total;
+
+ // পার পার্শনের টিপ কতো আসে সেটা হিসেব করা
+ let tip_per_person = tip / data.person;
+ // দশমিককে ফিক্সড করে দেওয়
+ tip_per_person = tip_per_person.toFixed(2);
+ // ডকুমেন্ট এ শো করানো
+ selectTipPerPerson.textContent = tip_per_person;
+
+ } else {
+ // ইনপুট ভ্যালিড না হলে এরর ক্লাস লাগাবো ইউজারকে সুন্দর একটা ভুল হয়েছে ইফেক্ট দেওয়ার জন্যে
+ e.target.classList.add('err');
+ }
+});
diff --git a/tip-calculator/script.js b/tip-calculator/script.js
new file mode 100644
index 0000000..b662155
--- /dev/null
+++ b/tip-calculator/script.js
@@ -0,0 +1,50 @@
+// Write your code here
+const tipCalculator = document.querySelector('.tip-calculator');
+const selectTotal = document.querySelector('.amount_total span');
+const selectTipPerPerson = document.querySelector('.tip_per_person span');
+
+const data = {
+ bill: 0,
+ tip: 0,
+ person: 1
+}
+
+tipCalculator.addEventListener('change', (e) => {
+ // ইনপুট ঠিক আছে কি নেই সেটার উপর ভিত্তি করে এখানে অ্যাকশন নিবো
+ if(validateInput(e.target.value)) {
+ // ইনপুট ঠিক থাকলে আমরা আমাদের এরর ক্লাস(যদি থাকে) সরিয়ে নিবো
+ // ইনপুট থেকে। এই অতিরিক্ত ক্লাসের সাহায্যে এরর থাকলে আমরা আলাদা
+ // সিএসএস দিয়ে স্টাইলিং করতে পারবো
+ e.target.classList.remove('err');
+
+ // এখন আমরা আমাদের টার্গেগেটেড ইলিমেন্টটার ভ্যালু অ্যাসাইন করবো
+ // (এজন্যেই ডাটা স্ট্রাকচারের কীগুলোর নাম ইনপুট ফিল্ডের নামের সাথে
+ // মিল রেখেছি), আর সেই ভ্যালো যাতে ফ্লোট নাম্বার হয় সেটাও খেয়াল রাখবো
+ data[e.target.name] = parseFloat(e.target.value);
+ // টোটাল টিপ কতো আসে সেটা হিসেব করবো
+ const tip = (data.bill * data.tip) / 100;
+ // টোটাল হিসেব করবো
+ let total = data.bill + tip;
+ // পার পার্সন হিসেব করবো
+ total = total / data.person;
+ // টোটালটার দশমিককে ফিক্সড করে দিবো
+ total = total.toFixed(2);
+ // টোটালটা আমাদের ডকুমেন্ট এ শো করাবো
+ selectTotal.textContent = total;
+
+ // পার পার্শনের টিপ কতো আসে সেটা হিসেব করবো
+ let tip_per_person = tip / data.person;
+ // দশমিককে ফিক্সড করে দিবো
+ tip_per_person = tip_per_person.toFixed(2);
+ // ডকুমেন্ট এ শো করাবো
+ selectTipPerPerson.textContent = tip_per_person;
+ } else {
+ // ইনপুট ভ্যালিড না হলে এরর ক্লাস লাগাবো ইউজারকে সুন্দর একটা
+ // ভুল হয়েছে ইফেক্ট দেওয়ার জন্যে
+ e.target.classList.add('err');
+ }
+});
+
+const validateInput = input => {
+ return (/^\d+$/).test(input);
+}
diff --git a/tip-calculator/style.css b/tip-calculator/style.css
new file mode 100644
index 0000000..9a3a95f
--- /dev/null
+++ b/tip-calculator/style.css
@@ -0,0 +1,124 @@
+@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,900');
+
+* {
+ box-sizing: border-box;
+ margin: 0;
+}
+
+html, body {
+ margin: 0;
+ padding: 0;
+ line-height: 1;
+}
+
+body {
+ min-height: 100vh;
+ width: 100%;
+ font-family: 'Roboto', sans-serif;
+ font-weight: 300;
+ text-align: center;
+ display: flex;
+ align-items: center;
+ background: url(cover.jpg);
+ background-size: cover;
+ background-position: center;
+}
+
+body>div {
+ flex: 1;
+}
+
+.header h2 {
+ color: #fff;
+ margin-bottom: 25px;
+}
+
+.calculator {
+ display: flex;
+ color: rgba(0, 0, 0, 0.75);
+ padding: 25px;
+ width: 600px;
+ margin: 0 auto;
+ border-radius: 4px;
+ background: #fff;
+}
+
+.calculator>div,
+.calculator>form {
+ flex: 1;
+ padding: 0 10px;
+}
+
+.result {
+ align-self: center;
+}
+
+.tip_per_person {
+ border-bottom: solid 1px rgba(255, 255, 255, 0.25);
+}
+
+.result div {
+ padding: 15px 0;
+}
+
+.result div p {
+ font-size: 18px;
+ text-transform: uppercase;
+}
+
+.result div .amount_tip,
+.result div .amount_total {
+ font-size: 36px;
+ font-weight: 900;
+ margin: 5px 0;
+}
+
+input {
+ border: solid 2px rgba(0, 0, 0, 0.2);
+ padding: 15px 10px;
+ font-size: 15px;
+ width: 100%;
+ border-radius: 4px;
+}
+
+input.err {
+ border: solid 2px #F44336;
+}
+
+.input-group {
+ margin: 10px 0;
+}
+
+.input-group label {
+ color: rgba(0, 0, 0, 0.75);
+ display: block;
+ text-align: left;
+ font-weight: 900;
+ text-transform: uppercase;
+ margin-bottom: 5px;
+}
+
+.copyright {
+ margin-top: 45px;
+ color: #fff;
+}
+
+.copyright ul {
+ margin: 0;
+ list-style: none;
+ padding: 0;
+}
+
+.copyright ul li {
+ display: inline-block;
+ margin: 0 5px;
+ font-weight: 900;
+ font-size: 13px;
+}
+
+.copyright ul li a {
+ text-decoration: none;
+ padding: 3px 8px;
+ border-radius: 4px;
+ background: #fff;
+}
diff --git a/to-do-list/cover.jpg b/to-do-list/cover.jpg
new file mode 100644
index 0000000..86ab480
Binary files /dev/null and b/to-do-list/cover.jpg differ
diff --git a/to-do-list/index.html b/to-do-list/index.html
new file mode 100644
index 0000000..5ef3cc2
--- /dev/null
+++ b/to-do-list/index.html
@@ -0,0 +1,38 @@
+
+
+
+
+ Simple To Do List - Practical JavaScript
+
+
+
+
+
+
+
To Do List
+
+
+
+
+ - X7 minutes exercise
+ - XBuy some chocolates
+ - XMake a Project
+ - XBuy a Jacket
+ - XMath Homework
+ - XStart React Native
+
+
+
+
+
+
+
+
diff --git a/to-do-list/script-solved.js b/to-do-list/script-solved.js
new file mode 100644
index 0000000..1f64c7e
--- /dev/null
+++ b/to-do-list/script-solved.js
@@ -0,0 +1,79 @@
+// প্রয়োজনীয় সব ইলিমেন্ট সিলেক্ট করে নিন
+const selectItem = document.querySelector('.body ul');
+const selectForm = document.querySelector('.todo');
+
+// আইটেমে ক্লিক করলে, ক্লিক হ্যান্ডেলারটা লাগিয়েছি আন-অর্ডার লিস্টের উপরে যাতে সবগুলো চাইল্ড লিস্টকে আমরা অ্যাক্সেস করতে পারি
+selectItem.addEventListener('click', (e) => {
+ // আইটেমটটা লিস্ট হলেও অ্যাকশন নেওয়া হবে
+ if(e.target.tagName==='LI') {
+ // লিস্ট কি অলরেডি ডান করা আছে?
+ if(e.target.classList.contains('done')) {
+ // ডান করা লিস্টে ক্লিক করলে সেটা আন-ডান হয়ে যাবে
+ e.target.classList.remove('done');
+ } else {
+ // ডান নাই এমন লিস্টে ক্লিক করলে সেটা ডান হবে
+ e.target.classList.add('done');
+ }
+ }
+
+ // লিস্টের ভিতরে রিমুভ বাটনে ক্লিক করা হয়েছে কিনা দেখার জন্যে
+ if(e.target.classList.contains('remove')) {
+ // রিমুভ বাটনে ক্লিক করা হলে সেটার প্যারেন্ট নোডে গিয়ে রিমুভ করে ফেলা
+ e.target.parentNode.remove()
+ }
+})
+
+// ফর্ম সাবমিশন হ্যান্ডেল করার জন্যে
+selectForm.addEventListener('submit', (e) => {
+ // ফর্মের ডিফল্ট আচরণ বন্ধ করার জন্যে
+ e.preventDefault();
+ // ইনপুট ফিল্ড থেকে ভ্যালুটা বের করে নিয়ে আসলাম
+ const input = e.target.task.value;
+ // ইনপুট ভ্যালিডেট করা হচ্ছে, ভ্যালিডেট ফাংশন দিয়ে
+ if(validateInput(input, e.target.task)) {
+ // ইনপুট ভ্যালিডেট হলে আমাদের লিস্টের প্রথম দিকে নতুন আইটেমটা ঢুকাবো নতুন আইটেমের একটা ফাংশন দিয়ে(পরে ডিফাইন করা হয়েছে)
+ selectItem.insertAdjacentElement('afterbegin', newItem(e.target.task.value));
+ // সব কাজ শেষে ইনপুট ফিল্ড খালি করে ফেলা
+ e.target.task.value = '';
+ }
+});
+
+// ইনপুট ভ্যালিডেট করা, ইনপুট ক্যালকুলেশন করার মতো কিনা
+const validateInput = (input, element) => {
+ // ইনপুট ফিল্ডে ইনপুট আছে কিনা?
+ if(input) {
+ // ইনপুট ফিল্ডে ইনপুট থাকলে যদি এরর ক্লাস থাকে তাহলে সেটা সরিয়ে ফেলা, আর এরর ক্লাস না থাকলেও কোনো সমস্যা নাই
+ element.parentNode.classList.remove('error');
+ // সত্য রিটার্ণ করা
+ return true;
+ } else {
+ // ইনপুট ফিল্ডে কোনো ইনপুট না থাকলে এরর ক্লাস অ্যাড করা
+ element.parentNode.classList.add('error');
+ // মিথ্যা রিটার্ণ করা
+ return false;
+ }
+}
+
+// নতুন আইটেম তৈরী করা
+const newItem = (content) => {
+ // নতুন লিস্ট নেওয়া
+ const createAItem = document.createElement('li');
+ // কন্টেন্টটা লিস্ট এর ভিতরে দেওয়া
+ createAItem.textContent = content;
+ // লিস্ট এ রিমুভ বাটন রিমুভ ফাংশনের সাহায্যে অ্যাড করা
+ createAItem.insertAdjacentElement('afterbegin', removeButton());
+ // এবার নতুন এই ইলিমেন্ট রিটার্ণ করা
+ return createAItem;
+}
+
+// রিমুভ বাটন তৈরী করা
+const removeButton = () => {
+ // নতুন একটা ইলিমেন্ট বানানো
+ const createRemoveBtn = document.createElement('span');
+ // ইলিমেন্ট এ রিমুভ এর ক্লাস লাগানো
+ createRemoveBtn.classList.add('remove');
+ // ইলিমেন্ট এর ভিতরে ক্রস বাটন অ্যাড করা
+ createRemoveBtn.textContent = 'X';
+ // এবার নতুন এই ইলিমেন্টটা রিটার্ন করা
+ return createRemoveBtn;
+}
diff --git a/to-do-list/script.js b/to-do-list/script.js
new file mode 100644
index 0000000..d6d7a04
--- /dev/null
+++ b/to-do-list/script.js
@@ -0,0 +1,75 @@
+// Write your code here
+const selectItem = document.querySelector('.body ul');
+const selectForm = document.querySelector('.todo');
+
+selectItem.addEventListener('click', (e) => {
+ // আইটেমটটা লিস্ট হলেই অ্যাকশন নেওয়া হবে
+ if(e.target.tagName==='LI') {
+ // লিস্ট কি অলরেডি কমপ্লিট করা আছে?
+ if(e.target.classList.contains('done')) {
+ // কমপ্লিট করা লিস্টে ক্লিক করলে সেটা ইন- কমপ্লিট হয়ে যাবে
+ e.target.classList.remove('done');
+ } else {
+ // কমপ্লিট নাই এমন লিস্টে ক্লিক করলে সেটা কমপ্লিট হবে
+ e.target.classList.add('done');
+ }
+ }
+
+ // লিস্টের ভিতরে রিমুভ বাটনে ক্লিক করা হয়েছে কিনা দেখার জন্যে
+ if(e.target.classList.contains('remove')) {
+ // রিমুভ বাটনে ক্লিক করা হলে সেটার প্যারেন্ট নোডে গিয়ে রিমুভ করে ফেলবো
+ e.target.parentNode.remove()
+ }
+})
+
+selectForm.addEventListener('submit', (e) => {
+ // ফর্মের ডিফল্ট আচরণ বন্ধ করবো
+ e.preventDefault();
+ // ইনপুট ফিল্ড থেকে ভ্যালুটা বের করে নিয়ে আসবো
+ const input = e.target.task.value;
+ // ইনপুট ভ্যালিডেট করা হচ্ছে, ভ্যালিডেট ফাংশন দিয়ে যেটা একটা পরেই ডিফাইন করবো
+ if(validateInput(input, e.target.task)) {
+ // ইনপুট ভ্যালিডেট হলে আমাদের লিস্টের প্রথম দিকে নতুন আইটেমটা ঢুকাবো নতুন আইটেমের একটা ফাংশন দিয়ে যেটা আমরা পরে ডিফাইন করবো
+ selectItem.insertAdjacentElement('afterbegin', newItem(e.target.task.value));
+ // সব কাজ শেষে ইনপুট ফিল্ড খালি করে ফেলবো
+ e.target.task.value = '';
+ }
+});
+
+const validateInput = (input, element) => {
+ // ইনপুট ফিল্ডে ইনপুট আছে কিনা সেটা দেখবো
+ if(input) {
+ // ইনপুট ফিল্ডে ইনপুট থাকলে যদি এরর ক্লাস থাকে তাহলে সেটা সরিয়ে ফেলবো
+ element.parentNode.classList.remove('error');
+ // এবং সত্য রিটার্ণ করবো
+ return true;
+ } else {
+ // ইনপুট ফিল্ডে কোনো ইনপুট না থাকলে এরর ক্লাস অ্যাড করবো
+ element.parentNode.classList.add('error');
+ // এবং মিথ্যা রিটার্ণ করা
+ return false;
+ }
+}
+
+
+const newItem = (content) => {
+ // নতুন লিস্ট ইলিমেন্ট তৈরী করবো
+ const createAItem = document.createElement('li');
+ // কন্টেন্টটা আমাদের তৈরীকৃত লিস্ট আইটেমে দিবো
+ createAItem.textContent = content;
+ // লিস্ট এর ভিতরে সবার আগে রিমুভ বাটন রিমুভ ফাংশনের সাহায্যে অ্যাড করবো, এই রিমুভ ফাংশন আমরা একটু পরেই ডিফাইন করবো
+ createAItem.insertAdjacentElement('afterbegin', removeButton());
+ // এবার নতুন এই ইলিমেন্টটা রিটার্ণ করবো
+ return createAItem;
+}
+
+const removeButton = () => {
+ // নতুন একটা span ইলিমেন্ট তৈরী করবো
+ const createRemoveBtn = document.createElement('span');
+ // ইলিমেন্ট এ রিমুভ এর ক্লাস লাগাবো
+ createRemoveBtn.classList.add('remove');
+ // ইলিমেন্ট এর ভিতরে একটা ক্রস বাটন অ্যাড করবো
+ createRemoveBtn.textContent = 'X';
+ // এবার নতুন এই ইলিমেন্টটা রিটার্ন করবো
+ return createRemoveBtn;
+}
diff --git a/to-do-list/style.css b/to-do-list/style.css
new file mode 100644
index 0000000..5153914
--- /dev/null
+++ b/to-do-list/style.css
@@ -0,0 +1,154 @@
+@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,900');
+
+* {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+}
+
+html, body {
+ margin: 0;
+ padding: 0;
+ line-height: 1;
+}
+
+body {
+ min-height: 100vh;
+ width: 100%;
+ font-family: 'Roboto', sans-serif;
+ font-weight: 300;
+ text-align: center;
+ display: flex;
+ color: #333;
+ align-items: center;
+ background-image: url(cover.jpg);
+ background-color: #f2f2f2;
+ background-size: cover;
+ background-position: center;
+}
+
+ul {
+ list-style: none;
+}
+
+body>div {
+ flex: 1;
+}
+
+.todolist {
+ background: #fff;
+ padding: 30px 15px;
+ width: 320px;
+ margin: 0 auto;
+ border-radius: 15px;
+ box-shadow: 2px 2px 15px -5px rgba(0, 0, 0, 0.5);
+}
+
+.head h3 {
+ font-size: 26px;
+ text-transform: uppercase;
+ margin-bottom: 25px;
+ color: rgba(0, 0, 0, 0.5);
+}
+
+.todo {
+ display: flex;
+ border-radius: 40px;
+ margin-bottom: 25px;
+ padding: 8px;
+ box-shadow: 0 0 30px -10px rgba(0, 0, 0, 0.5);
+}
+
+.todo.error {
+ box-shadow: 0 0 30px -5px #F44336;
+}
+
+.todo>* {
+ flex: 5;
+}
+
+.todo input {
+ padding: 10px 15px;
+ font-family: 'Roboto', sans-serif;
+ border: none;
+ font-size: 16px;
+}
+
+.todo input:focus {
+ outline: none;
+}
+
+.todo button[name=submit] {
+ flex: 1;
+ background: #4CAF50;
+ font-size: 38px;
+ border: none;
+ cursor: pointer;
+ color: #fff;
+ border-radius: 40px;
+}
+
+.remove {
+ visibility: hidden;
+ position: absolute;
+ left: 0;
+ display: inline-block;
+ background: #F44336;
+ color: #fff;
+ font-size: 13px;
+ padding: 2px 5px;
+ border-radius: 34px;
+ margin-right: 10px;
+ cursor: pointer;
+ transition: 0.2s all;
+}
+
+.body ul {
+ padding: 0 20px;
+}
+
+.body ul li {
+ position: relative;
+ font-size: 18px;
+ padding: 10px 0;
+ text-align: left;
+ transition: all 0.5s;
+}
+
+.body ul li:hover {
+ padding-left: 30px;
+}
+
+.body ul li:hover .remove {
+ visibility: visible;
+}
+
+.body ul li.done {
+ color: rgba(0, 0, 0, 0.3);
+ text-decoration: line-through;
+}
+
+.copyright {
+ margin-top: 45px;
+}
+
+.copyright ul {
+ margin: 0;
+ list-style: none;
+ padding: 0;
+}
+
+.copyright ul li {
+ display: inline-block;
+ margin: 0 5px;
+ font-weight: 900;
+ font-size: 13px;
+}
+
+.copyright ul li a {
+ text-decoration: none;
+ padding: 3px 8px;
+ border-radius: 4px;
+ background: #333;
+ color: #fff;
+}