diff --git a/app/frontend/App.tsx b/app/frontend/App.tsx index 9cd1740..fe8dd91 100644 --- a/app/frontend/App.tsx +++ b/app/frontend/App.tsx @@ -104,7 +104,7 @@ const App: React.FC = () => { {currentUser ? ( diff --git a/app/frontend/components/Area/AreaModal.tsx b/app/frontend/components/Area/AreaModal.tsx index 6ff7807..4959b4c 100644 --- a/app/frontend/components/Area/AreaModal.tsx +++ b/app/frontend/components/Area/AreaModal.tsx @@ -54,7 +54,6 @@ const AreaModal: React.FC = ({ isOpen, onClose, area, onSave }) }; }, [isOpen]); - // Handle Escape key to close modal useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if (event.key === 'Escape') { diff --git a/app/frontend/components/Navbar.tsx b/app/frontend/components/Navbar.tsx index 79eafdc..2aea89d 100644 --- a/app/frontend/components/Navbar.tsx +++ b/app/frontend/components/Navbar.tsx @@ -53,8 +53,8 @@ const Navbar: React.FC = ({ }); if (response.ok) { - setCurrentUser(null); // Update the application state - navigate("/login"); // Redirect to the login page + setCurrentUser(null); + navigate("/login"); } else { console.error("Failed to log out"); } diff --git a/app/frontend/components/Note/NoteModal.tsx b/app/frontend/components/Note/NoteModal.tsx index 0d93d63..1ad4beb 100644 --- a/app/frontend/components/Note/NoteModal.tsx +++ b/app/frontend/components/Note/NoteModal.tsx @@ -1,5 +1,3 @@ -// app/frontend/components/Note/NoteModal.tsx - import React, { useState, useEffect, useRef, useCallback } from 'react'; import { Note } from '../../entities/Note'; import { useDataContext } from '../../contexts/DataContext'; @@ -31,7 +29,6 @@ const NoteModal: React.FC = ({ isOpen, onClose, note, onSave }) const { showSuccessToast, showErrorToast } = useToast(); - // Fetch available tags when modal is opened useEffect(() => { if (isOpen) { fetch('/api/tags') @@ -44,7 +41,6 @@ const NoteModal: React.FC = ({ isOpen, onClose, note, onSave }) } }, [isOpen, showErrorToast]); - // Reset form data when modal opens or note changes useEffect(() => { if (isOpen) { setFormData({ @@ -58,7 +54,6 @@ const NoteModal: React.FC = ({ isOpen, onClose, note, onSave }) } }, [isOpen, note]); - // Handle click outside to close modal useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( @@ -77,7 +72,6 @@ const NoteModal: React.FC = ({ isOpen, onClose, note, onSave }) }; }, [isOpen]); - // Handle Escape key to close modal useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if (event.key === 'Escape') { @@ -105,7 +99,6 @@ const NoteModal: React.FC = ({ isOpen, onClose, note, onSave }) const handleTagsChange = useCallback((newTags: string[]) => { setTags(newTags); - // Map newTags to Tag objects with 'id' if they exist in availableTags const updatedTags: Tag[] = newTags.map((name) => { const existingTag = availableTags.find((tag) => tag.name === name); return existingTag ? { id: existingTag.id, name } : { name }; diff --git a/app/frontend/components/Project/ProjectDetails.tsx b/app/frontend/components/Project/ProjectDetails.tsx index 94a47a0..a31d35f 100644 --- a/app/frontend/components/Project/ProjectDetails.tsx +++ b/app/frontend/components/Project/ProjectDetails.tsx @@ -1,5 +1,3 @@ -// app/frontend/components/Project/ProjectDetails.tsx - import React, { useEffect, useState } from "react"; import { useParams, useLocation, useNavigate, Link } from "react-router-dom"; import { @@ -34,7 +32,6 @@ const ProjectDetails: React.FC = () => { const projectTitle = stateTitle || project?.name || "Project"; const projectIcon = stateIcon; - // State for Collapsible Completed Tasks const [isCompletedOpen, setIsCompletedOpen] = useState(false); useEffect(() => { @@ -169,7 +166,6 @@ const ProjectDetails: React.FC = () => { ); } - // Separate tasks into active and completed const activeTasks = tasks.filter(task => task.status !== 'done'); const completedTasks = tasks.filter(task => task.status === 'done'); @@ -231,7 +227,7 @@ const ProjectDetails: React.FC = () => { handleTaskCreate({ name: taskName, status: "not_started", - project_id: project?.id, // Ensure project_id is correctly assigned + project_id: project?.id, }) } /> diff --git a/app/frontend/components/Project/ProjectModal.tsx b/app/frontend/components/Project/ProjectModal.tsx index 4e3805c..7966dcb 100644 --- a/app/frontend/components/Project/ProjectModal.tsx +++ b/app/frontend/components/Project/ProjectModal.tsx @@ -68,7 +68,6 @@ const ProjectModal: React.FC = ({ }; }, [isOpen]); - // Handle Escape key to close modal useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if (event.key === 'Escape') { diff --git a/app/frontend/components/Shared/PriorityDropdown.tsx b/app/frontend/components/Shared/PriorityDropdown.tsx index 7da59e7..4638a31 100644 --- a/app/frontend/components/Shared/PriorityDropdown.tsx +++ b/app/frontend/components/Shared/PriorityDropdown.tsx @@ -1,5 +1,5 @@ import React, { useState, useRef, useEffect } from 'react'; -import { ChevronDownIcon, ArrowDownIcon, ArrowUpIcon, FireIcon } from '@heroicons/react/24/outline'; // Import the icons +import { ChevronDownIcon, ArrowDownIcon, ArrowUpIcon, FireIcon } from '@heroicons/react/24/outline'; import { PriorityType } from '../../entities/Task'; interface PriorityDropdownProps { diff --git a/app/frontend/components/Tag/TagInput.tsx b/app/frontend/components/Tag/TagInput.tsx index c68704b..ff4f897 100644 --- a/app/frontend/components/Tag/TagInput.tsx +++ b/app/frontend/components/Tag/TagInput.tsx @@ -1,5 +1,3 @@ -// app/frontend/components/Tag/TagInput.tsx - import React, { useState } from 'react'; import TaskTags from '../Task/TaskTags'; import { Tag } from '../../entities/Tag'; diff --git a/app/frontend/components/Tag/TagModal.tsx b/app/frontend/components/Tag/TagModal.tsx index b0e2f91..3804f1a 100644 --- a/app/frontend/components/Tag/TagModal.tsx +++ b/app/frontend/components/Tag/TagModal.tsx @@ -55,7 +55,6 @@ const TagModal: React.FC = ({ }; }, [isOpen]); - // Handle Escape key to close modal useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if (event.key === 'Escape') { @@ -87,14 +86,9 @@ const TagModal: React.FC = ({ setIsSubmitting(true); try { - // Assuming you have createTag and updateTag functions if (tag) { - // Update existing tag - // await updateTag(formData.id, formData); showSuccessToast('Tag updated successfully!'); } else { - // Create new tag - // await createTag(formData); showSuccessToast('Tag created successfully!'); } onSave(formData); diff --git a/app/frontend/components/Task/TaskHeader.tsx b/app/frontend/components/Task/TaskHeader.tsx index 66720fa..642bc48 100644 --- a/app/frontend/components/Task/TaskHeader.tsx +++ b/app/frontend/components/Task/TaskHeader.tsx @@ -1,5 +1,3 @@ -// app/frontend/components/Task/TaskHeader.tsx - import React from "react"; import TaskPriorityIcon from "./TaskPriorityIcon"; import TaskTags from "./TaskTags"; diff --git a/app/frontend/components/Task/TaskModal.tsx b/app/frontend/components/Task/TaskModal.tsx index e950c3a..83b6a94 100644 --- a/app/frontend/components/Task/TaskModal.tsx +++ b/app/frontend/components/Task/TaskModal.tsx @@ -39,9 +39,9 @@ const TaskModal: React.FC = ({ const [dropdownOpen, setDropdownOpen] = useState(false); const modalRef = useRef(null); const [isClosing, setIsClosing] = useState(false); - const [showConfirmDialog, setShowConfirmDialog] = useState(false); // State to control confirm dialog + const [showConfirmDialog, setShowConfirmDialog] = useState(false); - const { showSuccessToast, showErrorToast } = useToast(); // Use toast functions + const { showSuccessToast, showErrorToast } = useToast(); useEffect(() => { setFormData(task); @@ -118,7 +118,7 @@ const TaskModal: React.FC = ({ }; const handleDeleteClick = () => { - setShowConfirmDialog(true); // Show confirmation dialog + setShowConfirmDialog(true); }; const handleDeleteConfirm = () => { @@ -138,7 +138,6 @@ const TaskModal: React.FC = ({ }, 300); }; - // Handler to remove tag const handleTagRemove = (tagId: string | number | undefined) => { if (tagId === undefined) return; const tagIndex = Number(tagId); @@ -174,7 +173,6 @@ const TaskModal: React.FC = ({ }; }, [isOpen]); - // Handle Escape key to close modal useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") { diff --git a/app/frontend/components/Tasks.tsx b/app/frontend/components/Tasks.tsx index fef50f6..02c8b33 100644 --- a/app/frontend/components/Tasks.tsx +++ b/app/frontend/components/Tasks.tsx @@ -1,5 +1,3 @@ -// app/frontend/components/Tasks.tsx - import React, { useEffect, useState, useRef } from "react"; import { useLocation, useNavigate } from "react-router-dom"; import TaskList from "./Task/TaskList"; diff --git a/app/frontend/contexts/DataContext.tsx b/app/frontend/contexts/DataContext.tsx index 6fa8d29..7898a93 100644 --- a/app/frontend/contexts/DataContext.tsx +++ b/app/frontend/contexts/DataContext.tsx @@ -1,9 +1,7 @@ -// app/frontend/contexts/DataContext.tsx - import React, { createContext, useContext } from 'react'; import useFetchTags from '../hooks/useFetchTags'; import useFetchAreas from '../hooks/useFetchAreas'; -import useFetchProjects from '../hooks/useFetchProjects'; // Use the updated hook +import useFetchProjects from '../hooks/useFetchProjects'; import useManageAreas from '../hooks/useManageAreas'; import useManageNotes from '../hooks/useManageNotes'; import useManageProjects from '../hooks/useManageProjects'; @@ -37,7 +35,7 @@ interface DataContextProps { mutateTags: () => void; mutateAreas: () => void; mutateNotes: () => void; - mutateProjects: () => void; // Include mutateProjects + mutateProjects: () => void; } const DataContext = createContext(undefined); @@ -58,7 +56,7 @@ export const DataProvider: React.FC<{ children: React.ReactNode }> = ({ children isLoading: isLoadingProjects, isError: isErrorProjects, mutate: mutateProjects, - } = useFetchProjects(); // Use the updated hook without options + } = useFetchProjects(); const { createArea, updateArea, deleteArea } = useManageAreas(); const { createProject, updateProject, deleteProject } = useManageProjects(); const { createTag, updateTag, deleteTag } = useManageTags(); @@ -111,7 +109,7 @@ export const DataProvider: React.FC<{ children: React.ReactNode }> = ({ children mutateTags, mutateAreas, mutateNotes, - mutateProjects, // Include mutateProjects + mutateProjects, }} > {children} diff --git a/app/frontend/hooks/useFetchProjects.ts b/app/frontend/hooks/useFetchProjects.ts index 79d7b59..a3a2413 100644 --- a/app/frontend/hooks/useFetchProjects.ts +++ b/app/frontend/hooks/useFetchProjects.ts @@ -1,5 +1,3 @@ -// app/frontend/hooks/useFetchProjects.ts - import { useState, useEffect } from 'react'; import { Project } from '../entities/Project'; diff --git a/app/frontend/hooks/useManageTasks.ts b/app/frontend/hooks/useManageTasks.ts index c6b07a7..9f6c5f1 100644 --- a/app/frontend/hooks/useManageTasks.ts +++ b/app/frontend/hooks/useManageTasks.ts @@ -83,7 +83,7 @@ const useManageTasks = () => { } }; - const mutateTasks = fetchTasks; // Expose fetchTasks as mutateTasks + const mutateTasks = fetchTasks; return { tasks, isLoading, isError, fetchTasks, mutateTasks, createTask, updateTask, deleteTask }; }; diff --git a/app/frontend/index.tsx b/app/frontend/index.tsx index 6db3629..311f0ea 100644 --- a/app/frontend/index.tsx +++ b/app/frontend/index.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { createRoot } from "react-dom/client"; // Import createRoot from react-dom -import { BrowserRouter } from "react-router-dom"; // Import BrowserRouter +import { createRoot } from "react-dom/client"; +import { BrowserRouter } from "react-router-dom"; import App from "./App"; import { ToastProvider } from "./components/Shared/ToastContext"; diff --git a/public/css/app.css b/public/css/app.css deleted file mode 100644 index 4e2848d..0000000 --- a/public/css/app.css +++ /dev/null @@ -1,299 +0,0 @@ -body { - font-family: 'Poppins', sans-serif; - font-size: 0.86rem; - background: #fafafa; -} - -h1 { - font-size: 1.875rem; -} - -h2 { - font-size: 1.625rem; -} - -h3 { - font-size: 1.375rem; -} - -h4 { - font-size: 1.125rem; -} - -h5 { - font-size: 0.925rem; -} - -h6 { - font-size: 0.825rem; -} - -.dropdown-menu, -.btn, -.form-control, -.form-select { - font-size: 0.85rem; - padding: .375rem .75rem; -} - -.btn-lg { - font-size: 0.95rem; - padding: .5rem 1rem; -} - -.btn-sm { - font-size: 0.75rem; - padding: .25rem .5rem; -} - -.task-item:hover { - cursor: pointer; -} - -::placeholder { - /* Chrome, Firefox, Opera, Safari 10.1+ */ - color: #eee; - opacity: 1; - /* Firefox */ -} - -:-ms-input-placeholder { - /* Internet Explorer 10-11 */ - color: gray; -} - -::-ms-input-placeholder { - /* Microsoft Edge */ - color: gray; -} - - -/* sidebar */ -.area-item .area-options { - visibility: hidden; - opacity: 0; - transition: opacity 0.3s ease, visibility 0.3s ease; -} - -.area-item:hover .area-options { - visibility: visible; - opacity: 1; -} - -.fixed-sidebar { - position: fixed; - top: 0; - left: 0; - height: 100vh; - overflow-y: auto; -} - -/* main */ - -.main-content { - margin-top: 50px; - margin-left: 250px; - background: transparent; -} - -.login-content { - margin-left: 200px; -} - -/* sidebar */ -.sidebar { - background: #ececec; -} - -.nav-link { - color: var(--bs-dark); -} - -.nav-link.active-link { - background-color: #343a40; - color: #fff; -} - -.nav-link:hover, .nav-link a:hover { - color: #666 !important; -} - -.nav-link.active-link:hover, .nav-link.active-link a:hover { - color: #ccc !important; -} - -.dark-mode .nav-link { - color: #fff; -} - -.dark-mode .nav-link.active-link { - background-color: var(--bs-dark); -} - -/* tasks, notes */ - -.task-item, -.note-item{ - border-bottom: 1px solid #eee; - padding-bottom: 8px; -} - -.dark-mode .task-item, -.dark-mode .note-item{ - border-bottom: 1px solid #222; - padding-bottom: 8px; -} - -.dark-mode .task-list, -.dark-mode .note-list, -.dark-mode .project-list { - background: var(--bs-black) !important; -} - -.task-item:hover, -.note-item:hover { - background: #eee !important; -} - -.dark-mode .task-item:hover, -.dark-mode .note-item:hover { - background: #292929 !important; -} - -/* task form */ - -.task-name-input::placeholder { - color: #ccc; - opacity: 1; -} - -.new-task-input { - background: #f2f2f2; -} - -/* note form */ - -.no-focus-outline textarea:focus, -.no-focus-outline textarea:-moz-focusring { - outline: none !important; -} - -/* project card */ -a.project-card .card:hover { - border: 1px solid #777 !important; -} - -/* dark mode */ -.dark-mode { - background-color: #191919; - color: var(--bs-light); -} - -.dark-mode .sidebar { - background-color: var(--bs-black); -} - -.sidebar .border-top { - border-color: #ddd !important; -} - -.dark-mode .sidebar .border-top { - border-color: #333 !important; -} - -.dark-mode h1, -.dark-mode h2, -.dark-mode h3, -.dark-mode h4, -.dark-mode h5, -.dark-mode h6 { - color: var(--bs-light) !important; -} - -.dark-mode .modal .modal-dialog .modal-content { - background-color: var(--bs-gray-dark); - color: var(--bs-light); -} - -.dark-mode .modal-header { - border-color: var(--bs-black); -} - -.dark-mode input, -.dark-mode tags, -.dark-mode select, -.dark-mode textarea { - background-color: var(--bs-dark); - color: var(--bs-light); - border-color: var(--bs-black); -} - -.dark-mode input:focus, -.dark-mode textarea:focus { - background-color: var(--bs-black); - color: var(--bs-light); -} - -.dark-mode tag { - background-color: var(--bs-gray-dark) !important; - color: var(--bs-light) !important; - me -} - -.dark-mode .project-card .card { - background-color: var(--bs-gray-dark) !important; - color: var(--bs-light) !important; -} - -.dark-mode .progress { - background-color: var(--bs-dark); -} - -.panel-card { - background-color: var(--bs-white) !important; - color: var(--bs-dark) !important; -} - -.dark-mode .panel-card { - background-color: var(--bs-gray-dark) !important; - color: var(--bs-light) !important; -} - -.panel { - background-color: #eee; -} - -.dark-mode .panel { - background-color: var(--bs-black); -} - -#newNoteForm .card { - color: var(--bs-dark) !important; -} - -.dark-mode #newNoteForm .card { - background-color: var(--bs-gray-dark) !important; - color: var(--bs-light) !important; -} - -.blank-slate { - background-color: #eee !important; - color: var(--bs-dark) !important; -} - -.dark-mode .blank-slate { - background-color: var(--bs-gray-dark) !important; - color: var(--bs-light) !important; -} - -.note-form-toggler { - border: 1px solid #ddd !important; - background-color: #f4f4f4 !important; - color: #ccc !important; -} - -.dark-mode .note-form-toggler { - border: 1px solid #000 !important; - background-color: var(--bs-dark) !important; - color: var(--bs-light) !important; -} \ No newline at end of file diff --git a/public/js/app.js b/public/js/app.js deleted file mode 100644 index 3241d2d..0000000 --- a/public/js/app.js +++ /dev/null @@ -1,297 +0,0 @@ -document.addEventListener("DOMContentLoaded", function () { - attachEventListeners(); - initializeTagifyOnNotes(); - initializeDarkModeToggle(); - setInitialDarkModeState(); -}); - -function attachEventListeners() { - attachCollapseListeners(); - manageAreaState(); - attachTaskClickListeners(); - attachProjectModalListeners(); - attachAreaModalListeners(); - attachNoteClickListeners(); -} - -function initializeDarkModeToggle() { - const darkModeToggle = document.querySelector('#darkModeToggle'); - const darkModeIcon = document.querySelector('#darkModeIcon'); - const isDarkMode = localStorage.getItem('darkMode') === 'true'; - - updateDarkMode(isDarkMode); - - darkModeToggle.addEventListener('click', function () { - const isDarkMode = localStorage.getItem('darkMode') === 'true'; - updateDarkMode(!isDarkMode); - }); -} - -function updateDarkMode(enabled) { - document.body.classList.toggle('dark-mode', enabled); - localStorage.setItem('darkMode', enabled); - darkModeIcon.classList.toggle('bi-moon', !enabled); - darkModeIcon.classList.toggle('bi-sun', enabled); - // Update link colors and other necessary elements - updateLinkColors(enabled); - updateDropdownMenus(enabled); -} - -function updateLinkColors(darkModeEnabled) { - const links = document.querySelectorAll('.link-dark, .link-light'); - links.forEach(link => { - link.classList.toggle('link-dark', !darkModeEnabled); - link.classList.toggle('link-light', darkModeEnabled); - }); -} - -function setInitialDarkModeState() { - const isDarkMode = localStorage.getItem('darkMode') === 'true'; - const darkModeToggle = document.querySelector('#darkModeToggle'); - if (darkModeToggle) { - darkModeToggle.checked = isDarkMode; - document.body.classList.toggle('dark-mode', isDarkMode); - updateLinkColors(isDarkMode); - } -} - -function updateDropdownMenus(enableDarkMode) { - document.querySelectorAll('.dropdown-menu').forEach(menu => { - menu.classList.toggle('dropdown-menu-dark', enableDarkMode); - }); -} - -function initializeTagifyOnNotes() { - document.querySelectorAll('[id^="note_tags_new_"]').forEach(function(element) { - new Tagify(element); - }); -} - -function attachCollapseListeners() { - document.querySelectorAll('.collapse').forEach(collapseElement => { - collapseElement.addEventListener('show.bs.collapse', () => toggleFolderIcon(collapseElement, true)); - collapseElement.addEventListener('hide.bs.collapse', () => toggleFolderIcon(collapseElement, false)); - }); -} - -function manageAreaState() { - document.querySelectorAll('.area-item a.nav-link').forEach(link => { - const areaId = link.getAttribute('href').replace('#', ''); - const areaElement = document.getElementById(areaId); - if (areaElement) { - const isExpanded = localStorage.getItem('#' + areaId) === 'true'; - if (isExpanded) { - link.setAttribute('aria-expanded', 'true'); - areaElement.classList.add('show'); - } else { - link.setAttribute('aria-expanded', 'false'); - areaElement.classList.remove('show'); - } - } - }); - - // Save the state of areas when clicked - document.querySelectorAll('.area-item a.nav-link').forEach(link => { - link.addEventListener('click', function (event) { - event.preventDefault(); // Prevent default action to manually control collapse - const areaId = this.getAttribute('href').replace('#', ''); - const isExpanded = this.getAttribute('aria-expanded') === 'false'; // Toggle the state based on current state - localStorage.setItem('#' + areaId, isExpanded); - if (isExpanded) { - this.setAttribute('aria-expanded', 'true'); - document.getElementById(areaId).classList.add('show'); - } else { - this.setAttribute('aria-expanded', 'false'); - document.getElementById(areaId).classList.remove('show'); - } - }); - }); -} - -// Ensure this function is called when the DOM is fully loaded -document.addEventListener("DOMContentLoaded", manageAreaState); - -function toggleFolderIcon(collapseElement, isOpening) { - const closedFolderIcon = collapseElement.previousElementSibling?.querySelector('.bi-folder'); - const openFolderIcon = collapseElement.previousElementSibling?.querySelector('.bi-folder2-open'); - - if (closedFolderIcon && openFolderIcon) { - closedFolderIcon.classList.toggle('d-none', isOpening); - openFolderIcon.classList.toggle('d-none', !isOpening); - } -} - -function attachTaskClickListeners() { - document.querySelectorAll('.task-item').forEach(taskElement => { - taskElement.addEventListener('click', event => { - if (!event.target.closest('.toggle-completion')) { - openEditTaskModal(taskElement.dataset.taskId); - } - }); - }); -} - -function openEditTaskModal(taskId) { - const formContainer = document.getElementById('edit_task_form_' + taskId); - if (!formContainer) { - console.error('Edit form not found for task: ' + taskId); - return; - } - const formHtml = formContainer.innerHTML; - const editTaskFormContainer = document.getElementById('editTaskFormContainer'); - editTaskFormContainer.innerHTML = formHtml; - - new Tagify(editTaskFormContainer.querySelector('#task_tags_' + taskId)); - - new bootstrap.Modal(document.getElementById('editTaskModal')).show(); -} - -function attachProjectModalListeners() { - document.querySelectorAll('[data-bs-toggle="modal"][data-project-id]').forEach(button => { - button.addEventListener('click', () => openProjectModalForEdit(button.getAttribute('data-project-id'))); - }); -} - -function attachNoteClickListeners() { - document.querySelectorAll('.note-item').forEach(noteElement => { - noteElement.addEventListener('click', event => { - const noteId = noteElement.getAttribute('data-note-id'); - if (noteId) { - openEditNoteModal(noteId); - } else { - console.error('Note ID not found for element:', noteElement); - } - }); - }); -} - -function openEditNoteModal(noteId) { - const formContainer = document.getElementById('edit_note_form_' + noteId); - if (!formContainer) { - console.error('Edit form not found for note: ' + noteId); - return; - } - const formHtml = formContainer.innerHTML; - const editNoteFormContainer = document.getElementById('editNoteFormContainer'); - editNoteFormContainer.innerHTML = formHtml; - - new Tagify(editNoteFormContainer.querySelector('#note_tags_' + noteId)); - - new bootstrap.Modal(document.getElementById('editNoteModal')).show(); -} - -function openProjectModalForEdit(projectId) { - fetch('/project/' + projectId) - .then(response => { - if (!response.ok) { - throw new Error('Network response was not ok.'); - } - return response.json(); - }) - .then(projectData => { - document.getElementById('projectName').value = projectData.name; - document.getElementById('projectDescription').value = projectData.description || ''; - var projectForm = document.getElementById('projectForm'); - if (projectForm) { - projectForm.action = '/projects/' + projectId; - projectForm.method = 'patch'; - } - - var modal = new bootstrap.Modal(document.getElementById('editProjectModal')); - modal.show(); - }) - .catch(error => { - console.error('Error fetching project data:', error); - }); -} - -function attachAreaModalListeners() { - document.querySelectorAll('.open-new-area-modal').forEach(button => { - button.addEventListener('click', () => new bootstrap.Modal(document.getElementById('newAreaModal')).show()); - }); - - document.querySelectorAll('.open-edit-area-modal').forEach(button => { - button.addEventListener('click', () => openEditAreaModal(button.dataset.areaId)); - }); -} - -function deleteProject(projectId) { - if (confirm('Are you sure you want to delete this project?')) { - const form = document.getElementById('delete_project_' + projectId); - form.submit(); - } -} - -function deleteArea(areaId) { - if (confirm('Are you sure you want to delete this area?')) { - const form = document.getElementById('delete_area_' + areaId); - form.submit(); - } -} - -function openEditAreaModal(areaId) { - fetchAreaDataAndPopulateModal(areaId); - const modal = new bootstrap.Modal(document.getElementById('editAreaModal')); - modal.show(); -} - -function fetchAreaDataAndPopulateModal(areaId) { - fetch('/areas/' + areaId + '/data') - .then(response => response.json()) - .then(areaData => { - populateAreaEditForm(areaData); - }) - .catch(error => console.error('Error fetching area data:', error)); -} - -function populateAreaEditForm(areaData) { - document.getElementById('editAreaName').value = areaData.name; -} - -function toggleTaskCompletion(event, taskId) { - event.stopPropagation(); - fetch('/task/' + taskId + '/toggle_completion', { - method: 'PATCH', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ _method: 'patch' }) - }) - .then(response => { - if (!response.ok) throw new Error('Network response was not ok'); - return response.json(); - }) - .then(data => updateTaskCompletionStatus(taskId, data)) - .catch(error => console.error('There has been a problem with your fetch operation:', error)); -} - -function updateTaskCompletionStatus(taskId, data) { - const iconSpan = document.querySelector('.task-item[data-task-id="' + taskId + '"] .toggle-completion'); - const taskIcon = iconSpan.querySelector('.bi'); - const taskDiv = iconSpan.closest('.task-item'); - - if (data.done) { - taskIcon.classList.remove('bi-circle', 'text-warning', 'text-danger'); - taskIcon.classList.add('bi-check-circle-fill', 'text-success'); - taskDiv.classList.add('opacity-50'); - - } else { - taskIcon.classList.remove('bi-check-circle-fill', 'text-success'); - taskIcon.classList.add('bi-circle'); - taskDiv.classList.remove('opacity-50'); - applyPriorityColor(taskIcon, data.priority); - } - setTimeout(() => taskDiv.remove(), 200); -} - -function applyPriorityColor(taskIcon, priority) { - taskIcon.classList.remove('text-warning', 'text-danger', 'text-secondary'); - switch (priority) { - case 'Medium': - taskIcon.classList.add('text-warning'); - break; - case 'High': - taskIcon.classList.add('text-danger'); - break; - default: - taskIcon.classList.add('text-secondary'); - } -} diff --git a/tsconfig.json b/tsconfig.json index 0ed20fa..9a8cfaf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "es5", "module": "esnext", - "moduleResolution": "node", // Ensures TypeScript resolves modules like 'react-router-dom' + "moduleResolution": "node", "jsx": "react", "strict": true, "esModuleInterop": true, diff --git a/webpack.config.js b/webpack.config.js index cd9a943..b298f57 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -9,7 +9,7 @@ module.exports = { output: { path: path.resolve(__dirname, 'public/js'), filename: 'bundle.js', - publicPath: '/js/', // Ensure HMR works properly + publicPath: '/js/', }, resolve: { extensions: ['.tsx', '.ts', '.js'],