Skip to content

Commit bb60787

Browse files
committed
feat (tasks): tasks frontend (WIP)
1 parent 9ebe126 commit bb60787

File tree

18 files changed

+516
-177
lines changed

18 files changed

+516
-177
lines changed

src/client/app/tasks/page.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,16 +273,16 @@ function TasksPageContent() {
273273
}, [oneTimeTasks, recurringInstances, searchQuery])
274274

275275
return (
276-
<div className="flex-1 flex h-screen bg-black text-white overflow-hidden md:pl-20">
276+
<div className="flex-1 flex h-screen bg-brand-black text-white overflow-hidden md:pl-20">
277277
<Tooltip
278278
id="tasks-tooltip"
279279
place="right"
280280
style={{ zIndex: 9999 }}
281281
/>
282-
<div className="flex-1 flex flex-col md:flex-row overflow-hidden">
282+
<div className="flex-1 flex flex-col md:flex-row overflow-hidden bg-brand-black">
283283
{/* Main Content Panel */}
284284
<main className="flex-1 flex flex-col overflow-hidden relative">
285-
<header className="p-6 border-b border-neutral-800 flex-shrink-0 flex items-center justify-between">
285+
<header className="p-6 border-b border-neutral-800 flex-shrink-0 flex items-center justify-between bg-brand-black">
286286
<h1 className="text-3xl font-bold text-white">Tasks</h1>
287287
<div className="absolute top-6 left-1/2 -translate-x-1/2">
288288
<TaskViewSwitcher view={view} setView={setView} />
@@ -337,7 +337,7 @@ function TasksPageContent() {
337337
</main>
338338

339339
{/* Right Details Panel */}
340-
<aside className="w-full md:w-[500px] lg:w-[550px] bg-neutral-900/50 border-l border-neutral-800 flex-shrink-0 flex flex-col">
340+
<aside className="w-full md:w-[500px] lg:w-[550px] bg-brand-gray border-l border-neutral-800 flex-shrink-0 flex flex-col">
341341
<AnimatePresence mode="wait">
342342
{rightPanelContent.type === "task" &&
343343
rightPanelContent.data ? (

src/client/components/tasks/CalendarView.js

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ import TaskCardCalendar from "./TaskCardCalendar"
2626
const CalendarDayCell = ({
2727
day,
2828
tasks,
29-
isCurrentMonth,
3029
onSelectTask,
3130
onDayClick,
32-
onShowMoreClick
31+
onShowMoreClick,
32+
isCurrentMonth,
33+
isSelected
3334
}) => {
3435
const [isHovered, setIsHovered] = useState(false)
3536
const firstTask = tasks[0]
@@ -39,20 +40,24 @@ const CalendarDayCell = ({
3940
<div
4041
onMouseEnter={() => setIsHovered(true)}
4142
onMouseLeave={() => setIsHovered(false)}
43+
onClick={() => onDayClick(day)}
4244
className={cn(
43-
"border-r border-b border-neutral-800 p-2 flex flex-col gap-1 overflow-hidden relative min-h-[120px]",
44-
!isCurrentMonth && "bg-neutral-900/50",
45-
"hover:bg-neutral-800/70"
45+
"border-r border-b border-neutral-800 p-2 flex flex-col gap-1 overflow-hidden relative min-h-[120px] rounded-lg",
46+
!isCurrentMonth && "bg-brand-black text-neutral-600",
47+
"hover:bg-neutral-800/70",
48+
isSelected && "bg-brand-orange text-brand-black font-bold"
4649
)}
4750
>
4851
<div className="flex justify-between items-center">
4952
<span
5053
className={cn(
51-
"font-semibold text-sm",
52-
isToday(day)
53-
? "text-sentient-blue"
54-
: "text-neutral-300",
55-
!isCurrentMonth && "text-neutral-600"
54+
"font-sans font-semibold text-sm w-6 h-6 flex items-center justify-center rounded-full",
55+
isToday(day) ? "border border-brand-orange" : "",
56+
isSelected
57+
? "text-brand-black"
58+
: isCurrentMonth
59+
? "text-neutral-300"
60+
: "text-neutral-600"
5661
)}
5762
>
5863
{format(day, "d")}
@@ -84,6 +89,9 @@ const CalendarDayCell = ({
8489
onSelectTask={onSelectTask}
8590
/>
8691
)}
92+
{tasks.length > 0 && (
93+
<div className="w-1 h-1 bg-brand-yellow rounded-full mx-auto mt-1"></div>
94+
)}
8795
{hasMoreTasks && (
8896
<div className="w-full text-center text-xs text-neutral-400 p-1 rounded-md hover:bg-neutral-700/50">
8997
<IconDots size={16} className="mx-auto" />
@@ -96,6 +104,7 @@ const CalendarDayCell = ({
96104

97105
const CalendarView = ({ tasks, onSelectTask, onDayClick, onShowMoreClick }) => {
98106
const [currentMonth, setCurrentMonth] = useState(new Date())
107+
const [selectedDate, setSelectedDate] = useState(new Date())
99108

100109
const monthStart = startOfMonth(currentMonth)
101110
const monthEnd = endOfMonth(currentMonth)
@@ -107,28 +116,33 @@ const CalendarView = ({ tasks, onSelectTask, onDayClick, onShowMoreClick }) => {
107116
const nextMonth = () => setCurrentMonth(addMonths(currentMonth, 1))
108117
const prevMonth = () => setCurrentMonth(subMonths(currentMonth, 1))
109118

119+
const handleDayClickInternal = (day) => {
120+
setSelectedDate(day)
121+
onDayClick(day)
122+
}
123+
110124
return (
111-
<div className="p-6 h-full flex flex-col">
125+
<div className="p-4 h-full flex flex-col bg-brand-gray rounded-xl border border-zinc-700">
112126
<header className="flex items-center justify-between mb-4">
113-
<h2 className="text-xl font-semibold text-white">
127+
<h2 className="text-lg font-sans font-semibold text-white">
114128
{format(currentMonth, "MMMM yyyy")}
115129
</h2>
116130
<div className="flex items-center gap-2">
117131
<button
118132
onClick={prevMonth}
119-
className="p-2 rounded-full hover:bg-neutral-800"
133+
className="p-2 rounded-full hover:bg-neutral-800 text-brand-orange"
120134
>
121135
<IconChevronLeft size={20} />
122136
</button>
123137
<button
124138
onClick={nextMonth}
125-
className="p-2 rounded-full hover:bg-neutral-800"
139+
className="p-2 rounded-full hover:bg-neutral-800 text-brand-orange"
126140
>
127141
<IconChevronRight size={20} />
128142
</button>
129143
</div>
130144
</header>
131-
<div className="grid grid-cols-7 text-center text-sm text-neutral-400 border-b border-neutral-800 pb-2">
145+
<div className="grid grid-cols-7 text-center text-xs text-zinc-400 font-sans border-b border-neutral-800 pb-2">
132146
{["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"].map(
133147
(day) => (
134148
<div key={day}>{day}</div>
@@ -147,8 +161,9 @@ const CalendarView = ({ tasks, onSelectTask, onDayClick, onShowMoreClick }) => {
147161
tasks={tasksForDay}
148162
isCurrentMonth={isSameMonth(day, currentMonth)}
149163
onSelectTask={onSelectTask}
150-
onDayClick={onDayClick}
164+
onDayClick={handleDayClickInternal}
151165
onShowMoreClick={onShowMoreClick}
166+
isSelected={isSameDay(day, selectedDate)}
152167
/>
153168
)
154169
})}

src/client/components/tasks/CollapsibleSection.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
"use client"
22

3-
import React, { useState } from "react"
3+
import React, { useState, useEffect } from "react"
44
import { motion, AnimatePresence } from "framer-motion"
55
import { cn } from "@utils/cn"
66
import { IconChevronDown } from "@tabler/icons-react"
77

8-
const CollapsibleSection = ({
9-
title,
10-
children,
11-
isOpen: defaultOpen = true
12-
}) => {
8+
const CollapsibleSection = ({ title, children, defaultOpen = false }) => {
139
const [isOpen, setIsOpen] = useState(defaultOpen)
1410

1511
const onToggle = () => setIsOpen(!isOpen)
@@ -18,9 +14,9 @@ const CollapsibleSection = ({
1814
<motion.div layout className="mb-2">
1915
<button
2016
onClick={onToggle}
21-
className="w-full flex justify-between items-center p-2 hover:bg-neutral-800/50 rounded-lg transition-colors"
17+
className="w-full flex justify-between items-center py-2 hover:bg-neutral-800/50 rounded-lg transition-colors font-sans"
2218
>
23-
<div className="w-full text-left">{title}</div>
19+
<div className="w-full text-left text-brand-white">{title}</div>
2420
<IconChevronDown
2521
className={cn(
2622
"transform transition-transform duration-300 text-neutral-400",
@@ -36,9 +32,8 @@ const CollapsibleSection = ({
3632
animate={{ height: "auto", opacity: 1 }}
3733
exit={{ height: 0, opacity: 0 }}
3834
transition={{ duration: 0.3, ease: "easeInOut" }}
39-
className="overflow-hidden"
4035
>
41-
<div className="pt-2">{children}</div>
36+
<div className="pt-2 ">{children}</div>
4237
</motion.div>
4338
)}
4439
</AnimatePresence>

src/client/components/tasks/CreateTaskInput.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use client"
22
import React, { useState, useRef, useEffect } from "react"
3-
import { IconPlus, IconLoader } from "@tabler/icons-react"
3+
import { IconPlus, IconLoader, IconSend } from "@tabler/icons-react"
4+
import { cn } from "@utils/cn"
45
import { TextLoop } from "@components/ui/TextLoop"
56
import toast from "react-hot-toast"
67

@@ -43,8 +44,12 @@ const CreateTaskInput = ({ onTaskAdded, prompt, setPrompt }) => {
4344
}
4445

4546
return (
46-
<div className="p-4 border-t border-neutral-800 flex-shrink-0">
47-
<div className="relative flex items-end bg-neutral-900 border border-neutral-700 rounded-lg p-1">
47+
<div className="p-4 border-t border-neutral-800 flex-shrink-0 bg-brand-black">
48+
<div
49+
className={cn(
50+
"relative flex items-end bg-brand-gray rounded-xl p-1 transition-all border border-transparent focus-within:border-brand-orange"
51+
)}
52+
>
4853
<textarea
4954
ref={textareaRef}
5055
value={prompt}
@@ -56,13 +61,13 @@ const CreateTaskInput = ({ onTaskAdded, prompt, setPrompt }) => {
5661
}
5762
}}
5863
placeholder=" "
59-
className="w-full bg-transparent text-white placeholder-transparent resize-none focus:ring-0 focus:outline-none p-2 custom-scrollbar"
64+
className="w-full bg-transparent text-white placeholder-transparent resize-none focus:ring-0 focus:outline-none p-2 custom-scrollbar text-sm"
6065
rows={1}
6166
style={{ maxHeight: "120px" }}
6267
/>
6368
{!prompt && (
6469
<div className="absolute top-1/2 left-3 -translate-y-1/2 text-neutral-500 pointer-events-none">
65-
<TextLoop className="text-sm font-mono">
70+
<TextLoop className="text-sm">
6671
<span>Create a task...</span>
6772
<span>Summarize my unread emails from today</span>
6873
<span>
@@ -75,12 +80,12 @@ const CreateTaskInput = ({ onTaskAdded, prompt, setPrompt }) => {
7580
<button
7681
onClick={handleAddTask}
7782
disabled={isSaving || !prompt.trim()}
78-
className="p-2.5 bg-sentient-blue rounded-md text-white disabled:opacity-50 hover:bg-sentient-blue-dark transition-colors"
83+
className="p-2.5 bg-brand-orange rounded-lg text-brand-black disabled:opacity-50 hover:bg-opacity-80 transition-colors"
7984
>
8085
{isSaving ? (
8186
<IconLoader size={18} className="animate-spin" />
8287
) : (
83-
<IconPlus size={18} />
88+
<IconSend size={18} />
8489
)}
8590
</button>
8691
</div>

src/client/components/tasks/ExecutionUpdate.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ const ExecutionUpdate = ({ update }) => {
106106
colorClass="border-yellow-500/50"
107107
>
108108
<div className="p-3 bg-neutral-800/50 rounded-md">
109-
<ReactMarkdown className="prose prose-sm prose-invert text-neutral-300 whitespace-pre-wrap">
109+
<ReactMarkdown className="prose prose-sm prose-invert text-neutral-300 whitespace-pre-wrap break-words">
110110
{content}
111111
</ReactMarkdown>
112112
</div>
@@ -120,7 +120,7 @@ const ExecutionUpdate = ({ update }) => {
120120
colorClass="border-blue-500/50"
121121
>
122122
<div className="p-3 bg-neutral-800/50 rounded-md">
123-
<pre className="text-xs text-neutral-300 whitespace-pre-wrap font-mono">
123+
<pre className="text-xs text-neutral-300 whitespace-pre-wrap font-mono break-all">
124124
{JSON.stringify(parameters, null, 2)}
125125
</pre>
126126
</div>
@@ -145,7 +145,7 @@ const ExecutionUpdate = ({ update }) => {
145145
}
146146
>
147147
<div className="p-3 bg-neutral-800/50 rounded-md">
148-
<pre className="text-xs text-neutral-300 whitespace-pre-wrap font-mono">
148+
<pre className="text-xs text-neutral-300 whitespace-pre-wrap font-mono break-all">
149149
{typeof result === "object"
150150
? JSON.stringify(result, null, 2)
151151
: String(result)}

src/client/components/tasks/ListView.js

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"use client"
22
import React, { useMemo } from "react"
33
import { AnimatePresence } from "framer-motion"
4-
import { IconSearch } from "@tabler/icons-react"
4+
import { IconSearch, IconChevronDown } from "@tabler/icons-react"
55
import { groupTasksByDate } from "@utils/taskUtils"
66
import TaskCardList from "./TaskCardList"
77
import CollapsibleSection from "./CollapsibleSection"
@@ -62,44 +62,46 @@ const ListView = ({
6262
</div>
6363

6464
<AnimatePresence>
65-
{recurringTasks.length > 0 && (
66-
<CollapsibleSection
67-
key="recurring"
68-
title="Active Workflows"
69-
count={recurringTasks.length}
70-
>
71-
<div className="space-y-3">
72-
{recurringTasks.map((task) => (
73-
<TaskCardList
74-
key={task.task_id}
75-
task={task}
76-
onSelectTask={onSelectTask}
77-
/>
78-
))}
79-
</div>
80-
</CollapsibleSection>
81-
)}
65+
<div className="divide-y divide-zinc-700">
66+
{recurringTasks.length > 0 && (
67+
<CollapsibleSection
68+
key="recurring"
69+
title={`Active Workflows (${recurringTasks.length})`}
70+
defaultOpen={true}
71+
>
72+
<div className="space-y-3 pt-2">
73+
{recurringTasks.map((task) => (
74+
<TaskCardList
75+
key={task.task_id}
76+
task={task}
77+
onSelectTask={onSelectTask}
78+
/>
79+
))}
80+
</div>
81+
</CollapsibleSection>
82+
)}
8283

83-
{sections.map(
84-
(section) =>
85-
section.tasks.length > 0 && (
86-
<CollapsibleSection
87-
key={section.title}
88-
title={section.title}
89-
count={section.tasks.length}
90-
>
91-
<div className="space-y-3">
92-
{section.tasks.map((task) => (
93-
<TaskCardList
94-
key={task.instance_id}
95-
task={task}
96-
onSelectTask={onSelectTask}
97-
/>
98-
))}
99-
</div>
100-
</CollapsibleSection>
101-
)
102-
)}
84+
{sections.map(
85+
(section) =>
86+
section.tasks.length > 0 && (
87+
<CollapsibleSection
88+
key={section.title}
89+
title={`${section.title} (${section.tasks.length})`}
90+
defaultOpen={true}
91+
>
92+
<div className="space-y-3 pt-2">
93+
{section.tasks.map((task) => (
94+
<TaskCardList
95+
key={task.instance_id}
96+
task={task}
97+
onSelectTask={onSelectTask}
98+
/>
99+
))}
100+
</div>
101+
</CollapsibleSection>
102+
)
103+
)}
104+
</div>
103105
</AnimatePresence>
104106
</div>
105107
)

src/client/components/tasks/TaskCardCalendar.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const TaskCardCalendar = ({ task, onSelectTask }) => {
2626
<div
2727
className={cn(
2828
"w-2 h-2 rounded-full flex-shrink-0",
29-
statusInfo.color.replace("text-", "bg-")
29+
statusInfo.bgColor
3030
)}
3131
/>
3232
<span className="truncate">{task.description}</span>

0 commit comments

Comments
 (0)