made login screen
This commit is contained in:
@@ -7,6 +7,7 @@ import { ThemeButton, ThemeText } from './common/ThemeTypes';
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
import { useColors } from './common/colors';
|
||||
import {decode as atob, encode as btoa} from 'base-64'
|
||||
import Login from './screens/Login';
|
||||
|
||||
let errorObject;
|
||||
export const InterfaceContext = createContext<any>(null);
|
||||
@@ -167,7 +168,7 @@ const Interface = ({ children }) => {
|
||||
<ThemeText>{errorObject?.message}</ThemeText>
|
||||
<ThemeButton style={styles.button} onPress={refresh}><Text>Neu Versuchen</Text></ThemeButton>
|
||||
</View>
|
||||
<Settings />
|
||||
<Login />
|
||||
</View>
|
||||
)
|
||||
if (!loading) return (children)
|
||||
|
||||
@@ -19,7 +19,7 @@ const defaultSettings: SettingsType = {
|
||||
password: '',
|
||||
systemTheme: true,
|
||||
darkTheme: false,
|
||||
requireAuth: false,
|
||||
requireAuth: true,
|
||||
};
|
||||
|
||||
const SettingsProvider = ({ children }) => {
|
||||
|
||||
81
common/Credits.tsx
Normal file
81
common/Credits.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import React, { useState, useEffect, useContext } from 'react';
|
||||
import { View, Text, ScrollView, TextInput, Button, StyleSheet, Alert, Linking, TouchableOpacity, Platform, ActivityIndicator, Image } from 'react-native';
|
||||
import { SettingsContext } from '../SettingsProvider';
|
||||
import { useColors } from '../common/colors';
|
||||
import ErrorBoundary from 'react-native-error-boundary';
|
||||
import { ThemeSwitch, ThemeText, ThemeTextInput } from '../common/ThemeTypes'
|
||||
import * as Application from 'expo-application';
|
||||
import { ToastType, useToast } from '../common/ToastProvider';
|
||||
|
||||
const Credits = () => {
|
||||
const colors = useColors();
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
padding: 20,
|
||||
},
|
||||
label: {
|
||||
fontWeight: 'bold',
|
||||
marginTop: 8,
|
||||
marginBottom: 6,
|
||||
},
|
||||
title: {
|
||||
fontWeight: 'bold',
|
||||
marginBottom: 3,
|
||||
fontSize: 32,
|
||||
},
|
||||
section: {
|
||||
marginBottom: 40,
|
||||
},
|
||||
endSection: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
},
|
||||
switchContainer: {
|
||||
marginTop: 10,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
activityindicator: {
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
logo: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
resizeMode: 'contain'
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={[styles.section, { marginTop: 20 }]}>
|
||||
<ThemeText>EDV-Schule Plattling</ThemeText>
|
||||
<TouchableOpacity onPress={() => Linking.openURL('https://www.edvschule-plattling.de/impressum')}>
|
||||
<Text style={{ color: colors.primary }}>Impressum</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={[styles.section, styles.endSection]}>
|
||||
<View>
|
||||
{ /* Wer des löscht werd weggeklagt */}
|
||||
<ThemeText>Heinrich Thaler</ThemeText>
|
||||
<TouchableOpacity onPress={() => Linking.openURL('mailto:Heinrich.Thaler@edvschule-plattling.de')}>
|
||||
<Text style={{ color: colors.primary }}>Heinrich.Thaler@edvschule-plattling.de</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => Linking.openURL('https://www.it-thaler.de')}>
|
||||
<Text style={{ color: colors.primary }}>www.it-thaler.de</Text>
|
||||
</TouchableOpacity>
|
||||
{Platform.OS != 'web' && <ThemeText>Version: {Application.nativeApplicationVersion} ({Application.nativeBuildVersion})</ThemeText>}
|
||||
</View>
|
||||
<Image style={styles.logo} source={require('../assets/logo-thaler.png')} />
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Credits;
|
||||
139
screens/Login.tsx
Normal file
139
screens/Login.tsx
Normal file
@@ -0,0 +1,139 @@
|
||||
import React, { useState, useEffect, useContext } from 'react';
|
||||
import { View, Text, ScrollView, TextInput, Button, StyleSheet, Alert, Linking, TouchableOpacity, Platform, ActivityIndicator, Image } from 'react-native';
|
||||
import { SettingsContext } from '../SettingsProvider';
|
||||
import { useColors } from '../common/colors';
|
||||
import ErrorBoundary from 'react-native-error-boundary';
|
||||
import { ThemeSwitch, ThemeText, ThemeTextInput } from '../common/ThemeTypes'
|
||||
import { ToastType, useToast } from '../common/ToastProvider';
|
||||
import Credits from '../common/Credits';
|
||||
|
||||
const Login = () => {
|
||||
const { showToast, hideToast } = useToast();
|
||||
const colors = useColors();
|
||||
const { settings, updateSettings } = useContext(SettingsContext);
|
||||
|
||||
const [url, setUrl] = useState('');
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [isSystemTheme, setIsSystemTheme] = useState(settings.systemTheme);
|
||||
const [isDarkMode, setIsDarkMode] = useState(settings.darkTheme);
|
||||
const [requireAuth, setRequireAuth] = useState(settings.requireAuth);
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (settings) {
|
||||
setUrl(settings.url || '');
|
||||
setUsername(settings.username || '');
|
||||
setPassword(settings.password || '');
|
||||
setIsSystemTheme(settings.systemTheme);
|
||||
setIsDarkMode(settings.darkTheme);
|
||||
setRequireAuth(settings.requireAuth);
|
||||
}
|
||||
}, [settings]);
|
||||
|
||||
const handleSave = async () => {
|
||||
if (isSaving) return;
|
||||
|
||||
try {
|
||||
setIsSaving(true);
|
||||
await updateSettings({
|
||||
url,
|
||||
username,
|
||||
password,
|
||||
systemTheme: isSystemTheme,
|
||||
darkTheme: isDarkMode,
|
||||
requireAuth,
|
||||
});
|
||||
hideToast()
|
||||
} catch (error) {
|
||||
console.error('Error updating settings:', error);
|
||||
Alert.alert('Error', 'Failed to save settings.');
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleChange = (setter) => (value) => {
|
||||
setter(value);
|
||||
showToast(ToastType.Warn, 'Ungespeicherte Änderungen');
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
padding: 20,
|
||||
},
|
||||
label: {
|
||||
fontWeight: 'bold',
|
||||
marginTop: 8,
|
||||
marginBottom: 6,
|
||||
},
|
||||
title: {
|
||||
fontWeight: 'bold',
|
||||
marginBottom: 3,
|
||||
fontSize: 32,
|
||||
},
|
||||
section: {
|
||||
marginBottom: 40,
|
||||
},
|
||||
switchContainer: {
|
||||
marginTop: 15,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
activityindicator: {
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<ScrollView style={[styles.container, { backgroundColor: colors.backPrimary }]}>
|
||||
<View style={styles.section}>
|
||||
<ThemeText style={styles.label}>Benutzername</ThemeText>
|
||||
<ThemeTextInput
|
||||
value={username}
|
||||
onValueChange={handleChange(setUsername)}
|
||||
placeholder="Benutzername"
|
||||
disabled={!requireAuth}
|
||||
/>
|
||||
<ThemeText style={styles.label}>Passwort</ThemeText>
|
||||
<ThemeTextInput
|
||||
value={password}
|
||||
onValueChange={handleChange(setPassword)}
|
||||
secureTextEntry
|
||||
placeholder="Passwort"
|
||||
disabled={!requireAuth}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.section}>
|
||||
<Button title={isSaving ? "" : "Einloggen"} onPress={handleSave} disabled={isSaving} />
|
||||
{isSaving && <ActivityIndicator size="small" color={colors.primary} style={styles.activityindicator} />}
|
||||
</View>
|
||||
|
||||
|
||||
<View style={styles.section}>
|
||||
<ThemeText style={styles.label}>URL</ThemeText>
|
||||
<ThemeTextInput
|
||||
value={url}
|
||||
onValueChange={handleChange(setUrl)}
|
||||
placeholder="URL"
|
||||
/>
|
||||
<View style={styles.switchContainer}>
|
||||
<ThemeText>Authentifizierung</ThemeText>
|
||||
<ThemeSwitch
|
||||
value={requireAuth}
|
||||
onValueChange={handleChange(setRequireAuth)}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<Credits/>
|
||||
</ScrollView>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
export default Login;
|
||||
Reference in New Issue
Block a user