You are on page 1of 11

Below is the file structrue of my react notes app with the respective code written in the file.

Please make this app responsive by implementing the required changes in existing files.

Notes-app

Folder-> node_modules

Folder-> public

Folder-> src

Folder-> assets

delete1.png

plus.png

Folder-> components

Folder-> Note

Note.js

Note.css

Folder-> NoteContainer

NoteContainer.js

NoteContainer.css

Folder-> Sidebar

Sidebar.js

Sidebar.css

App.js

App.css

Index.js

Index.css

.gitignore

package

package-lock

README

1) App.js
import { useEffect, useState } from "react";
import "./App.css";
import NoteContainer from "./components/NoteContainer/NoteContainer";
import Sidebar from "./components/Sidebar/Sidebar";

function App() {
const [notes, setNotes] = useState(
JSON.parse(localStorage.getItem("notes-app")) || []
);

const addNote = (color) => {


//creating a copy of current notes array
const tempNotes = [...notes];
//adding new note to this tempNotes array
tempNotes.push({
id: Date.now() + "" + Math.floor(Math.random() * 78),
text: "",
time: Date.now(),
date: Date.now(),
color,
});
//updating the current notes array to this tempNotes
setNotes(tempNotes);
};

const deleteNote = (id) => {


// Filter out the note with the given ID and update the notes array
const updatedNotes = notes.filter((note) => note.id !== id);
setNotes(updatedNotes);
};

const updateText = (text, id) => {


const tempNotes = [...notes];

const index = tempNotes.findIndex((item) => item.id === id);


if (index < 0) return;

tempNotes[index].text = text;
setNotes(tempNotes);
};

useEffect(() => {
localStorage.setItem("notes-app", JSON.stringify(notes));
}, [notes]);

return (
<div className="App">
<Sidebar addNote={addNote} />
<NoteContainer
notes={notes}
deleteNote={deleteNote}
updateText={updateText}
/>
</div>
);
}

export default App;

2) App.css

.App {
height: 100vh;
display: flex;
gap: 20px;
padding: 40px;
}

.custom-scroll::-webkit-scrollbar {
width: 8px;
}

.custom-scroll::-webkit-scrollbar-track {
background-color: transparent;
}

.custom-scroll::-webkit-scrollbar-thumb {
border-radius: 20px;
background-color: lightgray;
transition: 300ms;
}
.custom-scroll::-webkit-scrollbar-thumb:hover {
background-color: gray;
}

3) index.js

import React from "react";


import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));


root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

4) index.css

* {
border: 0;
padding: 0;
box-sizing: border-box;
}

body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
"Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

5) Note.js

import React from "react";


import "./Note.css";
import deleteIcon from "../../assets/delete1.png";

let timer = 500,


timeout;
const Note = (props) => {
const getDate = (value) => {
if (!value) return "";
const months = [
"JAN",
"FEB",
"MAR",
"APR",
"MAY",
"JUN",
"JUL",
"AUG",
"SEP",
"OCT",
"NOV",
"DEC",
];
const today = new Date(value);
const day = today.getDate();
const month = months[today.getMonth()];
const year = today.getFullYear();
const currentDate = day + " " + month + " " + year;
return currentDate;
};

const getTime = (value) => {


if (!value) return "";
const today = new Date(value);
const time = today.toLocaleString("en-US", {
hour: "numeric",
minute: "numeric",
hour12: true,
});

return time;
};

const debounce = (func) => {


clearTimeout(timeout);
timeout = setTimeout(func, timer);
};

const updateText = (text, id) => {


debounce(() => props.updateText(text, id));
};

return (
<div className="note" style={{ backgroundColor:
props.note.color }}>
<img
src={deleteIcon}
alt="delete-icon"
className="delete-icon"
onClick={() => props.deleteNote(props.note.id)}
/>
<textarea
className="note_content"
style={{ backgroundColor: props.note.color }}
defaultValue={props.note.text}
onChange={(event) => updateText(event.target.value,
props.note.id)}
/>
<div className="date_and_time">
<p className="time">{getTime(props.note.time)}</p>
<p className="date">{getDate(props.note.date)}</p>
</div>
</div>
);
};

export default Note;

6) Note.css

.note {
position: relative;
padding: 25px;
border: none;
height: 20rem;
width: 20rem;
display: flex;
flex-direction: column;
border-radius: 30px;
}

.note_content {
flex: 1;
resize: none;
font-size: 1rem;
line-height: 1.875rem;
border: none;
outline: none;
}

.date_and_time {
display: flex;
justify-content: space-between;
align-items: center;
}

.delete-icon {
width: 20px;
cursor: pointer;
opacity: 0;
transition: opacity 300ms ease;
}

.note:hover .delete-icon {
opacity: 1;
}
7) NoteContainer.js

import React from "react";


import Note from "../Note/Note";
import "./NoteContainer.css";
import loginIcon from "../../assets/login1.png";
import noteIcon from "../../assets/panda.png";
import signUpIcon from "../../assets/signup1.png";

const NoteContainer = (props) => {


const reverseArray = (arr) => {
const array = [];
for (let i = arr.length - 1; i >= 0; i--) {
array.push(arr[i]);
}
return array;
};

const notes = reverseArray(props.notes);

return (
<div className="note-container">
<div className="heading">
<div className="left-heading">
<button className="left-btn">
<div className="left">
<div className="left-img">
<img src={noteIcon} alt="note" />
</div>
<div className="text">
<h2 className="notes-heading">Panda-Notes</h2>
</div>
</div>
</button>
</div>
<div className="right-heading">
<button className="right-btn">
<div className="right">
<div className="right-img">
<img src={signUpIcon} alt="signUp" />
</div>
<div className="text">
<h2 className="notes-heading">Sign Up</h2>
</div>
</div>
</button>
<button className="right-btn">
<div className="right">
<div className="right-img">
<img src={loginIcon} alt="login" />
</div>
<div className="text">
<h2 className="notes-heading">Login</h2>
</div>
</div>
</button>
</div>
</div>
<div className="note-container_notes custom-scroll">
{notes.length > 0 ? (
notes.map((item) => (
<Note
key={item.id}
note={item}
deleteNote={props.deleteNote}
updateText={props.updateText}
/>
))
) : (
<h3>No Notes Present</h3>
)}
</div>
</div>
);
};

export default NoteContainer;

8) NoteContainer.css

.note-container {
height: 100%;
}
.note-container_notes {
margin-top: 10px;
height: 90%;
display: flex;
flex-wrap: wrap;
gap: 20px;
overflow-y: scroll;
}

.heading {
display: flex;
align-items: center;
justify-content: space-between;
}

.left-img img {
width: 40px;
}

.right-img img {
width: 40px;
}

.left {
display: flex;
align-items: center;
}
.right {
display: flex;
align-items: center;
}

.right-btn {
margin-right: 60px;
}

button {
padding-left: 10px;
padding-right: 10px;
border-radius: 20px;
cursor: pointer;
}

.left-btn {
background-color: #97f19e;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* Add shadow */
transition: box-shadow 0.3s ease-in-out; /* Add transition for
smoother hover effect */
}

.left-btn:hover {
background-color: #85de77;
}

.right-btn {
background-color: #fcf5c7;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* Add shadow */
transition: box-shadow 0.3s ease-in-out; /* Add transition for
smoother hover effect */
}

.right-btn:hover {
background-color: #ffee93;
}

9) Sidebar.js

import React, { useState } from "react";


import "./Sidebar.css";
import plusIcon from "../../assets/plus.png";

const Sidebar = (props) => {


const [listOpen, setListOpen] = useState(false);

const colors = [
"#8e7ff6",
"#fcc453",
"#fd8d6f",
"#89d2bf",
"#85d0ef",
"#f786a8",
"#ee9aef",
];
return (
<div className="sidebar">
<img src={plusIcon} alt="plus" onClick={() => setListOpen(!
listOpen)} />
<ul className={`sidebar_list ${listOpen ? "sidebar_list_active" :
""}`}>
{colors.map((item, index) => (
<li
key={index}
className="sidebar_list_item"
style={{ backgroundColor: item }}
onClick={() => props.addNote(item)}
/>
))}
</ul>
</div>
);
};

export default Sidebar;


10) Sidebar.css

.sidebar {
display: flex;
flex-direction: column;
gap: 40px;
}

.sidebar img {
width: 40px;
cursor: pointer;
}

.sidebar_list {
display: flex;
flex-direction: column;
gap: 20px;
align-items: center;
height: 0;
transition: 300ms;
}

.sidebar_list_active {
height: 300px;
}

.sidebar_list_item {
border-radius: 50%;
height: 25px;
width: 25px;
list-style: none;
cursor: pointer;
}

You might also like