Skip to content

Commit c1c0efe

Browse files
author
yushan
committed
Develop the application
0 parents  commit c1c0efe

22 files changed

+970
-0
lines changed

.gitignore

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
node_modules/**/*
2+
.expo/*
3+
npm-debug.*
4+
*.jks
5+
*.p8
6+
*.p12
7+
*.key
8+
*.mobileprovision
9+
*.orig.*
10+
web-build/
11+
12+
# macOS
13+
.DS_Store

App.js

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import { StatusBar } from 'expo-status-bar';
2+
import React, { Component } from 'react';
3+
import { StyleSheet, Text, View } from 'react-native';
4+
import { NavigationContainer } from '@react-navigation/native';
5+
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
6+
import { createStackNavigator } from '@react-navigation/stack';
7+
import Constants from 'expo-constants';
8+
import { store, getDecks, setLocalNotification } from './utils/helpers';
9+
import DeckList from './components/DeckList';
10+
import NewDeck from './components/NewDeck';
11+
import Deck from './components/Deck';
12+
import Quiz from './components/Quiz';
13+
import Result from './components/Result';
14+
import AddCard from './components/AddCard';
15+
16+
function MyStatusBar({ backgroundColor, ...props }) {
17+
return (
18+
<View style={{ backgroundColor, height: Constants.statusBarHeight }}>
19+
<StatusBar translucent backgroundColor={backgroundColor} {...props} />
20+
</View>
21+
)
22+
}
23+
24+
const Tab = createBottomTabNavigator();
25+
26+
function Tabs(props) {
27+
const { data, fetchData } = props;
28+
return (
29+
<Tab.Navigator
30+
tabBarOptions={{
31+
activeTintColor: 'white',
32+
style: {
33+
height: 56,
34+
backgroundColor: '#fe5a37',
35+
shadowColor: 'rgba(0, 0, 0, 0.24)',
36+
shadowOffset: {
37+
width: 0,
38+
height: 3
39+
},
40+
shadowRadius: 6,
41+
shadowOpacity: 1,
42+
},
43+
tabStyle: {
44+
justifyContent: 'center'
45+
},
46+
labelStyle: {
47+
fontSize: 17,
48+
}
49+
}}>
50+
<Tab.Screen
51+
name="Decks"
52+
options={{ headerShown: false }}>
53+
{props => <DeckList {...props} data={data} />}
54+
</Tab.Screen>
55+
<Tab.Screen
56+
name="New Deck"
57+
options={{ headerShown: false }}>
58+
{props => <NewDeck {...props} fetchData={fetchData} />}
59+
</Tab.Screen>
60+
</Tab.Navigator>
61+
)
62+
}
63+
64+
const Stack = createStackNavigator();
65+
66+
export default class App extends Component {
67+
state = {
68+
flashCards: {}
69+
}
70+
71+
componentDidMount() {
72+
setLocalNotification();
73+
store()
74+
.then(() => this.fetchData());
75+
}
76+
77+
fetchData = () => {
78+
return getDecks()
79+
.then((flashCards) => {
80+
this.setState(() => ({
81+
flashCards
82+
}))});
83+
}
84+
85+
render() {
86+
const { flashCards } = this.state;
87+
return (
88+
<NavigationContainer>
89+
<View style={{ flex: 1 }}>
90+
<MyStatusBar backgroundColor='#fe5a37' barStyle='light-content' />
91+
<Stack.Navigator>
92+
<Stack.Screen
93+
name="Decks">
94+
{props => <Tabs {...props} data={flashCards} fetchData={this.fetchData} />}
95+
</Stack.Screen>
96+
<Stack.Screen
97+
name="Deck"
98+
component={Deck}
99+
options={({ route }) => ({
100+
title: route.params.title,
101+
})} />
102+
<Stack.Screen
103+
name="Quiz"
104+
component={Quiz}
105+
initialParams={{ correctCount: 0 }} />
106+
<Stack.Screen
107+
name="Result"
108+
component={Result} />
109+
<Stack.Screen
110+
name="AddCard">
111+
{props => <AddCard {...props} fetchData={this.fetchData} />}
112+
</Stack.Screen>
113+
</Stack.Navigator>
114+
</View>
115+
</NavigationContainer>
116+
)
117+
}
118+
}

README.md

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Mobile Flashcards
2+
3+
This is the final project in the Udacity React Nanodegree.
4+
5+
In the “Mobile Flashcards” Project, build a mobile application (Android or iOS - or both) that allows users to study collections of flashcards. The app will allow users to create different categories of flashcards called "decks", add flashcards to those decks, then take quizzes on those decks.
6+
7+
## TL;DR
8+
9+
To get started developing right away:
10+
11+
- install all project dependencies with `yarn install` or `npm install`.
12+
13+
## Available Scripts
14+
15+
If Yarn was installed when the project was initialized, then dependencies will have been installed via Yarn, and you should probably use it to run these commands as well. Unlike dependency installation, command running syntax is identical for Yarn and NPM at the time of this writing.
16+
17+
### `npm start`
18+
19+
Runs your app in development mode.
20+
21+
Open it in the [Expo app](https://expo.io) on your phone to view it. It will reload if you save edits to your files, and you will see build errors and logs in the terminal.
22+
23+
Sometimes you may need to reset or clear the React Native packager's cache. To do so, you can pass the `--reset-cache` flag to the start script:
24+
25+
```
26+
npm start -- --reset-cache
27+
# or
28+
yarn start -- --reset-cache
29+
```
30+
31+
#### `npm test`
32+
33+
Runs the [jest](https://github.com/facebook/jest) test runner on your tests.
34+
35+
#### `npm run ios`
36+
37+
Like `npm start`, but also attempts to open your app in the iOS Simulator if you're on a Mac and have it installed.
38+
39+
#### `npm run android`
40+
41+
Like `npm start`, but also attempts to open your app on a connected Android device or emulator. Requires an installation of Android build tools (see [React Native docs](https://facebook.github.io/react-native/docs/getting-started.html) for detailed setup). We also recommend installing Genymotion as your Android emulator. Once you've finished setting up the native build environment, there are two options for making the right copy of `adb` available to Create React Native App:
42+
43+
##### Using Android Studio's `adb`
44+
45+
1. Make sure that you can run adb from your terminal.
46+
2. Open Genymotion and navigate to `Settings -> ADB`. Select “Use custom Android SDK tools” and update with your [Android SDK directory](https://stackoverflow.com/questions/25176594/android-sdk-location).
47+
48+
##### Using Genymotion's `adb`
49+
50+
1. Find Genymotion’s copy of adb. On macOS for example, this is normally `/Applications/Genymotion.app/Contents/MacOS/tools/`.
51+
2. Add the Genymotion tools directory to your path (instructions for [Mac](http://osxdaily.com/2014/08/14/add-new-path-to-path-command-line/), [Linux](http://www.computerhope.com/issues/ch001647.htm), and [Windows](https://www.howtogeek.com/118594/how-to-edit-your-system-path-for-easy-command-line-access/)).
52+
3. Make sure that you can run adb from your terminal.
53+
54+
#### `npm run eject`
55+
56+
This will start the process of "ejecting" from Create React Native App's build scripts. You'll be asked a couple of questions about how you'd like to build your project.
57+
58+
**Warning:** Running eject is a permanent action (aside from whatever version control system you use). An ejected app will require you to have an [Xcode and/or Android Studio environment](https://facebook.github.io/react-native/docs/getting-started.html) set up.
59+
60+
61+
62+
63+
## Note
64+
65+
- This project develop in https://snack.expo.io
66+
- Project URL - https://snack.expo.io/@yushanwebdev/9c3d01
67+
- Checked in Android Device and iOS Emulator in Snack.
68+
69+
70+
71+

app.json

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"expo": {
3+
"name": "reactnd-mobile-flashcards",
4+
"slug": "snack-a72e4c13-dc22-4518-9d2b-27148db07534",
5+
"version": "1.0.0",
6+
"orientation": "portrait",
7+
"icon": "./assets/icon.png",
8+
"splash": {
9+
"image": "./assets/splash.png",
10+
"resizeMode": "contain",
11+
"backgroundColor": "#ffffff"
12+
},
13+
"updates": {
14+
"fallbackToCacheTimeout": 0
15+
},
16+
"assetBundlePatterns": [
17+
"**/*"
18+
],
19+
"ios": {
20+
"supportsTablet": true
21+
},
22+
"android": {
23+
"adaptiveIcon": {
24+
"foregroundImage": "./assets/adaptive-icon.png",
25+
"backgroundColor": "#FFFFFF"
26+
}
27+
},
28+
"web": {
29+
"favicon": "./assets/favicon.png"
30+
}
31+
}
32+
}

assets/adaptive-icon.png

17.1 KB
Loading

assets/favicon.png

1.43 KB
Loading

assets/icon.png

21.9 KB
Loading

assets/splash.png

47.3 KB
Loading

babel.config.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = function(api) {
2+
api.cache(true);
3+
return {
4+
presets: ['babel-preset-expo'],
5+
};
6+
};

components/AddCard.js

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React, { Component } from 'react';
2+
import { View, Text, TextInput, StyleSheet } from 'react-native';
3+
import { addCardToDeck } from '../utils/helpers';
4+
import Button from './Button';
5+
6+
export default class AddCard extends Component {
7+
state = {
8+
question: '',
9+
answer: '',
10+
}
11+
12+
onSubmit = () => {
13+
const { title } = this.props.route.params;
14+
const { fetchData, navigation } = this.props;
15+
16+
addCardToDeck(title, this.state)
17+
.then(() => {
18+
fetchData();
19+
});
20+
21+
navigation.navigate('Decks');
22+
}
23+
24+
render() {
25+
return(
26+
<View style={styles.container}>
27+
<TextInput
28+
style={styles.input}
29+
placeholder="Question"
30+
onChangeText={(question) => this.setState({question})}
31+
/>
32+
<TextInput
33+
style={styles.input}
34+
placeholder="Answer"
35+
onChangeText={(answer) => this.setState({answer})}
36+
/>
37+
<Button
38+
style={{ backgroundColor: '#000' }}
39+
onPress={this.onSubmit}>
40+
<Text style={{ color: '#fff', fontSize: 17 }}>Submit</Text>
41+
</Button>
42+
</View>
43+
)
44+
}
45+
}
46+
47+
const styles = StyleSheet.create({
48+
container: {
49+
flex: 1,
50+
justifyContent: 'center',
51+
alignItems: 'center',
52+
padding: 20
53+
},
54+
input: {
55+
width: '100%',
56+
borderColor: '#000',
57+
borderStyle: 'solid',
58+
borderWidth: 1,
59+
borderRadius: 10,
60+
paddingTop: 5,
61+
paddingBottom: 5,
62+
paddingLeft: 10,
63+
paddingRight: 10,
64+
marginBottom: 45,
65+
}
66+
})

components/Button.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
import { Text, TouchableOpacity, StyleSheet } from 'react-native';
3+
4+
export default function Button({ children, onPress, style = {} }) {
5+
return(
6+
<TouchableOpacity style={[styles.button, style]} onPress={onPress}>
7+
{children}
8+
</TouchableOpacity>
9+
)
10+
}
11+
12+
const styles = StyleSheet.create({
13+
button: {
14+
borderStyle: 'solid',
15+
borderWidth: 1,
16+
borderColor: '#000',
17+
paddingTop: 15,
18+
paddingBottom: 15,
19+
paddingLeft: 35,
20+
paddingRight: 35,
21+
borderRadius: 10,
22+
marginBottom: 20,
23+
alignItems: 'center'
24+
}
25+
})

components/Deck.js

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React from 'react';
2+
import { View, Text, StyleSheet } from 'react-native';
3+
import Button from './Button';
4+
import DeckInfo from './DeckInfo';
5+
6+
export default function Deck(props) {
7+
const { route: { params: { title, count } }, navigation } = props;
8+
9+
const goToQuiz = () => {
10+
navigation.navigate('Quiz', {
11+
title,
12+
count,
13+
quizNo: 0
14+
});
15+
}
16+
17+
const addCard = () => {
18+
navigation.navigate('AddCard', {
19+
title
20+
});
21+
}
22+
23+
return (
24+
<View style={styles.container}>
25+
<DeckInfo
26+
title={title}
27+
count={count}
28+
style={{ alignItems: 'center', marginBottom: 45 }} />
29+
<View>
30+
<Button
31+
onPress={addCard}>
32+
<Text>Add Card</Text>
33+
</Button>
34+
{count ? <Button
35+
style={{ backgroundColor: '#000' }}
36+
onPress={goToQuiz}>
37+
<Text style={{ color: "#fff" }}>Start Quiz</Text>
38+
</Button> : null}
39+
</View>
40+
</View>
41+
)
42+
}
43+
44+
const styles = StyleSheet.create({
45+
container: {
46+
justifyContent: 'center',
47+
alignItems: 'center',
48+
flex: 1,
49+
},
50+
});

0 commit comments

Comments
 (0)