diff --git a/web/app/components/base/quadrant-matrix/index.tsx b/web/app/components/base/quadrant-matrix/index.tsx index 07114ecb1c..43fc68e6b6 100644 --- a/web/app/components/base/quadrant-matrix/index.tsx +++ b/web/app/components/base/quadrant-matrix/index.tsx @@ -1,7 +1,10 @@ 'use client' import type { FC } from 'react' import type { QuadrantData } from './types' -import { useMemo } from 'react' +import { RiExpandDiagonalLine } from '@remixicon/react' +import { useCallback, useMemo, useState } from 'react' +import ActionButton from '@/app/components/base/action-button' +import FullScreenModal from '@/app/components/base/fullscreen-modal' import QuadrantCard from './quadrant-card' import { isValidQuadrantData, QUADRANT_CONFIGS } from './types' @@ -10,6 +13,8 @@ type QuadrantMatrixProps = { } const QuadrantMatrix: FC = ({ content }) => { + const [isExpanded, setIsExpanded] = useState(false) + const parsedData = useMemo(() => { try { const trimmed = content.trim() @@ -25,6 +30,14 @@ const QuadrantMatrix: FC = ({ content }) => { } }, [content]) + const handleExpand = useCallback(() => { + setIsExpanded(true) + }, []) + + const handleClose = useCallback(() => { + setIsExpanded(false) + }, []) + if (!parsedData) { return (
@@ -44,94 +57,120 @@ const QuadrantMatrix: FC = ({ content }) => { + parsedData.q3.length + parsedData.q4.length + // Shared grid content component + const renderGrid = (expanded: boolean) => ( +
+ {/* Row 1: Q1 (Do First), Q2 (Schedule) */} + + + + {/* Row 2: Q3 (Delegate), Q4 (Don't Do) */} + + +
+ ) + return ( -
- {/* Header */} -
-
-
- Eisenhower Matrix + <> +
+ {/* Header */} +
+
+
+ Eisenhower Matrix +
+
+ {totalTasks} + {' '} + task + {totalTasks !== 1 ? 's' : ''} + {' '} + prioritized +
-
- {totalTasks} - {' '} - task - {totalTasks !== 1 ? 's' : ''} - {' '} - prioritized -
-
- {/* Legend */} -
- - I - {' '} - = Importance - - - U - {' '} - = Urgency - -
-
- - {/* Axis Labels - Horizontal */} -
-
- - Not Urgent - -
-
- - Urgent - -
-
- - {/* Main Grid with Row Labels */} -
- {/* Row Labels - Vertical (rotated 90 degrees) */} -
-
- - Important - -
-
- - Not Important - + {/* Legend + Expand Button */} +
+
+ + I + {' '} + = Importance + + + U + {' '} + = Urgency + +
+ + +
{/* 2x2 Grid */} -
-
- {/* Row 1: Important */} - - + {renderGrid(false)} +
- {/* Row 2: Not Important */} - - + {/* Fullscreen Modal */} + +
+ {/* Modal Header */} +
+
+
+ Eisenhower Matrix +
+
+ {totalTasks} + {' '} + task + {totalTasks !== 1 ? 's' : ''} + {' '} + prioritized +
+
+
+ + I + {' '} + = Importance + + + U + {' '} + = Urgency + +
+
+ + {/* Expanded Grid */} +
+ {renderGrid(true)}
-
-
+ + ) } diff --git a/web/app/components/base/quadrant-matrix/quadrant-card.tsx b/web/app/components/base/quadrant-matrix/quadrant-card.tsx index 35ca20afa8..469c4c4082 100644 --- a/web/app/components/base/quadrant-matrix/quadrant-card.tsx +++ b/web/app/components/base/quadrant-matrix/quadrant-card.tsx @@ -7,29 +7,42 @@ import TaskItem from './task-item' type QuadrantCardProps = { config: QuadrantConfig tasks: Task[] + expanded?: boolean maxDisplay?: number } const QuadrantCard: FC = ({ config, tasks, + expanded = false, maxDisplay = 3, }) => { - const { title, subtitle, bgClass, borderClass, titleClass } = config - const displayTasks = tasks.slice(0, maxDisplay) - const remainingCount = Math.max(0, tasks.length - maxDisplay) + const { number, title, subtitle, bgClass, borderClass, titleClass } = config + const displayLimit = expanded ? Infinity : maxDisplay + const displayTasks = tasks.slice(0, displayLimit) + const remainingCount = Math.max(0, tasks.length - displayLimit) return (
- {/* Header */} + {/* Header with numbered circle */}
+ {/* Numbered circle */} + + {number} + {title} {tasks.length > 0 && ( @@ -40,12 +53,20 @@ const QuadrantCard: FC = ({
{subtitle}
- {/* Task List - scrollable area */} -
+ {/* Task List */} +
{displayTasks.length > 0 ? ( displayTasks.map((task, index) => ( - + )) ) : ( @@ -55,8 +76,8 @@ const QuadrantCard: FC = ({ )}
- {/* More indicator */} - {remainingCount > 0 && ( + {/* More indicator (only in non-expanded mode) */} + {!expanded && remainingCount > 0 && (
+ {remainingCount} diff --git a/web/app/components/base/quadrant-matrix/task-item.tsx b/web/app/components/base/quadrant-matrix/task-item.tsx index 403e1f7a97..728b692099 100644 --- a/web/app/components/base/quadrant-matrix/task-item.tsx +++ b/web/app/components/base/quadrant-matrix/task-item.tsx @@ -5,17 +5,24 @@ import { cn } from '@/utils/classnames' type TaskItemProps = { task: Task + expanded?: boolean showScores?: boolean } -const TaskItem: FC = ({ task, showScores = true }) => { +const TaskItem: FC = ({ task, expanded = false, showScores = true }) => { const { name, description, deadline, importance_score, urgency_score, action_advice } = task return (
{/* Header: Task Name + Scores */}
-
+
{name}
{showScores && ( @@ -34,7 +41,11 @@ const TaskItem: FC = ({ task, showScores = true }) => { {/* Description */} {description && ( -
+
{description}
)} @@ -42,11 +53,7 @@ const TaskItem: FC = ({ task, showScores = true }) => { {/* Deadline Badge */} {deadline && (
- + {deadline}
@@ -54,8 +61,14 @@ const TaskItem: FC = ({ task, showScores = true }) => { {/* Action Advice */} {action_advice && ( -
-

+

+

{action_advice}

diff --git a/web/app/components/base/quadrant-matrix/types.ts b/web/app/components/base/quadrant-matrix/types.ts index 044161aed1..b86e686cf4 100644 --- a/web/app/components/base/quadrant-matrix/types.ts +++ b/web/app/components/base/quadrant-matrix/types.ts @@ -15,11 +15,12 @@ export type QuadrantData = { q1: Task[] // Urgent & Important - Do First q2: Task[] // Not Urgent & Important - Schedule q3: Task[] // Urgent & Not Important - Delegate - q4: Task[] // Not Urgent & Not Important - Eliminate + q4: Task[] // Not Urgent & Not Important - Don't Do } export type QuadrantConfig = { key: 'q1' | 'q2' | 'q3' | 'q4' + number: number title: string subtitle: string bgClass: string @@ -27,9 +28,13 @@ export type QuadrantConfig = { titleClass: string } +// Layout based on Eisenhower Matrix: +// Q1 (Do First) - top-left, Q2 (Schedule) - top-right +// Q3 (Delegate) - bottom-left, Q4 (Don't Do) - bottom-right export const QUADRANT_CONFIGS: Record = { q1: { key: 'q1', + number: 1, title: 'Do First', subtitle: 'Urgent & Important', bgClass: 'bg-state-destructive-hover', @@ -38,6 +43,7 @@ export const QUADRANT_CONFIGS: Record = { }, q2: { key: 'q2', + number: 2, title: 'Schedule', subtitle: 'Important & Not Urgent', bgClass: 'bg-state-accent-hover', @@ -46,6 +52,7 @@ export const QUADRANT_CONFIGS: Record = { }, q3: { key: 'q3', + number: 3, title: 'Delegate', subtitle: 'Urgent & Not Important', bgClass: 'bg-state-warning-hover', @@ -54,7 +61,8 @@ export const QUADRANT_CONFIGS: Record = { }, q4: { key: 'q4', - title: 'Eliminate', + number: 4, + title: 'Don\'t Do', subtitle: 'Not Urgent & Not Important', bgClass: 'bg-components-panel-on-panel-item-bg', borderClass: 'border-divider-regular',