From 81836475268b3e2b44903dfa7532128c18d5755b Mon Sep 17 00:00:00 2001 From: Antoine-Lee Date: Sat, 22 Jul 2023 11:23:19 +0800 Subject: [PATCH] final. todo: clean up --- frontend/app/screens/LoginScreen.js | 1 + frontend/app/screens/PatientRegistration.js | 76 +++--- frontend/app/screens/SignupScreen.js | 264 ++++++++++---------- frontend/package-lock.json | 54 +++- frontend/package.json | 4 +- 5 files changed, 215 insertions(+), 184 deletions(-) diff --git a/frontend/app/screens/LoginScreen.js b/frontend/app/screens/LoginScreen.js index 745af77..6e50bd8 100644 --- a/frontend/app/screens/LoginScreen.js +++ b/frontend/app/screens/LoginScreen.js @@ -36,6 +36,7 @@ function LoginScreen({ navigation }) { const auth = getAuth(); await signInWithEmailAndPassword(auth, email, password); + // await signInWithEmailAndPassword(auth, "lee12048@gapps.uwcsea.edu.sg", "Supersecret1"); const idToken = await auth.currentUser.getIdToken(); diff --git a/frontend/app/screens/PatientRegistration.js b/frontend/app/screens/PatientRegistration.js index 0d8078b..23527eb 100644 --- a/frontend/app/screens/PatientRegistration.js +++ b/frontend/app/screens/PatientRegistration.js @@ -239,40 +239,22 @@ const PatientRegistration = ({ route, navigation }) => { language: "", }); - const ethnicityRef = useRef(); - const birthplaceRef = useRef(); - const languageRef = useRef(); - - const [pickerVisible, setPickerVisible] = useState(false); - - const renderPickerSelect = (selectedValue, onValueChange, items, pickerRef) => ( + const renderPickerSelect = (selectedValue, onValueChange, items) => ( - {pickerVisible && ( - { - onValueChange(itemValue); - setPickerVisible(false); - }} - style={styles.pickerSelectStyles} - > - - {items.map((item) => ( - - ))} - - )} - {!pickerVisible && ( - setPickerVisible(true)}> - - {selectedValue || "Select"} - - - )} + { + onValueChange(itemValue); + }} + style={styles.pickerSelectStyles} + > + + {items.map((item) => ( + + ))} + - ); - - + ); const [datePickerModalActive, setDatePickerModalActive] = useState(false); @@ -349,8 +331,7 @@ const PatientRegistration = ({ route, navigation }) => { {renderPickerSelect( formData.ethnicity, (value) => handleChange(value, "ethnicity"), - ethnicities, - ethnicityRef + ethnicities )} @@ -358,8 +339,7 @@ const PatientRegistration = ({ route, navigation }) => { {renderPickerSelect( formData.birthplace, (value) => handleChange(value, "birthplace"), - countries, - birthplaceRef + countries )} @@ -367,10 +347,10 @@ const PatientRegistration = ({ route, navigation }) => { {renderPickerSelect( formData.language, (value) => handleChange(value, "language"), - languages, - languageRef + languages )} + + { + const chars = "0123456789"; + const passwordLength = 5; + verificationCode = ""; for (var i = 0; i <= passwordLength; i++) { var randomNumber = Math.floor(Math.random() * chars.length); - pass += chars.substring(randomNumber, randomNumber + 1); + verificationCode += chars.substring(randomNumber, randomNumber + 1); } - console.log("actual password:" + pass); - return pass; + console.log("Verification Code: " + verificationCode); + + return verificationCode; } - function SendEmail(name, email, pass) { + const SendEmail = (name, email, pass) => + { var params = { to_name: name, to_email: email, password: pass, }; - emailjs.send(Constants.expoConfig.extra.serviceacc,Constants.expoConfig.extra.templateid,params,Constants.expoConfig.extra.publicapikey); + emailjs.send( + Constants.expoConfig.extra.serviceacc, + Constants.expoConfig.extra.templateid, + params, + Constants.expoConfig.extra.publicapikey + ); } - function Verifyemail() { - if (String(userpassword) == String(pass)) { + const verifyCode = () => + { + if (inputVerificationCode == verificationCode) return true; - } else { - console.log("wrong password"); + else { + Alert.alert("Invalid code", "Wrong code entered. Please try again!"); return false; } } - async function showAlert(name, email) { + async function showAlert(name, email) + { let passwordCorrect = false; let isCancelled = false; - while (!passwordCorrect && !isCancelled) { - userpassword = await new Promise((resolve) => { + while (!passwordCorrect && !isCancelled) + { + inputVerificationCode = await new Promise((resolve) => + { prompt( "Email Verification", - "We've just sent you a verification email with a password. Please enter your password here to proceed!", + "We've just sent you a verification email with a code. Please enter your code here to proceed!", [ { text: "Cancel", @@ -77,24 +99,19 @@ function SignupScreen({ navigation }) { { text: "OK", onPress: (inputPassword) => { - if (/^\d{6}$/.test(inputPassword)) { - resolve(inputPassword); - } else { + if (inputPassword === "") { Alert.alert( "Invalid Password", - "Please enter 6 digits only.", - [ - { - text: "OK", - onPress: () => resolve(null), - }, - ] + "Please enter a password!" ); + resolve(null); } + else + resolve(inputPassword); }, }, { - text: "Resend Email", + text: "Resend email", onPress: () => { SendEmail( name, @@ -106,7 +123,6 @@ function SignupScreen({ navigation }) { }, ], { - // type: "secure-text", cancelable: false, defaultValue: "", placeholder: "password", @@ -114,12 +130,12 @@ function SignupScreen({ navigation }) { ); }); - if (userpassword !== null && !isCancelled) { - if (Verifyemail()) { - console.log("email verified"); + if (inputVerificationCode !== null && !isCancelled) { + if (verifyCode()) { + console.log("Email verified!"); passwordCorrect = true; } else { - console.log("no"); + console.log("Email not verified!"); await new Promise((resolve) => { Alert.alert( "Invalid Password", @@ -134,33 +150,24 @@ function SignupScreen({ navigation }) { return !isCancelled; // Return true if not cancelled, false otherwise } - async function ValidateEmail(name, email) { - console.log("in validate email"); - pass = generateRandomPassword(); - SendEmail(name, email, pass); + const validateEmail = async (name, email) => + { + console.log("In validate email"); + verificationCode = generateRandomPassword(); + SendEmail(name, email, verificationCode); try { if ((await showAlert(name, email)) == true) { - console.log("verified!!!"); + console.log("Verified!!!"); return true; } else { return false; } } catch (error) { - console.log("Error occurred:", error); - // Handle the error as needed + console.log("An error occurred:", error); } } - const [name, setName] = useState(""); - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); - const [confirmedPassword, setConfirmedPassword] = useState(""); - - const { setIsLoading } = useContext(LoadingContext); - - const passwordRegex = /^(?=.*\d)[A-Za-z\d]{8,}$/; - let handleSignUp = async (evt) => { evt.preventDefault(); // Check if user has entered all fields @@ -181,103 +188,90 @@ function SignupScreen({ navigation }) { return; } - if (!passwordRegex.test(password)) { + // if ((await validateEmail(name, email)) == true) { + const getnames = await fetch(`https://project-fuxi-fsugt.ondigitalocean.app/institute/namerepeat?name=${name}`); + const values = await getnames.json(); + + if (values.message === "same") { Alert.alert( "Error", - "Password must have at least 8 characters and include a digit" + "Institute with the same name already exists, please choose a different name and try again." ); + setIsLoading(false); + console.log("EXISTS"); return; } - if ((await ValidateEmail(name, email)) == true) { - const getnames = await fetch( - `https://project-fuxi-fsugt.ondigitalocean.app/institute/namerepeat?name=${encodeURIComponent(name)}`, - { - method: "GET", - } + setIsLoading(true); + let userCredential; + const auth = getAuth(); + try { + userCredential = await createUserWithEmailAndPassword( + auth, + email, + password ); - const values = await getnames.json(); - - if (values.message === "same") { + } catch (error) { + console.log(error); + if (error.code === "auth/email-already-in-use") { Alert.alert( "Error", - "Institute with the same name already exists, please choose a different name and try again." + "Email is already in use. Please login instead.", + [ + { + text: "Go to Login", + onPress: () => navigation.navigate("Login"), + }, + ] ); - setIsLoading(false); - console.log("EXISTS"); - return; + } else { + Alert.alert("Error", error.message); } + setIsLoading(false); + return; + } - setIsLoading(true); - let userCredential; - const auth = getAuth(); - try { - userCredential = await createUserWithEmailAndPassword( - auth, - email, - password - ); - } catch (error) { - console.log(error); - if (error.code === "auth/email-already-in-use") { - Alert.alert( - "Error", - "Email is already in use. Please login instead.", - [ - { - text: "Go to Login", - onPress: () => navigation.navigate("Login"), - }, - ] - ); - } else { - Alert.alert("Error", error.message); + try { + const user = userCredential.user; + const response = await fetch( + `https://project-fuxi-fsugt.ondigitalocean.app/institute/signup`, + { + body: JSON.stringify({ + uid: user.uid, + email: user.email, + name, + }), + headers: { "Content-Type": "application/json" }, + method: "POST", } - setIsLoading(false); - return; - } - - try { - const user = userCredential.user; - const response = await fetch( - `https://project-fuxi-fsugt.ondigitalocean.app/institute/signup`, - { - body: JSON.stringify({ - uid: user.uid, - email: user.email, - name, - }), - headers: { "Content-Type": "application/json" }, - method: "POST", - } - ); - const data = await response.json(); + ); + const data = await response.json(); - const idToken = await auth.currentUser.getIdToken(); - const response2 = await fetch( - `https://project-fuxi-fsugt.ondigitalocean.app/institute/verify`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - token: idToken, - }, - } - ); - const data2 = await response2.json(); + const idToken = await auth.currentUser.getIdToken(); + const response2 = await fetch( + `https://project-fuxi-fsugt.ondigitalocean.app/institute/verify`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + token: idToken, + }, + } + ); + const data2 = await response2.json(); - setIsLoading(false); - navigation.navigate("Dashboard"); - } catch (error) { - console.log(error); - Alert.alert( - "Error", - "An error occurred while processing your request" - ); + setIsLoading(false); + navigation.navigate("Dashboard"); + } catch (error) { + console.log(error); + Alert.alert( + "Error", + "An error occurred while processing your request" + ); - setIsLoading(false); - } + setIsLoading(false); } + // } }; return ( diff --git a/frontend/package-lock.json b/frontend/package-lock.json index c801528..a7cd1d3 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -15,7 +15,7 @@ "@fortawesome/react-native-fontawesome": "^0.3.0", "@react-native-community/datetimepicker": "^6.5.2", "@react-native-community/slider": "4.2.4", - "@react-native-picker/picker": "^2.4.10", + "@react-native-picker/picker": "2.4.8", "@react-navigation/native": "^6.0.13", "@react-navigation/native-stack": "^6.9.0", "expo": "^47.0.0", @@ -24,8 +24,10 @@ "firebase": "^9.21.0", "react": "18.1.0", "react-native": "0.70.8", + "react-native-dialog": "^9.3.0", "react-native-dropdown-picker": "^5.4.6", "react-native-modern-datepicker": "^1.0.0-beta.91", + "react-native-picker-select": "^8.0.4", "react-native-prompt-android": "^1.1.0", "react-native-safe-area-context": "4.4.1", "react-native-screens": "~3.18.0", @@ -5572,9 +5574,9 @@ } }, "node_modules/@react-native-picker/picker": { - "version": "2.4.10", - "resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.4.10.tgz", - "integrity": "sha512-EvAlHmPEPOwvbP6Pjg/gtDV3XJzIjIxr10fXFNlX5r9HeHw582G1Zt2o8FLyB718nOttgj8HYUTGxvhu4N65sQ==", + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.4.8.tgz", + "integrity": "sha512-5NQ5XPo1B03YNqKFrV6h9L3CQaHlB80wd4ETHUEABRP2iLh7FHLVObX2GfziD+K/VJb8G4KZcZ23NFBFP1f7bg==", "peerDependencies": { "react": ">=16", "react-native": ">=0.57" @@ -9695,6 +9697,11 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, "node_modules/lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", @@ -12391,6 +12398,14 @@ "nullthrows": "^1.1.1" } }, + "node_modules/react-native-dialog": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/react-native-dialog/-/react-native-dialog-9.3.0.tgz", + "integrity": "sha512-JEOJY/0AzTM9grIl0BL8o/IJPIJru7k5MPj9POTE9RRezUEtgn0YSvCpTlBtG0obWgOdzg2otMz1OQvMXS0wMQ==", + "peerDependencies": { + "react-native": ">=0.63.0" + } + }, "node_modules/react-native-dotenv": { "version": "3.4.9", "resolved": "https://registry.npmjs.org/react-native-dotenv/-/react-native-dotenv-3.4.9.tgz", @@ -12429,6 +12444,37 @@ "react-native": ">=0.59" } }, + "node_modules/react-native-picker-select": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/react-native-picker-select/-/react-native-picker-select-8.0.4.tgz", + "integrity": "sha512-orBjPIwBkV5oipyVw263YNMI56f6Kj3p/ejabZoCYYNSG3AiLVVhC2RqsxMgDA7IayyURAW+AlV+mDJyVqLBkg==", + "dependencies": { + "@react-native-picker/picker": "^1.8.3", + "lodash.isequal": "^4.5.0" + } + }, + "node_modules/react-native-picker-select/node_modules/@react-native-picker/picker": { + "version": "1.16.8", + "resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-1.16.8.tgz", + "integrity": "sha512-pacdQDX6V6EmjF+HoiIh6u++qx4mTK0WnhgUHRc01B+Qt5eoeUwseBqmqfTSXTx/aHDEd6PiIw7UGvKgFoqgFQ==", + "peerDependencies": { + "react": "16 || 17", + "react-native": ">=0.57" + } + }, + "node_modules/react-native-picker-select/node_modules/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react-native-prompt-android": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/react-native-prompt-android/-/react-native-prompt-android-1.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index a17c116..3929cf8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,7 +16,7 @@ "@fortawesome/react-native-fontawesome": "^0.3.0", "@react-native-community/datetimepicker": "^6.5.2", "@react-native-community/slider": "4.2.4", - "@react-native-picker/picker": "^2.4.10", + "@react-native-picker/picker": "2.4.8", "@react-navigation/native": "^6.0.13", "@react-navigation/native-stack": "^6.9.0", "expo": "^47.0.0", @@ -25,8 +25,10 @@ "firebase": "^9.21.0", "react": "18.1.0", "react-native": "0.70.8", + "react-native-dialog": "^9.3.0", "react-native-dropdown-picker": "^5.4.6", "react-native-modern-datepicker": "^1.0.0-beta.91", + "react-native-picker-select": "^8.0.4", "react-native-prompt-android": "^1.1.0", "react-native-safe-area-context": "4.4.1", "react-native-screens": "~3.18.0",