todolist1st
parent
f0eabccb9d
commit
080e089de0
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "all"
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "snowpack dev",
|
"start": "snowpack dev",
|
||||||
"build": "snowpack build",
|
"build": "snowpack build"
|
||||||
"test": "echo \"This template does not include a test runner by default.\" && exit 1",
|
|
||||||
"format": "prettier --write \"src/**/*.{ts,js}\"",
|
|
||||||
"lint": "prettier --check \"src/**/*.{ts,js}\""
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"canvas-confetti": "^1.2.0"
|
"canvas-confetti": "^1.2.0",
|
||||||
|
"uuid": "^9.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@snowpack/plugin-typescript": "^1.2.1",
|
"@snowpack/plugin-typescript": "^1.2.1",
|
||||||
"@types/canvas-confetti": "^1.0.0",
|
"@types/canvas-confetti": "^1.0.0",
|
||||||
"@types/snowpack-env": "^2.3.3",
|
"@types/snowpack-env": "^2.3.3",
|
||||||
|
"@types/uuid": "^8.3.4",
|
||||||
"prettier": "^2.2.1",
|
"prettier": "^2.2.1",
|
||||||
"snowpack": "^3.3.7",
|
"snowpack": "^3.3.7",
|
||||||
"typescript": "^4.2.4"
|
"typescript": "^4.2.4",
|
||||||
|
"typings-for-css-modules-loader": "^1.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 15 KiB |
@ -1,14 +0,0 @@
|
|||||||
#img {
|
|
||||||
display: block;
|
|
||||||
margin: auto;
|
|
||||||
height: 128px;
|
|
||||||
width: 128px;
|
|
||||||
padding: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#canvas {
|
|
||||||
display: block;
|
|
||||||
margin: 2rem auto;
|
|
||||||
width: 540px;
|
|
||||||
height: 540px;
|
|
||||||
}
|
|
@ -1,27 +1,35 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="description" content="Web site created using create-snowpack-app" />
|
<script src="dist/index.js" type="module"></script>
|
||||||
<link rel="stylesheet" type="text/css" href="/index.css" />
|
<!-- <link rel="stylesheet" href="../css/default.css" media="only screen" /> -->
|
||||||
<title>Snowpack App</title>
|
<title>Document</title>
|
||||||
|
<style>
|
||||||
|
#list {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<img id="img" src="/logo.svg" />
|
<div class="container">
|
||||||
<canvas id="canvas"></canvas>
|
<div class="title">
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<h1>Would this be a <i>To-do-list</i>?</h1>
|
||||||
<script type="module" src="/dist/index.js"></script>
|
</div>
|
||||||
<!--
|
|
||||||
This HTML file is a template.
|
|
||||||
If you open it directly in the browser, you will see an empty page.
|
|
||||||
|
|
||||||
You can add webfonts, meta tags, or analytics to this file.
|
<div class="thelist">
|
||||||
The build step will place the bundled scripts into the <body> tag.
|
<div class="typingform">
|
||||||
|
<form id="new-task-form">
|
||||||
|
<input type="text" id="new-task-title" />
|
||||||
|
<button type="submit">Add</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
To begin the development, run `npm start` or `yarn start`.
|
<ul id="list"></ul>
|
||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
</div>
|
||||||
-->
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
|
||||||
<path fill="#E44D26" d="M107.6 470.9l-33-370.3h362.8l-33.1 370.2L255.8 512z"/>
|
|
||||||
<path fill="#F16529" d="M256 480.5l120-33.3 28.3-316.3H256z"/>
|
|
||||||
<path fill="#EBEBEB" d="M256 268.2h-60.1l-4.1-46.5H256v-45.4H142.1l1.1 12.2 11.2 125.1H256zM256 386.2h-.2l-50.6-13.6-3.2-36.3h-45.6l6.4 71.3 93 25.9.2-.1z"/>
|
|
||||||
<path d="M108.4 0h23v22.8h21.2V0h23v69h-23V46h-21.1v23h-23.1V0zM206 22.9h-20.3V0h63.7v22.9h-20.3V69H206V23zM259.5 0h24l14.9 24.3L313.2 0h24v69h-23V34.8l-15.8 24.6h-.4l-16-24.6V69h-22.5V0zM348.7 0h23.1v46.2h32.5V69h-55.6V0z"/>
|
|
||||||
<path fill="#FFF" d="M255.8 268.2v45.4h56l-5.3 58.9-50.7 13.7v47.2l93.1-25.8.7-7.6 10.7-119.6 1.1-12.2h-12.2zM255.8 176.3v45.4H365.5l.9-10.2 2.1-23 1.1-12.2z"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 767 B |
Binary file not shown.
@ -0,0 +1,61 @@
|
|||||||
|
body,
|
||||||
|
html {
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 70%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
background-color: pink;
|
||||||
|
padding-top: 2%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thelist {
|
||||||
|
background-color: azure;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh; /*notsure*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.typingform {
|
||||||
|
background-color: aliceblue;
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
#list {
|
||||||
|
margin: 0 auto;
|
||||||
|
background-color: beige;
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 1.5% 4%;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 1.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deletebtn {
|
||||||
|
width: 4px;
|
||||||
|
height: 4px;
|
||||||
|
background-color: orangered;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-top: 1.5%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
@ -1,11 +1,63 @@
|
|||||||
/**
|
import { v4 as uuidV4 } from "uuid";
|
||||||
* This file is just a silly example to show everything working in the browser.
|
import "./css/default.css";
|
||||||
* When you're ready to start on your site, clear the file. Happy hacking!
|
|
||||||
**/
|
|
||||||
|
|
||||||
import confetti from 'canvas-confetti';
|
type Task = {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
completed: boolean;
|
||||||
|
createdAt: Date;
|
||||||
|
};
|
||||||
|
|
||||||
confetti.create(document.getElementById('canvas') as HTMLCanvasElement, {
|
const list = document.querySelector<HTMLUListElement>("#list");
|
||||||
resize: true,
|
const form = document.getElementById("new-task-form") as HTMLFormElement | null;
|
||||||
useWorker: true,
|
const input = document.querySelector<HTMLInputElement>("#new-task-title");
|
||||||
})({ particleCount: 200, spread: 200 });
|
const tasks: Task[] = loadTasks();
|
||||||
|
tasks.forEach(addListItem); //for each task we'll render
|
||||||
|
|
||||||
|
form?.addEventListener("submit", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (input?.value == "" || input?.value == null) return;
|
||||||
|
|
||||||
|
const newTask: Task = {
|
||||||
|
id: uuidV4(),
|
||||||
|
title: input.value,
|
||||||
|
completed: false, //with this, checkbox is not (initially) ticked
|
||||||
|
createdAt: new Date(),
|
||||||
|
};
|
||||||
|
tasks.push(newTask); //하나아이템 type then push, then it's uploaded(stored). <-wrote it after line 13
|
||||||
|
|
||||||
|
addListItem(newTask);
|
||||||
|
input.value = ""; //clear the input type part, as you already made one to do item
|
||||||
|
});
|
||||||
|
|
||||||
|
function addListItem(task: Task) {
|
||||||
|
const item = document.createElement("li");
|
||||||
|
const label = document.createElement("label");
|
||||||
|
const deletebtn = document.createElement("button");
|
||||||
|
deletebtn.classList.add("deletebtn");
|
||||||
|
const checkbox = document.createElement("input");
|
||||||
|
checkbox.addEventListener("change", () => {
|
||||||
|
task.completed = checkbox.checked; //with this, checkbox will be ticked
|
||||||
|
saveTasks(); //create a function to save the item made -> after this, code 47 was written.
|
||||||
|
});
|
||||||
|
checkbox.type = "checkbox";
|
||||||
|
checkbox.checked = task.completed;
|
||||||
|
label.append(checkbox, task.title);
|
||||||
|
item.append(label);
|
||||||
|
item.append(deletebtn);
|
||||||
|
list?.append(item);
|
||||||
|
deletebtn.addEventListener("click", function () {
|
||||||
|
item.parentNode?.removeChild(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveTasks() {
|
||||||
|
localStorage.setItem("TASKS", JSON.stringify(tasks));
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadTasks(): Task[] {
|
||||||
|
const taskJSON = localStorage.getItem("TASKS");
|
||||||
|
if (taskJSON == null) return []; //if taskJSON is null, return to an empty array
|
||||||
|
return JSON.parse(taskJSON); // if it's not null, return to the taskJSON. As : Task[] is written after func loadTasks(), it will specifically parse the array. Without it, it will parse anything
|
||||||
|
}
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
export const list: string;
|
Loading…
Reference in New Issue