Skip to content

Commit 598689c

Browse files
authored
Display a shorter success message and proper color (#6711)
1 parent 3f823c9 commit 598689c

File tree

1 file changed

+24
-18
lines changed

1 file changed

+24
-18
lines changed

packages/web/docs/src/app/blog/components/newsletter-form-card.tsx

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
'use client';
22

3-
import { useRef, useState } from 'react';
3+
import { useState } from 'react';
44
import { CallToAction, cn, Heading, Input } from '@theguild/components';
55

66
export function NewsletterFormCard(props: React.HTMLAttributes<HTMLElement>) {
77
type Idle = undefined;
8-
type Pending = { status: 'pending'; message?: never };
8+
type Pending = {
9+
status: 'pending';
10+
/**
11+
* potentially revious error message to reduce layout shift
12+
*/
13+
message: string | undefined;
14+
};
915
type Success = { status: 'success'; message: string };
1016
type Error = { status: 'error'; message: string };
1117
type State = Idle | Pending | Success | Error;
1218
const [state, setState] = useState<State>();
1319

14-
// we don't want to blink a message on retries when request is pending
15-
const lastErrorMessage = useRef<string>();
16-
lastErrorMessage.current = state?.message || lastErrorMessage.current;
17-
1820
return (
1921
<article
2022
{...props}
@@ -47,7 +49,10 @@ export function NewsletterFormCard(props: React.HTMLAttributes<HTMLElement>) {
4749
return;
4850
}
4951

50-
setState({ status: 'pending' });
52+
setState(s => ({
53+
status: 'pending',
54+
message: s?.status === 'error' ? 'Retrying...' : undefined,
55+
}));
5156

5257
try {
5358
const response = await fetch('https://utils.the-guild.dev/api/newsletter-subscribe', {
@@ -57,8 +62,7 @@ export function NewsletterFormCard(props: React.HTMLAttributes<HTMLElement>) {
5762

5863
const json = await response.json();
5964
if (json.status === 'success') {
60-
lastErrorMessage.current = undefined;
61-
setState({ status: 'success', message: json.message });
65+
setState({ status: 'success', message: 'Please check your email to confirm.' });
6266
} else {
6367
setState({ status: 'error', message: json.message });
6468
}
@@ -78,12 +82,21 @@ export function NewsletterFormCard(props: React.HTMLAttributes<HTMLElement>) {
7882
setState({ status: 'error', message: 'Something went wrong. Please let us know.' });
7983
}
8084
}}
85+
onReset={() => {
86+
setState(undefined);
87+
}}
8188
>
8289
<Input
8390
name="email"
8491
placeholder="E-mail"
85-
severity={lastErrorMessage.current ? 'critical' : undefined}
86-
message={lastErrorMessage.current}
92+
severity={
93+
state?.status === 'error'
94+
? 'critical'
95+
: state?.status === 'success'
96+
? 'positive'
97+
: undefined
98+
}
99+
message={state?.message}
87100
/>
88101
{!state || state.status === 'error' ? (
89102
<CallToAction type="submit" variant="secondary-inverted" className="mt-2 !w-full">
@@ -103,13 +116,6 @@ export function NewsletterFormCard(props: React.HTMLAttributes<HTMLElement>) {
103116
type="reset"
104117
variant="secondary-inverted"
105118
className="group/button mt-2 !w-full before:absolute"
106-
onClick={() => {
107-
// the default behavior of <button type="reset"> doesn't work here
108-
// because it gets unmounted too fast
109-
setTimeout(() => {
110-
setState(undefined);
111-
}, 0);
112-
}}
113119
>
114120
<span className="group-hover/button:hidden group-focus/button:hidden">Subscribed</span>
115121
<span aria-hidden className="hidden group-hover/button:block group-focus/button:block">

0 commit comments

Comments
 (0)