diff --git a/src/renderer/src/AppContext.jsx b/src/renderer/src/AppContext.jsx
index eea5356..8ac2d5b 100644
--- a/src/renderer/src/AppContext.jsx
+++ b/src/renderer/src/AppContext.jsx
@@ -40,19 +40,14 @@ const appStateReducer = (state, action) => {
saveState(newState);
return newState;
}
- case "UPDATE_ITEM": {
- const newItems = state.items.map((i) => {
- if (i.key === action.item.key) {
- return Object.assign({}, i, {
- status: action.item.status,
- });
- }
- return i;
- });
- const newState = { ...state, items: newItems };
- saveState(newState);
- return newState;
- }
+ case "UPDATE_ITEM": {
+ const newItems = state.items.map((i) =>
+ i.key === action.item.key ? { ...i, ...action.item } : i
+ );
+ const newState = { ...state, items: newItems };
+ saveState(newState);
+ return newState;
+ }
case "DELETE_ITEM": {
const newState = {
...state,
diff --git a/src/renderer/src/components/EditModal.jsx b/src/renderer/src/components/EditModal.jsx
new file mode 100644
index 0000000..fb773dc
--- /dev/null
+++ b/src/renderer/src/components/EditModal.jsx
@@ -0,0 +1,31 @@
+import React, { useState } from "react";
+import styles from "./EditModal.module.css"; // Import styles
+
+const EditModal = ({ isOpen, onClose, onSave, initialText }) => {
+ const [newText, setNewText] = useState(initialText);
+
+ const handleSave = () => {
+ if (newText.trim() !== "") {
+ onSave(newText);
+ onClose();
+ }
+ };
+
+ return (
+
+
+
Edit Item
+ setNewText(e.target.value)}
+ className={styles.input}
+ />
+ Save & Close
+ Cancel
+
+
+ );
+};
+
+export default EditModal;
diff --git a/src/renderer/src/components/EditModal.module.css b/src/renderer/src/components/EditModal.module.css
new file mode 100644
index 0000000..b682f93
--- /dev/null
+++ b/src/renderer/src/components/EditModal.module.css
@@ -0,0 +1,81 @@
+.modal {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.5); /* semi-transparent overlay */
+ z-index: 999;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s ease, visibility 0s 0.3s;
+}
+
+.modal.open {
+ opacity: 1;
+ visibility: visible;
+ transition: opacity 0.3s ease;
+}
+
+.modalContent {
+ background: white;
+ padding: 20px;
+ border-radius: 8px;
+ width: 400px;
+ max-width: 100%;
+ box-sizing: border-box;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+}
+
+h2 {
+ margin-bottom: 20px;
+ font-size: 1.5rem;
+ color: #333; /* Darker color for readability */
+}
+
+.input {
+ width: 100%;
+ padding: 20px 70px 20px 20px;
+ height: 70px;
+ background: #f0f0f0; /* Lighter background for input */
+ border: 1px solid #ccc; /* Border for input field */
+ border-radius: 3px;
+ box-sizing: border-box;
+ color: #333; /* Dark text color */
+ font-size: 1rem; /* Fixed font size */
+ outline: none;
+ margin-bottom: 15px;
+}
+
+button {
+ position: relative;
+ width: 100%;
+ padding: 10px;
+ background-color: #007bff; /* Blue background for buttons */
+ color: white; /* White text on buttons */
+ border: none;
+ border-radius: 4px;
+ font-size: 1rem;
+ cursor: pointer;
+ transition: background-color 0.3s;
+ margin-bottom: 8px;
+}
+
+button:hover {
+ background-color: #0056b3; /* Darker blue when hovered */
+}
+
+button:focus {
+ outline: none;
+}
+
+button.cancel {
+ background-color: #ccc; /* Light grey for cancel button */
+}
+
+button.cancel:hover {
+ background-color: #bbb; /* Darker grey on hover */
+}
diff --git a/src/renderer/src/components/Item.jsx b/src/renderer/src/components/Item.jsx
index 9eb6d00..6839157 100644
--- a/src/renderer/src/components/Item.jsx
+++ b/src/renderer/src/components/Item.jsx
@@ -1,70 +1,91 @@
+import React, { useState } from "react";
import { useAppReducer } from "../AppContext.jsx";
+import EditModal from "./EditModal.jsx"; // Import the modal component
import styles from "./Item.module.css";
-// Individual todo item
function Item({ item }) {
- const dispatch = useAppReducer();
- let text = item.text;
- let paused = item.status === "paused";
- let completed = item.status === "completed";
+ const dispatch = useAppReducer();
+ const [isModalOpen, setIsModalOpen] = useState(false);
+ let text = item.text;
+ let paused = item.status === "paused";
+ let completed = item.status === "completed";
- function deleteItem() {
- dispatch({ type: "DELETE_ITEM", item });
- }
+ function deleteItem() {
+ dispatch({ type: "DELETE_ITEM", item });
+ }
- function pauseItem() {
- const pausedItem = { ...item, status: "paused" };
- dispatch({ type: "UPDATE_ITEM", item: pausedItem });
- }
+ function pauseItem() {
+ const pausedItem = { ...item, status: "paused" };
+ dispatch({ type: "UPDATE_ITEM", item: pausedItem });
+ }
- function resumeItem() {
- const pendingItem = { ...item, status: "pending" };
- dispatch({ type: "UPDATE_ITEM", item: pendingItem });
- }
+ function resumeItem() {
+ const pendingItem = { ...item, status: "pending" };
+ dispatch({ type: "UPDATE_ITEM", item: pendingItem });
+ }
- function completeItem() {
- const completedItem = { ...item, status: "completed" };
- dispatch({ type: "UPDATE_ITEM", item: completedItem });
- }
+ function completeItem() {
+ const completedItem = { ...item, status: "completed" };
+ dispatch({ type: "UPDATE_ITEM", item: completedItem });
+ }
- return (
-
-
{text}
-
- {completed && }
-
- {!paused && !completed && (
-
- )}
- {(paused || completed) && (
-
- )}
- {!completed && (
-
- )}
-
-
- );
+ // Function to handle saving the edited item
+ function handleEditSave(newText) {
+ const updatedItem = { ...item, text: newText };
+ dispatch({ type: "UPDATE_ITEM", item: updatedItem });
+ }
+
+ return (
+
+
{text}
+
+ {completed && }
+
+ {!paused && !completed && (
+
+ )}
+ {(paused || completed) && (
+
+ )}
+ {!completed && (
+ setIsModalOpen(true)} // Open the modal when editing
+ tabIndex="0"
+ >
+
+
+ )}
+ {!completed && (
+
+ )}
+
+
+ {/* Render the modal when it's open */}
+
setIsModalOpen(false)} // Close the modal
+ onSave={handleEditSave} // Save the new text
+ initialText={item.text}
+ />
+
+ );
}
export default Item;
diff --git a/src/renderer/src/components/Item.module.css b/src/renderer/src/components/Item.module.css
index 7ff8db6..43e6cac 100644
--- a/src/renderer/src/components/Item.module.css
+++ b/src/renderer/src/components/Item.module.css
@@ -78,6 +78,16 @@
}
}
+ &.edit {
+ width: 24px;
+ height: 24px;
+ background-color: var(--orange);
+ mask: url("../img/edit.svg") no-repeat center;
+ mask-size: contain;
+ -webkit-mask: url("../img/edit.svg") no-repeat center;
+ -webkit-mask-size: contain;
+ }
+
&.complete {
width: 30px;
background: no-repeat url("../img/check.svg");
diff --git a/src/renderer/src/img/edit.svg b/src/renderer/src/img/edit.svg
new file mode 100644
index 0000000..59bbb2e
--- /dev/null
+++ b/src/renderer/src/img/edit.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/src/renderer/src/styles/variables.css b/src/renderer/src/styles/variables.css
index b1ab8c1..18bbb21 100644
--- a/src/renderer/src/styles/variables.css
+++ b/src/renderer/src/styles/variables.css
@@ -3,6 +3,7 @@
--green: #62dca5;
--yellow: #f7f879;
--red: #e1675a;
+ --orange: #f4a261;
--input-color: #2e2d33;
--item-color: #4e4d5c;