Commit a6bc6f69 authored by Lelkada L L P S M's avatar Lelkada L L P S M

app login and home screen

parent f924fad8
node_modules/
.expo/
dist/
npm-debug.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
web-build/
# macOS
.DS_Store
# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*
import React from 'react';
import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer } from 'react-navigation';
import LoginScreen from './screens/LoginScreen';
import HomeScreen from './screens/HomeScreen';
const MainStack = createStackNavigator(
{
Login: {
screen: LoginScreen,
},
Home: {
screen: HomeScreen,
},
},
{
initialRouteName: 'Login',
defaultNavigationOptions: {
headerShown: false,
},
}
);
const AppContainer = createAppContainer(MainStack);
export default function App() {
return <AppContainer />;
}
{
"expo": {
"name": "HearMe",
"slug": "HearMe",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
},
"web": {
"favicon": "./assets/favicon.png"
}
}
}
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
};
};
This diff is collapsed.
{
"name": "hearme",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"@expo/vector-icons": "^13.0.0",
"@react-navigation/native": "^6.1.6",
"@react-navigation/stack": "^6.3.16",
"expo": "~48.0.9",
"expo-av": "^13.2.1",
"expo-status-bar": "~1.4.4",
"react": "18.2.0",
"react-native": "0.71.4",
"react-native-gesture-handler": "~2.9.0",
"react-native-reanimated": "~2.14.4",
"react-native-safe-area-context": "4.5.0",
"react-native-screens": "~3.20.0",
"react-native-swiper": "^1.6.0",
"react-navigation": "^4.4.4",
"react-navigation-stack": "^2.10.4"
},
"devDependencies": {
"@babel/core": "^7.20.0"
},
"private": true
}
import React, { useState } from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity } from 'react-native';
const cardsData = [
{
image: require('./assets/img_home.png'),
word: 'home',
},
{
image: require('./assets/img_garden.png'),
word: 'garden',
},
{
image: require('./assets/img_car.png'),
word: 'car',
},
];
export default function HomeScreen() {
const [currentCardIndex, setCurrentCardIndex] = useState(0);
const renderCard = (cardData) => (
<View style={styles.card}>
<Text style={styles.cardNumber}>{`${currentCardIndex + 1}/${cardsData.length}`}</Text>
<Image source={cardData.image} style={styles.cardImage} resizeMode="contain" />
<View style={styles.wordContainer}>
{cardData.word.split('').map((letter, index) => (
<View key={index} style={styles.letterCard}>
<Text style={styles.letter}>{letter}</Text>
</View>
))}
</View>
<View style={styles.navigationButtons}>
<TouchableOpacity
onPress={() => setCurrentCardIndex((prevIndex) => (prevIndex > 0 ? prevIndex - 1 : prevIndex))}
>
<Text style={styles.navigationButtonText}></Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() =>
setCurrentCardIndex((prevIndex) => (prevIndex < cardsData.length - 1 ? prevIndex + 1 : prevIndex))
}
>
<Text style={styles.navigationButtonText}></Text>
</TouchableOpacity>
</View>
</View>
);
return <View style={styles.container}>{renderCard(cardsData[currentCardIndex])}</View>;
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#61A6AB',
alignItems: 'center',
justifyContent: 'center',
},
card: {
backgroundColor: 'white',
borderRadius: 20,
width: '80%',
height: '60%',
alignItems: 'center',
justifyContent: 'center',
padding: 20,
},
cardNumber: {
position: 'absolute',
top: 10,
right: 10,
fontSize: 18,
color: 'black',
},
cardImage: {
height: '60%',
width: '80%',
},
wordContainer: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginBottom: 20,
},
letterCard: {
backgroundColor: '#FFCE6D',
borderRadius: 10,
paddingHorizontal: 10,
paddingVertical: 5,
marginHorizontal: 5,
},
letter: {
fontSize: 24,
color: 'white',
},
navigationButtons: {
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
width: '100%',
},
navigationButtonText: {
fontSize: 36,
color: 'black',
},
});
import React, { useState } from 'react';
import { StyleSheet, Text, View, Image, TextInput, TouchableOpacity, KeyboardAvoidingView } from 'react-native';
export default function LoginScreen({ navigation }) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleLogin = () => {
navigation.navigate('Home');
};
return (
<KeyboardAvoidingView style={styles.container} behavior="padding">
<Text style={styles.welcomeText}>Welcome</Text>
<TextInput
style={styles.input}
placeholder="Email"
placeholderTextColor="white"
onChangeText={setEmail}
value={email}
/>
<TextInput
style={styles.input}
placeholder="Password"
placeholderTextColor="white"
onChangeText={setPassword}
value={password}
secureTextEntry
/>
<TouchableOpacity style={styles.loginButton} onPress={handleLogin}>
<Text style={styles.loginButtonText}>Login</Text>
</TouchableOpacity>
<Image
source={require('./assets/giraffe_reading_book.png')}
style={styles.giraffeImage}
resizeMode="contain"
/>
</KeyboardAvoidingView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#61A6AB',
alignItems: 'center',
justifyContent: 'center',
},
welcomeText: {
fontSize: 46,
fontWeight: 'bold',
color: 'white',
marginBottom: 50,
position: 'absolute',
top: '25%',
},
input: {
width: '80%',
backgroundColor: 'rgba(255, 206, 109, 0.45)',
borderRadius: 25,
paddingHorizontal: 15,
fontSize: 18,
color: 'white',
marginVertical: 10,
paddingVertical:15,
borderColor: 'white',
borderWidth: 1,
},
loginButton: {
backgroundColor: '#FFCE6D',
paddingVertical: 15,
paddingHorizontal: 30,
borderRadius: 25,
marginTop: 20,
},
loginButtonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
giraffeImage: {
position: 'absolute',
bottom: 20,
right: 0,
height: '25%',
width: undefined,
aspectRatio: 1,
},
});
This diff is collapsed.
node_modules/
.expo/
dist/
npm-debug.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
web-build/
# macOS
.DS_Store
# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
{
"expo": {
"name": "hearme",
"slug": "hearme",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
},
"web": {
"favicon": "./assets/favicon.png"
}
}
}
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
};
};
This diff is collapsed.
{
"name": "hearme",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"expo": "~48.0.9",
"expo-status-bar": "~1.4.4",
"react": "18.2.0",
"react-native": "0.71.4"
},
"devDependencies": {
"@babel/core": "^7.20.0"
},
"private": true
}
> Why do I have a folder named ".expo" in my project?
The ".expo" folder is created when an Expo project is started using "expo start" command.
> What do the files contain?
- "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
- "packager-info.json": contains port numbers and process PIDs that are used to serve the application to the mobile device/simulator.
- "settings.json": contains the server configuration that is used to serve the application manifest.
> Should I commit the ".expo" folder?
No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
{
"hostType": "lan",
"lanType": "ip",
"dev": true,
"minify": false,
"urlRandomness": null,
"https": false
}
node_modules/
.expo/
dist/
npm-debug.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
web-build/
# macOS
.DS_Store
# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/native-stack';
import LoginScreen from './screens/LoginScreen';
import HomeScreen from './screens/HomeScreen';
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ headerShown: false }}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
{
"expo": {
"name": "hearme",
"slug": "hearme",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
},
"web": {
"favicon": "./assets/favicon.png"
}
}
}
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
};
};
This diff is collapsed.
{
"name": "hearme",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"@react-navigation/native": "^6.1.6",
"@react-navigation/native-stack": "^6.9.12",
"expo": "^1.0.0",
"expo-status-bar": "~1.4.4",
"react": "18.2.0",
"react-native": "0.71.4",
"react-navigation": "^4.4.4"
},
"devDependencies": {
"@babel/core": "^7.20.0"
},
"private": true
}
import React, { useState } from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity } from 'react-native';
const contentData = [
{
id: 1,
word: 'car',
image: require('./assets/img_car.png'),
audio: require('./assets/dog_audio.mp3'),
},
{
id: 2,
word: 'garden',
image: require('./assets/img_garden.png'),
audio: require('./assets/cat_audio.mp3'),
},
{
id: 3,
word: 'home',
image: require('./assets/img_home.png'),
audio: require('./assets/bird_audio.mp3'),
},
];
export default function HomeScreen() {
const [cardIndex, setCardIndex] = useState(0);
const handleNextPress = () => {
if (cardIndex === contentData.length - 1) {
setCardIndex(0);
} else {
setCardIndex(cardIndex + 1);
}
};
const currentCard = contentData[cardIndex];
return (
<View style={styles.container}>
<View style={styles.card}>
<View style={styles.cardHeader}>
<Text style={styles.cardHeaderText}>{`${cardIndex + 1}/${contentData.length}`}</Text>
</View>
<View style={styles.cardBody}>
<Image source={currentCard.image} style={styles.cardImage} resizeMode="contain" />
<Text style={styles.cardWord}>{currentCard.word}</Text>
<TouchableOpacity style={styles.cardButton} onPress={() => console.log('Audio button pressed')}>
<Text style={styles.cardButtonText}>Audio</Text>
</TouchableOpacity>
</View>
<TouchableOpacity style={styles.nextButton} onPress={handleNextPress}>
<Image source={require('./assets/arrow.png')} style={styles.nextButtonIcon} resizeMode="contain" />
</TouchableOpacity>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F4F4F4',
justifyContent: 'center',
alignItems: 'center',
},
card: {
width: '80%',
height: '80%',
backgroundColor: 'white',
borderRadius: 25,
padding: 20,
justifyContent: 'space-between',
alignItems: 'center',
},
cardHeader: {
alignSelf: 'flex-start',
paddingHorizontal: 10,
paddingVertical: 5,
backgroundColor: '#61A6AB',
borderRadius: 10,
},
cardHeaderText: {
color: 'white',
fontWeight: 'bold',
fontSize: 16,
},
cardBody: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
cardImage: {
height: '50%',
width: '80%',
},
cardWord: {
fontSize: 30,
fontWeight: 'bold',
marginVertical: 20,
},
cardButton: {
backgroundColor: '#61A6AB',
borderRadius: 20,
paddingVertical: 10,
paddingHorizontal: 30,
},
cardButtonText: {
color: 'white',
fontWeight: 'bold',
},
nextButton: {
position: 'absolute',
bottom: 20,
right: 20,
},
nextButtonIcon: {
height: 50,
width: 50,
},
});
import React from 'react';
import { StyleSheet, Text, View, Image, TextInput, TouchableOpacity } from 'react-native';
export default function LoginScreen({ navigation }) {
const handleLoginPress = () => {
navigation.navigate('Home');
};
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome</Text>
<View style={styles.formContainer}>
<TextInput
style={styles.input}
placeholder="Email"
placeholderTextColor="white"
/>
<TextInput
style={styles.input}
placeholder="Password"
placeholderTextColor="white"
secureTextEntry={true}
/>
<TouchableOpacity style={styles.loginButton} onPress={handleLoginPress}>
<Text style={styles.loginButtonText}>Login</Text>
</TouchableOpacity>
</View>
<Image
source={require('./assets/giraffe_reading_book.png')}
style={styles.image}
resizeMode="contain"
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#61A6AB',
justifyContent: 'flex-start',
alignItems: 'center',
paddingTop: '25%',
},
welcome: {
fontSize: 40,
fontWeight: 'bold',
color: 'white',
position: 'absolute',
top: 0,
paddingTop: '10%',
},
formContainer: {
backgroundColor: 'rgba(255, 206, 109, 0.45)',
borderRadius: 30,
padding: 20,
marginTop: '30%',
marginBottom: '5%',
width: '80%',
justifyContent: 'center',
alignItems: 'center',
},
input: {
borderRadius: 25,
borderWidth: 1,
borderColor: 'white',
backgroundColor: 'rgba(255, 206, 109, 0.45)',
padding: 10,
marginBottom: 10,
width: '80%',
color: 'white',
},
loginButton: {
backgroundColor: '#FFCE6D',
borderRadius: 25,
padding: 10,
width: '80%',
alignItems: 'center',
},
loginButtonText: {
fontWeight: 'bold',
color: 'white',
},
image: {
position: 'absolute',
bottom: 0,
height: '25%',
width: '100%',
},
});
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment