diff --git a/backend/boards/signals.py b/backend/boards/signals.py index c416de9..2c44daa 100644 --- a/backend/boards/signals.py +++ b/backend/boards/signals.py @@ -8,8 +8,10 @@ from users.models import CustomUser def create_default_board(sender, instance, created, **kwargs): """Signal handler to automatically create a default Board for a user upon creation.""" if created: - board = Board.objects.create(user=instance, name="My Default Board") - - ListBoard.objects.create(board=board, name="Todo", position=1) - ListBoard.objects.create(board=board, name="In Progress", position=2) - ListBoard.objects.create(board=board, name="Done", position=3) \ No newline at end of file + # Create unique board by user id + user_id = instance.id + board = Board.objects.create(user=instance, name=f"Board of #{user_id}") + ListBoard.objects.create(board=board, name="Backlog", position=1) + ListBoard.objects.create(board=board, name="Doing", position=2) + ListBoard.objects.create(board=board, name="Review", position=3) + ListBoard.objects.create(board=board, name="Done", position=4) \ No newline at end of file diff --git a/backend/tasks/signals.py b/backend/tasks/signals.py index 063292e..4c9e6f2 100644 --- a/backend/tasks/signals.py +++ b/backend/tasks/signals.py @@ -27,15 +27,63 @@ def update_priority(sender, instance, **kwargs): instance.priority = Todo.EisenhowerMatrix.NOT_IMPORTANT_NOT_URGENT -@receiver(post_save, sender=Todo) -def assign_todo_to_listboard(sender, instance, created, **kwargs): - """Signal handler to automatically assign a Todo to the first ListBoard in the user's Board upon creation.""" +# @receiver(post_save, sender=Todo) +# def assign_todo_to_listboard(sender, instance, created, **kwargs): +# """Signal handler to automatically assign a Todo to the first ListBoard in the user's Board upon creation.""" +# if created: +# user_board = instance.user.board_set.first() + +# if user_board: +# first_list_board = user_board.listboard_set.order_by('position').first() + +# if first_list_board: +# instance.list_board = first_list_board +# instance.save() + + +@receiver(post_save, sender=ListBoard) +def create_placeholder_tasks(sender, instance, created, **kwargs): + """ + Signal handler to create placeholder tasks for each ListBoard. + """ if created: - user_board = instance.user.board_set.first() + list_board_position = instance.position - if user_board: - first_list_board = user_board.listboard_set.order_by('position').first() + if list_board_position == 1: + placeholder_tasks = [ + {"title": "Normal Task Example"}, + {"title": "Task with Extra Information Example", "description": "Description for Task 2"}, + ] + elif list_board_position == 2: + placeholder_tasks = [ + {"title": "Time Task Example #1", "description": "Description for Task 2", + "start_event": timezone.now(), "end_event": timezone.now() + timezone.timedelta(days=5)}, + ] + elif list_board_position == 3: + placeholder_tasks = [ + {"title": "Time Task Example #2", "description": "Description for Task 2", + "start_event": timezone.now(), "end_event": timezone.now() + timezone.timedelta(days=30)}, + ] + elif list_board_position == 4: + placeholder_tasks = [ + {"title": "Completed Task Example", "description": "Description for Task 2", + "start_event": timezone.now(), "completed": True}, + ] + else: + placeholder_tasks = [ + {"title": "Default Task Example"}, + ] - if first_list_board: - instance.list_board = first_list_board - instance.save() \ No newline at end of file + for task_data in placeholder_tasks: + Todo.objects.create( + list_board=instance, + user=instance.board.user, + title=task_data["title"], + notes=task_data.get("description", ""), + is_active=True, + start_event=task_data.get("start_event"), + end_event=task_data.get("end_event"), + completed=task_data.get("completed", False), + creation_date=timezone.now(), + last_update=timezone.now(), + ) \ No newline at end of file diff --git a/frontend/src/components/authentication/SignUpPage.jsx b/frontend/src/components/authentication/SignUpPage.jsx index 08628e8..b0fdc60 100644 --- a/frontend/src/components/authentication/SignUpPage.jsx +++ b/frontend/src/components/authentication/SignUpPage.jsx @@ -55,6 +55,8 @@ export function SignUp() { const googleLoginImplicit = useGoogleLogin({ flow: "auth-code", redirect_uri: "postmessage", + scope: + "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/calendar.acls.readonly https://www.googleapis.com/auth/calendar.events.readonly", onSuccess: async (response) => { try { const loginResponse = await googleLogin(response.code); diff --git a/frontend/src/components/kanbanBoard/columnContainer.jsx b/frontend/src/components/kanbanBoard/columnContainer.jsx index 819a980..d6f4565 100644 --- a/frontend/src/components/kanbanBoard/columnContainer.jsx +++ b/frontend/src/components/kanbanBoard/columnContainer.jsx @@ -1,53 +1,16 @@ import { SortableContext, useSortable } from "@dnd-kit/sortable"; -import { BsFillTrashFill } from "react-icons/bs"; import { AiOutlinePlusCircle } from "react-icons/ai"; -import { CSS } from "@dnd-kit/utilities"; -import { useMemo, useState } from "react"; +import { useMemo } from "react"; import { TaskCard } from "./taskCard"; -export function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks, deleteTask, updateTask }) { - const [editMode, setEditMode] = useState(false); - +export function ColumnContainer({ column, createTask, tasks, deleteTask, updateTask }) { + // Memoize task IDs to prevent unnecessary recalculations const tasksIds = useMemo(() => { return tasks.map((task) => task.id); }, [tasks]); - const { setNodeRef, attributes, listeners, transform, transition, isDragging } = useSortable({ - id: column.id, - data: { - type: "Column", - column, - }, - disabled: editMode, - }); - - const style = { - transition, - transform: CSS.Transform.toString(transform), - }; - - if (isDragging) { - return ( -
- ); - } - return (
{/* Column title */}
{ - setEditMode(true); - }} className=" ml-3 text-md - cursor-grab font-bold flex items-center justify-between "> -
- {!editMode && column.title} - {editMode && ( - updateColumn(column.id, e.target.value)} - autoFocus - onBlur={() => { - setEditMode(false); - }} - onKeyDown={(e) => { - if (e.key !== "Enter") return; - setEditMode(false); - }} - /> - )} -
- +
{column.title}
{/* Column task container */}
+ {/* Provide a SortableContext for the tasks within the column */} + {/* Render TaskCard for each task in the column */} {tasks.map((task) => ( - + useSortable({ ...props, disabled: false })} + /> ))}
+ {/* Column footer */}
); }; diff --git a/frontend/src/components/navigations/IconSideNav.jsx b/frontend/src/components/navigations/IconSideNav.jsx index 02cc1a0..c5d1708 100644 --- a/frontend/src/components/navigations/IconSideNav.jsx +++ b/frontend/src/components/navigations/IconSideNav.jsx @@ -32,12 +32,12 @@ export const SideNav = () => { ); }; -const NavItem = ({ icon, selected, id, setSelected, logo, path }) => { +const NavItem = ({ icon, selected, id, setSelected, path }) => { const navigate = useNavigate(); return ( { setSelected(id); navigate(path);