Update guest PWA v2 UI and likes
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-02-05 15:09:19 +01:00
parent 6eafec2128
commit fa630e335d
22 changed files with 1288 additions and 200 deletions

View File

@@ -14,8 +14,8 @@ import { useGuestTaskProgress } from '@/guest/hooks/useGuestTaskProgress';
import { fetchPendingUploadsSummary, type PendingUpload } from '@/guest/services/pendingUploadsApi';
import { resolveUploadErrorDialog, type UploadErrorDialog } from '@/guest/lib/uploadErrorDialog';
import { fetchTasks, type TaskItem } from '../services/tasksApi';
import SurfaceCard from '../components/SurfaceCard';
import { pushGuestToast } from '../lib/toast';
import { getBentoSurfaceTokens } from '../lib/bento';
function getTaskValue(task: TaskItem, key: string): string | undefined {
const value = task?.[key as keyof TaskItem];
@@ -51,8 +51,12 @@ export default function UploadScreen() {
const [previewFile, setPreviewFile] = React.useState<File | null>(null);
const [previewUrl, setPreviewUrl] = React.useState<string | null>(null);
const { isDark } = useGuestThemeVariant();
const cardBorder = isDark ? 'rgba(255, 255, 255, 0.12)' : 'rgba(15, 23, 42, 0.12)';
const cardShadow = isDark ? '0 18px 40px rgba(2, 6, 23, 0.4)' : '0 16px 30px rgba(15, 23, 42, 0.12)';
const bentoSurface = getBentoSurfaceTokens(isDark);
const cardBorder = bentoSurface.borderColor;
const cardShadow = bentoSurface.shadow;
const hardShadow = isDark
? '0 18px 0 rgba(2, 6, 23, 0.55), 0 32px 40px rgba(2, 6, 23, 0.55)'
: '0 18px 0 rgba(15, 23, 42, 0.22), 0 30px 36px rgba(15, 23, 42, 0.2)';
const iconColor = isDark ? '#F8FAFF' : '#0F172A';
const mutedButton = isDark ? 'rgba(255, 255, 255, 0.08)' : 'rgba(15, 23, 42, 0.06)';
const mutedButtonBorder = isDark ? 'rgba(255, 255, 255, 0.2)' : 'rgba(15, 23, 42, 0.12)';
@@ -448,7 +452,19 @@ export default function UploadScreen() {
<AppShell>
<YStack gap="$4">
{taskId ? (
<SurfaceCard>
<YStack
padding="$3"
borderRadius="$bentoLg"
backgroundColor={bentoSurface.backgroundColor}
borderWidth={1}
borderBottomWidth={3}
borderColor={bentoSurface.borderColor}
borderBottomColor={bentoSurface.borderBottomColor}
gap="$2"
style={{
boxShadow: hardShadow,
}}
>
<XStack alignItems="center" gap="$2">
<Sparkles size={18} color={iconColor} />
<Text fontSize="$3" fontWeight="$7">
@@ -475,27 +491,21 @@ export default function UploadScreen() {
{taskError}
</Text>
) : null}
</SurfaceCard>
</YStack>
) : null}
<YStack
borderRadius="$card"
backgroundColor="$muted"
borderRadius="$bentoLg"
backgroundColor={bentoSurface.backgroundColor}
borderWidth={1}
borderColor={cardBorder}
borderBottomWidth={3}
borderColor={bentoSurface.borderColor}
borderBottomColor={bentoSurface.borderBottomColor}
overflow="hidden"
style={{
backgroundImage: isDark
? 'linear-gradient(135deg, rgba(15, 23, 42, 0.7), rgba(8, 12, 24, 0.9)), radial-gradient(circle at 20% 20%, rgba(255, 79, 216, 0.2), transparent 50%)'
: 'linear-gradient(135deg, rgba(255, 255, 255, 0.92), rgba(248, 250, 255, 0.82)), radial-gradient(circle at 20% 20%, color-mix(in oklab, var(--guest-primary, #FF5A5F) 16%, white), transparent 60%)',
boxShadow: isExpanded
? isDark
? '0 28px 60px rgba(2, 6, 23, 0.55)'
: '0 22px 44px rgba(15, 23, 42, 0.16)'
: isDark
? '0 22px 40px rgba(2, 6, 23, 0.5)'
: '0 18px 32px rgba(15, 23, 42, 0.12)',
borderRadius: isExpanded ? 28 : undefined,
transition: 'box-shadow 360ms ease, border-radius 360ms ease',
? 'radial-gradient(120% 120% at 12% 15%, rgba(56, 189, 248, 0.18), transparent 55%), radial-gradient(130% 130% at 88% 10%, rgba(251, 113, 133, 0.2), transparent 60%)'
: 'radial-gradient(120% 120% at 12% 15%, color-mix(in oklab, var(--guest-primary, #0EA5E9) 18%, white), transparent 55%), radial-gradient(130% 130% at 88% 10%, color-mix(in oklab, var(--guest-secondary, #F43F5E) 18%, white), transparent 60%)',
boxShadow: hardShadow,
}}
>
<YStack
@@ -697,61 +707,86 @@ export default function UploadScreen() {
</YStack>
) : null}
</YStack>
<XStack
gap="$2"
padding={isExpanded ? '$2' : '$3'}
alignItems="center"
justifyContent="space-between"
borderTopWidth={1}
borderColor={cardBorder}
backgroundColor={isDark ? 'rgba(10, 14, 28, 0.7)' : 'rgba(255, 255, 255, 0.75)'}
>
{cameraState === 'preview' ? null : (
<>
<Button
size="$3"
borderRadius="$pill"
backgroundColor={mutedButton}
borderWidth={1}
borderColor={mutedButtonBorder}
onPress={handlePick}
paddingHorizontal="$4"
gap="$2"
alignSelf="center"
flexShrink={0}
justifyContent="center"
>
<Image size={16} color={iconColor} />
<Text fontSize="$2" fontWeight="$6">
{t('uploadV2.galleryCta', 'Upload from gallery')}
</Text>
</Button>
{facingMode === 'user' ? (
<Button
size="$3"
circular
backgroundColor={mirror ? '$primary' : mutedButton}
borderWidth={1}
borderColor={mutedButtonBorder}
onPress={() => setMirror((prev) => !prev)}
>
<FlipHorizontal size={16} color={mirror ? '#FFFFFF' : iconColor} />
</Button>
) : null}
</>
)}
</XStack>
</YStack>
{cameraState === 'preview' ? null : (
<XStack gap="$2">
<Button
flex={1}
height={64}
borderRadius="$bento"
backgroundColor={bentoSurface.backgroundColor}
borderWidth={1}
borderBottomWidth={3}
borderColor={bentoSurface.borderColor}
borderBottomColor={bentoSurface.borderBottomColor}
onPress={() => {
if (cameraState === 'ready') {
void handleCapture();
return;
}
void startCamera();
}}
disabled={cameraState === 'starting' || cameraState === 'blocked' || cameraState === 'unsupported'}
style={{ boxShadow: cardShadow }}
>
<XStack alignItems="center" gap="$2">
<Camera size={18} color={iconColor} />
<Text fontSize="$3" fontWeight="$7">
{cameraState === 'ready'
? t('upload.captureButton', 'Foto aufnehmen')
: cameraState === 'starting'
? t('upload.buttons.starting', 'Kamera startet…')
: t('upload.buttons.startCamera', 'Kamera starten')}
</Text>
</XStack>
</Button>
<Button
flex={1}
height={64}
borderRadius="$bento"
backgroundColor={bentoSurface.backgroundColor}
borderWidth={1}
borderBottomWidth={3}
borderColor={bentoSurface.borderColor}
borderBottomColor={bentoSurface.borderBottomColor}
onPress={handlePick}
style={{ boxShadow: cardShadow }}
>
<XStack alignItems="center" gap="$2">
<Image size={18} color={iconColor} />
<Text fontSize="$3" fontWeight="$7">
{t('uploadV2.galleryCta', 'Aus Galerie')}
</Text>
</XStack>
</Button>
{facingMode === 'user' ? (
<Button
size="$3"
circular
backgroundColor={mirror ? '$primary' : mutedButton}
borderWidth={1}
borderBottomWidth={3}
borderColor={mutedButtonBorder}
borderBottomColor={mutedButtonBorder}
onPress={() => setMirror((prev) => !prev)}
>
<FlipHorizontal size={16} color={mirror ? '#FFFFFF' : iconColor} />
</Button>
) : null}
</XStack>
)}
<YStack
padding="$4"
borderRadius="$card"
backgroundColor="$surface"
borderRadius="$bentoLg"
backgroundColor={bentoSurface.backgroundColor}
borderWidth={1}
borderColor={cardBorder}
borderBottomWidth={3}
borderColor={bentoSurface.borderColor}
borderBottomColor={bentoSurface.borderBottomColor}
gap="$2"
style={{
boxShadow: cardShadow,
boxShadow: hardShadow,
}}
>
<Text fontSize="$4" fontWeight="$7">