Skip to content

Commit c841bd2

Browse files
Laurie T. Malauroboquat
authored andcommitted
Feedback modal
1 parent 0a68903 commit c841bd2

File tree

6 files changed

+113
-48
lines changed

6 files changed

+113
-48
lines changed

components/dashboard/src/Login.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import fresh from "./images/welcome/fresh.svg";
2222
import prebuild from "./images/welcome/prebuild.svg";
2323
import exclamation from "./images/exclamation.svg";
2424
import { getURLHash } from "./App";
25+
import ErrorMessage from "./components/ErrorMessage";
2526

2627
function Item(props: { icon: string; iconSize?: string; text: string }) {
2728
const iconSize = props.iconSize || 28;
@@ -225,17 +226,7 @@ export function Login() {
225226
))
226227
)}
227228
</div>
228-
229-
{errorMessage && (
230-
<div className="mt-16 flex space-x-2 py-6 px-6 w-96 justify-between bg-gitpod-kumquat-light rounded-xl">
231-
<div className="pr-3 self-center w-6">
232-
<img src={exclamation} />
233-
</div>
234-
<div className="flex-1 flex flex-col">
235-
<p className="text-gitpod-red text-sm">{errorMessage}</p>
236-
</div>
237-
</div>
238-
)}
229+
{errorMessage && <ErrorMessage imgSrc={exclamation} message={errorMessage} />}
239230
</div>
240231
</div>
241232
<div className="flex-none mx-auto h-20 text-center">
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3+
* Licensed under the GNU Affero General Public License (AGPL).
4+
* See License-AGPL.txt in the project root for license information.
5+
*/
6+
7+
import FeedbackComponent from "../feedback-form/FeedbackComponent";
8+
9+
function ErrorMessage(props: { imgSrc: string; imgAlt?: string; message: string }) {
10+
return (
11+
<>
12+
<div className="mt-16 flex space-x-2 py-6 px-6 w-96 justify-between bg-gitpod-kumquat-light rounded-xl">
13+
<div className="pr-3 self-center w-6">
14+
<img src={props.imgSrc} alt={props.imgAlt || "An error message"} />
15+
</div>
16+
<div className="flex-1 flex flex-col">
17+
<p className="text-gitpod-red text-sm">{props.message}</p>
18+
</div>
19+
</div>
20+
<FeedbackComponent
21+
message={"Was this error message helpful?"}
22+
initialSize={24}
23+
isError={true}
24+
isModal={false}
25+
/>
26+
</>
27+
);
28+
}
29+
30+
export default ErrorMessage;

components/dashboard/src/feedback-form/FeedbackComponent.tsx

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,23 @@ import meh from "../images/feedback/meh-emoji.svg";
1111
import crying from "../images/feedback/crying-emoji.svg";
1212
import { trackEvent } from "../Analytics";
1313

14-
function FeedbackComponent(props: { onClose: () => void; onSubmit: () => void; isModal: boolean }) {
14+
function FeedbackComponent(props: {
15+
onClose?: () => void;
16+
isModal: boolean;
17+
isError: boolean;
18+
message?: string;
19+
initialSize?: number;
20+
}) {
1521
const [text, setText] = useState<string>("");
1622
const [selectedEmoji, setSelectedEmoji] = useState<number | undefined>();
23+
const [isFeedbackSubmitted, setIsFeedbackSubmitted] = useState<boolean>(false);
1724

18-
const height = props.isModal ? "300px" : "";
19-
25+
const onClose = () => {
26+
if (props.onClose) {
27+
props.onClose();
28+
}
29+
setSelectedEmoji(undefined);
30+
};
2031
const onSubmit = () => {
2132
if (selectedEmoji) {
2233
const feedbackObj = {
@@ -28,7 +39,7 @@ function FeedbackComponent(props: { onClose: () => void; onSubmit: () => void; i
2839
trackEvent("feedback_submitted", feedbackObj);
2940
}
3041

31-
props.onSubmit();
42+
setIsFeedbackSubmitted(true);
3243
};
3344

3445
const handleClick = (emojiScore: number) => {
@@ -54,12 +65,42 @@ function FeedbackComponent(props: { onClose: () => void; onSubmit: () => void; i
5465
</button>
5566
));
5667
};
68+
69+
const minimisedFirstView = !selectedEmoji && !isFeedbackSubmitted;
70+
const expandedWithTextView = selectedEmoji && !isFeedbackSubmitted;
71+
5772
return (
5873
<>
59-
<h3 className="mb-4">Send Feedback</h3>
60-
{selectedEmoji ? (
74+
{props.isModal && !isFeedbackSubmitted && <h3 className="mb-4">Send Feedback</h3>}
75+
{minimisedFirstView && (
76+
<div
77+
className={
78+
"flex flex-col justify-center px-6 py-4 border-gray-200 dark:border-gray-800 " +
79+
(props.isError ? "mt-20 bg-gray-100 dark:bg-gray-800 rounded-xl" : "border-t")
80+
}
81+
>
82+
<p
83+
className={
84+
"text-center text-base mb-3 dark:text-gray-400 " +
85+
(props.isError ? "text-gray-400" : "text-gray-500")
86+
}
87+
>
88+
{props.message}
89+
</p>
90+
91+
<div className="flex items-center justify-center w-full">{emojiGroup(props.initialSize || 50)}</div>
92+
</div>
93+
)}
94+
{expandedWithTextView && (
6195
<>
62-
<div className="flex flex-col -mx-6 px-6 py-4 border-t border-b border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900">
96+
<div
97+
className={
98+
"flex flex-col px-6 py-4 border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900 " +
99+
(props.isError
100+
? "w-96 mt-6 bg-gray-100 dark:bg-gray-800 rounded-xl"
101+
: "-mx-6 border-t border-b")
102+
}
103+
>
63104
<div className="relative">
64105
<div className="absolute flex bottom-5 right-5 -space-x-3">{emojiGroup(24)}</div>
65106
<textarea
@@ -82,26 +123,27 @@ function FeedbackComponent(props: { onClose: () => void; onSubmit: () => void; i
82123
.
83124
</p>
84125
</div>
85-
</div>
86-
<div className="flex justify-end mt-6">
87-
<button className="secondary" onClick={props.onClose}>
88-
Cancel
89-
</button>
90-
<button className="ml-2" onClick={onSubmit}>
91-
Send Feedback
92-
</button>
126+
<div className="flex justify-end mt-6">
127+
<button className="secondary" onClick={onClose}>
128+
Cancel
129+
</button>
130+
<button className="ml-2" onClick={onSubmit}>
131+
Send Feedback
132+
</button>
133+
</div>
93134
</div>
94135
</>
95-
) : (
136+
)}
137+
{isFeedbackSubmitted && (
96138
<div
97-
className="flex flex-col justify-center -mx-6 px-6 py-4 border-t border-gray-200 dark:border-gray-800"
98-
style={{ height: height }}
139+
className={
140+
"flex flex-col px-6 py-4 border-gray-200 dark:border-gray-800 " +
141+
(props.isError ? "mt-20 bg-gray-100 dark:bg-gray-800 rounded-xl" : "")
142+
}
99143
>
100-
<p className="text-center text-lg mb-8 text-gray-500 dark:text-gray-400">
101-
We'd love to know what you think!
144+
<p className={"text-center text-base " + (props.isError ? "text-gray-400" : "text-gray-500")}>
145+
Thanks for your feedback, we appreciate it.
102146
</p>
103-
104-
<div className="flex items-center justify-center w-full space-x-3">{emojiGroup(50)}</div>
105147
</div>
106148
)}
107149
</>

components/dashboard/src/feedback-form/FeedbackModal.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ function FeedbackFormModal(props: { onClose: () => void }) {
1212
props.onClose();
1313
};
1414

15-
const onSubmit = () => {
16-
props.onClose();
17-
};
18-
1915
return (
2016
<Modal visible={true} onClose={onClose}>
21-
<FeedbackComponent onClose={onClose} onSubmit={onSubmit} isModal={true} />
17+
<FeedbackComponent
18+
onClose={onClose}
19+
isModal={true}
20+
isError={false}
21+
message="We'd love to know what you think!"
22+
/>
2223
</Modal>
2324
);
2425
}

components/dashboard/src/projects/NewProject.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import moment from "moment";
1919
import { UserContext } from "../user-context";
2020
import { trackEvent } from "../Analytics";
2121
import exclamation from "../images/exclamation.svg";
22+
import ErrorMessage from "../components/ErrorMessage";
2223

2324
export default function NewProject() {
2425
const location = useLocation();
@@ -744,16 +745,7 @@ function GitProviders(props: {
744745
})}
745746
</div>
746747

747-
{errorMessage && (
748-
<div className="mt-16 flex space-x-2 py-6 px-6 w-96 justify-between bg-gitpod-kumquat-light rounded-xl">
749-
<div className="pr-3 self-center w-6">
750-
<img src={exclamation} />
751-
</div>
752-
<div className="flex-1 flex flex-col">
753-
<p className="text-gitpod-red text-sm">{errorMessage}</p>
754-
</div>
755-
</div>
756-
)}
748+
{errorMessage && <ErrorMessage imgSrc={exclamation} message={errorMessage} />}
757749
</div>
758750
</div>
759751
);

components/dashboard/src/start/CreateWorkspace.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { SelectAccountPayload } from "@gitpod/gitpod-protocol/lib/auth";
2323
import { SelectAccountModal } from "../settings/SelectAccountModal";
2424
import { watchHeadlessLogs } from "../components/PrebuildLogs";
2525
import CodeText from "../components/CodeText";
26+
import FeedbackComponent from "../feedback-form/FeedbackComponent";
2627

2728
const WorkspaceLogs = React.lazy(() => import("../components/WorkspaceLogs"));
2829

@@ -432,6 +433,14 @@ function RepositoryNotFoundView(p: { error: StartWorkspaceError }) {
432433
<CodeText>{repoFullName}</CodeText>
433434
</p>
434435
{statusMessage}
436+
{p.error && (
437+
<FeedbackComponent
438+
isModal={false}
439+
message={"Was this error message helpful?"}
440+
isError={true}
441+
initialSize={24}
442+
/>
443+
)}
435444
</StartPage>
436445
);
437446
}

0 commit comments

Comments
 (0)