add simple buttons for settings

This commit is contained in:
2024-12-07 04:58:59 +01:00
parent c223989e9f
commit 8a28edaf6a
8 changed files with 145 additions and 11 deletions
+2 -3
View File
@@ -1,8 +1,7 @@
import React from "react"; import React from "react";
import { Slot } from "expo-router"; import {Slot} from "expo-router";
export default function App() { export default function App() {
return <Slot />; return <Slot/>;
} }
+1 -3
View File
@@ -85,7 +85,5 @@ export default function TabLayout() {
/> />
</Tabs> </Tabs>
</AuthenticatedWrapper> </AuthenticatedWrapper>
);
)
;
} }
+23 -1
View File
@@ -1,13 +1,35 @@
import ThemedHeader from "@/src/components/themed/ThemedHeader"; import ThemedHeader from "@/src/components/themed/ThemedHeader";
import React from "react"; import React, {useState} from "react";
import ThemedBackground from "@/src/components/themed/ThemedBackground"; import ThemedBackground from "@/src/components/themed/ThemedBackground";
import ChangePasswordModal from "@/src/components/ChangePasswordModal";
import ThemeToggleButton from "@/src/components/ThemeToggleButton";
import SpotifyAuthButton from "@/src/components/SpotifyAuthButton";
import {Token} from "@/src/services/RestService";
import {Text} from 'react-native-paper';
import * as WebBrowser from "expo-web-browser";
import {useAuth} from "@/src/context/AuthProvider";
WebBrowser.maybeCompleteAuthSession();
export default function SettingsScreen() { export default function SettingsScreen() {
const {token: jwtToken} = useAuth();
const [token, setToken] = useState<Token | null>(null);
const handleAuthSuccess = (token: Token) => {
setToken(token);
console.log('Erhaltener Authentifizierungscode:', token);
};
return ( return (
<ThemedBackground> <ThemedBackground>
<ThemedHeader> <ThemedHeader>
Settings Settings
</ThemedHeader> </ThemedHeader>
<ChangePasswordModal/>
<ThemeToggleButton/>
<SpotifyAuthButton onAuthSuccess={handleAuthSuccess} jwtToken={jwtToken!}/>
{token && <Text>Erhaltener Code: {token.access_token}</Text>}
</ThemedBackground> </ThemedBackground>
); );
} }
+24
View File
@@ -30,6 +30,7 @@
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-native": "0.76.3", "react-native": "0.76.3",
"react-native-gesture-handler": "~2.21.2", "react-native-gesture-handler": "~2.21.2",
"react-native-modal": "^13.0.1",
"react-native-paper": "^5.12.5", "react-native-paper": "^5.12.5",
"react-native-reanimated": "~3.16.3", "react-native-reanimated": "~3.16.3",
"react-native-status-bar-height": "^2.6.0", "react-native-status-bar-height": "^2.6.0",
@@ -15320,6 +15321,15 @@
} }
} }
}, },
"node_modules/react-native-animatable": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/react-native-animatable/-/react-native-animatable-1.3.3.tgz",
"integrity": "sha512-2ckIxZQAsvWn25Ho+DK3d1mXIgj7tITkrS4pYDvx96WyOttSvzzFeQnM2od0+FUMzILbdHDsDEqZvnz1DYNQ1w==",
"license": "MIT",
"dependencies": {
"prop-types": "^15.7.2"
}
},
"node_modules/react-native-gesture-handler": { "node_modules/react-native-gesture-handler": {
"version": "2.21.2", "version": "2.21.2",
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.21.2.tgz", "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.21.2.tgz",
@@ -15360,6 +15370,20 @@
"react-native": ">=0.73.0" "react-native": ">=0.73.0"
} }
}, },
"node_modules/react-native-modal": {
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/react-native-modal/-/react-native-modal-13.0.1.tgz",
"integrity": "sha512-UB+mjmUtf+miaG/sDhOikRfBOv0gJdBU2ZE1HtFWp6UixW9jCk/bhGdHUgmZljbPpp0RaO/6YiMmQSSK3kkMaw==",
"license": "MIT",
"dependencies": {
"prop-types": "^15.6.2",
"react-native-animatable": "1.3.3"
},
"peerDependencies": {
"react": "*",
"react-native": ">=0.65.0"
}
},
"node_modules/react-native-paper": { "node_modules/react-native-paper": {
"version": "5.12.5", "version": "5.12.5",
"resolved": "https://registry.npmjs.org/react-native-paper/-/react-native-paper-5.12.5.tgz", "resolved": "https://registry.npmjs.org/react-native-paper/-/react-native-paper-5.12.5.tgz",
+1
View File
@@ -39,6 +39,7 @@
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-native": "0.76.3", "react-native": "0.76.3",
"react-native-gesture-handler": "~2.21.2", "react-native-gesture-handler": "~2.21.2",
"react-native-modal": "^13.0.1",
"react-native-paper": "^5.12.5", "react-native-paper": "^5.12.5",
"react-native-reanimated": "~3.16.3", "react-native-reanimated": "~3.16.3",
"react-native-status-bar-height": "^2.6.0", "react-native-status-bar-height": "^2.6.0",
+88
View File
@@ -0,0 +1,88 @@
import React, {useState} from "react";
import {Paragraph, Button} from "react-native-paper";
import ThemedTextInput from "@/src/components/themed/ThemedTextInput";
import {useTheme} from "@/src/context/ThemeProvider";
import Modal from "react-native-modal";
import {View, StyleSheet} from "react-native";
export default function ChangePasswordModal() {
const {theme} = useTheme();
const [isVisible, setIsVisible] = useState(false);
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [error, setError] = useState<{ message: string } | null>(null);
const handleConfirm = () => {
if (password !== confirmPassword) {
setError({message: "Passwörter stimmen nicht überein!"});
return;
}
console.log("Passwort erfolgreich geändert!");
};
const resetModal = () => {
setIsVisible(false);
setError(null);
setPassword("");
setConfirmPassword("");
}
return (
<>
<Button mode="outlined" onPress={() => setIsVisible(true)}>
Passwort ändern
</Button>
<Modal isVisible={isVisible} onBackdropPress={resetModal}>
<View style={styles.modalContent}>
<Paragraph>Passwort ändern</Paragraph>
{error && (
<View style={[styles.errorBox, {backgroundColor: theme.colors.error}]}>
<Paragraph style={{color: theme.colors.onError}}>{error.message}</Paragraph>
</View>
)}
<ThemedTextInput
label="Passwort"
returnKeyType="next"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
<ThemedTextInput
label="Passwort bestätigen"
returnKeyType="done"
value={confirmPassword}
onChangeText={setConfirmPassword}
secureTextEntry
/>
<View style={styles.buttonGroup}>
<Button mode="contained" onPress={handleConfirm}>
Bestätigen
</Button>
<Button mode="elevated" onPress={resetModal}>
Abbrechen
</Button>
</View>
</View>
</Modal>
</>
);
}
const styles = StyleSheet.create({
modalContent: {
padding: 16,
borderRadius: 8,
},
errorBox: {
marginBottom: 8,
marginTop: 8,
padding: 8,
},
buttonGroup: {
flexDirection: "row",
justifyContent: "space-between",
marginTop: 16,
},
});
+3 -2
View File
@@ -5,10 +5,11 @@ import ThemedButton from "@/src/components/themed/ThemedButton";
interface SpotifyAuthButtonProps { interface SpotifyAuthButtonProps {
onAuthSuccess: (token: Token) => void; onAuthSuccess: (token: Token) => void;
jwtToken: string;
} }
const SpotifyAuthButton = ({onAuthSuccess}: SpotifyAuthButtonProps) => { const SpotifyAuthButton = ({onAuthSuccess, jwtToken}: SpotifyAuthButtonProps) => {
const {promptAuth, isReady, error} = useSpotifyAuth(onAuthSuccess); const {promptAuth, isReady, error} = useSpotifyAuth(onAuthSuccess, jwtToken);
if (error) { if (error) {
console.error('Spotify Auth Error:', error); console.error('Spotify Auth Error:', error);
+3 -2
View File
@@ -14,7 +14,8 @@ interface UseSpotifyAuthResult {
} }
export const useSpotifyAuth = ( export const useSpotifyAuth = (
onAuthSuccess: (token: Token) => void onAuthSuccess: (token: Token) => void,
jwtToken: string,
): UseSpotifyAuthResult => { ): UseSpotifyAuthResult => {
const [request, response, promptAsync] = useAuthRequest( const [request, response, promptAsync] = useAuthRequest(
{ {
@@ -34,7 +35,7 @@ export const useSpotifyAuth = (
if (response?.type === 'success') { if (response?.type === 'success') {
try { try {
const {code} = response.params; const {code} = response.params;
const token = (await RestService.exchangeSpotifyCodeForToken(code,"TODO")).token; const token = (await RestService.exchangeSpotifyCodeForToken(code,jwtToken)).token;
console.log('Token:', token); console.log('Token:', token);
onAuthSuccess(token); onAuthSuccess(token);
} catch (error) { } catch (error) {