diff --git a/assets/icons/brackets-icon.png b/assets/icons/brackets-icon.png new file mode 100644 index 0000000..b6c05ce Binary files /dev/null and b/assets/icons/brackets-icon.png differ diff --git a/assets/icons/color-pallete-icon.png b/assets/icons/color-pallete-icon.png new file mode 100644 index 0000000..500507a Binary files /dev/null and b/assets/icons/color-pallete-icon.png differ diff --git a/assets/icons/others-icon.svg b/assets/icons/others-icon.svg new file mode 100644 index 0000000..33d498a --- /dev/null +++ b/assets/icons/others-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/pinned-icon.png b/assets/icons/pinned-icon.png new file mode 100644 index 0000000..793c05d Binary files /dev/null and b/assets/icons/pinned-icon.png differ diff --git a/assets/icons/recover-arrow.png b/assets/icons/recover-arrow.png new file mode 100644 index 0000000..dd5903f Binary files /dev/null and b/assets/icons/recover-arrow.png differ diff --git a/assets/icons/trash-icon-gray.png b/assets/icons/trash-icon-gray.png new file mode 100644 index 0000000..18eaf9e Binary files /dev/null and b/assets/icons/trash-icon-gray.png differ diff --git a/assets/icons/trash-icon.png b/assets/icons/trash-icon.png new file mode 100644 index 0000000..4745657 Binary files /dev/null and b/assets/icons/trash-icon.png differ diff --git a/assets/icons/trash_lines.png b/assets/icons/trash_lines.png new file mode 100644 index 0000000..c354ab5 Binary files /dev/null and b/assets/icons/trash_lines.png differ diff --git a/assets/{keepable}.png b/assets/{keepable}.png new file mode 100644 index 0000000..d55ece9 Binary files /dev/null and b/assets/{keepable}.png differ diff --git a/css/components/aside.css b/css/components/aside.css new file mode 100644 index 0000000..abae130 --- /dev/null +++ b/css/components/aside.css @@ -0,0 +1,6 @@ +.aside { + min-width: 150px; + width: 280px; + border: 1px solid var(--gray-100); + padding-top: 10px; +} diff --git a/css/components/header.css b/css/components/header.css new file mode 100644 index 0000000..64f0689 --- /dev/null +++ b/css/components/header.css @@ -0,0 +1,21 @@ +.header { + height: 70px; + border: 1px solid var(--gray-100); + width: 100%; +} + +.header__container { + display: flex; + gap: 117px; + padding: 23px 0 23px 30px; +} + +.header__logo { + font-weight: 700; + font-size: 29px; + line-height: 24px; +} + +.header__logo span { + color: var(--gray-200); +} diff --git a/css/components/main-content.css b/css/components/main-content.css new file mode 100644 index 0000000..a755387 --- /dev/null +++ b/css/components/main-content.css @@ -0,0 +1,82 @@ +.main-content { + width: 100%; + border: 1px solid var(--gray-100); + padding: 23px; + overflow: auto; +} + +.form-container { + background-color: white; + border-radius: 8px; + max-width: 600px; + margin: 0px auto; + padding: 20px; + margin-bottom: 59px; +} + +.color-palette-container { + width: 36px; + height: 36px; + padding: 9px; + background: rgba(255, 255, 255, 0.5); + border-radius: 100px; + position: relative; +} + +.colors__container-custom-form { + background-color: white; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + border-radius: 8px; + padding: 5px; + gap: 5px; + display: none; + grid-template-columns: repeat(5, 1fr); + position: absolute; + top: 40px; + left: 5px; +} + +.colors__container-custom { + background-color: white; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + border-radius: 8px; + padding: 5px; + gap: 5px; + display: none; + grid-template-columns: repeat(5, 1fr); + position: absolute; + bottom: 42px; + left: 0px; +} + +.colors__container-custom-open { + display: grid; +} + +.color-custom { + width: 25px; + height: 25px; + border-radius: 100px; + cursor: pointer; +} + +.color-custom-note { + width: 25px; + height: 25px; + border-radius: 100px; + cursor: pointer; +} + +.color-custom:focus-within { + outline: solid; + outline-color: #999b9e; + background-color: red; +} + +.empty-container { + text-align: center; + height: 500px; + justify-content: center; + align-items: center; + display: none; +} diff --git a/css/components/notes.css b/css/components/notes.css new file mode 100644 index 0000000..d053a41 --- /dev/null +++ b/css/components/notes.css @@ -0,0 +1,122 @@ +.note-container { + position: relative; + background-color: white; + border-radius: 8px; + width: 260px; + height: 260px; + padding: 20px; + color: black; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.notes-container { + display: flex; + flex-wrap: wrap; + gap: 20px; +} +.deleted_notes-container { + display: flex; + flex-wrap: wrap; + gap: 20px; +} + +.modal { + display: none; /* Hidden by default */ + position: fixed; /* Stay in place */ + z-index: 1; /* Sit on top */ + left: 0; + top: 0; + gap: 20px; + width: 100%; /* Full width */ + height: 100%; /* Full height */ + overflow: auto; /* Enable scroll if needed */ + background-color: rgb(0, 0, 0); /* Fallback color */ + background-color: rgba(0, 0, 0, 0.4); /* Black w/ opacity */ +} + +/* Modal Content/Box */ +.modal-content { + background-color: #fefefe; + margin: 15% auto; /* 15% from the top and centered */ + padding: 20px; + border: 1px solid #888; + color: black; + display: flex; + flex-direction: column; + justify-content: space-between; + max-width: 600px; + height: 203px; + border-radius: 8px; + box-shadow: 3px 3px 8px rgba(40, 40, 40, 0.85); +} + +/* The Close Button */ +.close { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; +} + +.close:hover, +.close:focus { + color: black; + text-decoration: none; +} + +/* Background colors for palettes */ +.white-bg { + background-color: white; +} + +.red-100-bg { + background-color: var(--red-100); +} + +.yellow-100-bg { + background-color: var(--yellow-100); +} + +.yellow-200-bg { + background-color: var(--yellow-200); +} + +.green-100-bg { + background-color: var(--green-100); +} + +.cyan-100-bg { + background-color: var(--cyan-100); +} + +.blue-100-bg { + background-color: var(--blue-100); +} + +.blue-200-bg { + background-color: var(--blue-200); +} + +.pink-100-bg { + background-color: var(--pink-100); +} + +.purple-200-bg { + background-color: var(--purple-200); +} +.pin-container { + position: absolute; + justify-self: flex-end; + align-self: flex-end; + background: rgba(255, 255, 255, 0.5); + display: flex; + justify-content: center; + align-items: center; + width: 2em; + height: 2em; + border-radius: 50%; + + cursor: pointer; +} diff --git a/css/global.css b/css/global.css new file mode 100644 index 0000000..a7417af --- /dev/null +++ b/css/global.css @@ -0,0 +1,6 @@ +@import url("./global/colors.css"); +@import url("./global/layout.css"); +@import url("./global/reset.css"); +@import url("./global/typography.css"); +@import url("./global/utils.css"); +@import url("./components/notes.css"); \ No newline at end of file diff --git a/css/global/colors.css b/css/global/colors.css new file mode 100644 index 0000000..46836c3 --- /dev/null +++ b/css/global/colors.css @@ -0,0 +1,23 @@ +:root { + --red-100: #f28b82; + --yellow-100: #fff475; + --yellow-200: #fbbc04; + --green-100: #ccff90; + --cyan-100: #a7ffeb; + --blue-100: #cbf0f8; + --blue-200: #aecbfa; + --pink-100: #fdcfe8; + --purple-200: #d7aefb; + --gray-100: #d1d1d1; + --gray-200: #999b9e; + --gray-300: #1d2128; + + --white-transparent: #ffffff80; + --gray-transparent: #999b9e80; + --gray-placeholder-1: #8E9196; + --gray-placeholder-2: #7B8493; + + + --shadow-sm: 0px 4px 4px rgba(0, 0, 0, 0.25); + --shadow-white: 5px 5px 15px 0px #999B9ED9; +} \ No newline at end of file diff --git a/css/global/layout.css b/css/global/layout.css new file mode 100644 index 0000000..514c6fd --- /dev/null +++ b/css/global/layout.css @@ -0,0 +1,75 @@ +.container { + background-color: var(--gray-300); + color: #ffffff; + height: 100vh; +} +body { + background-color: var(--gray-300); +} + +section { + height: calc(100vh - 70px); + width: 100%; +} + +a { + text-decoration: none; + color: white; +} + +input { + border: none; +} + +input:focus { + outline: none; +} + +.card__title::placeholder { + color: var(--gray-placeholder-1); +} + +.card__content::placeholder { + color: var(--gray-placeholder-2); +} + +.button { + border: none; + background-color: transparent; + padding: 0px; + cursor: pointer; +} + +.aside__notes:hover, +.aside__trash:hover { + background-color: var(--gray-200); + border-radius: 0px 25px 25px 0px; +} + +.aside__notes-icon { + width: 20px; + height: 16px; +} + +.aside__active-menu { + background-color: var(--gray-200); + border-radius: 0px 25px 25px 0px; +} + +.text-container { + display: flex; + flex-direction: column; + gap: 10px; +} + +.actions-container { + display: flex; + justify-content: space-between; + margin-top: 20px; +} + +/* .aside__notes:active, +.aside__trash:active { + background-color: var(--gray-transparent); + border-radius: 0px 25px 25px 0px; +} */ diff --git a/css/global/reset.css b/css/global/reset.css new file mode 100644 index 0000000..69e48f2 --- /dev/null +++ b/css/global/reset.css @@ -0,0 +1,74 @@ +/* Box sizing rules */ +*, +*::before, +*::after { + box-sizing: border-box; +} + +/* Remove default margin */ +body, +h1, +h2, +h3, +h4, +p, +figure, +blockquote, +dl, +dd { + margin: 0; +} + +/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */ +ul[role="list"], +ol[role="list"] { + list-style: none; +} + +/* Set core root defaults */ +html:focus-within { + scroll-behavior: smooth; +} + +/* Set core body defaults */ +body { + min-height: 100vh; + text-rendering: optimizeSpeed; + line-height: 1.5; +} + +/* A elements that don't have a class get default styles */ +a:not([class]) { + text-decoration-skip-ink: auto; +} + +/* Make images easier to work with */ +img, +picture { + max-width: 100%; + display: block; +} + +/* Inherit fonts for inputs and buttons */ +input, +button, +textarea, +select { + font: inherit; +} + +/* Remove all animations, transitions and smooth scroll for people that prefer not to see them */ +@media (prefers-reduced-motion: reduce) { + html:focus-within { + scroll-behavior: auto; + } + + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } +} diff --git a/css/global/typography.css b/css/global/typography.css new file mode 100644 index 0000000..5cb5812 --- /dev/null +++ b/css/global/typography.css @@ -0,0 +1,32 @@ +@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap"); + +:root { + --font-primary: "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", + Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; +} + +body { + font-size: 18px; + line-height: 24px; + letter-spacing: 0.25px; + font-family: var(--font-primary); + color: var(black); + font-weight: 400; +} + +.heading { + font-size: 14px; + line-height: 20px; + font-weight: 700; +} + +.content-lg { + font-size: 36px; + line-height: 48px; + font-weight: 700; +} + +.content-sm { + font-size: 14px; + line-height: 20px; +} \ No newline at end of file diff --git a/css/global/utils.css b/css/global/utils.css new file mode 100644 index 0000000..8ad49ab --- /dev/null +++ b/css/global/utils.css @@ -0,0 +1,97 @@ +/* Contours */ +.gray-border { + border: 1px solid #999b9e; +} + +/* Display */ +.flex { + display: flex; +} + +.align-center { + align-items: center; +} + +.space-between { + justify-content: space-between; +} + +.flex-column { + flex-direction: column; +} + +.full-width { + width: 100%; +} + +.ds-none { + display: none; +} + +.center-vertically { + justify-content: center; +} + +.centered { + margin: auto; +} + +/* margin */ +.mt-20 { + margin-top: 20px; +} +/* padding */ + +.p-23 { + padding: 23px; +} + +.py-14 { + padding: 14px 0; +} + +.pl-20 { + padding-left: 20px; +} + +/* gap */ +.gap-5 { + gap: 5px; +} + +.gap-10 { + gap: 10px; +} + +.gap-20 { + gap: 20px; +} + +/* font weights */ +.bold { + font-weight: 700; +} + +/* colors */ + +.border-color { + border: 1px solid #999b9e; +} + +/* positions */ + +.absolute { + position: absolute; +} + +.inner-image { + position: absolute; + width: 6.25px; + height: 9px; + top: 5px; + right: 5.25px; +} + +.trash-div { + position: relative; +} diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..0043437 --- /dev/null +++ b/css/style.css @@ -0,0 +1,4 @@ +@import url("./global.css"); +@import url("./components/header.css"); +@import url("./components/aside.css"); +@import url("./components/main-content.css"); diff --git a/index.html b/index.html new file mode 100644 index 0000000..a12b3fd --- /dev/null +++ b/index.html @@ -0,0 +1,103 @@ + + + + + + Keepable + + + + +
+
+
+ +

Welcome to {keepable}

+
+
+
+ +
+
+
+
+ + +
+
+
+
+ color-pallete-icon +
+
+
+ + +
+
+
+ +
+ + +
+

No notes to keep

+
+
+

+
+
+
+

+
+
+ +
+
+
+ + + + + diff --git a/index.js b/index.js new file mode 100644 index 0000000..b7641c4 --- /dev/null +++ b/index.js @@ -0,0 +1,324 @@ +function renderNotes(notes) { + const othersTitle = document.querySelector("#others-title"); + const pinnedTitle = document.querySelector("#pinned-title"); + const pinnedList = document.querySelector("#pinned-container"); + const notesList = document.querySelector("#others-container"); + const emptyContainer = document.querySelector(".empty-container"); + + notesList.innerHTML = ""; + pinnedList.innerHTML = ""; + othersTitle.innerHTML = ""; + pinnedTitle.innerHTML = ""; + + if (pinned.length > 0) { + pinnedTitle.textContent = "PINNED"; + pinned.forEach((note) => { + const noteEl = createNoteEl(note); + pinnedList.append(noteEl); + }); + } + if (notes.length > 0) { + const othersTitle = document.querySelector("#others-title"); + othersTitle.textContent = "OTHERS"; + notes.forEach((note) => { + const noteEl = createNoteEl(note); + notesList.append(noteEl); + }); + } else if (pinned.length == 0 && notes.length == 0) { + emptyContainer.style.display = "flex"; + } +} + +function renderModal(note) { + const modalList = document.querySelector(".modal-list"); + modalList.innerHTML = ""; + + const modalEl = editNoteEl(note); + modalList.append(modalEl); +} + +function createNoteEl(note) { + // Create elements + const noteContainer = document.createElement("div"); + const textContainer = document.createElement("div"); + const title = document.createElement("p"); + const content = document.createElement("p"); + const actionsContainer = document.createElement("div"); + const colorButtonContainer = document.createElement("div"); + const colorButtonIcon = document.createElement("button"); + const colorButtonImg = document.createElement("img"); + const paletteContainerNote = document.createElement("div"); + const deleteButtonContainer = document.createElement("div"); + const deleteButtonIcon = document.createElement("button"); + const deleteButtonWrapper = document.createElement("div"); + const deleteButtonImg1 = document.createElement("img"); + const deleteButtonImg2 = document.createElement("img"); + const pinButtonContainer = document.createElement("div"); + const pinButtonImg = document.createElement("img"); + // Setup elements + noteContainer.classList.add("note-container"); + if (note.color) noteContainer.classList.add(note.color); + textContainer.className = "text-container"; + pinButtonContainer.className = "pin-container"; + title.className = "heading"; + title.textContent = note.title; + content.textContent = note.content; + actionsContainer.className = "flex gap-10"; + colorButtonContainer.className = "color-palette-container"; + colorButtonIcon.className = "button"; + colorButtonImg.src = "./assets/icons/color-pallete-icon.png"; + paletteContainerNote.className = "colors__container-custom"; + deleteButtonContainer.className = "color-palette-container"; + deleteButtonIcon.className = "button"; + deleteButtonWrapper.className = "trash-div"; + deleteButtonImg1.src = "./assets/icons/trash-icon-gray.png"; + deleteButtonImg2.className = "inner-image"; + deleteButtonImg2.src = "./assets/icons/trash_lines.png"; + + pinButtonImg.src = note.pin + ? "./assets/icons/pinned-icon.png" + : "./assets/icons/others-icon.svg"; + // Build template + noteContainer.append(textContainer, actionsContainer, pinButtonContainer); + textContainer.append(title, content); + actionsContainer.append(colorButtonContainer, deleteButtonContainer); + colorButtonContainer.append(colorButtonIcon, paletteContainerNote); + colorButtonIcon.append(colorButtonImg); + deleteButtonContainer.append(deleteButtonIcon); + deleteButtonIcon.append(deleteButtonWrapper); + deleteButtonWrapper.append(deleteButtonImg2, deleteButtonImg1); + pinButtonContainer.append(pinButtonImg); + + noteContainer.addEventListener("click", (event) => { + var target = event.target; + if ( + target === deleteButtonContainer || + deleteButtonContainer.contains(target) + ) { + return; + } + if (target === pinButtonContainer || pinButtonContainer.contains(target)) { + return; + } + if ( + target === colorButtonContainer || + colorButtonContainer.contains(target) + ) { + return; + } + if ( + target === paletteContainerNote || + paletteContainerNote.contains(target) + ) { + return; + } + event.preventDefault(); + renderModal(note); + }); + //Event Listeners + const colorsArrayNote = createColorPalette(paletteContainerNote, colors); + colorButtonContainer.addEventListener("click", function (event) { + event.preventDefault(); + paletteContainerNote.classList.toggle("colors__container-custom-open"); + console.log(colorsArrayNote); + }); + document.addEventListener("mouseup", function (event) { + paletteContainerNote.classList.remove("colors__container-custom-open"); + }); + colorsArrayNote.forEach((colorSelected) => { + colorSelected.addEventListener("click", function (event) { + event.preventDefault(); + colorClaseNote = event.currentTarget.classList[1]; + editColorNote(note, colorClaseNote); + renderNotes(notes); + paletteContainerNote.classList.toggle("colors__container-custom-open"); + }); + }); + + deleteButtonContainer.addEventListener("click", (event) => { + event.preventDefault(); + + deleteNote(note); + renderNotes(notes); + }); + + pinButtonContainer.addEventListener("click", (event) => { + event.preventDefault(); + if (note.pin == true) { + unpinNote(note); + } else { + pinNote(note); + } + + renderNotes(notes); + }); + return noteContainer; +} + +const form = document.querySelector(".js-form-container"); + +form.addEventListener("submit", (event) => { + event.preventDefault(); + const { title, content } = event.currentTarget; + const newNote = { + title: title.value, + content: content.value, + color: colorClase, + pin: false, + }; + createNote(newNote); + location.assign("/"); +}); + +const notesCtgry = document.querySelector("#notes_ctgry"); +const trashCtgry = document.querySelector("#trash_ctgry"); +notesCtgry.onclick = function () { + toogleCtgryStatus(this); +}; +trashCtgry.onclick = function () { + toogleCtgryStatus(this); +}; + +function toogleCtgryStatus(element) { + document + .querySelector(".aside__active-menu") + .classList.remove("aside__active-menu"); + element.classList.add("aside__active-menu"); +} + +renderNotes(notes); + +function editNoteEl(note) { + // Edit elements + const modalContainer = document.createElement("div"); + const modalContent = document.createElement("div"); + const formContainer = document.createElement("form"); + const textContainer = document.createElement("div"); + const title = document.createElement("input"); + const content = document.createElement("input"); + const footer = document.createElement("div"); + const actionsContainer = document.createElement("div"); + const colorButtonContainer = document.createElement("div"); + const colorButtonIcon = document.createElement("button"); + const colorButtonImg = document.createElement("img"); + const paletteContainerNote = document.createElement("div"); + const deleteButtonContainer = document.createElement("div"); + const deleteButtonIcon = document.createElement("button"); + const deleteButtonWrapper = document.createElement("div"); + const deleteButtonImg1 = document.createElement("img"); + const deleteButtonImg2 = document.createElement("img"); + const submitButtonContainer = document.createElement("div"); + const submitButtonIcon = document.createElement("button"); + // Setup elements + modalContainer.className = "modal"; + modalContainer.style.display = "block"; + formContainer.action = "#"; + formContainer.className = "modal-content"; + modalContent.className = "modal-content"; + textContainer.className = "text-container"; + title.className = "heading"; + title.id = "title"; + title.name = "title"; + title.value = note.title; + content.id = "content"; + content.name = "content"; + content.value = note.content; + footer.className = "flex space-between"; + actionsContainer.className = "flex gap-10"; + colorButtonContainer.className = "color-palette-container"; + colorButtonIcon.className = "button"; + paletteContainerNote.className = "colors__container-custom-form"; + colorButtonImg.src = "./assets/icons/color-pallete-icon.png"; + deleteButtonContainer.className = "color-palette-container"; + deleteButtonIcon.className = "button"; + deleteButtonWrapper.className = "trash-div"; + deleteButtonImg1.src = "./assets/icons/trash-icon-gray.png"; + deleteButtonImg2.className = "inner-image"; + deleteButtonImg2.src = "./assets/icons/trash_lines.png"; + submitButtonContainer.className = "color-palette-container"; + submitButtonIcon.className = "button bold"; + submitButtonIcon.textContent = "Keep it!"; + submitButtonIcon.type = "submit"; + + // Build template + modalContainer.append(formContainer); + formContainer.append(textContainer, footer); + textContainer.append(title, content); + footer.append(actionsContainer, submitButtonIcon); + // actionsContainer.append(colorButtonContainer, deleteButtonContainer); + actionsContainer.append(colorButtonContainer, deleteButtonContainer); + colorButtonContainer.append(colorButtonIcon, paletteContainerNote); + colorButtonIcon.append(colorButtonImg); + deleteButtonContainer.append(deleteButtonIcon); + deleteButtonIcon.append(deleteButtonWrapper); + deleteButtonWrapper.append(deleteButtonImg2, deleteButtonImg1); + console.log(note); + const colorModalDefault = note.color.replace(/-bg/, ""); + if (colorModalDefault == "white") { + formContainer.style.backgroundColor = "white"; + title.style.backgroundColor = "white"; + content.style.backgroundColor = "white"; + } else { + formContainer.style.backgroundColor = `var(--${colorModalDefault})`; + title.style.backgroundColor = `var(--${colorModalDefault})`; + content.style.backgroundColor = `var(--${colorModalDefault})`; + } + //Event Listeners + const colorsArrayNote = createColorPalette(paletteContainerNote, colors); + + colorButtonContainer.addEventListener("click", function (event) { + event.preventDefault(); + paletteContainerNote.classList.toggle("colors__container-custom-open"); + console.log(colorArrayForm); + }); + + document.addEventListener("mouseup", function (event) { + paletteContainerNote.classList.remove("colors__container-custom-open"); + }); + + let colorClaseModal = ""; + colorsArrayNote.forEach((colorSelected) => { + colorSelected.addEventListener("click", function (event) { + event.preventDefault(); + colorClaseModal = event.currentTarget.classList[1]; + const colorClaseStr = colorClaseModal.replace(/-bg/, ""); + if (colorClaseStr == "white") { + formContainer.style.backgroundColor = "white"; + title.style.backgroundColor = "white"; + content.style.backgroundColor = "white"; + } else { + formContainer.style.backgroundColor = `var(--${colorClaseStr})`; + title.style.backgroundColor = `var(--${colorClaseStr})`; + content.style.backgroundColor = `var(--${colorClaseStr})`; + } + }); + }); + if (!colorClaseModal) colorClaseModal = note.color; + + deleteButtonContainer.addEventListener("click", (event) => { + event.preventDefault(); + deleteNote(note); + renderNotes(notes); + modalContainer.style.display = "none"; + }); + + formContainer.addEventListener("submit", (event) => { + event.preventDefault(); + console.log(note); + const { title, content } = event.target; + modalContainer.style.display = "none"; + const editNoteContent = { + title: title.value, + content: content.value, + color: colorClaseModal, + }; + editNote(note, editNoteContent); + location.assign("index.html"); + }); + document.addEventListener("mouseup", function (event) { + if (!formContainer.contains(event.target)) { + modalContainer.style.display = "none"; + } + }); + return modalContainer; +} diff --git a/palette.js b/palette.js new file mode 100644 index 0000000..4946307 --- /dev/null +++ b/palette.js @@ -0,0 +1,68 @@ +const colors = [ + "white-bg", + "red-100-bg", + "yellow-100-bg", + "yellow-200-bg", + "green-100-bg", + "cyan-100-bg", + "blue-100-bg", + "blue-200-bg", + "purple-200-bg", + "pink-100-bg", +]; + +const paletteContainerForm = document.querySelector(".colors-container"); +paletteContainerForm.className = "colors__container-custom-form"; +const formContainer = document.querySelector(".form-container"); +const titleInput = document.getElementById("title"); +const contentInput = document.getElementById("content"); + +const colorArrayForm = createColorPalette(paletteContainerForm, colors); +const colorButton = document.getElementById("color-palette-container"); +let colorClase = ""; + +function createColorPalette(container, colors) { + const colorArray = []; + container.innerHTML = ""; + + colors.forEach((color) => { + let colorEl = document.createElement("div"); + if (color == "white-bg") { + colorEl.classList.add("color-custom", color, "border-color"); + } else { + colorEl.classList.add("color-custom", color); + } + colorArray.push(colorEl); + container.appendChild(colorEl); + }); + return colorArray; +} + +colorButton.addEventListener("click", function (event) { + event.preventDefault(); + + paletteContainerForm.classList.toggle("colors__container-custom-open"); + + console.log(colorArrayForm); +}); + +document.addEventListener("mouseup", function (event) { + paletteContainerForm.classList.remove("colors__container-custom-open"); +}); + +colorArrayForm.forEach((colorSelected) => { + colorSelected.addEventListener("click", function (event) { + event.preventDefault(); + colorClase = event.currentTarget.classList[1]; + const colorClaseStr = colorClase.replace(/-bg/, ""); + if (colorClaseStr == "white") { + formContainer.style.backgroundColor = "white"; + titleInput.style.backgroundColor = "white"; + contentInput.style.backgroundColor = "white"; + } else { + formContainer.style.backgroundColor = `var(--${colorClaseStr})`; + titleInput.style.backgroundColor = `var(--${colorClaseStr})`; + contentInput.style.backgroundColor = `var(--${colorClaseStr})`; + } + }); +}); diff --git a/store.js b/store.js new file mode 100644 index 0000000..6a4d081 --- /dev/null +++ b/store.js @@ -0,0 +1,97 @@ +// Data store +const initialNotes = []; + +const deletedNotes = []; + +const pinnedNotes = []; + +// // Adicion localStorage +const notesFromLocalStorage = JSON.parse(localStorage.getItem("notes")); //null +const notes = notesFromLocalStorage || initialNotes; +const pinnedFromLocalStorage = JSON.parse(localStorage.getItem("pinned")); //null +const pinned = pinnedFromLocalStorage || deletedNotes; +const deletedNotesFromLocalStorage = JSON.parse( + localStorage.getItem("deleted_notes") +); +const deleted = deletedNotesFromLocalStorage || pinnedNotes; + +function createNote(note) { + notes.push(note); + console.log(note); + localStorage.setItem("notes", JSON.stringify(notes)); +} + +function editColorNote(note, colorClaseNote) { + if (note.pin == true) { + const index = pinned.indexOf(note); + pinned[index].color = colorClaseNote; + localStorage.setItem("pinned", JSON.stringify(pinned)); + } else { + const index = notes.indexOf(note); + notes[index].color = colorClaseNote; + localStorage.setItem("notes", JSON.stringify(notes)); + } +} + +function editNote(note, editNoteContent) { + const index = notes.indexOf(note); + notes[index] = editNoteContent; + localStorage.setItem("notes", JSON.stringify(notes)); +} + +function deleteNote(note) { + deleted.push(note); + if (note.pin == true) { + const index = pinned.indexOf(note); + pinned.splice(index, 1); + localStorage.setItem("pinned", JSON.stringify(pinned)); + localStorage.setItem("deleted_notes", JSON.stringify(deleted)); + } else { + const index = notes.indexOf(note); + notes.splice(index, 1); + localStorage.setItem("notes", JSON.stringify(notes)); + localStorage.setItem("deleted_notes", JSON.stringify(deleted)); + } +} + +function deleteFromTrash(note) { + const index = deleted.indexOf(note); + deleted.splice(index, 1); + localStorage.setItem("deleted_notes", JSON.stringify(deleted)); +} + +function recoverFromTrash(note) { + // if (note.pin == false) { + note.pin = false; + notes.push(note); + const index = deleted.indexOf(note); + deleted.splice(index, 1); + localStorage.setItem("notes", JSON.stringify(notes)); + localStorage.setItem("deleted_notes", JSON.stringify(deleted)); + // } else { + // pinned.push(note); + // const index = deleted.indexOf(note); + // deleted.splice(index, 1); + // localStorage.setItem("pinned", JSON.stringify(pinned)); + // localStorage.setItem("deleted_notes", JSON.stringify(deleted)); + // } +} +function pinNote(note) { + // body + note.pin = true; + pinned.push(note); + const index = notes.indexOf(note); + notes.splice(index, 1); + localStorage.setItem("notes", JSON.stringify(notes)); + localStorage.setItem("pinned", JSON.stringify(pinned)); +} + +function unpinNote(note) { + // body + note.pin = false; + notes.push(note); + const index = pinned.indexOf(note); + pinned.splice(index, 1); + localStorage.setItem("notes", JSON.stringify(notes)); + localStorage.setItem("pinned", JSON.stringify(pinned)); +} diff --git a/trash.html b/trash.html new file mode 100644 index 0000000..b8144a0 --- /dev/null +++ b/trash.html @@ -0,0 +1,42 @@ + + + + + + Keepable + + + + +
+
+
+ +

Welcome to {keepable}

+
+
+
+ +
+
+
+
+
+
+ + + + diff --git a/trash.js b/trash.js new file mode 100644 index 0000000..ebf1e15 --- /dev/null +++ b/trash.js @@ -0,0 +1,69 @@ +function createDeletedNoteEl(note) { + // Create elements + const noteContainer = document.createElement("div"); + const textContainer = document.createElement("div"); + const title = document.createElement("p"); + const content = document.createElement("p"); + const actionsContainer = document.createElement("div"); + const recoverButtonContainer = document.createElement("div"); + const recoverButtonIcon = document.createElement("button"); + const recoverButtonImg = document.createElement("img"); + const deleteButtonContainer = document.createElement("div"); + const deleteButtonIcon = document.createElement("button"); + const deleteButtonWrapper = document.createElement("div"); + const deleteButtonImg1 = document.createElement("img"); + const deleteButtonImg2 = document.createElement("img"); + // Setup elements + noteContainer.classList.add("note-container"); + if (note.color) noteContainer.classList.add(note.color); + noteContainer.classList.add("activeNote"); + textContainer.className = "text-container"; + title.className = "heading"; + title.textContent = note.title; + content.textContent = note.content; + actionsContainer.className = "flex gap-10"; + recoverButtonContainer.className = "color-palette-container"; + recoverButtonIcon.className = "button"; + recoverButtonImg.src = "./assets/icons/recover-arrow.png"; + deleteButtonContainer.className = "color-palette-container"; + deleteButtonIcon.className = "button"; + deleteButtonWrapper.className = "trash-div"; + deleteButtonImg1.src = "./assets/icons/trash-icon-gray.png"; + deleteButtonImg2.className = "inner-image"; + deleteButtonImg2.src = "./assets/icons/trash_lines.png"; + + // Build template + noteContainer.append(textContainer, actionsContainer); + textContainer.append(title, content); + actionsContainer.append(deleteButtonContainer, recoverButtonContainer); + deleteButtonContainer.append(deleteButtonIcon); + deleteButtonIcon.append(deleteButtonWrapper); + deleteButtonWrapper.append(deleteButtonImg2, deleteButtonImg1); + recoverButtonContainer.append(recoverButtonIcon); + recoverButtonIcon.append(recoverButtonImg); + + //Event Listeners + deleteButtonContainer.addEventListener("click", (event) => { + event.preventDefault(); + deleteFromTrash(note); + renderDeletedNotes(deleted); + }); + recoverButtonContainer.addEventListener("click", (event) => { + event.preventDefault(); + recoverFromTrash(note); + renderDeletedNotes(deleted); + }); + return noteContainer; +} + +function renderDeletedNotes(notes) { + const deletedNotesList = document.querySelector(".deleted_notes-container"); + deletedNotesList.innerHTML = ""; + + notes.forEach((note) => { + const deletedNoteEl = createDeletedNoteEl(note); + deletedNotesList.append(deletedNoteEl); + }); +} + +renderDeletedNotes(deleted);