diff --git a/mobile/app/profile/_layout.tsx b/mobile/app/profile/_layout.tsx index 2d267936290b90e3d7922853babeb54d21d5594e..38c320f57c723487503397236c0c8ecbc2c6f3f7 100644 --- a/mobile/app/profile/_layout.tsx +++ b/mobile/app/profile/_layout.tsx @@ -28,6 +28,10 @@ export default function Layout() { title: "Set Up Profile", headerShown: true, }}/> + ); } \ No newline at end of file diff --git a/mobile/app/profile/change_password.tsx b/mobile/app/profile/change_password.tsx new file mode 100644 index 0000000000000000000000000000000000000000..871eae2e7045ba694afab7037b508eaa2d33e1eb --- /dev/null +++ b/mobile/app/profile/change_password.tsx @@ -0,0 +1,7 @@ +import { ChangePasswordPage } from "../../src/profile/screens/change_password_page"; + +export default function ChangePasswordScreen() { + return ( + + ); +} \ No newline at end of file diff --git a/mobile/package-lock.json b/mobile/package-lock.json index 8f3695020338e7d15e7ef3eca0240b54427bff74..e1b43956608d5e033814f97d6858ddeed19e005c 100644 --- a/mobile/package-lock.json +++ b/mobile/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "dependencies": { "@gorhom/bottom-sheet": "^4.6.1", + "@react-native-async-storage/async-storage": "1.21.0", "@react-native-community/datetimepicker": "7.6.1", "@react-native-community/slider": "4.4.2", "@react-native-picker/picker": "2.6.1", @@ -3916,6 +3917,17 @@ "react": "^16.8 || ^17.0 || ^18.0" } }, + "node_modules/@react-native-async-storage/async-storage": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.21.0.tgz", + "integrity": "sha512-JL0w36KuFHFCvnbOXRekqVAUplmOyT/OuCQkogo6X98MtpSaJOKEAeZnYO8JB0U/RIEixZaGI5px73YbRm/oag==", + "dependencies": { + "merge-options": "^3.0.4" + }, + "peerDependencies": { + "react-native": "^0.0.0-0 || >=0.60 <1.0" + } + }, "node_modules/@react-native-community/cli": { "version": "12.3.6", "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-12.3.6.tgz", @@ -10232,6 +10244,14 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -11548,6 +11568,17 @@ "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz", "integrity": "sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==" }, + "node_modules/merge-options": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", + "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", + "dependencies": { + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", diff --git a/mobile/package.json b/mobile/package.json index 380929d2fd3a053dabcf821bf5b8440f41d8518c..bb5ccad657f3d29e351b0c11e79b759fd6ee215f 100644 --- a/mobile/package.json +++ b/mobile/package.json @@ -42,7 +42,8 @@ "react-native-safe-area-context": "4.8.2", "react-native-screens": "~3.29.0", "react-native-svg": "14.1.0", - "@react-native-picker/picker": "2.6.1" + "@react-native-picker/picker": "2.6.1", + "@react-native-async-storage/async-storage": "1.21.0" }, "devDependencies": { "@babel/core": "^7.20.0", diff --git a/mobile/src/common/contexts/data_context.tsx b/mobile/src/common/contexts/data_context.tsx index 83d3a4f8bb5936e797fce2bdd48c73ffac90a4d1..85b25dee5c0735ca0f2359efbbf062b9703f4059 100644 --- a/mobile/src/common/contexts/data_context.tsx +++ b/mobile/src/common/contexts/data_context.tsx @@ -20,6 +20,8 @@ import { ProfileRepository } from "../../profile/domain/repositories/profile_rep import { ProfileDataSourceDev } from "../../profile/infrastructure/datasources/dev/profile_datasource"; import { ProfileRepositoryImpl } from "../../profile/infrastructure/repositories/profile_repository"; import { ActivityDatasourceProd } from "../../infrastructure/datasource/prod/activity_datasource"; +import { useTranslation } from "react-i18next"; +import { ProfileDataSourceProd } from "../../profile/infrastructure/datasources/prod/profile_datasource"; type DataContextType = { statesRepository: StateRepository | null; @@ -42,20 +44,26 @@ const DataContext = createContext({ }); export const DataContextProvider = ({ children }: DataContextProviderProps) => { - //const statesDataSource = new StateDataSourceDev(); - const statesDataSource = new StateDataSourceProd(); + const { i18n:{ language } } = useTranslation(); + const statesDataSource = new StateDataSourceDev(); + //const statesDataSource = new StateDataSourceProd(language); const statesRepository = new StateRepositoryImpl(statesDataSource); - //const authDataSource = new AuthDataSourceDev(); - const authDataSource = new AuthDatasourceProd(); + // + const authDataSource = new AuthDataSourceDev(); + //const authDataSource = new AuthDatasourceProd(); const authRepository = new AuthRepositoryImpl(authDataSource); - //const activityDataSource = new ActivityDatasourceDev(); - const activityDataSource = new ActivityDatasourceProd(); + // + const activityDataSource = new ActivityDatasourceDev(); + //const activityDataSource = new ActivityDatasourceProd(); const activityRepository = new ActivityRepositoryDev(activityDataSource); + // const travelDatasource = new TravelDatasourceDev(); const travelRepository = new TravelRepositoryImpl(travelDatasource); + // const routeDatasource = new RouteDataSourceDev(); const routeRepository = new RouteRepositoryImpl(routeDatasource); - const profileDataSource = new ProfileDataSourceDev(); + // + const profileDataSource = new ProfileDataSourceProd(); const profileRepository = new ProfileRepositoryImpl(profileDataSource); const value = { diff --git a/mobile/src/infrastructure/datasource/prod/activity_datasource.ts b/mobile/src/infrastructure/datasource/prod/activity_datasource.ts index 41e8b4acc45ec16568c2238cce136585b964b46a..4bd9cb84779cbb3eb5cd66c38090af32cbcc82fc 100644 --- a/mobile/src/infrastructure/datasource/prod/activity_datasource.ts +++ b/mobile/src/infrastructure/datasource/prod/activity_datasource.ts @@ -4,10 +4,12 @@ import { ActivityPlaceEntity } from "../../../domain/entities/activity_place_ent import { API_URL } from "../../../common/constants/api"; import { ActivityPlaceModel } from "../../models/prod/activity_place_model"; import { activityPlaceModelToEntity } from "../../utils/activity_utils"; +import { Languages } from "../../../lang/translations"; export class ActivityDatasourceProd implements ActivityDataSource { + constructor(private lang: string = Languages.SPANISH) {} async getPlaceActivity(activityId: number, townId: number, stateId: number, placeNumber: number): Promise { - const { data, status } = await axios.get(`${API_URL}/point/${placeNumber}lang?lang=es`); + const { data, status } = await axios.get(`${API_URL}/point/${placeNumber}lang?lang=${this.lang}`); if (status !== 200) { throw new Error("Error al obtener la información del lugar"); } diff --git a/mobile/src/infrastructure/datasource/prod/state_datasource.ts b/mobile/src/infrastructure/datasource/prod/state_datasource.ts index 7007dbc9102bbe29f52b818df7e5e42c9f9bab8d..d3940f85204d62aa5d4b5880b95cc23a91776105 100644 --- a/mobile/src/infrastructure/datasource/prod/state_datasource.ts +++ b/mobile/src/infrastructure/datasource/prod/state_datasource.ts @@ -12,6 +12,10 @@ import { ActivityModel } from "../../models/prod/activity_model"; import { placeModelToEntity } from "../../utils/place_utils"; export class StateDataSourceProd implements StateDataSource { + private lang: string; + constructor(lang: string = 'es') { + this.lang = lang; + } async getStates(): Promise { const {status, data} = await axios.get(API_URL + '/state'); if (status !== 200) { @@ -20,18 +24,15 @@ export class StateDataSourceProd implements StateDataSource { return data.map(stateModelToEntity); } async getTowns(stateId: number): Promise { - // TODO: get lang from user preferences - const {status, data} = await axios.get(API_URL + '/state/' + stateId + '/town?lang=es'); + const {status, data} = await axios.get(`${API_URL}/state/${stateId}/town?lang=${this.lang}`); if (status !== 200) { throw new Error('Error fetching towns'); } return data.map(townModelToEntity); } async getTownActivities(townId: number): Promise { - // TODO: get lang from user preferences - // TODO: get townId from user preferences console.log('townId', townId); - const {status, data} = await axios.get(API_URL + `/place/town/${townId}/place?lang=es`); + const {status, data} = await axios.get(`${API_URL}/place/town/${townId}/place?lang=${this.lang}`); if (status !== 200) { throw new Error('Error fetching activities'); } @@ -41,7 +42,7 @@ export class StateDataSourceProd implements StateDataSource { async getActivityInfo(activityId: number): Promise { // TODO: get lang from user preferences // TODO: get townId from user preferences - const {status, data} = await axios.get(API_URL + `/place/${activityId}`); + const {status, data} = await axios.get(`${API_URL}/place/${activityId}?lang=${this.lang}`); if (status !== 200) { throw new Error('Error fetching activity'); } diff --git a/mobile/src/lang/components/language_icon.tsx b/mobile/src/lang/components/language_icon.tsx index 94c31bcb393397b6fb97ee247b9aef6fc1c7605f..f2e212315a98681d98686def422ca71f7b6bf69f 100644 --- a/mobile/src/lang/components/language_icon.tsx +++ b/mobile/src/lang/components/language_icon.tsx @@ -1,15 +1,12 @@ import { Entypo } from '@expo/vector-icons'; import { TouchableOpacity } from 'react-native-gesture-handler'; import { useTranslation } from 'react-i18next'; +import { useLang } from '../hooks/useLang'; export const LanguageIcon = () => { - const { i18n } = useTranslation(); - const changeLanguage = () => { - i18n.changeLanguage(i18n.language === 'en' ? 'es' : 'en'); - } - + const { toggleLanguage } = useLang(); return ( - + ); diff --git a/mobile/src/lang/english_lang.ts b/mobile/src/lang/english_lang.ts index 73fb800cb1e9261521b5a08579f3a53750a0aacc..f433c8effb7a7ca807b2e8cd71a661499a11cb61 100644 --- a/mobile/src/lang/english_lang.ts +++ b/mobile/src/lang/english_lang.ts @@ -23,10 +23,15 @@ export const ENGLISH_LANG: Lang = { accountScreen:{ title: "Account", logoutButton: "Logout", + changePasswordButton: "Change password", changeLanguageButton: "Change App Language", selectLanguage: "Select language", saveButton: "Save", }, + changePasswordScreen:{ + title: "Change password", + saveButton: "Save", + }, selectTownScreen:{ title: "Select Town", }, diff --git a/mobile/src/lang/hooks/useLang.ts b/mobile/src/lang/hooks/useLang.ts new file mode 100644 index 0000000000000000000000000000000000000000..b871c59cccb30c859e7b3eae8d2b17f1982e23fb --- /dev/null +++ b/mobile/src/lang/hooks/useLang.ts @@ -0,0 +1,21 @@ +import { useTranslation } from "react-i18next"; +import { Languages } from "../translations"; +import AsyncStorage from '@react-native-async-storage/async-storage' + +export const useLang = () => { + const { i18n } = useTranslation(); + const changeLanguage = (lang: Languages) => { + i18n.changeLanguage(lang); + AsyncStorage.setItem("lang", lang); + } + + const toggleLanguage = () => { + const lang = i18n.language === Languages.SPANISH ? Languages.ENGLISH : Languages.SPANISH; + changeLanguage(lang); + } + + return { + changeLanguage, + toggleLanguage + }; +} \ No newline at end of file diff --git a/mobile/src/lang/lang.ts b/mobile/src/lang/lang.ts index 8bd3a094ff9901f72c7f007d59e0c4f6f82d7f67..e4dff6305e419bf747aabd1dd8266722cd9a250d 100644 --- a/mobile/src/lang/lang.ts +++ b/mobile/src/lang/lang.ts @@ -22,9 +22,14 @@ export interface Lang { title: string; logoutButton: string; changeLanguageButton: string; + changePasswordButton: string; selectLanguage: string; saveButton: string; }, + changePasswordScreen:{ + title: string; + saveButton: string; + }, selectTownScreen:{ title: string; }, diff --git a/mobile/src/lang/spanish_lang.ts b/mobile/src/lang/spanish_lang.ts index 0d6591c9ecf8f9a8f5b8511299578535a9569076..e74e205a7fe0b6f0e320412aaa79b252c3cdb3ab 100644 --- a/mobile/src/lang/spanish_lang.ts +++ b/mobile/src/lang/spanish_lang.ts @@ -23,10 +23,15 @@ export const SPANISH_LANG: Lang = { accountScreen:{ title: "Cuenta", logoutButton: "Cerrar sesión", + changePasswordButton: "Cambiar contraseña", changeLanguageButton: "Cambiar idioma de la aplicación", selectLanguage: "Seleccionar idioma", saveButton: "Guardar", }, + changePasswordScreen:{ + title: "Cambiar contraseña", + saveButton: "Guardar", + }, selectTownScreen:{ title: "Seleccionar Pueblo", }, diff --git a/mobile/src/lang/translations.ts b/mobile/src/lang/translations.ts index 7bd0b31032751f8b4c0be791475bf4dea6763f1e..12d068c3a637aaaaca13ec1d85e9b610a6b81c1d 100644 --- a/mobile/src/lang/translations.ts +++ b/mobile/src/lang/translations.ts @@ -3,6 +3,7 @@ import { initReactI18next } from 'react-i18next'; import * as Localization from 'expo-localization'; import { SPANISH_LANG } from './spanish_lang'; import { ENGLISH_LANG } from './english_lang'; +import AsyncStorage from '@react-native-async-storage/async-storage'; i18n.use(initReactI18next).init({ compatibilityJSON: 'v3', // Necesario para compatibilidad con Expo @@ -20,16 +21,28 @@ i18n.use(initReactI18next).init({ } }); +export enum Languages { + ENGLISH = 'en', + SPANISH = 'es' +}; + export const AvailableLanguages = [ { - key: 'en', + key: Languages.ENGLISH, value: 'English' }, { - key: 'es', + key: Languages.SPANISH, value: 'Español' } -] +]; + +(async () => { + const lang = await AsyncStorage.getItem("lang"); + if (lang) { + i18n.changeLanguage(lang); + } +})(); export default i18n; diff --git a/mobile/src/profile/components/change_password_form.tsx b/mobile/src/profile/components/change_password_form.tsx new file mode 100644 index 0000000000000000000000000000000000000000..2057ee0ea4709e73b09f56c5da6b67f752306f3c --- /dev/null +++ b/mobile/src/profile/components/change_password_form.tsx @@ -0,0 +1,67 @@ +import { Control, Controller } from "react-hook-form"; +import { View } from "react-native"; +import { EditProfileFormValues } from "../../hooks/useEditProfile"; +import { CustomTextInput } from "../../common/components/form/text_input"; + +interface ChangePasswordFormProps { + control: any; + isActive?: boolean; +} + +export const ChangePasswordForm = ({ control, isActive }: ChangePasswordFormProps) => { + return ( + + ( + + )} + /> + ( + + )} + /> + ( + + )} + /> + + ); +} \ No newline at end of file diff --git a/mobile/src/profile/domain/datasources/profile_datasource.ts b/mobile/src/profile/domain/datasources/profile_datasource.ts index 28bc6c33ac5bb3cb383b954dbf938d321e08d274..50ae766950dc075a071fabca060abc5eb284ca07 100644 --- a/mobile/src/profile/domain/datasources/profile_datasource.ts +++ b/mobile/src/profile/domain/datasources/profile_datasource.ts @@ -4,4 +4,5 @@ export interface ProfileDataSource { getInterests: () => Promise; saveInterests: (options: IOption[]) => Promise; setUpProfile: (birthdate: string, interests: IOption[]) => Promise; + changePassword: (oldPassword: string, newPassword: string) => Promise; }; \ No newline at end of file diff --git a/mobile/src/profile/domain/repositories/profile_repository.ts b/mobile/src/profile/domain/repositories/profile_repository.ts index 7f8164b9fd5eb8218525f30a9de5331f6b60e050..98634810fd001fb0b1ee3e233bc24fbbce53d4f7 100644 --- a/mobile/src/profile/domain/repositories/profile_repository.ts +++ b/mobile/src/profile/domain/repositories/profile_repository.ts @@ -4,4 +4,5 @@ export interface ProfileRepository { getInterests: () => Promise; saveInterests: (options: IOption[]) => Promise; setUpProfile: (birthdate: string, interests: IOption[]) => Promise; + changePassword: (oldPassword: string, newPassword: string) => Promise; }; \ No newline at end of file diff --git a/mobile/src/profile/hooks/useChangePassword.ts b/mobile/src/profile/hooks/useChangePassword.ts new file mode 100644 index 0000000000000000000000000000000000000000..d0f97a66e71f94dc045b72d426811c8c804ca5dc --- /dev/null +++ b/mobile/src/profile/hooks/useChangePassword.ts @@ -0,0 +1,40 @@ +import { useState } from "react"; +import { useForm } from "react-hook-form" +import { ApiRequestStatus } from "../../common/constants/api_request_states"; +import { useDataContext } from "../../common/contexts/data_context"; +import { router } from "expo-router"; + +interface ChangePasswordValues { + oldPassword: string; + newPassword: string; + confirmPassword: string; +} + +export const useChangePassword = () => { + const { control, handleSubmit, setError } = useForm(); + const [status, setStatus] = useState(ApiRequestStatus.IDLE); + const { profileRepository } = useDataContext(); + + const setLoading = async () => { + setStatus(ApiRequestStatus.LOADING); + } + + const request = async (values: ChangePasswordValues) => { + await setLoading(); + try { + await profileRepository!.changePassword(values.oldPassword, values.newPassword); + setStatus(ApiRequestStatus.SUCCESS); + router.back(); + } catch (error) { + setError("oldPassword", { type: "manual", message: "The current password is incorrect" }); + setStatus(ApiRequestStatus.ERROR); + } + } + + const onSubmit = async () => { + await handleSubmit(async (data) => { + await request(data); + })(); + } + return { control, onSubmit, status }; +} \ No newline at end of file diff --git a/mobile/src/profile/infrastructure/datasources/dev/profile_datasource.ts b/mobile/src/profile/infrastructure/datasources/dev/profile_datasource.ts index 1bf3b48e938501e80d530658116759be77c6264d..f7e598af23a97f74f462b8167a28d66fedbf5288 100644 --- a/mobile/src/profile/infrastructure/datasources/dev/profile_datasource.ts +++ b/mobile/src/profile/infrastructure/datasources/dev/profile_datasource.ts @@ -16,6 +16,10 @@ export class ProfileDataSourceDev implements ProfileDataSource { ]; } + async changePassword(oldPassword: string, newPassword: string): Promise { + console.log('Changing password', oldPassword, newPassword); + } + async saveInterests(options: IOption[]): Promise { console.log('Saving interests', options); } diff --git a/mobile/src/profile/infrastructure/datasources/prod/profile_datasource.ts b/mobile/src/profile/infrastructure/datasources/prod/profile_datasource.ts new file mode 100644 index 0000000000000000000000000000000000000000..eee7b181c9fb28d18f058986906113a78a0eb9ea --- /dev/null +++ b/mobile/src/profile/infrastructure/datasources/prod/profile_datasource.ts @@ -0,0 +1,26 @@ +import axios from "axios"; +import { IOption } from "../../../../common/domain/entities/option"; +import { ProfileDataSource } from "../../../domain/datasources/profile_datasource"; +import { API_URL } from "../../../../common/constants/api"; + +export class ProfileDataSourceProd implements ProfileDataSource { + async getInterests(): Promise { + throw new Error('Method not implemented.'); + } + + async saveInterests(options: IOption[]): Promise { + throw new Error('Method not implemented.'); + } + + async setUpProfile(birthdate: string, interests: IOption[]): Promise { + throw new Error('Method not implemented.'); + } + + async changePassword(oldPassword: string, newPassword: string): Promise { + const {status, data} = await axios.patch(`${API_URL}/user/change-password`, { + prevPassword: oldPassword, + newPassword: newPassword + }) + console.log(status, data); + } +} diff --git a/mobile/src/profile/infrastructure/repositories/profile_repository.ts b/mobile/src/profile/infrastructure/repositories/profile_repository.ts index a71049bc530712c83551f09dda85e9a022352f89..4dea398544246e0c303255c7fff907195e023e3c 100644 --- a/mobile/src/profile/infrastructure/repositories/profile_repository.ts +++ b/mobile/src/profile/infrastructure/repositories/profile_repository.ts @@ -6,6 +6,9 @@ export class ProfileRepositoryImpl implements ProfileRepository { constructor( private dataSource: ProfileDataSource ){} + async changePassword (oldPassword: string, newPassword: string): Promise { + return this.dataSource.changePassword(oldPassword, newPassword); + }; async getInterests() { return this.dataSource.getInterests(); } diff --git a/mobile/src/profile/screens/account_page.tsx b/mobile/src/profile/screens/account_page.tsx index 3bd39f9819b28aacc7a200452b3781fa14170f76..0a07160e468e39e192bb7f23ca8811812ac8b34d 100644 --- a/mobile/src/profile/screens/account_page.tsx +++ b/mobile/src/profile/screens/account_page.tsx @@ -21,9 +21,10 @@ import Modal from "react-native-modal"; import { set } from "react-hook-form"; import { AntDesign } from "@expo/vector-icons"; import RNPickerSelect from 'react-native-picker-select'; -import { AvailableLanguages } from "../../lang/translations"; +import { AvailableLanguages, Languages } from "../../lang/translations"; import i18n from 'i18next'; import { useTranslation } from "react-i18next"; +import { useLang } from "../../lang/hooks/useLang"; //TODO: Add source to CircleAvatar const source = require("../../../assets/avatar.png"); @@ -56,11 +57,12 @@ export const AccountPage = () => { /> } onPress={() => router.push("/profile/edit")} - /> + /> */} } - />*/} + title={LANG.t("accountScreen.changePasswordButton")} + leadingIcon={} + onPress={() => router.push("/profile/change_password")} + /> } @@ -95,10 +97,10 @@ const ChangeLanguageModal = ({ onClose, isVisible, }: ChangeLanguageModalProps) => { - const [selectedLanguage, setSelectedLanguage] = useState(null); - const {i18n} = useTranslation(); + const { changeLanguage } = useLang(); + const [selectedLanguage, setSelectedLanguage] = useState(null); const onSave = () => { - i18n.changeLanguage(selectedLanguage || 'en'); + changeLanguage(selectedLanguage || Languages.SPANISH); onClose(); } return ( diff --git a/mobile/src/profile/screens/change_password_page.tsx b/mobile/src/profile/screens/change_password_page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..ccdc6eacb070e554ec57bdcaf0d733cb15a976c1 --- /dev/null +++ b/mobile/src/profile/screens/change_password_page.tsx @@ -0,0 +1,46 @@ +import { ScrollView, StyleSheet, TouchableOpacity, Text } from "react-native"; +import { ChangePasswordForm } from "../components/change_password_form"; +import { useChangePassword } from "../hooks/useChangePassword"; +import { LIGHT_THEME } from "../../common/constants/theme"; + +export const ChangePasswordPage = () => { + const { control, onSubmit } = useChangePassword(); + return ( + + + { + //TODO: ADD a modal to show the success message + } + + Change password + + + ); +}; + +export const styles = StyleSheet.create({ + container: { + flex: 1, + padding: 20, + }, + innerContainer: { + alignItems: "center", + }, + confirmBtn: { + backgroundColor: LIGHT_THEME.color.primary, + marginTop: 30, + padding: 10, + borderRadius: 20, + height: 40, + width: "70%", + justifyContent: "center", + alignItems: "center", + }, + confirmBtnText: { + color: "white", + fontWeight: "bold", + }, +});