Added basic login, signup, settings and password reset pages
This commit is contained in:
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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}
|
||||
|
||||
132
jukebox/src/screens/LoginScreen.js
Normal file
132
jukebox/src/screens/LoginScreen.js
Normal 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,
|
||||
},
|
||||
});
|
||||
80
jukebox/src/screens/PasswordResetScreen.js
Normal file
80
jukebox/src/screens/PasswordResetScreen.js
Normal 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,
|
||||
},
|
||||
});
|
||||
87
jukebox/src/screens/SettingsScreen.js
Normal file
87
jukebox/src/screens/SettingsScreen.js
Normal 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,
|
||||
},
|
||||
});
|
||||
99
jukebox/src/screens/SignUpScreen.js
Normal file
99
jukebox/src/screens/SignUpScreen.js
Normal 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,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user