diff --git a/Template.js b/Template.js
index 73716b8..965079c 100644
--- a/Template.js
+++ b/Template.js
@@ -8,7 +8,7 @@ const Component = () => {
// View -----------------------
return (
-
+
);
};
diff --git a/package-lock.json b/package-lock.json
index 65b89e7..362c06a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "1.0.0",
"dependencies": {
"@expo/vector-icons": "^15.0.3",
+ "@react-native-picker/picker": "^2.11.4",
"@react-navigation/native": "^7.1.18",
"@react-navigation/native-stack": "^7.5.1",
"expo": "^54.0.20",
@@ -3054,6 +3055,19 @@
"node": ">=14"
}
},
+ "node_modules/@react-native-picker/picker": {
+ "version": "2.11.4",
+ "resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.11.4.tgz",
+ "integrity": "sha512-Kf8h1AMnBo54b1fdiVylP2P/iFcZqzpMYcglC28EEFB1DEnOjsNr6Ucqc+3R9e91vHxEDnhZFbYDmAe79P2gjA==",
+ "license": "MIT",
+ "workspaces": [
+ "example"
+ ],
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
"node_modules/@react-native/assets-registry": {
"version": "0.81.5",
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.81.5.tgz",
diff --git a/package.json b/package.json
index 47f7106..edb9d14 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
},
"dependencies": {
"@expo/vector-icons": "^15.0.3",
+ "@react-native-picker/picker": "^2.11.4",
"@react-navigation/native": "^7.1.18",
"@react-navigation/native-stack": "^7.5.1",
"expo": "^54.0.20",
diff --git a/src/components/UI/Form.js b/src/components/UI/Form.js
new file mode 100644
index 0000000..394c141
--- /dev/null
+++ b/src/components/UI/Form.js
@@ -0,0 +1,114 @@
+import {KeyboardAvoidingView, ScrollView, StyleSheet, Text, TextInput, View} from "react-native";
+import {Picker} from "@react-native-picker/picker";
+
+import {Button, ButtonTray} from "./Button";
+import Icons from "./Icons";
+
+
+const Form = ({children, onSubmit, onCancel, submitLabel, submitIcon}) => {
+
+ // Initialisation -------------
+ // State ----------------------
+ // Handlers -------------------
+ // View -----------------------
+
+ return (
+
+
+
+ {children}
+
+
+
+
+
+ );
+};
+
+const InputText = ({label, value, onChange}) => {
+ // Initialisation -------------
+ // State ----------------------
+ // Handlers -------------------
+ // View -----------------------
+ return (
+
+ {label}
+
+
+ )
+};
+
+const InputSelect = ({label, prompt, options, value, onChange}) => {
+ // Initialisation -------------
+ // State ----------------------
+ // Handlers -------------------
+ // View -----------------------
+ return (
+
+ {label}
+
+
+ {
+ options.map((option, index) => )
+ }
+
+
+ )
+};
+
+// Compose components
+Form.InputText = InputText;
+Form.InputSelect = InputSelect;
+
+// Styles
+
+const styles = StyleSheet.create({
+ itemLabel: {
+ color: 'gray',
+ fontSize: 16,
+ margin: 5,
+ },
+ itemTextInput: {
+ height: 50,
+ paddingLeft: 10,
+ fontSize: 16,
+ backgroundColor: 'white',
+ borderRadius: 7,
+ borderWidth: 1,
+ borderColor: 'lightgray',
+ },
+ formItems: {
+ gap: 5,
+ },
+ formContainer: {
+ gap: 10
+ },
+ itemPickerStyle: {
+ height: 50,
+ backgroundColor: 'whitesmoke',
+ },
+ itemPickerPromptStyle: {
+ color: 'gray',
+ },
+});
+
+export default Form;
\ No newline at end of file
diff --git a/src/components/entity/modules/ModuleView.js b/src/components/entity/modules/ModuleView.js
index d1852ec..134aad3 100644
--- a/src/components/entity/modules/ModuleView.js
+++ b/src/components/entity/modules/ModuleView.js
@@ -3,7 +3,7 @@ import FullWidthImage from "react-native-fullwidth-image";
import {Button, ButtonTray} from "../../UI/Button";
import Icons from "../../UI/Icons.js"
-const ModuleView = ({module, onDelete}) => {
+const ModuleView = ({module, onDelete, onModify}) => {
// Initialisation -------------
// State ----------------------
// Handlers -------------------
@@ -35,7 +35,11 @@ const ModuleView = ({module, onDelete}) => {
- } label={"Modify"}/>
+ }
+ label={"Modify"}
+ onClick={onModify}
+ />
}
label={"Delete"}
diff --git a/src/components/entity/modules/moduleForm.js b/src/components/entity/modules/moduleForm.js
new file mode 100644
index 0000000..a46990b
--- /dev/null
+++ b/src/components/entity/modules/moduleForm.js
@@ -0,0 +1,103 @@
+import {StyleSheet, Text, TextInput, View} from "react-native";
+import {useState} from "react";
+import Icons from "../../UI/Icons";
+import Form from "../../UI/Form";
+
+const defaultModule = {
+ ModuleID: null,
+ ModuleCode: null,
+ ModuleName: null,
+ ModuleLevel: null,
+ ModuleLeaderID: null,
+ ModuleLeaderName: null,
+ ModuleImage: null,
+};
+
+const ModuleForm = ({originalModule, onSubmit, onCancel}) => {
+
+ // Initialisation -------------
+
+ defaultModule.ModuleID = Math.floor(100000 + Math.random() * 900000);
+ defaultModule.ModuleImage = 'https://images.freeimages.com/images/small-preview/cf5/cellphone-1313194.jpg';
+
+ const levels = [
+ {value: 3, label: '3 (Foundation)'},
+ {value: 4, label: '4 (First Year)'},
+ {value: 5, label: '5 (Second Year)'},
+ {value: 6, label: '6 (Third Year)'},
+ {value: 7, label: '7 (Masters)'},
+ ];
+
+
+ // State ----------------------
+
+ const [module, setModule] = useState(originalModule || defaultModule);
+
+ // Handlers -------------------
+
+ const handleChange = (field, value) => {
+ setModule({...module, [field]: value})
+ };
+
+ const handleSubmit = () => onSubmit(module);
+
+
+ // View -----------------------
+
+ const submitLabel = originalModule ? 'Modify' : 'Add';
+ const submitIcon = originalModule ? : ;
+
+
+ return (
+ handleChange('ModuleCode', value)}
+ />
+
+ handleChange('ModuleName', value)}
+ />
+
+ handleChange('ModuleLevel', value)}
+ />
+
+ handleChange('ModuleLeaderName', value)}
+ />
+
+ handleChange('ModuleImage', value)}
+ />
+
+ {/* This is to test whether the correct Data was being stored in Local State */}
+ {/* {module.ModuleCode} {module.ModuleName} */}
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ formContainer: {},
+ item: {},
+});
+
+export default ModuleForm;
\ No newline at end of file
diff --git a/src/components/screens/ModuleAddScreen.js b/src/components/screens/ModuleAddScreen.js
index ef5a929..6a2f192 100644
--- a/src/components/screens/ModuleAddScreen.js
+++ b/src/components/screens/ModuleAddScreen.js
@@ -1,36 +1,20 @@
-import {StyleSheet, Text} from "react-native";
+import {StyleSheet, Text, TextInput, View} from "react-native";
import Screen from "../layout/Screen";
-import {Button, ButtonTray} from "../UI/Button";
-import Icons from "../UI/Icons";
+import ModuleForm from "../entity/modules/moduleForm";
-const defaultModule = {
- ModuleID: Math.floor(100000 + Math.random()*900000),
- ModuleCode: "CI6330",
- ModuleName: "Mobile Application Development",
- ModuleLevel: 6,
- ModuleLeaderID: 1,
- ModuleLeaderName: "Graeme Jones",
- ModuleImage: 'https://images.freeimages.com/images/small-preview/cf5/cellphone-1313194.jpg',
-};
export const ModuleAddScreen = ({navigation, route}) => {
// Initialisation -------------
- const { onAdd } = route.params;
-
+ const {onAdd} = route.params;
// State ----------------------
// Handlers -------------------
- const handleAdd = () => onAdd(defaultModule);
const handleCancel = navigation.goBack;
// View -----------------------
return (
- Add
-
-
- } onClick={handleAdd} />
-
+
);
};
diff --git a/src/components/screens/ModuleListScreen.js b/src/components/screens/ModuleListScreen.js
index 115e9e4..1947231 100644
--- a/src/components/screens/ModuleListScreen.js
+++ b/src/components/screens/ModuleListScreen.js
@@ -15,7 +15,6 @@ const ModuleListScreen = ({navigation}) => {
// State ----------------------
const [modules, setModules] = useState(initialModules);
-
// Handlers -------------------
const handleDelete = (module) =>
@@ -27,17 +26,28 @@ const ModuleListScreen = ({navigation}) => {
navigation.goBack();
}
- const handleAdd = (module) => setModules([ ...modules, module]);
+ const handleAdd = (module) => setModules([...modules, module]);
+
+ const handleModify = (updatedModule) => setModules(
+ modules.map((module) => (module.ModuleID === updatedModule.ModuleID) ? updatedModule : module),
+ );
const onAdd = (module) => {
handleAdd(module);
navigation.goBack();
};
+ const onModify = (module) => {
+ handleModify(module);
+ navigation.replace('ModuleViewScreen', { module, onDelete, onModify });
+ };
+
const goToViewScreen = (module) =>
- navigation.navigate('ModuleViewScreen', {module, onDelete});
+ navigation.navigate('ModuleViewScreen', {module, onDelete, onModify});
+
+ const goToAddScreen = () =>
+ navigation.navigate('ModuleAddScreen', {onAdd});
- const goToAddScreen = () => navigation.navigate('ModuleAddScreen', {onAdd});
// View -----------------------
@@ -45,9 +55,9 @@ const ModuleListScreen = ({navigation}) => {
{/**/}
- } onClick={goToAddScreen} />
+ } onClick={goToAddScreen}/>
-
+
);
};
diff --git a/src/components/screens/ModuleModifyScreen.js b/src/components/screens/ModuleModifyScreen.js
index ae2ccec..a0ec622 100644
--- a/src/components/screens/ModuleModifyScreen.js
+++ b/src/components/screens/ModuleModifyScreen.js
@@ -1,14 +1,24 @@
import {StyleSheet, Text} from "react-native";
import Screen from "../layout/Screen";
+import ModuleForm from "../entity/modules/moduleForm";
-export const ModuleModifyScreen = () => {
+export const ModuleModifyScreen = ({navigation, route}) => {
// Initialisation -------------
+ const {module, onModify} = route.params;
+
// State ----------------------
// Handlers -------------------
+
+ const handleCancel = () => navigation.navigate.goBack();
+
// View -----------------------
return (
- Modify
+
);
};
diff --git a/src/components/screens/ModuleViewScreen.js b/src/components/screens/ModuleViewScreen.js
index 3e90694..2a9da5f 100644
--- a/src/components/screens/ModuleViewScreen.js
+++ b/src/components/screens/ModuleViewScreen.js
@@ -3,16 +3,23 @@ import Screen from "../layout/Screen";
import ModuleView from "../entity/modules/ModuleView";
-export const ModuleViewScreen = ({route}) => {
+export const ModuleViewScreen = ({navigation, route}) => {
// Initialisation -------------
- const {module, onDelete} = route.params;
+ const {module, onDelete, onModify} = route.params;
// State ----------------------
// Handlers -------------------
+
+ const goToModifyScreen = () => navigation.replace("ModuleModifyScreen", { module, onModify });
+
// View -----------------------
return (
-
+
);
};