Mobile App design
Run Tests on Branches / Detect Changes (push) Successful in 10s
Run Tests on Branches / Backend Tests (push) Successful in 2m12s
Run Tests on Branches / Frontend Tests (push) Has been skipped
Run Tests on Branches / Frontend Mobile Tests (push) Successful in 1m47s

This commit is contained in:
Ichitux
2026-07-09 13:33:54 +02:00
parent 5f604b11ba
commit 2f36ef685d
32 changed files with 1793 additions and 926 deletions
@@ -2,7 +2,8 @@ import React, { useState } from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import { CameraView, useCameraPermissions } from 'expo-camera';
import { Ionicons } from '@expo/vector-icons';
import { colors, spacing, borderRadius } from '../constants/theme';
import { useThemeContext } from './ThemeProvider';
import { spacing, borderRadius } from '../constants/theme';
interface BarcodeScannerProps {
onBarcodeScanned: (barcode: string) => void;
@@ -12,6 +13,7 @@ interface BarcodeScannerProps {
export function BarcodeScanner({ onBarcodeScanned, onClose }: BarcodeScannerProps) {
const [permission, requestPermission] = useCameraPermissions();
const [scanned, setScanned] = useState(false);
const { colors } = useThemeContext();
if (!permission) {
return <View style={styles.container} />;
@@ -19,17 +21,17 @@ export function BarcodeScanner({ onBarcodeScanned, onClose }: BarcodeScannerProp
if (!permission.granted) {
return (
<View style={styles.permissionContainer}>
<View style={[styles.permissionContainer, { backgroundColor: colors.background }]}>
<Ionicons name="camera" size={64} color={colors.textSecondary} />
<Text style={styles.permissionTitle}>Permiso de cámara requerido</Text>
<Text style={styles.permissionText}>
<Text style={[styles.permissionTitle, { color: colors.text }]}>Permiso de cámara requerido</Text>
<Text style={[styles.permissionText, { color: colors.textSecondary }]}>
Necesitamos acceso a la cámara para escanear códigos de barras
</Text>
<TouchableOpacity style={styles.permissionButton} onPress={requestPermission}>
<TouchableOpacity style={[styles.permissionButton, { backgroundColor: colors.primary }]} onPress={requestPermission}>
<Text style={styles.permissionButtonText}>Conceder permiso</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.cancelButton} onPress={onClose}>
<Text style={styles.cancelButtonText}>Cancelar</Text>
<Text style={[styles.cancelButtonText, { color: colors.textSecondary }]}>Cancelar</Text>
</TouchableOpacity>
</View>
);
@@ -54,10 +56,10 @@ export function BarcodeScanner({ onBarcodeScanned, onClose }: BarcodeScannerProp
<View style={styles.overlay}>
<View style={styles.scannerFrame}>
<View style={[styles.corner, styles.topLeft]} />
<View style={[styles.corner, styles.topRight]} />
<View style={[styles.corner, styles.bottomLeft]} />
<View style={[styles.corner, styles.bottomRight]} />
<View style={[styles.corner, styles.topLeft, { borderColor: colors.primary }]} />
<View style={[styles.corner, styles.topRight, { borderColor: colors.primary }]} />
<View style={[styles.corner, styles.bottomLeft, { borderColor: colors.primary }]} />
<View style={[styles.corner, styles.bottomRight, { borderColor: colors.primary }]} />
</View>
<Text style={styles.instruction}>
@@ -72,7 +74,7 @@ export function BarcodeScanner({ onBarcodeScanned, onClose }: BarcodeScannerProp
{scanned && (
<View style={styles.scannedOverlay}>
<TouchableOpacity
style={styles.scanAgainButton}
style={[styles.scanAgainButton, { backgroundColor: colors.primary }]}
onPress={() => setScanned(false)}
>
<Text style={styles.scanAgainText}>Escanear de nuevo</Text>
@@ -92,30 +94,26 @@ const styles = StyleSheet.create({
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: colors.background,
padding: spacing.xl,
},
permissionTitle: {
fontSize: 20,
fontWeight: 'bold',
color: colors.text,
marginTop: spacing.lg,
},
permissionText: {
fontSize: 16,
color: colors.textSecondary,
textAlign: 'center',
marginTop: spacing.sm,
marginBottom: spacing.xl,
},
permissionButton: {
backgroundColor: colors.primary,
borderRadius: borderRadius.md,
paddingVertical: spacing.md,
paddingHorizontal: spacing.xl,
},
permissionButtonText: {
color: colors.textInverse,
color: '#ffffff',
fontSize: 16,
fontWeight: '600',
},
@@ -123,7 +121,6 @@ const styles = StyleSheet.create({
marginTop: spacing.md,
},
cancelButtonText: {
color: colors.textSecondary,
fontSize: 14,
},
overlay: {
@@ -143,7 +140,6 @@ const styles = StyleSheet.create({
position: 'absolute',
width: 30,
height: 30,
borderColor: colors.primary,
},
topLeft: {
top: 0,
@@ -170,7 +166,7 @@ const styles = StyleSheet.create({
borderRightWidth: 3,
},
instruction: {
color: colors.textInverse,
color: '#ffffff',
fontSize: 14,
textAlign: 'center',
marginTop: spacing.xl,
@@ -194,13 +190,12 @@ const styles = StyleSheet.create({
right: spacing.xl,
},
scanAgainButton: {
backgroundColor: colors.primary,
borderRadius: borderRadius.md,
padding: spacing.md,
alignItems: 'center',
},
scanAgainText: {
color: colors.textInverse,
color: '#ffffff',
fontSize: 16,
fontWeight: '600',
},