feat: Implement initial admin and mobile application UI, including styling, layouts, authentication, and legal page components.

This commit is contained in:
Timo Knuth
2026-03-03 16:54:11 +01:00
parent 59f3efaaed
commit b7d826e29c
15 changed files with 265 additions and 33 deletions

View File

@@ -4,6 +4,8 @@ import { Stack, SplashScreen } from 'expo-router'
import { useAuthStore } from '@/store/auth.store'
import { TRPCProvider } from '@/lib/trpc'
import { LoadingScreen } from '@/components/ui/LoadingScreen'
SplashScreen.preventAutoHideAsync()
export default function RootLayout() {
@@ -14,7 +16,7 @@ export default function RootLayout() {
initAuth().finally(() => SplashScreen.hideAsync())
}, [initAuth])
if (!isInitialized) return null
if (!isInitialized) return <LoadingScreen />
return (
<TRPCProvider>

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 KiB

View File

@@ -0,0 +1,140 @@
import React, { useEffect, useRef } from 'react'
import {
View,
Text,
StyleSheet,
ActivityIndicator,
Animated,
ImageBackground,
Dimensions,
} from 'react-native'
const { width, height } = Dimensions.get('window')
export function LoadingScreen() {
const fadeAnim = useRef(new Animated.Value(0)).current
const scaleAnim = useRef(new Animated.Value(0.95)).current
useEffect(() => {
Animated.parallel([
Animated.timing(fadeAnim, {
toValue: 1,
duration: 800,
useNativeDriver: true,
}),
Animated.spring(scaleAnim, {
toValue: 1,
friction: 8,
tension: 40,
useNativeDriver: true,
}),
]).start()
}, [])
return (
<View style={styles.container}>
<ImageBackground
source={require('../../assets/loading_bg.png')}
style={styles.backgroundImage}
resizeMode="cover"
>
<Animated.View
style={[
styles.content,
{
opacity: fadeAnim,
transform: [{ scale: scaleAnim }],
},
]}
>
{/* Card with rounded corners and semi-transparent background */}
<View style={styles.glassCard}>
<View style={styles.logoContainer}>
<View style={styles.logoBox}>
<Text style={styles.logoLetter}>I</Text>
</View>
<Text style={styles.appName}>InnungsApp</Text>
</View>
<View style={styles.loaderContainer}>
<ActivityIndicator size="large" color="#003B7E" />
<Text style={styles.loadingText}>Wird geladen...</Text>
</View>
</View>
</Animated.View>
</ImageBackground>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#003B7E',
},
backgroundImage: {
flex: 1,
width: width,
height: height,
justifyContent: 'center',
alignItems: 'center',
},
content: {
width: '80%',
maxWidth: 320,
alignItems: 'center',
},
glassCard: {
width: '100%',
padding: 32,
borderRadius: 32, // Rounded corners as requested
borderWidth: 1,
borderColor: 'rgba(255, 255, 255, 0.4)',
backgroundColor: 'rgba(255, 255, 255, 0.95)', // Solid-ish background for clean look without blur
alignItems: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: 10 },
shadowOpacity: 0.1,
shadowRadius: 20,
elevation: 10,
},
logoContainer: {
alignItems: 'center',
marginBottom: 24,
},
logoBox: {
width: 64,
height: 64,
backgroundColor: '#003B7E',
borderRadius: 20,
alignItems: 'center',
justifyContent: 'center',
marginBottom: 12,
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.2,
shadowRadius: 8,
elevation: 5,
},
logoLetter: {
color: '#FFFFFF',
fontSize: 32,
fontWeight: '900',
},
appName: {
fontSize: 24,
fontWeight: '800',
color: '#0F172A',
letterSpacing: -0.5,
},
loaderContainer: {
alignItems: 'center',
gap: 12,
},
loadingText: {
fontSize: 14,
color: '#64748B',
fontWeight: '600',
marginTop: 8,
},
})