Fix refactor pt2 (#734)

* Cleanup task routes

* Cleanup frontend tasks

* Clean tasks

* Cleanup project uid

* Cleanup quick capture old modal

* Cleanup taskmodal

* Move all icons to shared components

* Test inbox flow

* fixup! Test inbox flow
This commit is contained in:
Chris 2025-12-27 17:46:34 +02:00 committed by GitHub
parent b443f73129
commit ad8ab3ec72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
59 changed files with 716 additions and 4592 deletions

View file

@ -9,13 +9,10 @@ import ProjectModal from './components/Project/ProjectModal';
import NoteModal from './components/Note/NoteModal';
import AreaModal from './components/Area/AreaModal';
import TagModal from './components/Tag/TagModal';
import InboxModal from './components/Inbox/InboxModal';
import TaskModal from './components/Task/TaskModal';
import { Note } from './entities/Note';
import { Area } from './entities/Area';
import { Tag } from './entities/Tag';
import { Project } from './entities/Project';
import { Task } from './entities/Task';
import { User } from './entities/User';
import { useStore } from './store/useStore';
import { createNote, updateNote } from './utils/notesService';
@ -26,9 +23,8 @@ import {
createProject,
updateProject,
} from './utils/projectsService';
import { createTask, updateTask } from './utils/tasksService';
import { isAuthError } from './utils/authUtils';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import { useLocation, useNavigate } from 'react-router-dom';
interface LayoutProps {
currentUser: User;
@ -46,7 +42,7 @@ const Layout: React.FC<LayoutProps> = ({
children,
}) => {
const { t } = useTranslation();
const { showSuccessToast } = useToast();
const { showSuccessToast, showErrorToast } = useToast();
const navigate = useNavigate();
const location = useLocation();
const isUpcomingView = location.pathname === '/upcoming';
@ -54,14 +50,10 @@ const Layout: React.FC<LayoutProps> = ({
window.innerWidth >= 1024
);
const [isMobileSearchOpen, setIsMobileSearchOpen] = useState(false);
const [isTaskModalOpen, setIsTaskModalOpen] = useState(false);
const [isProjectModalOpen, setIsProjectModalOpen] = useState(false);
const [isNoteModalOpen, setIsNoteModalOpen] = useState(false);
const [isAreaModalOpen, setIsAreaModalOpen] = useState(false);
const [isTagModalOpen, setIsTagModalOpen] = useState(false);
const [taskModalType, setTaskModalType] = useState<'simplified' | 'full'>(
'simplified'
);
const [selectedNote, setSelectedNote] = useState<Note | null>(null);
const [selectedArea, setSelectedArea] = useState<Area | null>(null);
@ -70,7 +62,11 @@ const Layout: React.FC<LayoutProps> = ({
const {
notesStore: { notes, isLoading: isNotesLoading, isError: isNotesError },
areasStore: { areas, isLoading: isAreasLoading, isError: isAreasError },
tasksStore: { isLoading: isTasksLoading, isError: isTasksError },
tasksStore: {
isLoading: isTasksLoading,
isError: isTasksError,
createTask: createTaskInStore,
},
projectsStore: {
projects,
setProjects,
@ -80,9 +76,27 @@ const Layout: React.FC<LayoutProps> = ({
tagsStore: { tags, isLoading: isTagsLoading, isError: isTagsError },
} = useStore();
const openTaskModal = (type: 'simplified' | 'full' = 'simplified') => {
setIsTaskModalOpen(true);
setTaskModalType(type);
const createAndOpenTaskDetails = async () => {
try {
const newTask = await createTaskInStore({
name: t('task.newTaskPlaceholder', 'New Task'),
status: 'not_started',
completed_at: null,
});
if (newTask?.uid) {
navigate(`/task/${newTask.uid}`);
} else {
throw new Error('New task missing UID');
}
} catch (error) {
console.error('Error creating task from Layout:', error);
showErrorToast(t('task.createError', 'Failed to create task.'));
}
};
const openTaskModal = () => {
void createAndOpenTaskDetails();
};
useEffect(() => {
@ -136,10 +150,6 @@ const Layout: React.FC<LayoutProps> = ({
setSelectedNote(null);
};
const closeTaskModal = () => {
setIsTaskModalOpen(false);
};
const openProjectModal = () => {
setIsProjectModalOpen(true);
};
@ -205,46 +215,6 @@ const Layout: React.FC<LayoutProps> = ({
}
};
const handleSaveTask = async (taskData: Task) => {
try {
if (taskData.uid) {
await updateTask(taskData.uid, taskData);
const taskLink = (
<span>
{t('task.updated', 'Task')}{' '}
<Link
to="/tasks"
className="text-green-200 underline hover:text-green-100"
>
{taskData.name}
</Link>{' '}
{t('task.updatedSuccessfully', 'updated successfully!')}
</span>
);
showSuccessToast(taskLink);
} else {
const createdTask = await createTask(taskData);
// Notify Tasks component that a task was created
window.dispatchEvent(
new CustomEvent('taskCreated', { detail: createdTask })
);
}
// Don't refetch all tasks here - let individual components handle their own state
// This prevents unnecessary re-renders and race conditions
closeTaskModal();
} catch (error: any) {
console.error('Error saving task:', error);
// Don't close modal if there's an auth error (user will be redirected)
if (isAuthError(error)) {
return;
}
// For other errors, still close the modal but let the error bubble up
closeTaskModal();
throw error;
}
};
const handleCreateProject = async (name: string): Promise<Project> => {
try {
const newProject = await createProject({
@ -478,30 +448,6 @@ const Layout: React.FC<LayoutProps> = ({
</div>
</div>
{isTaskModalOpen &&
(taskModalType === 'simplified' ? (
<InboxModal
isOpen={isTaskModalOpen}
onClose={closeTaskModal}
onSave={handleSaveTask}
projects={projects}
/>
) : (
<TaskModal
isOpen={isTaskModalOpen}
onClose={closeTaskModal}
task={{
name: '',
status: 'not_started',
completed_at: null,
}}
onSave={handleSaveTask}
onDelete={async () => {}}
projects={projects}
onCreateProject={handleCreateProject}
/>
))}
{isProjectModalOpen && (
<ProjectModal
isOpen={isProjectModalOpen}