chore: remove Letterspace newsletter integration and all LETTERSPACE_* variables
This commit is contained in:
10
DOCKER.md
10
DOCKER.md
@@ -53,9 +53,6 @@ docker run -d \
|
||||
-e PUBLIC_API_URL=https://api.pivoine.art \
|
||||
-e PUBLIC_URL=https://sexy.pivoine.art \
|
||||
-e PUBLIC_UMAMI_ID=your-umami-id \
|
||||
-e LETTERSPACE_API_URL=https://api.letterspace.com/v1 \
|
||||
-e LETTERSPACE_API_KEY=your-api-key \
|
||||
-e LETTERSPACE_LIST_ID=your-list-id \
|
||||
sexy.pivoine.art:latest
|
||||
```
|
||||
|
||||
@@ -117,9 +114,6 @@ docker-compose -f docker-compose.production.yml up -d --scale frontend=3
|
||||
| Variable | Description | Example |
|
||||
|----------|-------------|---------|
|
||||
| `PUBLIC_UMAMI_ID` | Umami analytics tracking ID | `abc123def-456` |
|
||||
| `LETTERSPACE_API_URL` | Letterspace API endpoint | `https://api.letterspace.com/v1` |
|
||||
| `LETTERSPACE_API_KEY` | Letterspace authentication key | `sk_live_...` |
|
||||
| `LETTERSPACE_LIST_ID` | Mailing list identifier | `list_abc123` |
|
||||
| `PORT` | Application port (inside container) | `3000` |
|
||||
| `HOST` | Host binding | `0.0.0.0` |
|
||||
| `NODE_ENV` | Node environment | `production` |
|
||||
@@ -224,12 +218,12 @@ docker run -d \
|
||||
|
||||
```bash
|
||||
# Create secrets
|
||||
echo "your-api-key" | docker secret create letterspace_api_key -
|
||||
echo "your-db-password" | docker secret create db_password -
|
||||
|
||||
# Deploy with secrets
|
||||
docker service create \
|
||||
--name sexy-pivoine-frontend \
|
||||
--secret letterspace_api_key \
|
||||
--secret db_password \
|
||||
-p 3000:3000 \
|
||||
sexy.pivoine.art:latest
|
||||
```
|
||||
|
||||
@@ -123,10 +123,7 @@ ENV NODE_ENV=production \
|
||||
# Runtime environment variables (will be passed at container start)
|
||||
ENV PUBLIC_API_URL="" \
|
||||
PUBLIC_URL="" \
|
||||
PUBLIC_UMAMI_ID="" \
|
||||
LETTERSPACE_API_URL="" \
|
||||
LETTERSPACE_API_KEY="" \
|
||||
LETTERSPACE_LIST_ID=""
|
||||
PUBLIC_UMAMI_ID=""
|
||||
|
||||
# Expose application port
|
||||
EXPOSE 3000
|
||||
|
||||
@@ -22,9 +22,6 @@ cat > .env.production << EOF
|
||||
PUBLIC_API_URL=https://api.your-domain.com
|
||||
PUBLIC_URL=https://your-domain.com
|
||||
PUBLIC_UMAMI_ID=
|
||||
LETTERSPACE_API_URL=
|
||||
LETTERSPACE_API_KEY=
|
||||
LETTERSPACE_LIST_ID=
|
||||
EOF
|
||||
```
|
||||
|
||||
@@ -132,9 +129,6 @@ docker pull ghcr.io/valknarxxx/sexy:latest
|
||||
| Variable | Description | Example |
|
||||
|----------|-------------|---------|
|
||||
| `PUBLIC_UMAMI_ID` | Analytics tracking ID | `abc-123-def` |
|
||||
| `LETTERSPACE_API_URL` | Newsletter API | `https://api.letterspace.com/v1` |
|
||||
| `LETTERSPACE_API_KEY` | Newsletter API key | `sk_live_...` |
|
||||
| `LETTERSPACE_LIST_ID` | Mailing list ID | `list_abc123` |
|
||||
|
||||
## Common Commands
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ Like Beate Uhse breaking barriers in post-war Germany, we believe in the freedom
|
||||
- 📱 **Responsive Design** that looks sexy on any device
|
||||
- 🌍 **Internationalization** — pleasure speaks all languages
|
||||
- 📊 **Analytics Integration** (Umami) — know your admirers
|
||||
- 📧 **Newsletter Integration** (Letterspace) — stay connected
|
||||
|
||||
<div align="center">
|
||||
|
||||
@@ -213,9 +212,6 @@ pnpm --filter @sexy.pivoine.art/frontend start
|
||||
### 💜 Optional (The Extras)
|
||||
|
||||
- `PUBLIC_UMAMI_ID` — Analytics tracking
|
||||
- `LETTERSPACE_API_URL` — Newsletter endpoint
|
||||
- `LETTERSPACE_API_KEY` — Newsletter key
|
||||
- `LETTERSPACE_LIST_ID` — Mailing list
|
||||
|
||||
See [.env.production.example](.env.production.example) for the full configuration.
|
||||
|
||||
|
||||
@@ -7,8 +7,7 @@ SvelteKit's `PUBLIC_*` environment variables are **baked into the JavaScript** a
|
||||
1. ✅ Changing `PUBLIC_API_URL`
|
||||
2. ✅ Changing `PUBLIC_URL`
|
||||
3. ✅ Changing `PUBLIC_UMAMI_ID`
|
||||
4. ✅ Changing any `LETTERSPACE_*` variables
|
||||
5. ❌ NOT needed for Directus env vars (those are runtime)
|
||||
4. ❌ NOT needed for Directus env vars (those are runtime)
|
||||
|
||||
## Quick Rebuild Process
|
||||
|
||||
@@ -25,9 +24,6 @@ Set your production values:
|
||||
PUBLIC_API_URL=https://sexy.pivoine.art/api
|
||||
PUBLIC_URL=https://sexy.pivoine.art
|
||||
PUBLIC_UMAMI_ID=your-umami-id
|
||||
LETTERSPACE_API_URL=https://api.letterspace.com/v1
|
||||
LETTERSPACE_API_KEY=your-key
|
||||
LETTERSPACE_LIST_ID=your-list-id
|
||||
```
|
||||
|
||||
### 2. Rebuild the Image
|
||||
@@ -254,7 +250,6 @@ These are runtime environment variables and can be changed in docker-compose.
|
||||
| `PUBLIC_API_URL` | ✅ Yes | Rebuild image |
|
||||
| `PUBLIC_URL` | ✅ Yes | Rebuild image |
|
||||
| `PUBLIC_UMAMI_ID` | ✅ Yes | Rebuild image |
|
||||
| `LETTERSPACE_*` | ✅ Yes | Rebuild image |
|
||||
| `SEXY_DIRECTUS_*` | ❌ No | Restart container |
|
||||
| `DB_*` | ❌ No | Restart container |
|
||||
| `EMAIL_*` | ❌ No | Restart container |
|
||||
|
||||
@@ -103,9 +103,6 @@ services:
|
||||
PUBLIC_API_URL: ${SEXY_FRONTEND_PUBLIC_API_URL}
|
||||
PUBLIC_URL: ${SEXY_FRONTEND_PUBLIC_URL}
|
||||
PUBLIC_UMAMI_ID: ${SEXY_FRONTEND_PUBLIC_UMAMI_ID:-}
|
||||
LETTERSPACE_API_URL: ${SEXY_FRONTEND_LETTERSPACE_API_URL:-}
|
||||
LETTERSPACE_API_KEY: ${SEXY_FRONTEND_LETTERSPACE_API_KEY:-}
|
||||
LETTERSPACE_LIST_ID: ${SEXY_FRONTEND_LETTERSPACE_LIST_ID:-}
|
||||
|
||||
# Override volume for production path
|
||||
volumes:
|
||||
|
||||
@@ -136,11 +136,6 @@ services:
|
||||
PUBLIC_URL: ${SEXY_FRONTEND_PUBLIC_URL:-http://localhost:3000}
|
||||
PUBLIC_UMAMI_ID: ${SEXY_FRONTEND_PUBLIC_UMAMI_ID:-}
|
||||
|
||||
# Letterspace newsletter integration
|
||||
LETTERSPACE_API_URL: ${SEXY_FRONTEND_LETTERSPACE_API_URL:-}
|
||||
LETTERSPACE_API_KEY: ${SEXY_FRONTEND_LETTERSPACE_API_KEY:-}
|
||||
LETTERSPACE_LIST_ID: ${SEXY_FRONTEND_LETTERSPACE_LIST_ID:-}
|
||||
|
||||
# Timezone
|
||||
TZ: ${TIMEZONE:-Europe/Amsterdam}
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
PUBLIC_API_URL=https://sexy.pivoine.art/api
|
||||
PUBLIC_URL=https://sexy.pivoine.art
|
||||
PUBLIC_UMAMI_ID=
|
||||
LETTERSPACE_API_URL=
|
||||
LETTERSPACE_API_KEY=
|
||||
LETTERSPACE_LIST_ID=
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { _ } from "svelte-i18n";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "$lib/components/ui/dialog";
|
||||
import { Button } from "$lib/components/ui/button";
|
||||
import { Separator } from "$lib/components/ui/separator";
|
||||
import type { Snippet } from "svelte";
|
||||
import Label from "../ui/label/label.svelte";
|
||||
import Input from "../ui/input/input.svelte";
|
||||
import { toast } from "svelte-sonner";
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
email: string;
|
||||
children?: Snippet;
|
||||
}
|
||||
|
||||
let isLoading = $state(false);
|
||||
|
||||
async function handleSubscription(e: Event) {
|
||||
e.preventDefault();
|
||||
try {
|
||||
isLoading = true;
|
||||
await fetch("/newsletter", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ email }),
|
||||
});
|
||||
toast.success(
|
||||
$_("newsletter_signup.toast_subscribe", { values: { email } }),
|
||||
);
|
||||
} finally {
|
||||
isLoading = false;
|
||||
open = false;
|
||||
}
|
||||
}
|
||||
|
||||
let { open = $bindable(), email = $bindable() }: Props = $props();
|
||||
</script>
|
||||
|
||||
<Dialog bind:open>
|
||||
<DialogContent class="sm:max-w-md">
|
||||
<DialogHeader class="space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<div
|
||||
class="w-10 h-10 rounded-full bg-gradient-to-br from-primary to-purple-600 flex items-center justify-center shrink-0 grow-0"
|
||||
>
|
||||
<span class="icon-[ri--newspaper-line]"></span>
|
||||
</div>
|
||||
<div class="">
|
||||
<DialogTitle
|
||||
class="text-left text-xl font-semibold text-primary-foreground"
|
||||
>{$_('newsletter_signup.title')}</DialogTitle
|
||||
>
|
||||
<DialogDescription class="text-left text-sm">
|
||||
{$_('newsletter_signup.description')}
|
||||
</DialogDescription>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DialogHeader>
|
||||
|
||||
<Separator class="my-4" />
|
||||
|
||||
<form onsubmit={handleSubscription}>
|
||||
<!-- Email -->
|
||||
<div class="space-y-2 flex gap-4 items-center">
|
||||
<Label for="email" class="m-0">{$_('newsletter_signup.email')}</Label>
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
placeholder={$_('newsletter_signup.email_placeholder')}
|
||||
bind:value={email}
|
||||
required
|
||||
class="bg-background/50 border-primary/20 focus:border-primary"
|
||||
/>
|
||||
</div>
|
||||
<Separator class="my-8" />
|
||||
|
||||
<!-- Close Button -->
|
||||
<div class="flex justify-end gap-4">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onclick={() => (open = false)}
|
||||
class="text-muted-foreground hover:text-foreground cursor-pointer"
|
||||
>
|
||||
<span class="icon-[ri--close-large-line]"></span>
|
||||
{$_('newsletter_signup.close')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
type="submit"
|
||||
class="cursor-pointer"
|
||||
disabled={isLoading}
|
||||
>
|
||||
{#if isLoading}
|
||||
<div
|
||||
class="w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin mr-2"
|
||||
></div>
|
||||
{$_('newsletter_signup.subscribing')}
|
||||
{:else}
|
||||
<span class="icon-[ri--check-line]"></span>
|
||||
{$_('newsletter_signup.subscribe')}
|
||||
{/if}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
@@ -1,26 +0,0 @@
|
||||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
import { Button } from "../ui/button";
|
||||
import { Card, CardContent } from "../ui/card";
|
||||
import NewsletterSignupPopup from "./newsletter-signup-popup.svelte";
|
||||
let isPopupOpen = $state(false);
|
||||
|
||||
let { email = "" } = $props();
|
||||
</script>
|
||||
|
||||
<!-- Newsletter Signup -->
|
||||
<Card class="p-0 not-last:bg-gradient-to-br from-primary/10 to-accent/10">
|
||||
<CardContent class="p-6 text-center">
|
||||
<h3 class="font-semibold mb-2">{$_('newsletter_signup.title')}</h3>
|
||||
<p class="text-sm text-muted-foreground mb-4">
|
||||
{$_('newsletter_signup.description')}
|
||||
</p>
|
||||
<Button
|
||||
onclick={() => (isPopupOpen = true)}
|
||||
target="_blank"
|
||||
class="cursor-pointer w-full bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90"
|
||||
>{$_('newsletter_signup.cta')}</Button
|
||||
>
|
||||
<NewsletterSignupPopup bind:open={isPopupOpen} {email} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -870,18 +870,6 @@ export default {
|
||||
exit: "Exit",
|
||||
exit_url: "https://pivoine.art",
|
||||
},
|
||||
newsletter_signup: {
|
||||
title: "Stay Updated",
|
||||
description:
|
||||
"Get the latest articles and insights delivered to your inbox.",
|
||||
email: "Email",
|
||||
email_placeholder: "your@email.com",
|
||||
cta: "Subscribe to Newsletter",
|
||||
close: "Close",
|
||||
subscribe: "Subscribe",
|
||||
subscribing: "Subscribing",
|
||||
toast_subscribe: "Your email has been added to the newsletter list!",
|
||||
},
|
||||
sharing_popup_button: {
|
||||
share: "Share",
|
||||
},
|
||||
|
||||
@@ -123,7 +123,6 @@ class Logger {
|
||||
PUBLIC_API_URL: process.env.PUBLIC_API_URL,
|
||||
PUBLIC_URL: process.env.PUBLIC_URL,
|
||||
PUBLIC_UMAMI_ID: process.env.PUBLIC_UMAMI_ID ? '***set***' : 'not set',
|
||||
LETTERSPACE_API_URL: process.env.LETTERSPACE_API_URL || 'not set',
|
||||
PORT: process.env.PORT || '3000',
|
||||
HOST: process.env.HOST || '0.0.0.0',
|
||||
};
|
||||
|
||||
@@ -9,7 +9,6 @@ import { getAssetUrl } from "$lib/directus";
|
||||
import SharingPopup from "$lib/components/sharing-popup/sharing-popup.svelte";
|
||||
import Meta from "$lib/components/meta/meta.svelte";
|
||||
import PeonyBackground from "$lib/components/background/peony-background.svelte";
|
||||
import NewsletterSignup from "$lib/components/newsletter-signup/newsletter-signup-widget.svelte";
|
||||
import SharingPopupButton from "$lib/components/sharing-popup/sharing-popup-button.svelte";
|
||||
|
||||
const { data } = $props();
|
||||
@@ -215,8 +214,6 @@ const timeAgo = new TimeAgo("en");
|
||||
</Card>
|
||||
-->
|
||||
|
||||
<!-- <NewsletterSignup email={data.authStatus.user?.email}/> -->
|
||||
|
||||
<!-- Back to Magazine -->
|
||||
<Button
|
||||
variant="outline"
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import {
|
||||
LETTERSPACE_API_KEY,
|
||||
LETTERSPACE_API_URL,
|
||||
LETTERSPACE_LIST_ID,
|
||||
} from "$env/static/private";
|
||||
import { json } from "@sveltejs/kit";
|
||||
|
||||
export async function POST({ request, fetch }) {
|
||||
const { email } = await request.json();
|
||||
const lists = [LETTERSPACE_LIST_ID];
|
||||
|
||||
await fetch(`${LETTERSPACE_API_URL}/subscribers`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-API-Key": LETTERSPACE_API_KEY,
|
||||
},
|
||||
body: JSON.stringify({ email, lists }),
|
||||
});
|
||||
|
||||
return json({ email }, { status: 201 });
|
||||
}
|
||||
@@ -16,7 +16,6 @@ import { formatVideoDuration, getUserInitials } from "$lib/utils";
|
||||
import { invalidateAll } from "$app/navigation";
|
||||
import { toast } from "svelte-sonner";
|
||||
import { createCommentForVideo, likeVideo, unlikeVideo, recordVideoPlay, updateVideoPlay } from "$lib/services";
|
||||
import NewsletterSignup from "$lib/components/newsletter-signup/newsletter-signup-widget.svelte";
|
||||
import SharingPopupButton from "$lib/components/sharing-popup/sharing-popup-button.svelte";
|
||||
|
||||
const { data } = $props();
|
||||
@@ -539,8 +538,6 @@ let showPlayer = $state(false);
|
||||
</CardContent>
|
||||
</Card> -->
|
||||
|
||||
<!-- <NewsletterSignup /> -->
|
||||
|
||||
<!-- Back to Videos -->
|
||||
<Button
|
||||
variant="outline"
|
||||
|
||||
Reference in New Issue
Block a user