├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
├── assets
│ └── favicon.png
├── index.html
├── style.css
└── tooltips.js
├── screenshots
└── 1.PNG
└── src
├── app.jsx
├── components
├── footer.jsx
├── header.jsx
├── minors
│ └── card.jsx
├── newNote.jsx
└── note.jsx
├── index.js
└── notes.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 | .now
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](http://hits.dwyl.com/ishandeveloper/Notes-Keeper)
2 |
3 |
4 |
5 | # NOTES KEEPER
6 |
7 |
8 | This is a Google Keep inspired, Notes keeping app. The best part? All the notes you save are kept locally on your computer! using your browser's LocalStorage.
9 |
10 | So, no more worrying about giving access to your secrets to 3rd-party companies.
11 |
12 | Built in React.js with ❤️
13 |
14 |
15 | #### View Live Demo
16 |
keep.ishandeveloper.com
17 |
18 | ## Setup
19 |
20 | ##### Clone the repository
21 | ```bash
22 | git clone https://github.com/ishandeveloper/Notes-Keeper.git
23 | ```
24 | ##### Move to the desired folder
25 | ```bash
26 | cd \Notes-Keeper
27 | ```
28 | ##### To install the dependencies, simply write
29 | ```bash
30 | npm install
31 | ```
32 |
33 | ##### To run the app, simply write
34 | ```bash
35 | npm start
36 | ```
37 |
38 | ## Learn More
39 |
40 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
41 |
42 | ##### Made with ♥ by ishandeveloper
43 |
44 | [](https://github.com/ishandeveloper)
45 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "keeper",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^10.3.0",
8 | "@testing-library/user-event": "^10.4.0",
9 | "local-storage": "^2.0.0",
10 | "materialize-css": "^1.0.0-rc.2",
11 | "react": "^16.13.1",
12 | "react-dom": "^16.13.1",
13 | "react-scripts": "3.4.1"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test",
19 | "eject": "react-scripts eject"
20 | },
21 | "eslintConfig": {
22 | "extends": "react-app"
23 | },
24 | "browserslist": {
25 | "production": [
26 | ">0.2%",
27 | "not dead",
28 | "not op_mini all"
29 | ],
30 | "development": [
31 | "last 1 chrome version",
32 | "last 1 firefox version",
33 | "last 1 safari version"
34 | ]
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/public/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishandeveloper/Notes-Keeper/32b020ecf07e21127e866e40d8f08336daa72f07/public/assets/favicon.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | NotesKeeper
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/public/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Poppins&display=swap');
2 |
3 | .logo {
4 | padding: 0px 20px !important;
5 | }
6 |
7 | .hero-text {
8 | font-size: 0.8em;
9 | }
10 |
11 | .input-field {
12 | width: 70%;
13 | height: 50px !important;
14 | padding: 0px !important;
15 | position: absolute;
16 | /* margin-left:15%!important; */
17 | margin: 10px 18% !important;
18 | background: #f1f3f4;
19 | }
20 |
21 | input[type=note] {
22 | background-color: transparent;
23 | border: none;
24 | border-radius: 0;
25 | outline: none;
26 | height: 3rem;
27 | width: 100%;
28 | font-size: 1.5em;
29 | margin: 0 0 8px 0;
30 | padding: 0;
31 | border-bottom: 0px !important;
32 | }
33 |
34 | .text-justify {
35 | text-align: justify;
36 | }
37 |
38 | .search-icon {
39 | height: 100%;
40 | font-size: 2em !important;
41 | }
42 |
43 | .close-icon {
44 | height: 100%;
45 | margin-top: -5px !important;
46 | font-size: 1.5em !important;
47 | }
48 |
49 | .label-icon {
50 | margin-top: -5px !important;
51 | }
52 |
53 | .row {
54 | width: 90%;
55 | padding: 20px 10px;
56 | min-height: calc(90vh - 74px);
57 | }
58 |
59 | .newnote {
60 | height: auto !important;
61 | margin-left: auto;
62 | margin-right: auto;
63 | margin-top: 50px;
64 | margin-bottom: 50px;
65 | width: 50%;
66 | }
67 |
68 | .materialize-textarea {
69 | font-size: 1.2em !important;
70 | border-bottom: 0px !important;
71 | transition: none !important;
72 | box-shadow: none !important;
73 | }
74 |
75 | .hero-icon {
76 | font-size: 1.25em;
77 | }
78 |
79 | nav {
80 | font-family: 'Poppins';
81 | min-height: 70px;
82 | }
83 |
84 | nav .brand-logo i,
85 | nav .brand-logo [class^="mdi-"],
86 | nav .brand-logo [class*="mdi-"],
87 | nav .brand-logo i.material-icons {
88 | font-size: 1.25em;
89 | }
90 |
91 | .card {
92 | transition: all 1s !important;
93 | }
94 |
95 | .card-content {
96 | transition: all 1s !important;
97 | }
98 |
99 | .input-title {
100 |
101 | transition: all ease-in-out 1s !important;
102 |
103 | }
104 |
105 | .page-footer {
106 | position: relative;
107 | bottom: 0;
108 | width: 100%;
109 | }
110 |
111 | /* CUSTOM SCROLLBAR */
112 |
113 | ::-webkit-scrollbar {
114 | width: 5px;
115 | }
116 |
117 | /* Track */
118 | ::-webkit-scrollbar-track {
119 | background: white;
120 |
121 | }
122 |
123 | /* Handle */
124 | ::-webkit-scrollbar-thumb {
125 | background: #2196F3;
126 | border-radius: 50px;
127 |
128 | }
129 |
130 | /* Handle on hover */
131 | ::-webkit-scrollbar-thumb:hover {
132 | background: #64B5F6;
133 |
134 | }
135 |
136 |
137 | @media only screen and (max-width: 768px) {
138 | .newnote {
139 | width: 80%;
140 | }
141 |
142 | .m3 {
143 | width: 50% !important;
144 | min-width: 50% !important;
145 | }
146 | }
147 |
148 | @media only screen and (max-width: 1072px) {
149 |
150 | .m3 {
151 | min-width: 33.333333% !important;
152 | }
153 | }
154 |
155 | @media only screen and (max-width: 600px) {
156 | .newnote {
157 | width: 80%;
158 | }
159 |
160 | .m3 {
161 | width: 100% !important;
162 | min-width: 100% !important;
163 | }
164 | }
--------------------------------------------------------------------------------
/public/tooltips.js:
--------------------------------------------------------------------------------
1 | M.AutoInit();
--------------------------------------------------------------------------------
/screenshots/1.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ishandeveloper/Notes-Keeper/32b020ecf07e21127e866e40d8f08336daa72f07/screenshots/1.PNG
--------------------------------------------------------------------------------
/src/app.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Header from "./components/header";
3 | import createCard from "./components/minors/card";
4 | import Footer from "./components/footer";
5 | import NewNote from "./components/newNote";
6 | var ls = require("local-storage");
7 |
8 | function App() {
9 | const storedNotes = JSON.parse(ls.get("notes"));
10 | const nullNote = {
11 | id: 9999999,
12 | title: "NULL",
13 | note: "NULL",
14 | };
15 | // console.log(storedNotes);
16 | const [notes, setnotes] = React.useState(() => {
17 | if (storedNotes != null) {
18 | return [
19 | storedNotes[0] ? storedNotes[0] : nullNote,
20 | storedNotes[2] ? storedNotes[2] : nullNote,
21 | storedNotes[1] ? storedNotes[1] : nullNote,
22 | storedNotes[3] ? storedNotes[3] : nullNote,
23 | storedNotes[4] ? storedNotes[4] : nullNote,
24 | storedNotes[5] ? storedNotes[5] : nullNote,
25 | storedNotes[6] ? storedNotes[6] : nullNote,
26 | storedNotes[7] ? storedNotes[7] : nullNote,
27 | ];
28 | }
29 | return [
30 | {
31 | id: 0,
32 | title: "Hey, I'm a note!",
33 | note:
34 | "Click the delete icon below to delete me and start making your own notes ;)",
35 | },
36 | ];
37 | });
38 |
39 | function saveNotestoLocal(oldNotes, id) {
40 | if (notes !== oldNotes) {
41 | const savedNotes = notes.filter((note) => {
42 | return note.id !== 9999999;
43 | });
44 | ls("notes", JSON.stringify(savedNotes));
45 | console.log("Notes Saved");
46 | } else {
47 | console.log(id);
48 | setnotes((prevNotes) => {
49 | oldNotes = prevNotes;
50 | return prevNotes.filter((note) => note.id !== id);
51 | });
52 | setTimeout(() => {
53 | saveNotestoLocal(oldNotes, id);
54 | }, 1000);
55 | }
56 | }
57 |
58 | function addNote(title, content) {
59 | const newId = Math.round(Math.random() * 100);
60 | setnotes((prev) => {
61 | return [
62 | ...prev,
63 | {
64 | id: newId,
65 | title: title,
66 | note: content,
67 | },
68 | ];
69 | });
70 | setTimeout(saveNotestoLocal, 1000);
71 | }
72 | function deleteNote(id) {
73 | var oldnotes;
74 | setnotes((prevNotes) => {
75 | oldnotes = prevNotes;
76 | return prevNotes.filter((note) => note.id !== id);
77 | });
78 | saveNotestoLocal(oldnotes, id);
79 | }
80 | return (
81 |
82 |
83 |
84 |
85 | {notes.map((note) => createCard(note, deleteNote))}
86 |
87 |
88 |
89 | );
90 | }
91 |
92 | export default App;
93 |
--------------------------------------------------------------------------------
/src/components/footer.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | // const year=new Date().getFullYear();
4 |
5 | function Footer() {
6 | return (
7 |
18 | );
19 | }
20 |
21 | export default Footer;
22 |
--------------------------------------------------------------------------------
/src/components/header.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function Heading() {
4 | return (
5 |
41 | );
42 | }
43 |
44 | export default Heading;
45 |
--------------------------------------------------------------------------------
/src/components/minors/card.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function createCard(content, deletenote) {
4 | if (content.note !== "NULL") {
5 | return (
6 |
13 | );
14 | }
15 | }
16 |
17 | function Card(props) {
18 | function copyToClipboard() {
19 | navigator.clipboard.writeText(props.content);
20 | }
21 | function taskDelete() {
22 | props.del(props.id);
23 | }
24 | return (
25 |
26 |
27 |
28 |
29 |
{props.title}
30 |
{props.content}
31 |
32 |
61 |
62 |
63 |
64 | );
65 | }
66 |
67 | export default createCard;
68 |
--------------------------------------------------------------------------------
/src/components/newNote.jsx:
--------------------------------------------------------------------------------
1 | import React, {useState} from "react";
2 |
3 | function NewNote(props) {
4 |
5 | const [typing, settyping] = useState(false);
6 |
7 | const [textareaStyle, settextareaStyle] = React.useState({
8 | textAlign: "justfiy",
9 | });
10 | const [content, setcontent] = useState('')
11 | const [title, settitle] = useState('');
12 |
13 | function newnoteadded() {
14 | {props.add(title,content)};
15 | settitle('');
16 | setcontent('');
17 | }
18 |
19 | function textareaHeight(e) {
20 | settextareaStyle({
21 | height: e.target.scrollHeight + "px",
22 | textAlign: "justfiy",
23 | maxHeight: "500px",
24 | });
25 | }
26 | function titlechanged(e) {
27 | settitle(e.target.value);
28 | }
29 | function contentchanged(e) {
30 | settyping(true);
31 | setcontent(e.target.value);
32 | }
33 | return (
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | {typing?
42 |
43 |
:null}
44 |
45 |
55 |
56 |
57 | {typing?
58 | add
59 | :null}
60 |
61 |
62 |
63 | );
64 | }
65 |
66 | export default NewNote;
67 |
--------------------------------------------------------------------------------
/src/components/note.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import createCard from "./minors/card";
3 | import notes from "../notes";
4 |
5 | function Notes() {
6 | return {notes.map(createCard)}
;
7 | }
8 |
9 | export default Notes;
10 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import App from "./app";
4 |
5 | ReactDOM.render(, document.getElementById("root"));
6 |
--------------------------------------------------------------------------------
/src/notes.js:
--------------------------------------------------------------------------------
1 | const notes = [
2 | {
3 | id: 0,
4 | title: "First Note",
5 | note:
6 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi elementum dictum tincidunt. Nullam in convallis lectus. Donec vestibulum sagittis lectus, sit amet posuere odio pharetra ac. Nullam pulvinar orci vel aliquet malesuada. Nulla maximus, lorem non rutrum viverra, mauris mi interdum neque, id commodo dui ante sit amet nisi. ",
7 | },
8 | {
9 | id: 0,
10 | title: "First Note",
11 | note:
12 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi elementum dictum tincidunt. Nullam in convallis lectus. Donec vestibulum sagittis lectus, sit amet posuere odio pharetra ac. Nullam pulvinar orci vel aliquet malesuada. Nulla maximus, lorem non rutrum viverra, mauris mi interdum neque, id commodo dui ante sit amet nisi. ",
13 | },
14 | {
15 | id: 0,
16 | title: "First Note",
17 | note:
18 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi elementum dictum tincidunt. Nullam in convallis lectus. Donec vestibulum sagittis lectus, sit amet posuere odio pharetra ac. Nullam pulvinar orci vel aliquet malesuada. Nulla maximus, lorem non rutrum viverra, mauris mi interdum neque, id commodo dui ante sit amet nisi. ",
19 | },
20 | ];
21 |
22 | export default notes;
23 |
--------------------------------------------------------------------------------