diff --git a/README.md b/README.md
index ccd6ef1..7827381 100644
--- a/README.md
+++ b/README.md
@@ -86,6 +86,22 @@ The updating screen provides a form for updating an existing `Move`.
>
+## Some business logic
+
+While the back end doesn't forbid a `Move` from being both weak against and effective against the same one type,
+it should. That's one of the flaws of that API.
+
+In this app, we did implement the business logic described above in our callbacks for our `MultiSelect` elements, like
+so:
+
+```typescript
+const handleSelectType = (selectedTypes: string[], setTypes: React.Dispatch>, otherSelectedTypes: string[]) => {
+ const uniqueSelectedTypes = Array.from(new Set(selectedTypes));
+ const withoutDuplicatesFromOtherColumn = uniqueSelectedTypes.filter(type => !otherSelectedTypes.includes(type));
+ setTypes(withoutDuplicatesFromOtherColumn);
+};
+```
+
## Using the app
### Running the backend
@@ -94,10 +110,10 @@ In order to use this app, you will need to run the dedicated backend. A `README`
with [instructions](https://github.com/draialexis/pokemong_api#user-content-prep-steps) is provided
for that purpose.
-### Connecting to the backend locally
+### Connecting to the backend locally
First, please find the `config.ts` file at the root of this project, and replace ~~`192.168.0.15`~~
-with the IPv4 address associated with your own Wi-Fi adapter.
+with the IPv4 address associated with your own Wi-Fi adapter.
To find that address out, you can run `ipconfig` on Windows or `ifconfig` on macOS/Linux in your terminal.
diff --git a/screens/moves/MoveFormScreen.tsx b/screens/moves/MoveFormScreen.tsx
index 576ffe6..d581a3f 100644
--- a/screens/moves/MoveFormScreen.tsx
+++ b/screens/moves/MoveFormScreen.tsx
@@ -1,23 +1,32 @@
// screens/moves/MoveFormScreen.tsx
-import React, { useEffect, useState } from 'react';
-import { Button, StyleSheet, Text, TextInput } from 'react-native';
-import { StackNavigationProp } from '@react-navigation/stack';
-import { RootStackParamList } from "../../navigation/navigationTypes";
-import { useDispatch, useSelector } from 'react-redux';
-import { createMove, updateMove } from '../../redux/actions/moveActions';
-import { AppDispatch, RootState } from "../../redux/store";
-import { Move } from "../../entities/Move";
-import { RouteProp } from "@react-navigation/native";
-import { MOVE_FORM } from "../../navigation/constants";
-import { Picker } from "@react-native-community/picker";
-import { ItemValue } from "@react-native-community/picker/typings/Picker";
-import { MoveCategoryName } from "../../entities/MoveCategoryName";
-import { TypeName } from "../../entities/TypeName";
-import MultiSelect from "react-native-multiple-select";
-import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
-import AlertModal from "../../components/AlertModal";
-import { MOVE_ERROR } from "../../redux/constants";
+import React, { useEffect, useState } from 'react';
+import {
+ Button,
+ KeyboardAvoidingView,
+ Modal,
+ Platform,
+ ScrollView,
+ StyleSheet,
+ Text,
+ TextInput,
+ View
+} from 'react-native';
+import { StackNavigationProp } from '@react-navigation/stack';
+import { RootStackParamList } from "../../navigation/navigationTypes";
+import { useDispatch, useSelector } from 'react-redux';
+import { createMove, updateMove } from '../../redux/actions/moveActions';
+import { AppDispatch, RootState } from "../../redux/store";
+import { Move } from "../../entities/Move";
+import { RouteProp } from "@react-navigation/native";
+import { MOVE_FORM } from "../../navigation/constants";
+import { Picker } from "@react-native-community/picker";
+import { ItemValue } from "@react-native-community/picker/typings/Picker";
+import { MoveCategoryName } from "../../entities/MoveCategoryName";
+import { TypeName } from "../../entities/TypeName";
+import MultiSelect from "react-native-multiple-select";
+import AlertModal from "../../components/AlertModal";
+import { MOVE_ERROR } from "../../redux/constants";
type MoveFormScreenNavigationProp = StackNavigationProp;
type MoveFormScreenRouteProp = RouteProp;
@@ -50,6 +59,14 @@ const MoveFormScreen = ({ navigation, route }: Props) => {
});
}, [navigation, route.params?.move]);
+ const [isModalVisible, setModalVisible] = useState(false);
+ const [currentMultiSelect, setCurrentMultiSelect] = useState<'weakAgainst' | 'effectiveAgainst'>('weakAgainst');
+
+ const handleOpenModal = (multiSelect: 'weakAgainst' | 'effectiveAgainst') => {
+ setCurrentMultiSelect(multiSelect);
+ setModalVisible(true);
+ };
+
const [selectedWeakAgainst, setSelectedWeakAgainst] = useState(move.type.weakAgainst);
const [selectedEffectiveAgainst, setSelectedEffectiveAgainst] = useState(move.type.effectiveAgainst);
@@ -76,89 +93,113 @@ const MoveFormScreen = ({ navigation, route }: Props) => {
};
return (
-
- dispatch({ type: MOVE_ERROR, payload: null })}
- />
- Name:
- setMove({ ...move, name: text })}
- style={styles.input}
- />
- Category:
-
- setMove({ ...move, category: itemValue as MoveCategoryName })
- }>
- {Object.values(MoveCategoryName).map((value) =>
-
- )}
-
- Power:
- {
- if (!isNaN(Number(text))) {
- setMove({ ...move, power: Number(text) });
- }
- }}
- style={styles.input}
- keyboardType="numeric"
- />
- Accuracy:
- {
- if (!isNaN(Number(text))) {
- setMove({ ...move, accuracy: Number(text) });
- }
- }}
- style={styles.input}
- keyboardType="numeric"
- />
- Type:
-
- setMove({ ...move, type: { ...move.type, name: itemValue as TypeName } })
- }>
- {Object.values(TypeName).map((value) =>
-
- )}
-
- Weak Against:
- ({ id: value, name: value }))
- }
- uniqueKey="id"
- onSelectedItemsChange={
- (selectedItems) => handleSelectType(selectedItems, setSelectedWeakAgainst, selectedEffectiveAgainst)
- }
- selectedItems={selectedWeakAgainst}
- displayKey="name"
- />
- Effective Against:
- ({ id: value, name: value }))
- }
- uniqueKey="id"
- onSelectedItemsChange={
- (selectedItems) => handleSelectType(selectedItems, setSelectedEffectiveAgainst, selectedWeakAgainst)
- }
- selectedItems={selectedEffectiveAgainst}
- displayKey="name"
- />
-
+
+
+ dispatch({ type: MOVE_ERROR, payload: null })}
+ />
+
+ Name:
+ setMove({ ...move, name: text })}
+ style={styles.input}
+ />
+
+
+ Category:
+
+ setMove({ ...move, category: itemValue as MoveCategoryName })
+ }>
+ {Object.values(MoveCategoryName).map((value) =>
+
+ )}
+
+
+
+ Power:
+ {
+ if (!isNaN(Number(text))) {
+ setMove({ ...move, power: Number(text) });
+ }
+ }}
+ style={styles.input}
+ keyboardType="numeric"
+ />
+
+
+ Accuracy:
+ {
+ if (!isNaN(Number(text))) {
+ setMove({ ...move, accuracy: Number(text) });
+ }
+ }}
+ style={styles.input}
+ keyboardType="numeric"
+ />
+
+
+ Type:
+
+ setMove({ ...move, type: { ...move.type, name: itemValue as TypeName } })
+ }>
+ {Object.values(TypeName).map((value) =>
+
+ )}
+
+
+ Weak Against: {selectedWeakAgainst.join(', ')}
+
+
+ Effective Against: {selectedEffectiveAgainst.join(', ')}
+
+
+
+
+
+ {
+ setModalVisible(!isModalVisible);
+ }}>
+
+
+ ({ id: value, name: value }))
+ }
+ uniqueKey="id"
+ onSelectedItemsChange={
+ (selectedItems) => handleSelectType(selectedItems, currentMultiSelect === 'weakAgainst' ? setSelectedWeakAgainst : setSelectedEffectiveAgainst, currentMultiSelect === 'weakAgainst' ? selectedEffectiveAgainst : selectedWeakAgainst)
+ }
+ selectedItems={currentMultiSelect === 'weakAgainst' ? selectedWeakAgainst : selectedEffectiveAgainst}
+ displayKey="name"
+ />
+
+
+
+
);
};
@@ -167,14 +208,49 @@ const styles = StyleSheet.create({
flex: 1,
padding: 16,
},
+ label: {
+ marginRight: 8,
+ },
input: {
backgroundColor: '#CEC',
borderRadius: 8,
- height: 32,
+ minHeight: 32,
+ flex: 1,
},
- label: {
+ row: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'flex-start',
margin: 8,
- }
+ flexWrap: 'wrap',
+ },
+ centeredView: {
+ flex: 1,
+ justifyContent: "center",
+ alignItems: "center",
+ marginTop: 22
+ },
+ modalView: {
+ margin: 20,
+ backgroundColor: "white",
+ borderRadius: 20,
+ padding: 35,
+ alignItems: "center",
+ shadowColor: "#000",
+ shadowOffset: {
+ width: 0,
+ height: 2
+ },
+ shadowOpacity: 0.25,
+ shadowRadius: 4,
+ elevation: 5
+ },
+ buttonContainer: {
+ margin: 8,
+ },
+ saveButton: {
+ backgroundColor: '#BADA55',
+ },
});
export default MoveFormScreen;