Files
mindfulness/client/components/onboarding/OnboardingLayout.tsx

136 lines
3.3 KiB
TypeScript

import React from 'react';
import { View, StyleSheet, SafeAreaView, TouchableOpacity, StatusBar, Text, Image, Platform } from 'react-native';
import { useTranslation } from 'react-i18next';
import { OnboardingColors, OnboardingFont } from '@/constants/OnboardingTheme';
interface OnboardingLayoutProps {
children: React.ReactNode;
title?: string;
currentStep: number;
totalSteps: number;
onSkip: () => void;
onBack?: () => void;
showBackButton?: boolean;
}
export function OnboardingLayout({
children,
title,
currentStep,
totalSteps,
onSkip,
onBack,
showBackButton = false
}: OnboardingLayoutProps) {
const { t } = useTranslation();
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
<SafeAreaView style={styles.safeArea}>
{/* Header: Back & Skip */}
<View style={styles.header}>
<View style={styles.headerLeft}>
{showBackButton && onBack && (
<TouchableOpacity onPress={onBack} style={styles.iconButton}>
<Image
source={require('@/assets/images/icon/back_icon.png')}
style={styles.backIcon}
/>
</TouchableOpacity>
)}
</View>
<TouchableOpacity onPress={onSkip} style={styles.skipButton}>
<Text style={styles.skipText}>{t('onboarding.skipAll')}</Text>
<Image
source={require('@/assets/images/icon/skip_icon.png')}
style={styles.skipIcon}
/>
</TouchableOpacity>
</View>
{/* Title & Progress Row */}
<View style={styles.titleRow}>
<Text style={styles.questionTitle}>{title}</Text>
<Text style={styles.progressText}>({currentStep}/{totalSteps})</Text>
</View>
{/* Content */}
<View style={styles.content}>
{children}
</View>
</SafeAreaView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: OnboardingColors.background,
},
safeArea: {
flex: 1,
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: 20,
height: 44,
},
headerLeft: {
width: 44,
height: 44,
justifyContent: 'center',
},
iconButton: {
padding: 8,
},
backIcon: {
width: 19,
height: 19,
resizeMode: 'contain',
},
skipButton: {
flexDirection: 'row',
alignItems: 'center',
padding: 8,
},
skipText: {
fontSize: 13,
color: OnboardingColors.textMuted,
fontFamily: Platform.OS === 'ios' ? 'STIX Two Text' : 'serif',
marginRight: 4,
},
skipIcon: {
width: 10,
height: 4,
resizeMode: 'contain',
},
titleRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'flex-end',
paddingHorizontal: 20,
marginTop: 20,
marginBottom: 20,
},
questionTitle: {
fontSize: 22,
color: OnboardingColors.questionTitle,
fontFamily: OnboardingFont.question,
flex: 1,
},
progressText: {
fontSize: 18,
color: OnboardingColors.textProgress,
fontFamily: OnboardingFont.question,
marginLeft: 10,
},
content: {
flex: 1,
paddingHorizontal: 20,
},
});