Add photobooth uploader download email

This commit is contained in:
Codex Agent
2026-01-13 09:59:39 +01:00
parent 775786c6f1
commit 5f3d6af9f0
12 changed files with 309 additions and 1 deletions

View File

@@ -2068,6 +2068,13 @@ export async function createEventPhotoboothConnectCode(
};
}
export async function sendEventPhotoboothUploaderEmail(slug: string): Promise<void> {
const response = await authorizedFetch(`${photoboothEndpoint(slug)}/uploader-email`, {
method: 'POST',
});
await jsonOrThrow<{ message?: string }>(response, 'Failed to send photobooth uploader email');
}
export async function submitTenantFeedback(payload: {
category: string;
sentiment?: 'positive' | 'neutral' | 'negative';

View File

@@ -1211,6 +1211,9 @@
"uploaderDownload": {
"title": "Fotospiel Uploader App",
"description": "Die Fotospiel Uploader App wird benötigt, damit Uploads stabil laufen, die Zugangsdaten geschützt bleiben und keine Dateien verloren gehen.",
"emailAction": "Download-Links per E-Mail senden",
"emailSuccess": "Download-Links wurden per E-Mail gesendet.",
"emailFailed": "E-Mail konnte nicht gesendet werden.",
"actionWindows": "Uploader herunterladen (Windows)",
"actionMac": "Uploader herunterladen (macOS)",
"actionLinux": "Uploader herunterladen (Linux)"

View File

@@ -924,6 +924,9 @@
"uploaderDownload": {
"title": "Fotospiel Uploader App",
"description": "The Fotospiel Uploader App is required so uploads stay stable, credentials remain protected, and no files are lost.",
"emailAction": "Send download links by email",
"emailSuccess": "Download links were sent by email.",
"emailFailed": "Email could not be sent.",
"actionWindows": "Download uploader (Windows)",
"actionMac": "Download uploader (macOS)",
"actionLinux": "Download uploader (Linux)"

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { RefreshCcw, PlugZap, RefreshCw, ShieldCheck, Copy, Power, Clock3 } from 'lucide-react';
import { RefreshCcw, PlugZap, RefreshCw, ShieldCheck, Copy, Power, Clock3, Mail } from 'lucide-react';
import { YStack, XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { Switch } from '@tamagui/switch';
@@ -15,6 +15,7 @@ import {
disableEventPhotobooth,
rotateEventPhotobooth,
createEventPhotoboothConnectCode,
sendEventPhotoboothUploaderEmail,
PhotoboothStatus,
TenantEvent,
} from '../api';
@@ -41,6 +42,7 @@ export default function MobileEventPhotoboothPage() {
const [connectCode, setConnectCode] = React.useState<string | null>(null);
const [connectExpiresAt, setConnectExpiresAt] = React.useState<string | null>(null);
const [connectLoading, setConnectLoading] = React.useState(false);
const [sendingEmail, setSendingEmail] = React.useState(false);
const [showCredentials, setShowCredentials] = React.useState(false);
const back = useBackNavigation(slug ? adminPath(`/mobile/events/${slug}`) : adminPath('/mobile/events'));
@@ -138,6 +140,23 @@ export default function MobileEventPhotoboothPage() {
}
};
const handleSendDownloadEmail = async () => {
if (!slug) return;
setSendingEmail(true);
try {
await sendEventPhotoboothUploaderEmail(slug);
toast.success(t('photobooth.uploaderDownload.emailSuccess', 'Download-Links wurden per E-Mail gesendet.'));
} catch (err) {
if (!isAuthError(err)) {
toast.error(
getApiErrorMessage(err, t('photobooth.uploaderDownload.emailFailed', 'E-Mail konnte nicht gesendet werden.'))
);
}
} finally {
setSendingEmail(false);
}
};
const spark = status?.sparkbooth ?? null;
const metrics = spark?.metrics ?? null;
const expiresAt = spark?.expires_at ?? status?.expires_at;
@@ -261,6 +280,17 @@ export default function MobileEventPhotoboothPage() {
'Die Fotospiel Uploader App ist verpflichtend, damit Uploads stabil laufen, die Zugangsdaten geschützt bleiben und keine Dateien verloren gehen.'
)}
</Text>
<CTAButton
label={
sendingEmail
? t('common.processing', '...')
: t('photobooth.uploaderDownload.emailAction', 'Download-Links per E-Mail senden')
}
tone="ghost"
onPress={handleSendDownloadEmail}
iconLeft={<Mail size={14} color={text} />}
disabled={sendingEmail}
/>
<CTAButton
label={t('photobooth.uploaderDownload.actionWindows', 'Uploader herunterladen (Windows)')}
onPress={() => {