Add photobooth connect code UI
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-01-12 17:59:35 +01:00
parent 6edc890e01
commit e32b1fa45a
4 changed files with 100 additions and 0 deletions

View File

@@ -14,6 +14,7 @@ import {
enableEventPhotobooth,
disableEventPhotobooth,
rotateEventPhotobooth,
createEventPhotoboothConnectCode,
PhotoboothStatus,
TenantEvent,
} from '../api';
@@ -38,6 +39,9 @@ export default function MobileEventPhotoboothPage() {
const [loading, setLoading] = React.useState(true);
const [updating, setUpdating] = React.useState(false);
const [error, setError] = React.useState<string | null>(null);
const [connectCode, setConnectCode] = React.useState<string | null>(null);
const [connectExpiresAt, setConnectExpiresAt] = React.useState<string | null>(null);
const [connectLoading, setConnectLoading] = React.useState(false);
const back = useBackNavigation(slug ? adminPath(`/mobile/events/${slug}`) : adminPath('/mobile/events'));
const locale = i18n.language?.startsWith('en') ? 'en-GB' : 'de-DE';
@@ -124,6 +128,25 @@ export default function MobileEventPhotoboothPage() {
}
};
const handleGenerateConnectCode = async () => {
if (!slug) return;
setConnectLoading(true);
try {
const result = await createEventPhotoboothConnectCode(slug);
setConnectCode(result.code || null);
setConnectExpiresAt(result.expires_at ?? null);
toast.success(t('photobooth.connectCode.actions.generated', 'Verbindungscode erstellt'));
} catch (err) {
if (!isAuthError(err)) {
toast.error(
getApiErrorMessage(err, t('photobooth.connectCode.errors.failed', 'Verbindungscode konnte nicht erstellt werden.'))
);
}
} finally {
setConnectLoading(false);
}
};
const activeMode = selectedMode ?? status?.mode ?? 'ftp';
const isSpark = activeMode === 'sparkbooth';
const spark = status?.sparkbooth ?? null;
@@ -286,6 +309,32 @@ export default function MobileEventPhotoboothPage() {
<Text fontSize="$xs" color={muted}>
{t('photobooth.sparkbooth.hint', 'POST with media file or base64 "media" field; username/password required.')}
</Text>
<YStack space="$2" marginTop="$2">
<Text fontSize="$xs" color={muted}>
{t('photobooth.connectCode.description', 'Create a 6-digit code for the uploader app.')}
</Text>
<CTAButton
label={
connectLoading
? t('common.processing', '...')
: t('photobooth.connectCode.actions.generate', 'Generate connect code')
}
onPress={handleGenerateConnectCode}
iconLeft={<PlugZap size={14} color={surface} />}
disabled={!isActive || updating || connectLoading}
style={{ width: '100%', paddingHorizontal: 10, paddingVertical: 10 }}
/>
{connectCode ? (
<CredentialRow label={t('photobooth.connectCode.label', 'Connect code')} value={connectCode} border={border} />
) : null}
{connectExpiresAt ? (
<Text fontSize="$xs" color={muted}>
{t('photobooth.connectCode.expires', 'Expires: {{date}}', {
date: formatEventDate(connectExpiresAt, locale),
})}
</Text>
) : null}
</YStack>
</>
) : (
<>