Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add email subscription component #474

Merged
merged 12 commits into from
May 22, 2024
13 changes: 13 additions & 0 deletions locale/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,19 @@
"scrollToTop": "Scroll to top",
"goToFeedback": "Was this page helpful?"
},
"releaseSubscription": {
"title": "Get future LTS release notice via email",
"placeholder": "Your email",
"button": {
"subscribe": "Subscribe",
"subscribing": "Subscribing..."
},
"error": {
"invalidEmail": "Invalid email address.",
"networkError": "Network error, please try again later."
},
"success": "Thank you! You will be notified when new LTS release comes out."
},
"banner": {
"docDash2024": {
"link": "https://www.pingcap.com/event/tidb-docs-dash/",
Expand Down
13 changes: 13 additions & 0 deletions locale/zh/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,19 @@
"scrollToTop": "回到顶部",
"goToFeedback": "文档内容是否有帮助?"
},
"releaseSubscription": {
"title": "订阅 LTS 版本更新",
"placeholder": "邮箱地址",
"button": {
"subscribe": "订阅",
"subscribing": "订阅中..."
},
"error": {
"invalidEmail": "无效邮箱地址。",
"networkError": "网络错误,请稍后重试。"
},
"success": "感谢订阅!当新的 LTS 版本发布时,我们会通过邮件通知您。"
},
"banner": {
"docDash2024": {
"link": "https://asktug.com/t/topic/1019364",
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@
"redux": "^4.1.2",
"rehype-katex": "5.0.0",
"remark-math": "3.0.1",
"signale": "^1.4.0"
"signale": "^1.4.0",
"zod": "^3.22.4"
},
"devDependencies": {
"@prantlf/railroad-diagrams": "^1.0.1",
Expand Down
139 changes: 139 additions & 0 deletions src/components/MDXComponents/EmailSubscriptionForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { Trans, useI18next } from "gatsby-plugin-react-i18next";
import { useState } from "react";
import { z } from "zod";

import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import TextField from "@mui/material/TextField";

import { errorMessage } from "./email-subscription-form.module.css";

type FormType = {
email: string;
loading: boolean;
error: null | "invalidEmail" | "networkError";
};

// Collect email address that subscribe to TiDB release and send it to the SendGrid API
export function EmailSubscriptionForm() {
const { t, navigate } = useI18next();

const API_URL =
"https://03tryjsrrb.execute-api.us-west-2.amazonaws.com/Prod/subscribe/";

const [formData, setFormData] = useState<FormType>({
email: "",
loading: false,
error: null,
});
const [success, setSuccess] = useState(false);

const validateEmail = (): boolean => {
// Set up a schema for validating the email address
const schema = z.string().email();

try {
schema.parse(formData.email);
console.log("Email is valid");
return true;
} catch (e) {
console.error(e);
setFormData({ ...formData, error: "invalidEmail" });
return false;
}
};

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { value } = event.target;
setFormData((prevState) => ({ ...prevState, email: value }));
};

const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();

if (validateEmail()) {
// Submitting...
setFormData({ ...formData, loading: true, error: null });

try {
await fetch(API_URL, {
method: "POST",
body: `email=${formData.email}`,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});

setFormData({ ...formData, loading: false, error: null });
setSuccess(true);
console.log("Email subscription form submitted");
} catch (e) {
setFormData({ ...formData, loading: false, error: "networkError" });
console.error(e);
}
}
};

return (
<div>
<p>
<strong>
<Trans i18nKey="releaseSubscription.title" />:
</strong>
</p>

{!success ? (
<div>
<form onSubmit={handleSubmit}>
<Box display="flex" alignItems="center">
<TextField
size="small"
variant="outlined"
type="text"
name="email"
placeholder={t("releaseSubscription.placeholder")}
value={formData.email}
onChange={handleChange}
/>
<Button
type="submit"
disabled={formData.loading}
variant="contained"
color="primary"
sx={{ marginLeft: "1rem" }}
>
{formData.loading ? (
<Trans i18nKey="releaseSubscription.button.subscribing" />
) : (
<Trans i18nKey="releaseSubscription.button.subscribe" />
)}
</Button>
</Box>
</form>
{formData.error && (
<p className={errorMessage}>
{formData.error === "invalidEmail" ? (
<Trans i18nKey="releaseSubscription.error.invalidEmail" />
) : (
<Trans i18nKey="releaseSubscription.error.networkError" />
)}
</p>
)}
</div>
) : (
<Box>
<p>
<span
role="img"
aria-label="love-letter"
style={{ marginRight: "0.2rem" }}
>
💌
</span>
<Trans i18nKey="releaseSubscription.success" />
</p>
</Box>
)}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.error-message {
/* Same color as the MUI error alert */
color: #ef5350;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// This file is automatically generated. Do not modify this file manually -- YOUR CHANGES WILL BE ERASED!
export const errorMessage: string;
25 changes: 13 additions & 12 deletions src/components/MDXComponents/index.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
export {
Tip,
Note,
CustomAlert,
Important,
Note,
Tip,
Warning,
CustomAlert,
} from "components/MDXComponents/Alert";
export {
ColumnTitle,
NavColumn,
NavColumns,
} from "components/MDXComponents/ColumnDeprecated";
export { SimpleTab } from "components/MDXComponents/SimpleTab";
export { SyntaxDiagram } from "components/MDXComponents/SyntaxDiagram";
export { TabsPanel } from "components/MDXComponents/TabsPanel";
export { CustomContent } from "components/MDXComponents/CustomContent";
export {
LearningPathContainer,
LearningPath,
} from "components/MDXComponents/LearningPath";
export {
DocHomeCard,
DocHomeCardContainer,
DocHomeContainer,
DocHomeSection,
DocHomeCardContainer,
DocHomeCard,
} from "components/MDXComponents/DocHome";
export { EmailSubscriptionForm } from "components/MDXComponents/EmailSubscriptionForm";
export {
LearningPath,
LearningPathContainer,
} from "components/MDXComponents/LearningPath";
export { MDSvgIcon } from "components/MDXComponents/MDSvgIcon";
export { SimpleTab } from "components/MDXComponents/SimpleTab";
export { SyntaxDiagram } from "components/MDXComponents/SyntaxDiagram";
export { TabsPanel } from "components/MDXComponents/TabsPanel";
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14603,6 +14603,11 @@ z-schema@^5.0.1:
optionalDependencies:
commander "^2.7.1"

zod@^3.22.4:
version "3.22.4"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff"
integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==

zwitch@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"
Expand Down