feat(mobile): improve login, profile, alerts screens and dark mode background
Run Tests on Branches / Detect Changes (push) Successful in 8s
Run Tests on Branches / Backend Tests (push) Has been skipped
Run Tests on Branches / Frontend Tests (push) Successful in 1m41s
Run Tests on Branches / Frontend Mobile Tests (push) Successful in 1m46s

- Unify login/register into single screen with tab switcher, logo, and themed inputs
- Redesign profile with header card, segmented theme toggle, icon-based menu, and bottom-sheet modals
- Add auth guard to alerts screen showing login prompt instead of 401 error
- Switch ImageBackground to explicit Image+View layering for reliable rendering
- Add dark mode background image switching in root layout
- Add dark mode override for recent-tag in PWA search view
This commit is contained in:
Antoni Nuñez Romeu
2026-07-10 16:39:59 +02:00
parent bf519e43c9
commit 2a7ab64bbf
7 changed files with 763 additions and 1255 deletions
+46 -37
View File
@@ -1,7 +1,7 @@
import { useEffect, useRef } from 'react';
import React, { useEffect, useRef } from 'react';
import { Stack } from 'expo-router';
import { StatusBar } from 'expo-status-bar';
import { ImageBackground, StyleSheet, View } from 'react-native';
import { Image, StyleSheet, View } from 'react-native';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';
@@ -11,6 +11,9 @@ import { ThemeProvider, useThemeContext } from '../components/ThemeProvider';
const queryClient = new QueryClient();
const bgLight = require('../assets/bg.png');
const bgDark = require('../assets/bg_dark.png');
function RootLayoutInner() {
const { checkAuth } = useAuthStore();
const { colors, isDark } = useThemeContext();
@@ -19,17 +22,17 @@ function RootLayoutInner() {
useEffect(() => {
checkAuth();
registerForPushNotifications();
notificationListener.current = addNotificationListener((notification) => {
console.log('Notification received:', notification);
});
responseListener.current = addNotificationResponseListener((response) => {
console.log('Notification clicked:', response);
});
return () => {
notificationListener.current?.remove();
responseListener.current?.remove();
@@ -46,34 +49,34 @@ function RootLayoutInner() {
}}
>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen
name="medicine/[id]"
options={{ title: 'Medicamento' }}
<Stack.Screen
name="medicine/[id]"
options={{ title: 'Medicamento' }}
/>
<Stack.Screen
name="pharmacy/[id]"
options={{ title: 'Farmacia' }}
<Stack.Screen
name="pharmacy/[id]"
options={{ title: 'Farmacia' }}
/>
<Stack.Screen
name="scanner"
options={{
<Stack.Screen
name="scanner"
options={{
title: 'Escanear',
headerShown: false,
}}
}}
/>
<Stack.Screen
name="auth/login"
options={{
<Stack.Screen
name="auth/login"
options={{
title: 'Iniciar Sesión',
headerShown: false,
}}
}}
/>
<Stack.Screen
name="auth/register"
options={{
<Stack.Screen
name="auth/register"
options={{
title: 'Registrarse',
headerShown: false,
}}
}}
/>
</Stack>
<StatusBar style={isDark ? 'light' : 'auto'} />
@@ -85,21 +88,23 @@ function ThemedBackground({ children }: { children: React.ReactNode }) {
const { isDark } = useThemeContext();
return (
<ImageBackground
source={isDark ? require('../assets/bg_dark.png') : require('../assets/bg.png')}
style={bgStyles.background}
resizeMode="cover"
imageStyle={bgStyles.backgroundImage}
>
<View style={[bgStyles.overlay, isDark && bgStyles.overlayDark]} />
{children}
</ImageBackground>
<View style={styles.root}>
<Image
source={isDark ? bgDark : bgLight}
style={styles.bgImage}
resizeMode="cover"
/>
<View style={[styles.overlay, isDark && styles.overlayDark]} pointerEvents="none" />
<View style={styles.content}>
{children}
</View>
</View>
);
}
export default function RootLayout() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<GestureHandlerRootView style={styles.root}>
<SafeAreaProvider>
<QueryClientProvider client={queryClient}>
<ThemeProvider>
@@ -113,11 +118,12 @@ export default function RootLayout() {
);
}
const bgStyles = StyleSheet.create({
background: {
const styles = StyleSheet.create({
root: {
flex: 1,
},
backgroundImage: {
bgImage: {
...StyleSheet.absoluteFillObject,
opacity: 0.55,
},
overlay: {
@@ -127,4 +133,7 @@ const bgStyles = StyleSheet.create({
overlayDark: {
backgroundColor: 'rgba(0, 0, 0, 0.25)',
},
content: {
flex: 1,
},
});