Build RoomScan AI starter app
This commit is contained in:
54
src/components/InstructionOverlay.tsx
Normal file
54
src/components/InstructionOverlay.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
|
||||
import { colors } from '../theme/colors';
|
||||
|
||||
type InstructionOverlayProps = {
|
||||
title: string;
|
||||
detail: string;
|
||||
tone?: 'info' | 'warning' | 'danger';
|
||||
};
|
||||
|
||||
export function InstructionOverlay({ title, detail, tone = 'info' }: InstructionOverlayProps) {
|
||||
const toneColor = tone === 'warning' ? colors.warning : tone === 'danger' ? colors.danger : colors.primary;
|
||||
|
||||
return (
|
||||
<View style={[styles.container, { borderColor: toneColor }]}>
|
||||
<View style={[styles.indicator, { backgroundColor: toneColor }]} />
|
||||
<View style={styles.textBlock}>
|
||||
<Text style={styles.title}>{title}</Text>
|
||||
<Text style={styles.detail}>{detail}</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'rgba(8, 17, 31, 0.92)',
|
||||
borderRadius: 20,
|
||||
borderWidth: 1,
|
||||
flexDirection: 'row',
|
||||
gap: 14,
|
||||
padding: 16,
|
||||
},
|
||||
indicator: {
|
||||
borderRadius: 999,
|
||||
height: 14,
|
||||
width: 14,
|
||||
},
|
||||
textBlock: {
|
||||
flex: 1,
|
||||
},
|
||||
title: {
|
||||
color: colors.textPrimary,
|
||||
fontSize: 16,
|
||||
fontWeight: '800',
|
||||
},
|
||||
detail: {
|
||||
color: colors.textSecondary,
|
||||
fontSize: 13,
|
||||
lineHeight: 19,
|
||||
marginTop: 4,
|
||||
},
|
||||
});
|
||||
51
src/components/PrimaryButton.tsx
Normal file
51
src/components/PrimaryButton.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Pressable, StyleSheet, Text } from 'react-native';
|
||||
|
||||
import { colors } from '../theme/colors';
|
||||
|
||||
type PrimaryButtonProps = {
|
||||
label: string;
|
||||
onPress: () => void;
|
||||
variant?: 'primary' | 'secondary';
|
||||
};
|
||||
|
||||
export function PrimaryButton({ label, onPress, variant = 'primary' }: PrimaryButtonProps) {
|
||||
return (
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
onPress={onPress}
|
||||
style={({ pressed }) => [
|
||||
styles.button,
|
||||
variant === 'secondary' && styles.secondary,
|
||||
pressed && styles.pressed,
|
||||
]}
|
||||
>
|
||||
<Text style={[styles.label, variant === 'secondary' && styles.secondaryLabel]}>{label}</Text>
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
button: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: colors.primary,
|
||||
borderRadius: 18,
|
||||
paddingHorizontal: 22,
|
||||
paddingVertical: 16,
|
||||
},
|
||||
secondary: {
|
||||
backgroundColor: colors.surfaceRaised,
|
||||
borderColor: colors.border,
|
||||
borderWidth: 1,
|
||||
},
|
||||
pressed: {
|
||||
opacity: 0.82,
|
||||
},
|
||||
label: {
|
||||
color: colors.background,
|
||||
fontSize: 16,
|
||||
fontWeight: '800',
|
||||
},
|
||||
secondaryLabel: {
|
||||
color: colors.textPrimary,
|
||||
},
|
||||
});
|
||||
62
src/components/ScanProgressCard.tsx
Normal file
62
src/components/ScanProgressCard.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
|
||||
import { colors } from '../theme/colors';
|
||||
|
||||
type ScanProgressCardProps = {
|
||||
progress: number;
|
||||
};
|
||||
|
||||
export function ScanProgressCard({ progress }: ScanProgressCardProps) {
|
||||
return (
|
||||
<View style={styles.card}>
|
||||
<View style={styles.row}>
|
||||
<Text style={styles.label}>Scan-Fortschritt</Text>
|
||||
<Text style={styles.value}>{progress}%</Text>
|
||||
</View>
|
||||
<View style={styles.track}>
|
||||
<View style={[styles.fill, { width: `${progress}%` }]} />
|
||||
</View>
|
||||
<Text style={styles.hint}>Halte das iPhone ruhig und bewege dich entlang der Wandkontur.</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
card: {
|
||||
backgroundColor: colors.surface,
|
||||
borderColor: colors.border,
|
||||
borderRadius: 22,
|
||||
borderWidth: 1,
|
||||
padding: 18,
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
label: {
|
||||
color: colors.textSecondary,
|
||||
fontSize: 14,
|
||||
},
|
||||
value: {
|
||||
color: colors.textPrimary,
|
||||
fontSize: 18,
|
||||
fontWeight: '800',
|
||||
},
|
||||
track: {
|
||||
backgroundColor: colors.surfaceRaised,
|
||||
borderRadius: 999,
|
||||
height: 10,
|
||||
marginTop: 14,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
fill: {
|
||||
backgroundColor: colors.accent,
|
||||
height: '100%',
|
||||
},
|
||||
hint: {
|
||||
color: colors.textSecondary,
|
||||
fontSize: 13,
|
||||
lineHeight: 19,
|
||||
marginTop: 14,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user