Merge and use newsletter-api for immediate welcome emails
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
commit
0ee8179093
|
|
@ -0,0 +1,13 @@
|
|||
FROM node:20-alpine AS builder
|
||||
WORKDIR /app
|
||||
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||
COPY package.json pnpm-lock.yaml* package-lock.json* ./
|
||||
RUN if [ -f pnpm-lock.yaml ]; then pnpm install --frozen-lockfile; elif [ -f package-lock.json ]; then npm ci; else npm install; fi
|
||||
COPY . .
|
||||
RUN if [ -f pnpm-lock.yaml ]; then pnpm build; else npm run build; fi
|
||||
|
||||
FROM nginx:alpine
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY --from=builder /app/out /usr/share/nginx/html
|
||||
EXPOSE 80
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
|
@ -8,6 +8,7 @@ const _geist = Geist({ subsets: ["latin"] })
|
|||
const _geistMono = Geist_Mono({ subsets: ["latin"] })
|
||||
|
||||
export const metadata: Metadata = {
|
||||
metadataBase: new URL("https://alltor.net"),
|
||||
title: "alltor.net - The Alternative Internet",
|
||||
description:
|
||||
"A distributed, local-first, collaborative digital ecosystem. Access the alternative internet through physical USB keys and local mesh networks.",
|
||||
|
|
@ -15,6 +16,30 @@ export const metadata: Metadata = {
|
|||
icons: {
|
||||
icon: "data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🧅</text></svg>",
|
||||
},
|
||||
openGraph: {
|
||||
title: "alltor.net - The Alternative Internet",
|
||||
description:
|
||||
"A distributed, local-first, collaborative digital ecosystem. Access the alternative internet through physical USB keys and local mesh networks.",
|
||||
url: "https://alltor.net",
|
||||
siteName: "alltor.net",
|
||||
images: [
|
||||
{
|
||||
url: "/og-image.jpg",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: "alltor.net - The Alternative Internet",
|
||||
},
|
||||
],
|
||||
locale: "en_US",
|
||||
type: "website",
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "alltor.net - The Alternative Internet",
|
||||
description:
|
||||
"A distributed, local-first, collaborative digital ecosystem. Access the alternative internet through physical USB keys and local mesh networks.",
|
||||
images: ["/og-image.jpg"],
|
||||
},
|
||||
}
|
||||
|
||||
export default function RootLayout({
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import { useState } from "react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
const LISTMONK_URL = "https://newsletter.jeffemmett.com"
|
||||
const NEWSLETTER_API = "https://newsletter.jeffemmett.com/api/subscribe"
|
||||
const LIST_UUID = "0c541da4-3f04-4e72-978a-5a328b43c995" // Alltornet list
|
||||
|
||||
export function NewsletterSignup() {
|
||||
|
|
@ -19,21 +19,20 @@ export function NewsletterSignup() {
|
|||
setStatus("loading")
|
||||
|
||||
try {
|
||||
const response = await fetch(`${LISTMONK_URL}/subscription/form`, {
|
||||
const response = await fetch(`${NEWSLETTER_API}/subscribe`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
body: JSON.stringify({
|
||||
email: email,
|
||||
list: LIST_UUID,
|
||||
name: "",
|
||||
list_uuid: LIST_UUID,
|
||||
}),
|
||||
})
|
||||
|
||||
if (response.ok) {
|
||||
setStatus("success")
|
||||
setMessage("Check your email to confirm your subscription!")
|
||||
setMessage("Connect to the Alltor.net. Something's emerging.")
|
||||
setEmail("")
|
||||
} else {
|
||||
throw new Error("Subscription failed")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ $uri.html =404;
|
||||
}
|
||||
|
||||
error_page 404 /404.html;
|
||||
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
Loading…
Reference in New Issue