diff --git a/index.html b/index.html
new file mode 100644
index 0000000..0aa31ca
--- /dev/null
+++ b/index.html
@@ -0,0 +1,47 @@
+
+
+
+
+ vanilla-todo 백승선
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..dbd106a
--- /dev/null
+++ b/style.css
@@ -0,0 +1,287 @@
+
+
+/*reset*/
+body {
+ margin: 0;
+ font-family: arial, sans-serif;
+ background: #e2e8f0;
+}
+
+/* Header layout with flexbox */
+.header {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: #0f172a;
+ color: white;
+ padding: 14px 16px;
+}
+
+.menu {
+ position: absolute;
+ left: 16px;
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: 8px;
+}
+
+.menuIcon,
+.menuIcon::before,
+.menuIcon::after {
+ display: block;
+ width: 24px;
+ height: 2px;
+ background: white;
+ border-radius: 2px;
+ content: "";
+ position: relative;
+}
+
+.menuIcon::before,
+.menuIcon::after {
+ position: absolute;
+ left: 0;
+}
+
+.menuIcon::before { top: -10px; }
+.menuIcon::after { top: 10px; }
+
+.menuTab {
+ position: fixed;
+ background: #e2e8f0;
+ width: 300px;
+ top: 0; left: 0; bottom: 0;
+ transform: translateX(-100%);
+ transition: transform .25s ease;
+}
+
+.menuTab.active {
+ transform: translateX(0);
+}
+
+.menuContent {
+ display: flex;
+ height: 100%;
+ flex-direction: column;
+ gap: 8px;
+ font-size: 15px;
+}
+
+.options {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ margin-top: 80px;
+ align-items: center;
+ gap: 110px;
+ padding: 20px;
+
+}
+
+.nWeek {
+ width: 120px;
+ height: 30px;
+ font-size: 16px;
+ border-radius: 10px;
+}
+
+.lWeek {
+ width: 120px;
+ height: 30px;
+ font-size: 16px;
+ border-radius: 10px;
+}
+
+.menuDatePicker{
+ margin-top: 80px;
+ margin-left: 88px;
+ font-size: 16px;
+ width: 120px;
+ height: 30px;
+ border-radius: 10px;
+
+}
+
+#closeMenu {
+ position: absolute;
+ font-size: 30px;
+ width: 22px;
+ margin-top: 15px;
+ margin-left: 20px;
+ background: none;
+ border: none;
+ cursor: pointer;
+}
+/* Centered title */
+.title {
+ margin: 0;
+ font-size: 35px;
+ font-weight: 600;
+}
+
+.dateSelector {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: none;
+ margin: 30px;
+ gap: 20px;
+}
+
+.date {
+ font-size: 20px;
+ background: none;
+ border: none;
+}
+
+.today {
+ display: flex;
+ color: #0f172a;
+ font-size: 20px;
+ background: none;
+ border: none;
+}
+
+.inputContainer {
+ display: flex;
+ justify-content: center;
+ gap: 20px;
+ margin: 40px auto;
+ background: whitesmoke;
+ border-radius: 20px;
+ padding-left: 10px;
+ width: 400px;
+ height: 50px;
+}
+
+.input {
+ font-size: 23px;
+ border: none;
+ outline: none;
+ background: none;
+ color: #0f172a;
+}
+
+.register {
+ font-size: 15px;
+ width: 60px;
+ height: 25px;
+ border-radius: 13px;
+ border: 2px solid black;
+ cursor: pointer;
+ background: #0f172a;
+ color: white;
+ margin-right: 1px;
+ margin-top: auto;
+ margin-bottom: auto;
+}
+
+.list {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ height: 425px;
+ width: 600px;
+ margin: 0 auto;
+ background: whitesmoke;
+ border: 6px solid #0f172a;
+ border-radius: 20px;
+}
+
+.event {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 14px;
+ font-size: 26px;
+ padding: 0;
+ margin: 5px;
+ max-height: 350px;
+ overflow-y: auto;
+}
+
+.topRowList {
+ display: flex;
+}
+
+.clearAll{
+ color: #0f172a;
+ font-size: 20px;
+ border-radius: 20px;
+ width: 120px;
+ margin-top: 5px;
+ margin-left: 10px;
+ background: #e2e8f0;
+}
+
+.numEvent {
+ line-height: 1.5;
+ color: #0f172a;
+ font-size: 18px;
+ border-radius: 20px;
+ width: 120px;
+ margin-top: 5px;
+ margin-left: auto;
+ margin-right: 10px;
+ background: #e2e8f0;
+ border: 2px solid #0f172a;
+ padding-left: 20px;
+}
+.event li {
+ line-height: 1.5;
+ display: flex;
+ padding: 10px 5px;
+ border: 3px solid #0f172a;
+ border-radius: 15px;
+ height: 30px;
+ width: 550px;
+ background: #e2e8f0;
+}
+
+.delEvent {
+ background: #0f172a;
+ color: white;
+ border: none;
+ font-size: 16px;
+ border-radius: 20px;
+}
+
+.text {
+ margin-left: 10px;
+ margin-right: auto;
+ font-size: 20px;
+}
+
+.pinEvent {
+ background: none;
+ color: white;
+ border: black solid 1px;
+ font-size: 15px;
+ border-radius: 20px;
+ margin-right: 8px;
+}
+
+.doneEvent {
+ background: #0f172a;
+ color: white;
+ border: none;
+ font-size: 15px;
+ border-radius: 20px;
+}
+
+.markDone {
+ text-decoration: line-through;
+ text-decoration-color: red;
+ color: grey;
+}
+
+.markPin {
+ background: red;
+}
+
+body.invert {
+ filter: invert(1);
+}
+
+
diff --git a/todolist.js b/todolist.js
new file mode 100644
index 0000000..23641f7
--- /dev/null
+++ b/todolist.js
@@ -0,0 +1,233 @@
+document.addEventListener('DOMContentLoaded', () => {
+
+ //menu tab
+ const menuTab = document.getElementById('menuTab');
+ const openBtn = document.querySelector('.menu');
+ const closeBtn = document.getElementById('closeMenu');
+
+ //open and close menu drawer
+ const openDrawer = () => {
+ menuTab.classList.add('active');
+ };
+ const closeDrawer = () => {
+ menuTab.classList.remove('active');
+ };
+
+ openBtn.addEventListener('click', openDrawer);
+ closeBtn.addEventListener('click', closeDrawer);
+
+ //close menu when clicked outside of menu tab
+ document.addEventListener('click', (e) => {
+ if (menuTab.classList.contains('active') && !menuTab.contains(e.target) && !openBtn.contains(e.target)) {
+ closeDrawer();
+ }
+ });
+
+ //close menu when user presses esc
+ document.addEventListener('keydown', (e) => {
+ if (e.key === 'Escape' && menuTab.classList.contains('active')) closeDrawer();
+ });
+
+ //define date manipulating buttons
+ const today = document.querySelector('.today');
+ const prevBtn = document.getElementById('yesterday');
+ const nextBtn = document.getElementById('tomorrow');
+
+ //get date
+ let current = new Date();
+ const fmt = { year: 'numeric', month: 'long', day: 'numeric' };
+
+ //Date manipulation
+ function render() {
+ today.textContent = current.toLocaleDateString(undefined, fmt);
+ }
+ render();
+
+ //define next and last week buttons in menu
+ const nWeek = document.querySelector('.nWeek');
+ const lWeek = document.querySelector('.lWeek');
+
+ nWeek.addEventListener('click', e => {
+ saveList(current);
+ current.setDate(current.getDate() + 7);
+ render();
+ loadList(current);
+ })
+
+ lWeek.addEventListener('click', e => {
+ saveList(current);
+ current.setDate(current.getDate() - 7);
+ render();
+ loadList(current);
+ })
+
+ const dateKey = (d) => new Date(d).toLocaleDateString('en-CA');
+ // "YYYY-MM-DD" in local time
+ const storageKey = (d) => `${dateKey(d)}`;
+
+ const numEvent = document.querySelector('.numEvent');
+
+ //saves the events for a date
+ function saveList(date) {
+ sessionStorage.setItem(storageKey(date), event.innerHTML);
+ }
+
+ //loads the events for a date
+ function loadList(date) {
+ event.innerHTML = sessionStorage.getItem(storageKey(date) || '');
+ getNumEvent();
+ }
+
+ //save current events when prevBtn is pressed
+ prevBtn.addEventListener('click', () => {
+ if (event.firstChild){
+ saveList(current);
+ }
+ current.setDate(current.getDate() - 1);
+ render();
+ loadList(current);
+ })
+
+ //save current events when nextBtn is pressed
+ nextBtn.addEventListener('click', () => {
+ if (event.firstChild){
+ saveList(current);
+ }
+ current.setDate(current.getDate() + 1);
+ render();
+ loadList(current);
+ })
+
+ //when the date is clicked on, change current date to today
+ today.addEventListener('click', () => {
+ current = new Date();
+ render();
+ loadList(current);
+ })
+
+
+
+ const input = document.querySelector('.input');
+ const add = document.querySelector('.register');
+ const event = document.querySelector('.event');
+ const clearAll = document.querySelector('.clearAll');
+
+ //event listener that is restored once loaded from storage
+ event.addEventListener('click', (e) => {
+ //delete button
+ if (e.target && e.target.classList.contains('delEvent')) {
+ e.target.closest('li')?.remove();
+ saveList(current);
+ }
+
+ //done button
+ if (e.target && e.target.classList.contains('doneEvent')) {
+ const li = e.target.closest('li');
+ const span = li?.querySelector('.text'); // get the text span
+ span.classList.toggle('markDone');
+ saveList(current);
+ }
+
+ //pin and unpin events
+ if (e.target && e.target.classList.contains('pinEvent')) {
+ const li = e.target.closest('li');
+ const span = li?.querySelector('.pinEvent');
+ if (li.dataset.originalIndex === undefined) {
+ li.dataset.originalIndex = Array.from(event.children).indexOf(li);
+ }
+ //save the original index of event for unpinning
+ const originalIndex = parseInt(li.dataset.originalIndex, 10);
+ //unpin
+ if (li.classList.contains('pinned')) {
+ li.classList.remove('pinned');
+ console.log(originalIndex);
+ span.classList.toggle('markPin');
+ event.insertBefore(li, event.children[originalIndex+1]);
+ }
+ //pin
+ else {
+ console.log(originalIndex);
+ span.classList.toggle('markPin');
+ event.insertBefore(li, event.firstChild);
+ li.classList.add('pinned');
+ }
+ }
+ getNumEvent();
+ });
+
+ //add event using enter and button click
+ add.addEventListener('click', addToList);
+ input.addEventListener('keydown', (e) => {
+ if (e.key === 'Enter') {
+ addToList();
+ }
+ });
+
+ //adding event to list
+ function addToList() {
+ const li = document.createElement('li');
+
+ const span = document.createElement('span');
+ //event as text
+ span.textContent = input.value;
+ span.className = 'text';
+
+ //delete event button
+ const delEvent = document.createElement('button');
+ delEvent.className = 'delEvent';
+ delEvent.textContent = 'Delete';
+ //done event button
+ const doneEvent = document.createElement('button');
+ doneEvent.className = 'doneEvent';
+ doneEvent.textContent = 'Done';
+ //pin event button
+ const pinEvent = document.createElement('button');
+ pinEvent.className = 'pinEvent';
+ pinEvent.textContent = 'Pin';
+
+ //add event to list
+ if (span && span.textContent !== '') {
+ li.appendChild(doneEvent);
+ li.appendChild(span);
+ li.appendChild(pinEvent);
+ li.appendChild(delEvent);
+ event.appendChild(li);
+ }
+
+ getNumEvent();
+ saveList(current);
+ input.value = '';
+ }
+
+ //clear all events for a date
+ function clearALlEvents() {
+ while (event.firstChild) {
+ event.removeChild(event.firstChild);
+ }
+ }
+ clearAll.addEventListener('click', () => {
+ clearALlEvents();
+ getNumEvent();
+ })
+
+ //get the number of Events
+ function getNumEvent() {
+ numEvent.textContent = "To-do: " + event.children.length;
+ }
+
+ //calendar manipulation
+ const menuContent = document.getElementById('menuContent');
+ datePickerEl = document.createElement('input');
+ datePickerEl.type = 'date';
+ datePickerEl.className = 'menuDatePicker';// make it obvious
+ menuContent.appendChild(datePickerEl);
+ datePickerEl.addEventListener('change', () => {
+ if (!datePickerEl.value) return;
+ const [y, m, d] = datePickerEl.value.split('-').map(Number);
+ saveList(current);
+ current = new Date(y, m - 1, d);
+ render();
+ loadList(current);
+
+ });
+});
\ No newline at end of file