diff --git a/src/database/migrations/00.ts b/src/database/migrations/00.ts index 3d58b7a..b3ea2af 100644 --- a/src/database/migrations/00.ts +++ b/src/database/migrations/00.ts @@ -42,8 +42,8 @@ const createSchoolTable = (db: SQLiteDatabase) => { _status TEXT, name TEXT, - key TEXT null, region TEXT null, + schoolKey TEXT null, emis_number TEXT null, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, @@ -67,7 +67,6 @@ const createCoacherTable = (db: SQLiteDatabase) => { phone TEXT null, surname TEXT null, birthdate TEXT null, - birthday TIMESTAMP null, image_id TEXT REFERENCES image(id), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, diff --git a/src/providers/coach.provider.tsx b/src/providers/coach.provider.tsx index 57f2c8a..d4429be 100644 --- a/src/providers/coach.provider.tsx +++ b/src/providers/coach.provider.tsx @@ -7,11 +7,15 @@ import {School} from '../types/school'; import {Coach} from '../types/coach'; import {useNavigate} from 'react-router-native'; import PathRoutes from '../routers/paths'; +import {CoachService} from '../services/coach.service'; +import {CoachSchool} from '../types/coach_school'; +import {SessionService} from '../services/session.service'; type CoachContextType = { currentCoach: Coach | null; currentSchool: School | null; logout: () => Promise; + loginOTP: (coach: Coach) => Promise; selectCoach: (coach: Coach | null) => Promise; selectSchool: (school: School | null) => Promise; }; @@ -30,12 +34,45 @@ const CoachProvider: React.FC<{children: ReactNode}> = ({children}) => { await StorageService.setCurrentCoach(coach); }; + const loginOTP = async (coach: Coach) => { + setCurrentCoach(coach); + + await CoachService.insertOrUpdateCoach(coach); + + if (coach.coachSchools) { + await Promise.all( + coach.coachSchools.map(async ({school}: CoachSchool) => { + if (school) { + await SchoolService.insertASchoolFromServer(school); + } + }), + ); + + await Promise.all( + coach.coachSchools.map(coachSchool => + CoachService.insertOrUpdateCoachSchool(coachSchool), + ), + ); + } + + if (coach.sessions) { + await SessionService.insertSessionsFromServer(coach.sessions); + } + + await StorageService.setCurrentCoach(coach); + }; + const selectSchool = async (school: School | null) => { - setCurrentSchool(school); - await StorageService.setCurrentSchool(school); if (school) { - await SchoolService.insertSchool(school); + await SchoolService.insertASchoolFromServer(school); + + if (currentCoach) { + await CoachService.assignCoachToSchool(currentCoach, school); + } } + + setCurrentSchool(school); + await StorageService.setCurrentSchool(school); }; const logout = async () => { @@ -59,6 +96,7 @@ const CoachProvider: React.FC<{children: ReactNode}> = ({children}) => { { return ( @@ -63,8 +62,6 @@ const RouterProvider: React.FC = () => { - - { question_id => ({question_id, value: answers[question_id]}), ); - const sessionId = await SessionService.create( + const sessionId = await SessionService.createLocalSession( { students_count: session.students_count, subject: session.subject, diff --git a/src/screens/CoachForm/index.tsx b/src/screens/CoachForm/index.tsx index 23391f4..e6002f9 100644 --- a/src/screens/CoachForm/index.tsx +++ b/src/screens/CoachForm/index.tsx @@ -18,7 +18,6 @@ import DatePicker from 'react-native-date-picker'; import {TouchableOpacity} from 'react-native'; import moment from 'moment'; import i18n from '../../i18n'; -import {Coach} from '../../types/coach'; export type FormValuesType = { name?: string; @@ -60,7 +59,7 @@ const CoachFormScreen: React.FC = () => { } if (currentSchool) { - const coach = await CoachService.create(currentSchool, { + const coach = await CoachService.createNewLocalCoach({ ...values, image_id, }); diff --git a/src/screens/FeedbackSession/Form/index.tsx b/src/screens/FeedbackSession/Form/index.tsx index ca34d47..0ce5afd 100644 --- a/src/screens/FeedbackSession/Form/index.tsx +++ b/src/screens/FeedbackSession/Form/index.tsx @@ -46,7 +46,7 @@ const FeedbackSessionForm: React.FC = () => { const finishCoachSession = async () => { setLoading(true); if (actions) { - const feedbackId = await SessionService.createFeedback( + const feedbackId = await SessionService.createLocalFeedback( { answer_id: answerId, value: actions, diff --git a/src/screens/Home/index.tsx b/src/screens/Home/index.tsx index 30e859c..c618184 100644 --- a/src/screens/Home/index.tsx +++ b/src/screens/Home/index.tsx @@ -1,17 +1,39 @@ -import React from 'react'; +import React, {useEffect, useState} from 'react'; import {TeacherItemType} from '../../types/teacher'; import {useNavigate} from 'react-router-native'; import HorizontalMenu from './HorizontalMenu'; import PathRoutes from '../../routers/paths'; import TeachersList from './TeachersList'; -import {VStack} from 'native-base'; +import {Spinner, VStack} from 'native-base'; import Page from '../../components/Page'; import HomeHeader from './HomeHeader'; import {isTablet} from 'react-native-device-info'; import BottomNavigator from './BottomNavigator'; +import {StorageService} from '../../services/storage.service'; +import SyncService from '../../services/sync.service'; const HomeScreen: React.FC = () => { const navigate = useNavigate(); + const [isLoading, setIsLoading] = useState(false); + + useEffect(() => { + const asyncFunction = async () => { + const lastSync = await StorageService.getLastSync(); + const ONE_HOUR = 60 * 60 * 1000; + + if ( + !lastSync || + new Date().getTime() - new Date(lastSync).getTime() > ONE_HOUR + ) { + console.log('START SYNC'); + setIsLoading(true); + await SyncService.trySyncData(); + setIsLoading(false); + } + }; + + asyncFunction(); + }, []); const onSelectTeacher = (teacher: TeacherItemType) => { navigate(PathRoutes.teacher.details.replace(':id', teacher.id)); @@ -25,7 +47,11 @@ const HomeScreen: React.FC = () => { - + {isLoading ? ( + + ) : ( + + )} diff --git a/src/screens/Login/FastLogin/index.tsx b/src/screens/Login/FastLogin/index.tsx deleted file mode 100644 index 5fe3827..0000000 --- a/src/screens/Login/FastLogin/index.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import React from 'react'; -import Page from '../../../components/Page'; -import {Center, HStack, Image, Text, VStack} from 'native-base'; -import {useTranslation} from 'react-i18next'; -import {LoginLogo} from '../../../assets/images/logos'; -import {useNavigate} from 'react-router-native'; -import PathRoutes from '../../../routers/paths'; -import Button from '../../../components/Button'; - -const FastLoginScreen: React.FC = () => { - const navigate = useNavigate(); - const {t} = useTranslation(); - - //change this variable to logged user - const id = 'Mohamed B.S. Ansumana'; - - const handleLoginAgain = () => { - try { - //do logic to login user - - navigate(PathRoutes.selectSchool, {replace: true}); - } catch (err) { - console.log(err); - } - }; - - return ( - - - - {'Logo - - - {t('login.fastlogin.welcome')} - - - - - - {t('login.fastlogin.title')} - - - {id} - - - - - - {t('login.fastlogin.change_coach_button')} - - - - - - {t('login.main.create_account')} - - - navigate(PathRoutes.signup.main)}> - {t('login.main.create_account_button')} - - - - - ); -}; - -export default FastLoginScreen; diff --git a/src/screens/Login/OTP/index.tsx b/src/screens/Login/OTP/index.tsx index c2e01ca..322eb3c 100644 --- a/src/screens/Login/OTP/index.tsx +++ b/src/screens/Login/OTP/index.tsx @@ -9,29 +9,39 @@ import Icon from '../../../components/Icon'; import {useTranslation} from 'react-i18next'; import {CoachService} from '../../../services/coach.service'; import {useCoachContext} from '../../../providers/coach.provider'; +import CompetenceService from '../../../services/competence.service'; +import {QuestionService} from '../../../services/question.service'; +import {StorageService} from '../../../services/storage.service'; const OTPScreen: React.FC = () => { const [OTPCode, setOTPCode] = useState<{hasError: boolean; value: string}>(); + const {loginOTP} = useCoachContext(); + const [isLoading, setIsLoading] = useState(false); const navigate = useNavigate(); const {t} = useTranslation(); const theme = useTheme(); const {id} = useParams(); - const {selectCoach} = useCoachContext(); const handleVerifyCode = async () => { + setIsLoading(true); try { if (id && OTPCode?.value) { const {data} = await CoachService.verifyOTP( id.toLowerCase().trim(), OTPCode.value, ); - selectCoach(data.coach); + + await loginOTP(data.coach); + await CompetenceService.sync(data.competencies); + await QuestionService.sync(data.questions); + await StorageService.setLastSync(new Date()); + navigate(PathRoutes.selectSchool, {replace: true}); } } catch (err) { - console.log(err); setOTPCode(otp => ({value: otp?.value || '', hasError: true})); } + setIsLoading(false); }; const handleResendCode = async () => { @@ -53,12 +63,12 @@ const OTPScreen: React.FC = () => { + fontSize={'TXL'} + fontWeight={700} + alignSelf={'center'} + color={'primary.200'}> {id} @@ -81,7 +91,11 @@ const OTPScreen: React.FC = () => { )} -