Archived
feat: Integrate Expo mobile application into monorepo (#16)
- Add mobile/ directory with Expo React Native project - Create API client with JWT auth and token refresh using AsyncStorage - Implement AuthContext for login/register/logout flow - Add screens: Login, Register, Library, Search, Settings - Set up React Navigation with AuthStack and MainTabs - Create packages/shared/ with shared types and utilities - Add shared validation utilities (email, password strength) - Update root package.json workspaces to include mobile + shared - Add spec document docs/backend/009-expo-integration.md
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import { type ReactNode } from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
StyleSheet,
|
||||
Alert,
|
||||
} from "react-native";
|
||||
import { useAuth } from "../context/AuthContext";
|
||||
|
||||
export default function SettingsScreen(): ReactNode {
|
||||
const { state, logout } = useAuth();
|
||||
|
||||
const handleLogout = () => {
|
||||
Alert.alert("Logout", "Are you sure you want to sign out?", [
|
||||
{ text: "Cancel", style: "cancel" },
|
||||
{ text: "Sign Out", style: "destructive", onPress: logout },
|
||||
]);
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>Account</Text>
|
||||
<View style={styles.infoRow}>
|
||||
<Text style={styles.label}>Username</Text>
|
||||
<Text style={styles.value}>{state.user?.username ?? "—"}</Text>
|
||||
</View>
|
||||
<View style={styles.infoRow}>
|
||||
<Text style={styles.label}>Email</Text>
|
||||
<Text style={styles.value}>{state.user?.email ?? "—"}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity style={styles.logoutButton} onPress={handleLogout}>
|
||||
<Text style={styles.logoutText}>Sign Out</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: "#0f0f23",
|
||||
padding: 16,
|
||||
},
|
||||
section: {
|
||||
backgroundColor: "#1a1a2e",
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
marginBottom: 24,
|
||||
borderWidth: 1,
|
||||
borderColor: "#333",
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: "600",
|
||||
color: "#fff",
|
||||
marginBottom: 16,
|
||||
},
|
||||
infoRow: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
paddingVertical: 12,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: "#333",
|
||||
},
|
||||
label: {
|
||||
fontSize: 14,
|
||||
color: "#888",
|
||||
},
|
||||
value: {
|
||||
fontSize: 14,
|
||||
color: "#fff",
|
||||
fontWeight: "500",
|
||||
},
|
||||
logoutButton: {
|
||||
backgroundColor: "rgba(255, 69, 58, 0.15)",
|
||||
borderRadius: 8,
|
||||
padding: 16,
|
||||
alignItems: "center",
|
||||
borderWidth: 1,
|
||||
borderColor: "rgba(255, 69, 58, 0.3)",
|
||||
},
|
||||
logoutText: {
|
||||
color: "#ff453a",
|
||||
fontSize: 16,
|
||||
fontWeight: "600",
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user