diff --git a/actions/index.js b/actions/index.js
index 33428bb..823c73a 100644
--- a/actions/index.js
+++ b/actions/index.js
@@ -1,6 +1,8 @@
export const LOAD_DECKS = "LOAD_DECKS";
export const NEW_DECK = "NEW_DECK";
+export const ADD_CARD = "ADD_CARD";
+
export function loadDecks(decks){
return {
type: LOAD_DECKS,
@@ -13,4 +15,12 @@ export function newDeck(deck){
type: NEW_DECK,
deck
}
+}
+
+export function addCard(deckKey, card){
+ return {
+ type: ADD_CARD,
+ deckKey,
+ card
+ }
}
\ No newline at end of file
diff --git a/components/flashcards/AddCard.js b/components/flashcards/AddCard.js
index 4bac0b5..52397b4 100644
--- a/components/flashcards/AddCard.js
+++ b/components/flashcards/AddCard.js
@@ -1,15 +1,128 @@
import React, { Component } from 'react';
-import { Text, View } from 'react-native';
+import { StyleSheet, Text, View, TextInput, TouchableOpacity, Alert } from 'react-native';
+import { connect } from 'react-redux';
+import { NavigationActions } from 'react-navigation';
+import MaterialIcons from '@expo/vector-icons/MaterialIcons';
-export default class AddCard extends Component {
+import { addCard } from '../../actions';
+import { addCardToDeck, getDeck } from '../../services';
+
+import { COLOR_WHITE, COLOR_B_5 } from '../../utils/colors';
+
+class AddCard extends Component {
+
+ state = {
+ card: {
+ question: '',
+ answer: ''
+ }
+ }
+
+ reset() {
+ this.setState({
+ deck: {
+ question: '',
+ answer: ''
+ }
+ });
+ }
+
+ async addCard() {
+ const { deckKey, refresher } = this.props.navigation.state.params;
+
+ try {
+ if (this.state.card.question.trim() === '' || this.state.card.answer.trim() === '') {
+ Alert.alert(
+ 'Required',
+ "Type a valid question/answer.",
+ [{ text: 'Ok', onPress: () => { } }],
+ { cancelable: false });
+ return;
+ }
+
+
+ await addCardToDeck(deckKey, this.state.card);
+ this.props.dispatch(addCard(deckKey, this.state.card));
+ refresher();
+ this.props.navigation.goBack();
+
+ } catch (e) {
+ Alert.alert(
+ 'Error',
+ `Error adding a new card to deck '${deckKey}'.`,
+ [
+ { text: 'Ok', onPress: () => { } }
+ ]);
+ console.error(e);
+ }
+
+ this.reset();
+ }
render() {
+ const { deckKey } = this.props.navigation.state.params;
return (
-
- AddCard
+
+ Question
+ {
+ this.setState((prev) => {
+ const prevCard = prev.card;
+ return {
+ card: {
+ ...prevCard,
+ question
+ }
+ }
+ })
+ }} />
+
+ Answer
+ {
+ this.setState((prev) => {
+ const prevCard = prev.card;
+ return {
+ card: {
+ ...prevCard,
+ answer
+ }
+ }
+ })
+ }} />
+
+
+
+
+
+
);
}
-}
\ No newline at end of file
+}
+
+const styles = StyleSheet.create({
+ container: {
+ alignItems: 'center',
+ flex: 1
+ },
+ rowContainer: {
+ flexDirection: 'row',
+ justifyContent: 'space-between'
+ },
+ text: {
+ fontSize: 20
+ },
+ saveBtn: {
+ backgroundColor: COLOR_B_5,
+ borderRadius: 2,
+ margin: 5,
+ padding: 10
+ }
+})
+
+export default connect()(AddCard);
\ No newline at end of file
diff --git a/components/flashcards/DeckDetails.js b/components/flashcards/DeckDetails.js
index 8bd4554..acd064f 100644
--- a/components/flashcards/DeckDetails.js
+++ b/components/flashcards/DeckDetails.js
@@ -17,6 +17,14 @@ class DeckDetails extends Component {
}
}
+ /**
+ * Child navigate.goBack() does not re-render state.
+ * https://github.com/react-navigation/react-navigation/issues/922
+ */
+ refresher(){
+ this.setState({});
+ }
+
render() {
const { deck } = this.props;
if (typeof deck === 'undefined') {
@@ -42,7 +50,7 @@ class DeckDetails extends Component {
{deck.cards.length} Card(s)
-
+ this.props.navigation.navigate('AddCard', { deckKey: deck.name, refresher: this.refresher.bind(this) })}>
Add Card
diff --git a/reducers/index.js b/reducers/index.js
index eb12deb..480cff4 100644
--- a/reducers/index.js
+++ b/reducers/index.js
@@ -1,6 +1,7 @@
import {
LOAD_DECKS,
- NEW_DECK
+ NEW_DECK,
+ ADD_CARD
} from '../actions';
function decks(state = { decks: {} }, action) {
@@ -26,6 +27,21 @@ function decks(state = { decks: {} }, action) {
decks
}
}
+ case ADD_CARD: {
+ const { card, deckKey } = action;
+ const freshDeck = decks[deckKey];
+
+ freshDeck.cards.push(card);
+
+ const freshDecks = {
+ ...decks,
+ [deckKey]: freshDeck
+ }
+ return {
+ decks: freshDecks
+ }
+
+ }
default: {
return state;
}
diff --git a/services/index.js b/services/index.js
index 12835c4..f67180f 100644
--- a/services/index.js
+++ b/services/index.js
@@ -11,4 +11,22 @@ export async function persistDeck(deck){
export async function loadDecks() {
const decks = JSON.parse(await AsyncStorage.getItem(FLASHCARDS_STORAGE_KEY));
return decks !== null ? decks : [];
+}
+
+export async function getDeck(deckKey){
+ const decks = await loadDecks();
+ const deck = decks[deckKey];
+ return deck;
+}
+
+export async function addCardToDeck(deckKey, card){
+ const deck = await getDeck(deckKey);
+
+ if(typeof deck === 'undefined'){
+ console.warn(`Trying to fetch invalid deck: ${deckKey}`);
+ return;
+ }
+
+ deck.cards.push(card)
+ await persistDeck(deck);
}
\ No newline at end of file