Refine guest v2 gallery empty states
This commit is contained in:
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { Button } from '@tamagui/button';
|
||||
import { Image as ImageIcon, Filter } from 'lucide-react';
|
||||
import { Camera, Image as ImageIcon, Filter } from 'lucide-react';
|
||||
import AppShell from '../components/AppShell';
|
||||
import PhotoFrameTile from '../components/PhotoFrameTile';
|
||||
import { useEventData } from '../context/EventDataContext';
|
||||
@@ -56,6 +56,7 @@ export default function GalleryScreen() {
|
||||
const [loading, setLoading] = React.useState(false);
|
||||
const { data: delta } = usePollGalleryDelta(token ?? null, { locale });
|
||||
const [filter, setFilter] = React.useState<GalleryFilter>('latest');
|
||||
const uploadPath = React.useMemo(() => buildEventPath(token ?? null, '/upload'), [token]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!token) {
|
||||
@@ -139,6 +140,8 @@ export default function GalleryScreen() {
|
||||
const displayPhotos = filteredPhotos;
|
||||
const leftColumn = displayPhotos.filter((_, index) => index % 2 === 0);
|
||||
const rightColumn = displayPhotos.filter((_, index) => index % 2 === 1);
|
||||
const isEmpty = !loading && displayPhotos.length === 0;
|
||||
const isSingle = !loading && displayPhotos.length === 1;
|
||||
|
||||
React.useEffect(() => {
|
||||
if (filter === 'photobooth' && !photos.some((photo) => photo.ingestSource === 'photobooth')) {
|
||||
@@ -265,10 +268,88 @@ export default function GalleryScreen() {
|
||||
</XStack>
|
||||
</YStack>
|
||||
|
||||
<XStack gap="$3">
|
||||
<YStack flex={1} gap="$3">
|
||||
{(loading || leftColumn.length === 0 ? Array.from({ length: 5 }, (_, index) => index) : leftColumn).map(
|
||||
(tile, index) => {
|
||||
{isEmpty ? (
|
||||
<YStack
|
||||
padding="$4"
|
||||
borderRadius="$card"
|
||||
backgroundColor="$surface"
|
||||
borderWidth={1}
|
||||
borderColor={cardBorder}
|
||||
gap="$3"
|
||||
alignItems="center"
|
||||
style={{
|
||||
boxShadow: cardShadow,
|
||||
}}
|
||||
>
|
||||
<YStack
|
||||
width={64}
|
||||
height={64}
|
||||
borderRadius={20}
|
||||
backgroundColor="$primary"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
style={{ boxShadow: cardShadow }}
|
||||
>
|
||||
<Camera size={28} color="#FFFFFF" />
|
||||
</YStack>
|
||||
<Text fontSize="$4" fontWeight="$7" textAlign="center">
|
||||
{t('galleryPage.emptyTitle', 'Noch keine Fotos')}
|
||||
</Text>
|
||||
<Text fontSize="$2" color="$color" opacity={0.7} textAlign="center">
|
||||
{t('galleryPage.emptyDescription', 'Lade das erste Foto hoch und starte die Galerie.')}
|
||||
</Text>
|
||||
<Button
|
||||
size="$3"
|
||||
backgroundColor="$primary"
|
||||
borderRadius="$pill"
|
||||
onPress={() => navigate(uploadPath)}
|
||||
>
|
||||
<Text fontSize="$2" fontWeight="$7" color="#FFFFFF">
|
||||
{t('galleryPage.emptyCta', 'Foto hochladen')}
|
||||
</Text>
|
||||
</Button>
|
||||
</YStack>
|
||||
) : isSingle ? (
|
||||
<YStack gap="$3">
|
||||
<Button unstyled onPress={() => openLightbox(displayPhotos[0].id)}>
|
||||
<PhotoFrameTile height={360} borderRadius="$card">
|
||||
<YStack flex={1} width="100%" height="100%" alignItems="center" justifyContent="center">
|
||||
<img
|
||||
src={displayPhotos[0].imageUrl}
|
||||
alt={t('galleryPage.photo.alt', { id: displayPhotos[0].id }, 'Photo {id}')}
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||||
/>
|
||||
</YStack>
|
||||
</PhotoFrameTile>
|
||||
</Button>
|
||||
<Button unstyled onPress={() => navigate(uploadPath)}>
|
||||
<PhotoFrameTile height={160} borderRadius="$card">
|
||||
<YStack flex={1} alignItems="center" justifyContent="center" gap="$2" padding="$3">
|
||||
<YStack
|
||||
width={48}
|
||||
height={48}
|
||||
borderRadius={16}
|
||||
backgroundColor="$primary"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
style={{ boxShadow: cardShadow }}
|
||||
>
|
||||
<Camera size={20} color="#FFFFFF" />
|
||||
</YStack>
|
||||
<Text fontSize="$3" fontWeight="$7" textAlign="center">
|
||||
{t('galleryPage.promptTitle', 'Füge dein nächstes Foto hinzu')}
|
||||
</Text>
|
||||
<Text fontSize="$2" color="$color" opacity={0.7} textAlign="center">
|
||||
{t('galleryPage.promptDescription', 'Teile den Moment mit allen Gästen.')}
|
||||
</Text>
|
||||
</YStack>
|
||||
</PhotoFrameTile>
|
||||
</Button>
|
||||
</YStack>
|
||||
) : (
|
||||
<XStack gap="$3">
|
||||
<YStack flex={1} gap="$3">
|
||||
{(loading ? Array.from({ length: 5 }, (_, index) => index) : leftColumn).map((tile, index) => {
|
||||
if (typeof tile === 'number') {
|
||||
return <PhotoFrameTile key={`left-${tile}`} height={140 + (index % 3) * 24} shimmer shimmerDelayMs={200 + index * 120} />;
|
||||
}
|
||||
@@ -289,12 +370,10 @@ export default function GalleryScreen() {
|
||||
</PhotoFrameTile>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</YStack>
|
||||
<YStack flex={1} gap="$3">
|
||||
{(loading || rightColumn.length === 0 ? Array.from({ length: 5 }, (_, index) => index) : rightColumn).map(
|
||||
(tile, index) => {
|
||||
})}
|
||||
</YStack>
|
||||
<YStack flex={1} gap="$3">
|
||||
{(loading ? Array.from({ length: 5 }, (_, index) => index) : rightColumn).map((tile, index) => {
|
||||
if (typeof tile === 'number') {
|
||||
return <PhotoFrameTile key={`right-${tile}`} height={120 + (index % 3) * 28} shimmer shimmerDelayMs={260 + index * 140} />;
|
||||
}
|
||||
@@ -315,10 +394,35 @@ export default function GalleryScreen() {
|
||||
</PhotoFrameTile>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</YStack>
|
||||
</XStack>
|
||||
})}
|
||||
{!loading && rightColumn.length === 0 ? (
|
||||
<Button unstyled onPress={() => navigate(uploadPath)}>
|
||||
<PhotoFrameTile height={180}>
|
||||
<YStack flex={1} alignItems="center" justifyContent="center" gap="$2" padding="$3">
|
||||
<YStack
|
||||
width={46}
|
||||
height={46}
|
||||
borderRadius={16}
|
||||
backgroundColor="$primary"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
style={{ boxShadow: cardShadow }}
|
||||
>
|
||||
<Camera size={20} color="#FFFFFF" />
|
||||
</YStack>
|
||||
<Text fontSize="$3" fontWeight="$7" textAlign="center">
|
||||
{t('galleryPage.promptTitle', 'Füge dein nächstes Foto hinzu')}
|
||||
</Text>
|
||||
<Text fontSize="$2" color="$color" opacity={0.7} textAlign="center">
|
||||
{t('galleryPage.promptDescription', 'Teile den Moment mit allen Gästen.')}
|
||||
</Text>
|
||||
</YStack>
|
||||
</PhotoFrameTile>
|
||||
</Button>
|
||||
) : null}
|
||||
</YStack>
|
||||
</XStack>
|
||||
)}
|
||||
|
||||
<YStack
|
||||
padding="$4"
|
||||
|
||||
Reference in New Issue
Block a user