Files
fotospiel-app/resources/js/admin/mobile/components/MobileInstallBanner.tsx

90 lines
3.0 KiB
TypeScript

import React from 'react';
import { Download, Share2, X } from 'lucide-react';
import { YStack, XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { Pressable } from '@tamagui/react-native-web-lite';
import { InstallBannerState } from '../lib/installBanner';
import { CTAButton, MobileCard } from './Primitives';
import { useTranslation } from 'react-i18next';
import { useAdminTheme } from '../theme';
type MobileInstallBannerProps = {
state: InstallBannerState | null;
onInstall?: () => void;
onDismiss?: () => void;
density?: 'default' | 'compact';
};
export function MobileInstallBanner({
state,
onInstall,
onDismiss,
density = 'default',
}: MobileInstallBannerProps) {
const { t } = useTranslation('common');
const { textStrong, muted, border, primary, surfaceMuted, accentSoft } = useAdminTheme();
if (!state) {
return null;
}
const isPrompt = state.variant === 'prompt';
const isCompact = density === 'compact';
return (
<MobileCard
space={isCompact ? '$1.5' : '$2'}
borderColor={border}
backgroundColor={surfaceMuted}
padding={isCompact ? '$2' : '$3'}
>
<XStack alignItems="center" justifyContent="space-between" gap="$2">
<XStack alignItems="center" space="$2" flex={1}>
<XStack
width={isCompact ? 32 : 36}
height={isCompact ? 32 : 36}
borderRadius={12}
alignItems="center"
justifyContent="center"
backgroundColor={accentSoft}
>
{isPrompt ? <Download size={16} color={primary} /> : <Share2 size={16} color={primary} />}
</XStack>
<YStack flex={1} space="$0.5">
<Text fontSize={isCompact ? '$xs' : '$sm'} fontWeight="800" color={textStrong}>
{t('installBanner.title', 'Install Fotospiel Admin')}
</Text>
<Text fontSize={isCompact ? 10 : '$xs'} color={muted}>
{isPrompt
? t('installBanner.body', 'Add the app to your home screen for faster access and offline support.')
: t('installBanner.iosHint', 'On iOS: Share → Add to Home Screen.')}
</Text>
</YStack>
</XStack>
<XStack alignItems="center" space="$2">
{isPrompt && onInstall && isCompact ? (
<Pressable onPress={onInstall}>
<Text fontSize={10} fontWeight="700" color={primary}>
{t('installBanner.action', 'Install')}
</Text>
</Pressable>
) : null}
{onDismiss ? (
<Pressable onPress={onDismiss} aria-label={t('actions.dismiss', 'Dismiss')}>
<X size={14} color={muted} />
</Pressable>
) : null}
</XStack>
</XStack>
{isPrompt && onInstall && !isCompact ? (
<CTAButton
label={t('installBanner.action', 'Install')}
onPress={onInstall}
fullWidth={false}
tone="ghost"
/>
) : null}
</MobileCard>
);
}