diff --git a/components/blog-post.tsx b/components/blog-post.tsx
index c4a8f12..c4584c4 100644
--- a/components/blog-post.tsx
+++ b/components/blog-post.tsx
@@ -8,6 +8,8 @@ import { Link, useConfig } from "nextra-theme-docs";
import React from 'react';
import Picture from './picture';
import { GithubIcon, LinkIcon, LinkedinIcon, MailIcon, XIcon } from 'lucide-react';
+import { Separator } from './ui/separator';
+import { SubscribeDialog } from './blog';
// Reference for styling: https://github.com/vercel/turbo/blob/22585c9dcc23eb010ab01f177394358af03210d7/docs/pages/blog/turbo-1-10-0.mdx
@@ -131,5 +133,10 @@ export function BlogPostHeader() {
}
export function BlogPostFooter() {
- return
+ return <>
+
+
+
+
+ >
}
diff --git a/components/blog.tsx b/components/blog.tsx
new file mode 100644
index 0000000..baad4ad
--- /dev/null
+++ b/components/blog.tsx
@@ -0,0 +1,174 @@
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle
+} from "@/components/ui/alert-dialog"
+import {
+ Form,
+ FormControl,
+ FormField,
+ FormItem,
+ FormMessage
+} from "@/components/ui/form"
+import { websiteConfig } from '@/lib/data'
+import { dayjsTz } from '@/lib/utils'
+import { zodResolver } from "@hookform/resolvers/zod"
+import { useRouter } from 'next/router'
+import { MdxFile } from "nextra"
+import { Link } from "nextra-theme-docs"
+import { getPagesUnderRoute } from "nextra/context"
+import { useState } from "react"
+import { useForm } from "react-hook-form"
+import { z } from "zod"
+import { Button } from "./ui/button"
+import { Input } from "./ui/input"
+
+// Header and Index derived from https://github.com/vercel/turbo/blob/66196a70d02cddc8899ed1423684b1f716aa310e/docs/pages/blog.mdx
+export function BlogHeader() {
+ return (
+
+
+ Breadcrumbs
+
+
+ A record of the big and small things happening at WATcloud
+
+
+ );
+}
+
+export function BlogIndex() {
+ const { locale = websiteConfig.default_locale } = useRouter()
+
+ return getPagesUnderRoute("/blog").map((page) => {
+ const frontMatter = (page as MdxFile).frontMatter
+ const { date, timezone } = frontMatter || {}
+ const dateObj = date && timezone && dayjsTz(date, timezone).toDate()
+
+ return (
+
+
+ {page.meta?.title || frontMatter?.title || page.name}
+
+
+ {frontMatter?.description}{" "}
+
+ {"Read more →"}
+
+
+ {dateObj ? (
+
+ {/* suppressHydrationWarning is used to prevent warnings due to differing server/client locales */}
+
+ {dateObj.toLocaleDateString(locale, {
+ day: 'numeric',
+ month: 'long',
+ year: 'numeric'
+ })}
+
+
+ ) : null}
+
+ );
+ });
+}
+
+const subscribeFormSchema = z.object({
+ email: z.string().email({
+ message: "Please enter a valid email.",
+ }),
+});
+
+export function SubscribeDialog() {
+
+ function subscribe(e: React.MouseEvent) {
+ // Add your subscribe logic here
+ console.log("Subscribed!");
+ e.preventDefault();
+ }
+
+ const [isAlertOpen, setIsAlertOpen] = useState(false);
+ const [alertTitle, setAlertTitle] = useState("");
+ const [alertDescription, setAlertDescription] = useState("");
+ const [isSubmitting, setIsSubmitting] = useState(false);
+
+ const form = useForm>({
+ resolver: zodResolver(subscribeFormSchema),
+ defaultValues: {
+ email: "",
+ },
+ });
+
+ async function onSubmit({ email }: z.infer) {
+ setIsSubmitting(true);
+ try {
+ const res = await fetch(
+ "https://mailing-list-gateway.watonomous.ca/sign-up",
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ email, mailing_list: "watcloud-blog-updates@watonomous.ca" }),
+ }
+ );
+
+ if (res.status === 200) {
+ setAlertTitle("Success!");
+ setAlertDescription(`Success! Please check your email inbox to confirm your subscription.`);
+ form.reset();
+ } else {
+ setAlertTitle("Error");
+ setAlertDescription(`Something went wrong! Error code: ${res.status}. Error message: \`${(await res.text())}\`.`);
+ }
+ } catch (e) {
+ setAlertTitle("Error");
+ setAlertDescription(`Something went wrong! Network request failed with error "${e}".`);
+ }
+ setIsAlertOpen(true);
+ setIsSubmitting(false);
+ }
+
+ return (
+
+
{"Subscribe to WATcloud's blog"}
+
{"Get the latest posts delivered right to your inbox. We won't spam you!"}
+
+
+
+
+
+ {alertTitle}
+ {alertDescription}
+
+
+ OK
+
+
+
+
+ );
+}
diff --git a/components/giscus-comments.tsx b/components/giscus-comments.tsx
index baf9ab8..85f786a 100644
--- a/components/giscus-comments.tsx
+++ b/components/giscus-comments.tsx
@@ -1,6 +1,7 @@
import Giscus from "@giscus/react";
import websiteConfig from "@/build/fixtures/website-config.json";
import { useTheme } from "nextra-theme-docs";
+import { Separator } from "./ui/separator";
export default function CommentSection() {
const { theme } = useTheme();
@@ -18,7 +19,6 @@ export default function CommentSection() {
return (
<>
-
{repo && repo_id && category && category_id ? (
-
- Breadcrumbs
-
-
- A record of the big and small things happening at WATcloud
-
-
- );
-}
-
-export function BlogIndex() {
- return getPagesUnderRoute("/blog").map((page) => {
- const { date, timezone } = page.frontMatter || {}
- const dateObj = date && timezone && dayjsTz(date, timezone).toDate()
- const { locale = websiteConfig.default_locale } = useRouter()
-
- return (
-
-
- {page.meta?.title || page.frontMatter?.title || page.name}
-
-
- {page.frontMatter?.description}{" "}
-
- {"Read more →"}
-
-
- {dateObj ? (
-
- {/* suppressHydrationWarning is used to prevent warnings due to differing server/client locales */}
-
- {dateObj.toLocaleDateString(locale, {
- day: 'numeric',
- month: 'long',
- year: 'numeric'
- })}
-
-
- ) : null}
-
- );
- });
-}
+import { BlogHeader, BlogIndex, SubscribeDialog } from '@/components/blog'
+import { Separator } from "@/components/ui/separator";
-
\ No newline at end of file
+
+
+
diff --git a/styles/global.css b/styles/global.css
index 67846f1..b5a4f1b 100644
--- a/styles/global.css
+++ b/styles/global.css
@@ -139,5 +139,5 @@ section.footnotes is created by the remark-gfm plugin:
- https://github.com/micromark/micromark-extension-gfm-footnote/blob/533e041238c15e7995afbffa7721b0e8d427f68e/readme.md
*/
section.footnotes {
- @apply border-t mt-6;
+ @apply border-t mt-6 border-gray-400 border-opacity-20;
}
\ No newline at end of file