Build RoomScan AI starter app

This commit is contained in:
Ismail Ali
2026-04-28 11:43:56 +02:00
parent 306c93fb47
commit bdc0c97431
16 changed files with 1071 additions and 18 deletions

View 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,
},
});

View 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,
},
});

View 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,
},
});