lesson 7
This commit is contained in:
parent
f82ea59048
commit
39574a6599
@ -3,44 +3,48 @@
|
|||||||
|
|
||||||
/* font: sans-serif for headers, serif for paragraphs, mono for whatever */
|
/* font: sans-serif for headers, serif for paragraphs, mono for whatever */
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Cutive+Mono&family=EB+Garamond:ital,wght@0,400..800;1,400..800&display=swap');
|
@import url("https://fonts.googleapis.com/css2?family=Cutive+Mono&family=EB+Garamond:ital,wght@0,400..800;1,400..800&display=swap");
|
||||||
|
|
||||||
body{
|
body {
|
||||||
background-color: rgb(232, 163, 217);
|
background-color: rgb(232, 163, 217);
|
||||||
color: rgb(146, 0, 24)
|
color: rgb(146, 0, 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4, h5 {
|
h1,
|
||||||
font-family: 'Cutive Mono', monospace;
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5 {
|
||||||
|
font-family: "Cutive Mono", monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-family: 'EB Garamond', serif;
|
font-family: "EB Garamond", serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title-text {
|
.title-text {
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-submit {
|
.form-submit {
|
||||||
background-color: rgb(151, 227, 29);
|
background-color: rgb(151, 227, 29);
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-submit:hover {
|
.form-submit:hover {
|
||||||
background:rgb(62, 100, 2);
|
background: rgb(62, 100, 2);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-input {
|
.todo-input {
|
||||||
background: rgb(16, 232, 236)
|
background: rgb(16, 232, 236);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-content: space-around;
|
align-content: space-around;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
@ -3,158 +3,178 @@
|
|||||||
|
|
||||||
/* font: sans-serif for headers, serif for paragraphs, mono for whatever */
|
/* font: sans-serif for headers, serif for paragraphs, mono for whatever */
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Cutive+Mono&family=EB+Garamond:ital,wght@0,400..800;1,400..800&display=swap');
|
@import url("https://fonts.googleapis.com/css2?family=Cutive+Mono&family=EB+Garamond:ital,wght@0,400..800;1,400..800&display=swap");
|
||||||
|
|
||||||
body{
|
body {
|
||||||
background-color: rgb(238, 213, 232);
|
background-color: rgb(238, 213, 232);
|
||||||
color: rgb(92, 89, 92)
|
color: rgb(92, 89, 92);
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4, h5 {
|
h1,
|
||||||
font-family: 'EB Garamond', serif;
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5 {
|
||||||
|
font-family: "EB Garamond", serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-family: 'Curtive Mono', monospace;
|
font-family: "Curtive Mono", monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title-text {
|
.title-text {
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 10%;
|
width: 10%;
|
||||||
height: auto;
|
height: auto;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-submit {
|
.form-submit {
|
||||||
background-color: rgb(255, 124, 192);
|
background-color: rgb(255, 124, 192);
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-submit:hover {
|
.form-submit:hover {
|
||||||
background:rgb(252, 27, 121);
|
background: rgb(252, 27, 121);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
form input, form textarea {
|
form input,
|
||||||
font-family: 'Cutive Mono', monospace;
|
form textarea {
|
||||||
}
|
font-family: "Cutive Mono", monospace;
|
||||||
|
}
|
||||||
|
|
||||||
.todo-input {
|
.todo-input {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
label, input, button {
|
label,
|
||||||
display: block;
|
input,
|
||||||
width: 100%;
|
button {
|
||||||
padding: 0;
|
display: block;
|
||||||
border: none;
|
width: 100%;
|
||||||
outline: none;
|
padding: 0;
|
||||||
box-sizing: border-box;
|
border: none;
|
||||||
}
|
outline: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
label:nth-of-type(2) {
|
label:nth-of-type(2) {
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input::placeholder {
|
input::placeholder {
|
||||||
color: gray;
|
color: gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
background: #ecf0f3;
|
background: #ecf0f3;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
border-radius: 50px;
|
border-radius: 50px;
|
||||||
box-shadow: inset 6px 6px 6px #cbced1, inset -6px -6px 6px white;
|
box-shadow: inset 6px 6px 6px #cbced1, inset -6px -6px 6px white;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
.form-submit {
|
||||||
color: white;
|
color: white;
|
||||||
font-family: 'Curtive Mono', monospace;
|
font-family: "Curtive Mono", monospace;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-content: space-around;
|
align-content: space-around;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-container {
|
.todo-container {
|
||||||
max-width: 300px;
|
max-width: 300px;
|
||||||
font-family: 'Curtive Mono', monospace;
|
font-family: "Curtive Mono", monospace;
|
||||||
background-color: #fff5f7; /* Soft cream background for the list */
|
background-color: #fff5f7; /* Soft cream background for the list */
|
||||||
border: 4px solid #ffd0dc; /* Pink border */
|
border: 4px solid #ffd0dc; /* Pink border */
|
||||||
border-radius: 30px;
|
border-radius: 30px;
|
||||||
box-shadow: 6px 4px 10px rgba(0, 0, 0, 0.1); /* Soft shadow */
|
box-shadow: 6px 4px 10px rgba(0, 0, 0, 0.1); /* Soft shadow */
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 20px 20px 20px 20px;/* up left down right */
|
padding: 20px 20px 20px 20px; /* up left down right */
|
||||||
background-image: url('/images/polka.jpg'); /* Add your image path */
|
background-image: url("/images/polka.jpg"); /* Add your image path */
|
||||||
background-size: cover; /* Scale the image to cover the entire list item */
|
background-size: cover; /* Scale the image to cover the entire list item */
|
||||||
background-repeat: no-repeat; /* Prevent the image from repeating */
|
background-repeat: no-repeat; /* Prevent the image from repeating */
|
||||||
background-position: center; /* Center thse image within the list item */
|
background-position: center; /* Center thse image within the list item */
|
||||||
}
|
|
||||||
|
|
||||||
.inner-todo {
|
|
||||||
background-color: #fee6eb;
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 20px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Heading */
|
.inner-todo {
|
||||||
.todo-container h1 {
|
background-color: #fee6eb;
|
||||||
font-size: 25px;
|
padding: 20px;
|
||||||
font-family: 'EB Garamond', serif;
|
border-radius: 20px;
|
||||||
color: #545353; /* Pink color for title */
|
}
|
||||||
margin-top: 10px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* List Styling */
|
/* Heading */
|
||||||
ol {
|
.todo-container h1 {
|
||||||
list-style: none;
|
font-size: 25px;
|
||||||
padding: 0;
|
font-family: "EB Garamond", serif;
|
||||||
margin: 0;
|
color: #545353; /* Pink color for title */
|
||||||
}
|
margin-top: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
ol li {
|
/* List Styling */
|
||||||
color: #545353; /* Adjust text color for visibility */
|
ol {
|
||||||
margin: 10px;
|
padding: 0;
|
||||||
background-color: #ffffff; /* Soft cream background for the list */
|
margin: 0;
|
||||||
padding: 20px; /* Increase padding for better layout */
|
}
|
||||||
border-radius: 20px;
|
|
||||||
text-align: left;
|
|
||||||
font-family: 'Curtive Mono', monospace; /* Consistent font */
|
|
||||||
min-width: 250px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decoration Image */
|
ol li {
|
||||||
.decor {
|
color: #545353; /* Adjust text color for visibility */
|
||||||
position: absolute;
|
margin: 10px;
|
||||||
bottom: -20px;
|
background-color: #ffffff; /* Soft cream background for the list */
|
||||||
right: -20px;
|
padding: 20px; /* Increase padding for better layout */
|
||||||
}
|
border-radius: 20px;
|
||||||
|
text-align: left;
|
||||||
|
font-family: "Curtive Mono", monospace; /* Consistent font */
|
||||||
|
min-width: 250px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
.decor img {
|
ol li i {
|
||||||
width: 150px;
|
font-size: 20px;
|
||||||
height: auto;
|
}
|
||||||
}
|
|
||||||
|
li button {
|
||||||
|
background-color: white;
|
||||||
|
color: rgb(61, 61, 61); /* Button text color */
|
||||||
|
cursor: pointer; /* Pointer cursor for interactivity */
|
||||||
|
width: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decoration Image */
|
||||||
|
.decor {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -20px;
|
||||||
|
right: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decor img {
|
||||||
|
width: 150px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|||||||
69
nodeJS/Learning/05/public/html/index.html
Normal file
69
nodeJS/Learning/05/public/html/index.html
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Tiffy's to-do list website</title>
|
||||||
|
|
||||||
|
<meta name="description" content="Tiffy's todo list website" />
|
||||||
|
<meta name="keywords" content="list, todo" />
|
||||||
|
<meta name="author" content="Tiffany" />
|
||||||
|
|
||||||
|
<link rel="icon" href="images/favicon.ico" />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="css/main.css" />
|
||||||
|
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"
|
||||||
|
integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg=="
|
||||||
|
crossorigin="anonymous"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<section>
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="title-text">Tiffy's to-do list website</h1>
|
||||||
|
|
||||||
|
<img src="images/image.jpg" alt="Image not found" />
|
||||||
|
|
||||||
|
<p><i>Add something cute to my to-do list!</i></p>
|
||||||
|
<form action="/form-action" method="post">
|
||||||
|
<label for="to-do"></label>
|
||||||
|
<input
|
||||||
|
name="todo"
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter a to-do"
|
||||||
|
required
|
||||||
|
class="todo-input"
|
||||||
|
/>
|
||||||
|
<button type="submit" class="form-submit">Add</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- List -->
|
||||||
|
<!-- ordered list -->
|
||||||
|
|
||||||
|
<div class="todo-container">
|
||||||
|
<div class="inner-todo">
|
||||||
|
<h1>To do list</h1>
|
||||||
|
<ol>
|
||||||
|
<!-- <li>Learn from Ronald</li>
|
||||||
|
<li>Watch movies</li>
|
||||||
|
<li>Sleep</li> -->
|
||||||
|
</ol>
|
||||||
|
<div class="decor">
|
||||||
|
<img src="images/cryinggirl.gif" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- unordered list -->
|
||||||
|
<!-- <ul></ul> -->
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script src="js/todo.js"></script>
|
||||||
|
</html>
|
||||||
@ -1,15 +1,51 @@
|
|||||||
//fetch: send a url request, client side rendering
|
//fetch: send a url request, client side rendering
|
||||||
//update the list, by default: fetch uses get
|
//update the list, by default: fetch uses "get"
|
||||||
fetch('/get-todos', {method: 'GET'}). then((response) => {
|
fetch("/get-todos", { method: "GET" }).then((response) => {
|
||||||
response.json(). then((data) => {
|
response.json().then((data) => {
|
||||||
const ol = document.querySelector('ol');
|
const ol = document.querySelector("ol");
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
//Create li
|
//Create li
|
||||||
const li = document.createElement('li');
|
const li = document.createElement("li");
|
||||||
//add text to li
|
//add text to li
|
||||||
li.textContent = item;
|
li.textContent = item;
|
||||||
//add li underneath (child) ol
|
|
||||||
ol.appendChild(li);
|
// Create button
|
||||||
})
|
const button = document.createElement("button");
|
||||||
});
|
button.type = "submit";
|
||||||
|
|
||||||
|
// Add icon to button
|
||||||
|
const icon = document.createElement("i");
|
||||||
|
icon.className = "fa-solid fa-delete-left";
|
||||||
|
|
||||||
|
// Append icon to button
|
||||||
|
button.appendChild(icon);
|
||||||
|
|
||||||
|
// Append button to li
|
||||||
|
li.appendChild(button);
|
||||||
|
|
||||||
|
// Add delete functionality
|
||||||
|
button.addEventListener("click", () => {
|
||||||
|
// Send DELETE request
|
||||||
|
fetch(`/delete-todo`, {
|
||||||
|
method: "DELETE",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ todo: item }),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
// Remove the item from the DOM
|
||||||
|
li.remove();
|
||||||
|
} else {
|
||||||
|
console.error("Failed to delete to-do item");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => console.error("Error:", error));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Append li underneath (child) ol
|
||||||
|
ol.appendChild(li);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
@ -1,62 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Tiffy's to-do list website</title>
|
|
||||||
|
|
||||||
<meta name="description" content="Tiffy's todo list website" />
|
|
||||||
<meta name="keywords" content="list, todo" />
|
|
||||||
<meta name="author" content="Tiffany" />
|
|
||||||
|
|
||||||
<link rel="icon" href="images/favicon.ico" />
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="css/main.css"/>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<section>
|
|
||||||
<div class="container">
|
|
||||||
<h1 class="title-text">Tiffy's to-do list website</h1>
|
|
||||||
<p><i>Add something cute to my to-do list!</i></p>
|
|
||||||
|
|
||||||
<img src="images/image.jpg" alt="Image not found">
|
|
||||||
|
|
||||||
<form action="/form-action" method="post">
|
|
||||||
<label for="to-do"></label>
|
|
||||||
<input name="todo" type="text" placeholder="Enter a to-do" required class="todo-input"/>
|
|
||||||
|
|
||||||
<!-- button, if it's a submit button then it will end the form and submit it, other than that the button doesnt do anything -->
|
|
||||||
<button type="submit" class="form-submit">Add</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<!-- List -->
|
|
||||||
<!-- ordered list -->
|
|
||||||
|
|
||||||
<div class="todo-container">
|
|
||||||
<div class="inner-todo">
|
|
||||||
<h1>To do list</h1>
|
|
||||||
<ol>
|
|
||||||
<!-- <li>Learn from Ronald</li>
|
|
||||||
<li>Watch movies</li>
|
|
||||||
<li>Sleep</li> -->
|
|
||||||
</ol>
|
|
||||||
<div class="decor">
|
|
||||||
<img src="images/cryinggirl.gif"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- unordered list -->
|
|
||||||
<!-- <ul></ul> -->
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<script src="js/todo.js"> </script>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@ -1,23 +1,24 @@
|
|||||||
//importing the dotenv package (secret file), configuring dotenv for our project
|
//importing the dotenv package (secret file), configuring dotenv for our project
|
||||||
//dotenv, secret file, people cant read
|
//dotenv, secret file, people cant read
|
||||||
import dotenv from 'dotenv';
|
import dotenv from "dotenv";
|
||||||
dotenv.config({ path: `${__dirname}/../.env` });
|
dotenv.config({ path: `${__dirname}/../.env` });
|
||||||
|
|
||||||
//Variable declaration
|
//Variable declaration
|
||||||
|
|
||||||
//we named express as a variable name, usually name same as imported package
|
//we named express as a variable name, usually name same as imported package
|
||||||
//express: designed to easily make a web server
|
//express: designed to easily make a web server
|
||||||
import express, { Request, Response } from 'express';
|
import express, { Application, Request, Response } from "express";
|
||||||
|
|
||||||
//bodyParser: sending form action to my server, wrap the user's data in "body" to my server, and my server is unwrapping it
|
//bodyParser: sending form action to my server, wrap the user's data in "body" to my server, and my server is unwrapping it
|
||||||
import bodyParser from 'body-parser';
|
import bodyParser from "body-parser";
|
||||||
import fs from 'fs';
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
const filePath = 'todolist.txt';
|
const filePath: string = "todolist.txt";
|
||||||
|
|
||||||
//initializing the express web server, everything in express, we want to put in app
|
//initializing the express web server, everything in express, we want to put in app
|
||||||
const app = express();
|
const app: Application = express();
|
||||||
const port = process.env.PORT || 3000;
|
const port: Number = parseInt(process.env.PORT as string) || 3000;
|
||||||
|
|
||||||
// Middleware
|
// Middleware
|
||||||
//unwrap the words
|
//unwrap the words
|
||||||
@ -31,45 +32,93 @@ app.use(bodyParser.json());
|
|||||||
//to make icon files, because icon files are always downloaded
|
//to make icon files, because icon files are always downloaded
|
||||||
app.use(express.static(`${__dirname}/../public`));
|
app.use(express.static(`${__dirname}/../public`));
|
||||||
|
|
||||||
app.get(`/`, (req, res) => {
|
app.get(`/`, (_req: Request, res: Response): void => {
|
||||||
res.sendFile(`${__dirname}/index.html`);
|
res.sendFile(path.join(__dirname, "../public/html/index.html"));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post('/form-action', (req, res) => {
|
app.post("/form-action", (req: Request, res: Response): void => {
|
||||||
const todo = req.body.todo;
|
const todo = req.body.todo;
|
||||||
console.log(todo);
|
|
||||||
|
|
||||||
// use fs to add the item to the file
|
// use fs to add the item to the file
|
||||||
|
|
||||||
fs.appendFile(filePath, todo + '\n', (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.log(err)
|
|
||||||
res.send("Hey there is an error.")
|
|
||||||
} else {
|
|
||||||
res.redirect("/");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
fs.appendFile(filePath, "\n" + todo, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
res.send("Hey there is an error.");
|
||||||
|
} else {
|
||||||
|
res.redirect("/");
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/get-todos', (req: Request, res: Response): void => {
|
app.get("/get-todos", (_req: Request, res: Response): void => {
|
||||||
//Using the fs module to read the file
|
//Using the fs module to read the file
|
||||||
fs.readFile(filePath, 'utf-8', (err:NodeJS.ErrnoException | null, data: string) => {
|
fs.readFile(
|
||||||
if (err) {
|
filePath,
|
||||||
console.log(err)
|
"utf-8",
|
||||||
res.send("An error occured.")
|
(err: NodeJS.ErrnoException | null, data: string) => {
|
||||||
} else {
|
if (err) {
|
||||||
//Return the file contents as a response of each list item data.split
|
console.log(err);
|
||||||
//Send the response back to the client as a json object res.json
|
res.send("An error occured.");
|
||||||
res.json(data.split('\n'))
|
} else {
|
||||||
}
|
//Return the file contents as a response of each list item data.split
|
||||||
})
|
//Send the response back to the client as a json object res.json
|
||||||
})
|
res.json(data.split("\n").filter((data) => data.trim() !== ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.delete("/delete-todo", (req: Request, res: Response): void => {
|
||||||
|
const todoToDelete = (req.body.todo || "").trim(); // Ensure input is trimmed
|
||||||
|
|
||||||
|
if (!todoToDelete) {
|
||||||
|
res.status(400).json({ error: "No to-do item provided to delete" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the file to get the current list of todos
|
||||||
|
fs.readFile(filePath, "utf8", (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("Error reading file:", err);
|
||||||
|
res.status(500).json({ error: "Internal Server Error" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split the content into lines and trim whitespace from each line
|
||||||
|
const todos = data
|
||||||
|
.split("\n")
|
||||||
|
.map((line) => line.trim())
|
||||||
|
.filter((line) => line !== ""); // Remove empty lines
|
||||||
|
|
||||||
|
// Filter out the todo item to delete
|
||||||
|
const updatedTodos = todos.filter((todo) => todo !== todoToDelete);
|
||||||
|
|
||||||
|
if (todos.length === updatedTodos.length) {
|
||||||
|
res.status(404).json({ error: "Todo not found" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join the updated list back into a string
|
||||||
|
const updatedContent = updatedTodos.join("\n");
|
||||||
|
|
||||||
|
// Write the updated content back to the file
|
||||||
|
fs.writeFile(filePath, updatedContent, "utf8", (writeErr) => {
|
||||||
|
if (writeErr) {
|
||||||
|
console.error("Error writing file:", writeErr);
|
||||||
|
res.status(500).json({ error: "Internal Server Error" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Deleted todo: ${todoToDelete}`);
|
||||||
|
res.status(200).json({ message: "Todo deleted successfully" });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// slash'/' is the home page, /about is the about page
|
// slash'/' is the home page, /about is the about page
|
||||||
//get, post, put, delete
|
//get, post, put, delete
|
||||||
|
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
console.log(`Server is running on http://localhost:${port}`);
|
console.log(`Server is running on http://localhost:${port}`);
|
||||||
});
|
});
|
||||||
@ -1,6 +1,3 @@
|
|||||||
Learn coding
|
ABC
|
||||||
Cook dinner
|
CDE
|
||||||
Make a pretty website
|
FADDGD
|
||||||
Delete list items
|
|
||||||
Edit list items
|
|
||||||
Move items to database!!!
|
|
||||||
@ -30,7 +30,9 @@
|
|||||||
"moduleResolution": "node10" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
"moduleResolution": "node10" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
||||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||||
"rootDirs": ["./"], /* Allow multiple folders to be treated as one when resolving modules. */
|
"rootDirs": [
|
||||||
|
"./"
|
||||||
|
] /* Allow multiple folders to be treated as one when resolving modules. */,
|
||||||
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||||
@ -85,18 +87,18 @@
|
|||||||
/* Type Checking */
|
/* Type Checking */
|
||||||
"strict": true /* Enable all strict type-checking options. */,
|
"strict": true /* Enable all strict type-checking options. */,
|
||||||
"noImplicitAny": true /* Enable error reporting for expressions and declarations with an implied 'any' type. */,
|
"noImplicitAny": true /* Enable error reporting for expressions and declarations with an implied 'any' type. */,
|
||||||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
"strictNullChecks": true /* When type checking, take into account 'null' and 'undefined'. */,
|
||||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
"strictFunctionTypes": true /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */,
|
||||||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||||
// "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
|
// "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
|
||||||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
"noImplicitThis": true /* Enable error reporting when 'this' is given the type 'any'. */,
|
||||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||||
"alwaysStrict": true /* Ensure 'use strict' is always emitted. */,
|
"alwaysStrict": true /* Ensure 'use strict' is always emitted. */,
|
||||||
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
"noUnusedParameters": true /* Raise an error when a function parameter isn't read. */,
|
||||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
"noImplicitReturns": true /* Enable error reporting for codepaths that do not explicitly return in a function. */,
|
||||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||||
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user