Skip to content

Commit e598fda

Browse files
committed
Merge branch 'ui-ux-refresh_eunsoo' into feature/ui-ux-refresh
2 parents 9e09257 + db5c031 commit e598fda

File tree

14 files changed

+302
-275
lines changed

14 files changed

+302
-275
lines changed
-816 Bytes
Binary file not shown.
-1.93 KB
Binary file not shown.
6.58 KB
Loading
13.9 KB
Binary file not shown.
12.1 KB
Loading
55.1 KB
Loading

src/frontend_react/src/components/content/HomeInput.tsx

Lines changed: 127 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,152 +1,154 @@
11
import {
2-
Body1,
3-
Body1Strong,
4-
Button,
5-
Caption1,
6-
Card,
7-
Title2,
2+
Body1Strong,
3+
Button,
4+
Caption1,
5+
Title2,
86
} from "@fluentui/react-components";
9-
import { FoodToast20Regular, Send20Regular } from "@fluentui/react-icons";
7+
import { Send20Regular } from "@fluentui/react-icons";
108
import React, { useRef, useEffect, useState } from "react";
11-
import { useNavigate } from "react-router-dom";
9+
import { useNavigate, useLocation } from "react-router-dom";
1210

1311
import "./../../styles/Chat.css";
1412
import "../../styles/prism-material-oceanic.css";
1513
import "./../../styles/HomeInput.css";
14+
1615
import { HomeInputProps, quickTasks, QuickTask } from "../../models/homeInput";
1716
import { TaskService } from "../../services/TaskService";
1817
import { NewTaskService } from "../../services/NewTaskService";
18+
1919
import ChatInput from "@/coral/modules/ChatInput";
2020
import InlineToaster, { useInlineToaster } from "../toast/InlineToaster";
2121
import PromptCard from "@/coral/components/PromptCard";
22+
import { Send } from "@/coral/imports/bundleicons";
2223

2324
const HomeInput: React.FC<HomeInputProps> = ({
24-
onInputSubmit,
25-
onQuickTaskSelect,
25+
onInputSubmit,
26+
onQuickTaskSelect,
2627
}) => {
27-
const [submitting, setSubmitting] = useState(false);
28-
const [input, setInput] = useState("");
29-
const textareaRef = useRef<HTMLTextAreaElement>(null);
30-
const navigate = useNavigate();
31-
const { showToast, dismissToast } = useInlineToaster();
32-
33-
const resetTextarea = () => {
28+
const [submitting, setSubmitting] = useState(false);
29+
const [input, setInput] = useState("");
30+
31+
const textareaRef = useRef<HTMLTextAreaElement>(null);
32+
const navigate = useNavigate();
33+
const location = useLocation(); // ✅ location.state used to control focus
34+
const { showToast, dismissToast } = useInlineToaster();
35+
36+
useEffect(() => {
37+
if (location.state?.focusInput) {
38+
textareaRef.current?.focus();
39+
}
40+
}, [location]);
41+
42+
const resetTextarea = () => {
43+
setInput("");
44+
if (textareaRef.current) {
45+
textareaRef.current.style.height = "auto";
46+
textareaRef.current.focus();
47+
}
48+
};
49+
50+
useEffect(() => {
51+
const cleanup = NewTaskService.addResetListener(resetTextarea);
52+
return cleanup;
53+
}, []);
54+
55+
const handleSubmit = async () => {
56+
if (input.trim()) {
57+
setSubmitting(true);
58+
let id = showToast("Creating a plan", "progress");
59+
60+
try {
61+
const response = await TaskService.submitInputTask(input.trim());
3462
setInput("");
35-
if (textareaRef.current) {
36-
textareaRef.current.style.height = "auto";
37-
textareaRef.current.focus();
38-
}
39-
};
40-
41-
useEffect(() => {
42-
const cleanup = NewTaskService.addResetListener(resetTextarea);
43-
return cleanup;
44-
}, []);
45-
46-
const handleSubmit = async () => {
47-
if (input.trim()) {
48-
setSubmitting(true);
49-
let id = showToast("Creating a plan", "progress");
50-
try {
51-
const response = await TaskService.submitInputTask(input.trim());
52-
53-
setInput("");
54-
if (textareaRef.current) {
55-
textareaRef.current.style.height = "auto";
56-
}
57-
58-
59-
console.log('Task response', response);
60-
if (response.plan_id && response.plan_id !== null) {
61-
// plan_id is valid (not null or undefined)
62-
showToast("Plan created!", "success");
63-
dismissToast(id);
64-
navigate(`/plan/${response.plan_id}`);
65-
} else {
66-
// plan_id is not valid, handle accordingly
67-
console.log('Invalid plan:', response.status);
68-
69-
showToast("Failed to create plan", "error");
70-
dismissToast(id);
71-
}
72-
} catch (error) {
73-
console.error("Failed to create plan:", error);
74-
dismissToast(id);
75-
showToast("Something went wrong", "error");
76-
} finally {
77-
setInput("");
78-
setSubmitting(false);
79-
}
80-
}
81-
};
8263

83-
const handleQuickTaskClick = (task: QuickTask) => {
84-
setInput(task.description);
8564
if (textareaRef.current) {
86-
textareaRef.current.focus();
65+
textareaRef.current.style.height = "auto";
8766
}
88-
onQuickTaskSelect(task.description);
89-
};
9067

91-
useEffect(() => {
92-
if (textareaRef.current) {
93-
textareaRef.current.style.height = "auto";
94-
textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
68+
if (response.plan_id && response.plan_id !== null) {
69+
showToast("Plan created!", "success");
70+
dismissToast(id);
71+
navigate(`/plan/${response.plan_id}`);
72+
} else {
73+
console.log("Invalid plan:", response.status);
74+
showToast("Failed to create plan", "error");
75+
dismissToast(id);
9576
}
96-
}, [input]);
97-
98-
99-
100-
return (
101-
<div className="home-input-container">
102-
<div className="home-input-content">
103-
<div className="home-input-center-content">
104-
<div className="home-input-title-wrapper">
105-
<Title2>How can I help?</Title2>
106-
</div>
107-
108-
<ChatInput
109-
value={input}
110-
placeholder="Tell us what needs planning, building, or connecting—we'll handle the rest."
111-
onChange={setInput}
112-
onEnter={handleSubmit}
113-
disabledChat={submitting}
114-
>
115-
<Button
116-
appearance="subtle"
117-
className="home-input-send-button"
118-
onClick={handleSubmit}
119-
disabled={submitting}
120-
icon={<Send20Regular />}
121-
/>
122-
123-
</ChatInput>
124-
125-
{/* Inline Toaster lives right under chat input */}
126-
<InlineToaster />
127-
128-
<div className="home-input-quick-tasks-section">
129-
<div className="home-input-quick-tasks-header">
130-
<Body1Strong>Quick tasks</Body1Strong>
131-
</div>
132-
<div className="home-input-quick-tasks">
133-
{quickTasks.map((task) => (
134-
<PromptCard
135-
key={task.id}
136-
title={task.title}
137-
icon={task.icon}
138-
description={task.description}
139-
onClick={() => handleQuickTaskClick(task)}
140-
disabled={submitting}
141-
/>
142-
))}
143-
</div>
144-
</div>
145-
</div>
77+
} catch (error) {
78+
console.error("Failed to create plan:", error);
79+
dismissToast(id);
80+
showToast("Something went wrong", "error");
81+
} finally {
82+
setInput("");
83+
setSubmitting(false);
84+
}
85+
}
86+
};
87+
88+
const handleQuickTaskClick = (task: QuickTask) => {
89+
setInput(task.description);
90+
if (textareaRef.current) {
91+
textareaRef.current.focus();
92+
}
93+
onQuickTaskSelect(task.description);
94+
};
95+
96+
useEffect(() => {
97+
if (textareaRef.current) {
98+
textareaRef.current.style.height = "auto";
99+
textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
100+
}
101+
}, [input]);
102+
103+
return (
104+
<div className="home-input-container">
105+
<div className="home-input-content">
106+
<div className="home-input-center-content">
107+
<div className="home-input-title-wrapper">
108+
<Title2>How can I help?</Title2>
109+
</div>
110+
111+
<ChatInput
112+
ref={textareaRef} // forwarding
113+
value={input}
114+
placeholder="Tell us what needs planning, building, or connecting—we'll handle the rest."
115+
onChange={setInput}
116+
onEnter={handleSubmit}
117+
disabledChat={submitting}
118+
>
119+
<Button
120+
appearance="subtle"
121+
className="home-input-send-button"
122+
onClick={handleSubmit}
123+
disabled={submitting}
124+
icon={<Send />}
125+
/>
126+
</ChatInput>
127+
128+
<InlineToaster />
129+
130+
<div className="home-input-quick-tasks-section">
131+
<div className="home-input-quick-tasks-header">
132+
<Body1Strong>Quick tasks</Body1Strong>
146133
</div>
134+
135+
<div className="home-input-quick-tasks">
136+
{quickTasks.map((task) => (
137+
<PromptCard
138+
key={task.id}
139+
title={task.title}
140+
icon={task.icon}
141+
description={task.description}
142+
onClick={() => handleQuickTaskClick(task)}
143+
disabled={submitting}
144+
/>
145+
))}
146+
</div>
147+
</div>
147148
</div>
148-
);
149+
</div>
150+
</div>
151+
);
149152
};
150153

151154
export default HomeInput;
152-

src/frontend_react/src/components/content/PlanPanelLeft.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@ import PanelFooter from "@/coral/components/Panels/PanelFooter";
2929
import PanelUserCard from "../../coral/components/Panels/UserCard";
3030
import { getUserInfoGlobal } from "@/api/config";
3131

32-
const PlanPanelLeft: React.FC<PlanPanelLefProps> = ({
33-
reloadTasks,
34-
onNewTaskButton,
35-
}) => {
32+
const PlanPanelLeft: React.FC<PlanPanelLefProps> = ({ reloadTasks }) => {
3633
const { dispatchToast } = useToastController("toast");
3734
const navigate = useNavigate();
3835
const { planId } = useParams<{ planId: string }>();
@@ -118,14 +115,22 @@ const PlanPanelLeft: React.FC<PlanPanelLefProps> = ({
118115
</PanelLeftToolbar>
119116

120117
<br />
121-
<div className="tab tab-new-task" onClick={onNewTaskButton}>
122-
<div className="tab tab-new-task-icon"
123-
>
118+
<div
119+
className="tab tab-new-task"
120+
onClick={() => navigate("/", { state: { focusInput: true } })}
121+
tabIndex={0} // ✅ allows tab focus
122+
role="button" // ✅ announces as button
123+
onKeyDown={(e) => {
124+
if (e.key === "Enter" || e.key === " ") {
125+
e.preventDefault();
126+
navigate("/", { state: { focusInput: true } });
127+
}
128+
}}
129+
>
130+
<div className="tab tab-new-task-icon">
124131
<ChatAdd20Regular />
125-
126132
</div>
127133
<Body1Strong>New task</Body1Strong>
128-
129134
</div>
130135

131136
<br />
@@ -139,7 +144,7 @@ const PlanPanelLeft: React.FC<PlanPanelLefProps> = ({
139144

140145
<PanelFooter>
141146
<PanelUserCard
142-
name={userInfo ? userInfo.user_first_last_name : "Guess"}
147+
name={userInfo ? userInfo.user_first_last_name : "Guest"}
143148
alias={userInfo ? userInfo.user_email : ""}
144149
size={32}
145150
/>

src/frontend_react/src/components/content/TaskDetails.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,11 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
154154
</div>
155155
<div className="task-details-subtask-content">
156156
<Body1
157-
className={`task-details-subtask-description ${step.human_approval_status === "rejected"
158-
? "strikethrough"
159-
: ""
160-
}`}
157+
className={`task-details-subtask-description ${
158+
step.human_approval_status === "rejected"
159+
? "strikethrough"
160+
: ""
161+
}`}
161162
>
162163
{description}{" "}
163164
{functionOrDetails && (
@@ -167,10 +168,8 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
167168
<div className="task-details-action-buttons">
168169
{step.human_approval_status !== "accepted" &&
169170
step.human_approval_status !== "rejected" && (
170-
<div>
171-
<Tooltip relationship="label" content="Approve">
171+
<> <Tooltip relationship="label" content="Approve">
172172
<Button
173-
174173
icon={<Checkmark20Regular />}
175174
appearance="subtle"
176175
onClick={
@@ -201,8 +200,8 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
201200
: "task-details-action-button-disabled"
202201
}
203202
/>
204-
</Tooltip>
205-
</div>
203+
</Tooltip></>
204+
206205
)}
207206
</div>
208207
</div>

0 commit comments

Comments
 (0)