Added basic login, signup, settings and password reset pages

This commit is contained in:
2026-03-05 11:07:36 +01:00
parent c8546d325a
commit fe07112b1f
8 changed files with 416 additions and 14 deletions

View File

@@ -2,13 +2,21 @@ import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View, Pressable } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import MediaPlayer from "./src/components/MediaPlayer";
import HomeScreen from "./src/screens/HomeScreen";
import { createContext, useState, useContext } from "react";
import MediaPlayer from "./src/components/MediaPlayer";
import HomeScreen from "./src/screens/HomeScreen";
import LikedTracksScreen from "./src/screens/LikedTracksScreen";
import AlbumScreen from "./src/screens/AlbumScreen";
import LoginScreen from "./src/screens/LoginScreen";
import PasswordResetScreen from "./src/screens/PasswordResetScreen";
import SettingsScreen from "./src/screens/SettingsScreen";
import SignUpScreen from "./src/screens/SignUpScreen";
import { LibraryProvider } from "./src/contexts/LibraryContext";
const Stack = createNativeStackNavigator();
const playerContext = createContext(null);
@@ -40,6 +48,10 @@ function AppNavigator() {
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="LikedTracks" component={LikedTracksScreen} />
<Stack.Screen name="Album" component={AlbumScreen} />
<Stack.Screen name="SignUp" component={SignUpScreen} />
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="PasswordReset" component={PasswordResetScreen} />
<Stack.Screen name="Settings" component={SettingsScreen} />
</Stack.Navigator>
</NavigationContainer>
);

View File

@@ -16,10 +16,6 @@ export default function HomeScreen() {
const navigation = useNavigation();
const { albums, likedTracks, toggleLike } = useLibrary();
// Same behavior as before: show all albums in "Liked albums" section
const likedAlbums = albums;
// Optional: limit shown liked tracks on Home
const homeLikedTracks = useMemo(() => likedTracks.slice(0, 5), [likedTracks]);
return (
@@ -29,17 +25,13 @@ export default function HomeScreen() {
<View style={styles.headerActions}>
<Pressable
style={styles.iconBtn}
onPress={() => {
console.log("Login pressed");
}}
onPress={() => navigation.navigate("Login")}
>
<Ionicons name="person-outline" size={24} color="#fff" />
</Pressable>
<Pressable
style={styles.iconBtn}
onPress={() => {
console.log("Settings pressed");
}}
onPress={() => navigation.navigate("Settings")}
>
<Ionicons name="settings-outline" size={24} color="#fff" />
</Pressable>
@@ -67,10 +59,10 @@ export default function HomeScreen() {
);
})}
<Text style={[styles.sectionTitle, { marginTop: 24 }]}>Liked albums</Text>
<Text style={[styles.sectionTitle, { marginTop: 24 }]}>Albums</Text>
<FlatList
data={likedAlbums}
data={albums}
keyExtractor={(item) => item.id}
numColumns={2}
columnWrapperStyle={styles.albumRow}

View File

@@ -0,0 +1,132 @@
import React, { useState } from "react";
import { View, Text, StyleSheet, TextInput, Pressable } from "react-native";
export default function LoginScreen({ navigation }) {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const onLogin = () => {
console.log("Login button pressed");
};
const OnPasswordReset = () => {
navigation.navigate("PasswordReset");
};
const OnSignUp = () => {
navigation.navigate("SignUp");
};
return (
<View style={styles.container}>
<Pressable onPress={() => navigation.goBack()} style={styles.backBtn}>
<Text style={styles.backText}> Back</Text>
</Pressable>
<Text style={styles.title}>Login</Text>
<TextInput
value={email}
onChangeText={setEmail}
placeholder="Email"
placeholderTextColor="#9ca3af"
style={styles.input}
autoCapitalize="none"
keyboardType="email-address"
/>
<TextInput
value={password}
onChangeText={setPassword}
placeholder="Password"
placeholderTextColor="#9ca3af"
style={styles.input}
secureTextEntry
/>
<Pressable style={styles.loginBtn} onPress={onLogin}>
<Text style={styles.loginBtnText}>Log In</Text>
</Pressable>
<Pressable style={styles.passwordResetBtn} onPress={OnPasswordReset}>
<Text style={styles.passwordResetBtnText}>Reset password</Text>
</Pressable>
<Pressable style={styles.SignupBtn} onPress={OnSignUp}>
<Text style={styles.SignupBtnText}>Sign Up</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#000",
paddingTop: 24,
paddingHorizontal: 16,
},
backBtn: {
marginBottom: 10,
alignSelf: "flex-start",
},
backText: {
color: "#fff",
fontSize: 16,
fontWeight: "600",
},
title: {
color: "#fff",
fontSize: 30,
fontWeight: "700",
marginBottom: 16,
},
input: {
backgroundColor: "#1f2937",
color: "#fff",
borderRadius: 10,
paddingHorizontal: 12,
paddingVertical: 12,
fontSize: 16,
marginBottom: 12,
},
loginBtn: {
backgroundColor: "#dbdbdb",
borderRadius: 10,
paddingVertical: 12,
alignItems: "center",
marginTop: 4,
marginBottom: 6,
},
loginBtnText: {
color: "#000",
fontWeight: "700",
fontSize: 16,
},
passwordResetBtn: {
backgroundColor: "#e36d6d",
borderRadius: 10,
paddingVertical: 12,
alignItems: "center",
marginTop: 4,
marginBottom: 6,
},
passwordResetBtnText: {
color: "#000",
fontWeight: "700",
fontSize: 16,
},
SignupBtn: {
backgroundColor: "#dbdbdb",
borderRadius: 10,
paddingVertical: 12,
alignItems: "center",
marginTop: 24,
},
SignupBtnText: {
color: "#000",
fontWeight: "700",
fontSize: 16,
},
});

View File

@@ -0,0 +1,80 @@
import React, { useState } from "react";
import { View, Text, StyleSheet, TextInput, Pressable } from "react-native";
export default function PasswordResetScreen({ navigation }) {
const [email, setEmail] = useState("");
const onResetButtonPress = () => {
console.log("Send email button pressed");
};
return (
<View style={styles.container}>
<Pressable onPress={() => navigation.goBack()} style={styles.backBtn}>
<Text style={styles.backText}> Back</Text>
</Pressable>
<Text style={styles.title}>Reset password</Text>
<TextInput
value={email}
onChangeText={setEmail}
placeholder="Email"
placeholderTextColor="#9ca3af"
style={styles.input}
autoCapitalize="none"
keyboardType="email-address"
/>
<Pressable style={styles.primaryBtn} onPress={onResetButtonPress}>
<Text style={styles.primaryBtnText}>Send email</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#000",
paddingTop: 24,
paddingHorizontal: 16,
},
backBtn: {
marginBottom: 10,
alignSelf: "flex-start",
},
backText: {
color: "#fff",
fontSize: 16,
fontWeight: "600",
},
title: {
color: "#fff",
fontSize: 30,
fontWeight: "700",
marginBottom: 16,
},
input: {
backgroundColor: "#1f2937",
color: "#fff",
borderRadius: 10,
paddingHorizontal: 12,
paddingVertical: 12,
fontSize: 16,
marginBottom: 12,
},
primaryBtn: {
backgroundColor: "#dbdbdb",
borderRadius: 10,
paddingVertical: 12,
alignItems: "center",
marginTop: 4,
marginBottom: 6,
},
primaryBtnText: {
color: "#000",
fontWeight: "700",
fontSize: 16,
},
});

View File

@@ -0,0 +1,87 @@
import React, { useState } from "react";
import { View, Text, StyleSheet, Pressable, Switch } from "react-native";
export default function SettingsScreen({ navigation }) {
const [notificationsEnabled, setNotificationsEnabled] = useState(true);
const [highQuality, setHighQuality] = useState(false);
return (
<View style={styles.container}>
<Pressable onPress={() => navigation.goBack()} style={styles.backBtn}>
<Text style={styles.backText}> Back</Text>
</Pressable>
<Text style={styles.title}>Settings</Text>
<View style={styles.row}>
<Text style={styles.rowText}>Enable notifications</Text>
<Switch
value={notificationsEnabled}
onValueChange={setNotificationsEnabled}
/>
</View>
<View style={styles.row}>
<Text style={styles.rowText}>High quality streaming</Text>
<Switch value={highQuality} onValueChange={setHighQuality} />
</View>
<Pressable
style={[styles.logoutBtn]}
onPress={() => console.log("Logged out")}
>
<Text style={styles.logoutBtnText}>Log out</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#000",
paddingTop: 24,
paddingHorizontal: 16,
},
backBtn: {
marginBottom: 10,
alignSelf: "flex-start",
},
backText: {
color: "#fff",
fontSize: 16,
fontWeight: "600",
},
title: {
color: "#fff",
fontSize: 30,
fontWeight: "700",
marginBottom: 16,
},
row: {
backgroundColor: "#111827",
borderRadius: 10,
paddingHorizontal: 12,
paddingVertical: 14,
marginBottom: 10,
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
},
rowText: {
color: "#fff",
fontSize: 16,
},
logoutBtn: {
borderRadius: 10,
paddingVertical: 12,
alignItems: "center",
marginTop: 16,
backgroundColor: "#e36d6d",
},
logoutBtnText: {
color: "#000000",
fontWeight: "700",
fontSize: 16,
},
});

View File

@@ -0,0 +1,99 @@
import React, { useState } from "react";
import { View, Text, StyleSheet, TextInput, Pressable } from "react-native";
export default function SignUpScreen({ navigation }) {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const onSignUp = () => {
console.log("Sign up button pressed");
};
return (
<View style={styles.container}>
<Pressable onPress={() => navigation.goBack()} style={styles.backBtn}>
<Text style={styles.backText}> Back</Text>
</Pressable>
<Text style={styles.title}>Sign up</Text>
<TextInput
value={email}
onChangeText={setEmail}
placeholder="Email"
placeholderTextColor="#9ca3af"
style={styles.input}
autoCapitalize="none"
keyboardType="email-address"
/>
<TextInput
value={password}
onChangeText={setPassword}
placeholder="Password"
placeholderTextColor="#9ca3af"
style={styles.input}
secureTextEntry
/>
<TextInput
value={password}
onChangeText={setPassword}
placeholder="Confirm Password"
placeholderTextColor="#9ca3af"
style={styles.input}
secureTextEntry
/>
<Pressable style={styles.primaryBtn} onPress={onSignUp}>
<Text style={styles.primaryBtnText}>Sign Up</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#000",
paddingTop: 24,
paddingHorizontal: 16,
},
backBtn: {
marginBottom: 10,
alignSelf: "flex-start",
},
backText: {
color: "#fff",
fontSize: 16,
fontWeight: "600",
},
title: {
color: "#fff",
fontSize: 30,
fontWeight: "700",
marginBottom: 16,
},
input: {
backgroundColor: "#1f2937",
color: "#fff",
borderRadius: 10,
paddingHorizontal: 12,
paddingVertical: 12,
fontSize: 16,
marginBottom: 12,
},
primaryBtn: {
backgroundColor: "#dbdbdb",
borderRadius: 10,
paddingVertical: 12,
alignItems: "center",
marginTop: 4,
marginBottom: 6,
},
primaryBtnText: {
color: "#000",
fontWeight: "700",
fontSize: 16,
},
});