Add DOB field, Offlinepage and fix bug

This commit is contained in:
Menaka 2024-08-21 18:45:40 +05:30
parent 2d7dcf3859
commit 3b4afdcef2
14 changed files with 230 additions and 41 deletions

View File

@ -83,24 +83,25 @@ class Sidebar extends React.Component<any, any> {
const token = await AsyncStorage.getItem('token')
this.imageBaseUrl = await fetchBaseUrl()
this.props.getMenuList({ token: token, app_type: 'mobile' })
if (userInfo) {
const userDetails: any = JSON.parse(userInfo)
const profileDetails: any = JSON.parse(profileInfo)
this.isLoggedinAs = userDetails.usertype
this.filterRoleBaseSideBar(userDetails, profileDetails)
} else {
if (this.props.userinfo.hasOwnProperty('status')) {
if (this.props.userinfo.status) {
this.isLoggedinAs = this.props.userinfo.data.usertype
this.filterRoleBaseSideBar(this.props.userinfo.data, this.props.profileInfo.data)
}
}
}
// if (userInfo) {
// const userDetails: any = JSON.parse(userInfo)
// const profileDetails: any = JSON.parse(profileInfo)
// this.isLoggedinAs = userDetails.usertype
// this.filterRoleBaseSideBar(userDetails, profileDetails)
// } else {
// if (this.props.userinfo.hasOwnProperty('status')) {
// if (this.props.userinfo.status) {
// this.isLoggedinAs = this.props.userinfo.data.usertype
// this.filterRoleBaseSideBar(this.props.userinfo.data, this.props.profileInfo.data)
// }
// }
// }
}
async componentDidUpdate(prevProps: any) {
if (prevProps.menuList !== this.props.menuList) {
const userInfo: any = await AsyncStorage.getItem('userInfo')
const profileInfo: any = await AsyncStorage.getItem('profileInfo')
if (userInfo) {
const { menuList } = this.props
const { routes } = this.state
@ -123,7 +124,20 @@ class Sidebar extends React.Component<any, any> {
this.setState({ routes: concatenatedMenu })
}
}
}
}
if (userInfo && profileInfo) {
const userDetails: any = JSON.parse(userInfo)
const profileDetails: any = JSON.parse(profileInfo)
this.isLoggedinAs = userDetails.usertype
this.filterRoleBaseSideBar(userDetails, profileDetails)
} else {
if (this.props.userinfo.hasOwnProperty('status')) {
if (this.props.userinfo.status) {
this.isLoggedinAs = this.props.userinfo.data.usertype
this.filterRoleBaseSideBar(this.props.userinfo.data, this.props.profileInfo.data)
}
}
}
}
}

View File

@ -7,7 +7,7 @@ import AuthNavigator from '../../navigation/AuthNavigator'
import * as Analytics from 'expo-firebase-analytics'
import * as Location from 'expo-location'
import * as SplashScreen from 'expo-splash-screen'
import NetInfo from '@react-native-community/netinfo'
import NetInfo, { NetInfoState } from '@react-native-community/netinfo'
import { ActivityIndicator, SafeAreaView, StyleSheet, View, StatusBar, KeyboardAvoidingView } from 'react-native'
import FlashMessage from 'react-native-flash-message'
import * as Font from 'expo-font'
@ -19,6 +19,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage'
import { common } from '@constants/Constants' //NOSONAR
import * as ImagePicker from 'expo-image-picker'
import messaging from '@react-native-firebase/messaging'
import OfflinePage from '@screens/OfflinePage';
const Stack = createStackNavigator();
class ExpoBare extends React.Component<any, any> {
@ -31,7 +32,8 @@ class ExpoBare extends React.Component<any, any> {
state = {
appIsReady: false,
location: '',
assetsLoaded: false
assetsLoaded: false,
isConnected: true,
}
constructor(Props: any) {
@ -42,6 +44,8 @@ class ExpoBare extends React.Component<any, any> {
}
async componentDidMount() {
this.unsubscribe = NetInfo.addEventListener(this.handleNetworkChange);
// Prevent native splash screen from autohiding
this.token = await AsyncStorage.getItem('token')
try {
@ -60,6 +64,20 @@ class ExpoBare extends React.Component<any, any> {
}
componentWillUnmount() {
if (this.unsubscribe) {
this.unsubscribe();
}
}
private handleNetworkChange = (state: NetInfoState) => {
this.setState({
isConnected: state.isConnected,
});
};
private unsubscribe: (() => void) | undefined;
async componentDidUpdate() {
if (this.props.profileInfo.hasOwnProperty('status')) {
if (!this.props.profileInfo.status) {
@ -240,7 +258,7 @@ class ExpoBare extends React.Component<any, any> {
render() {
const { assetsLoaded } = this.state
const { assetsLoaded, isConnected } = this.state
const initial = this.token ? "app" : "auth"
const onNavigationStateChange = (prevState:any, currentState:any) => {
this.getActiveUserCheck(currentState)
@ -259,6 +277,9 @@ class ExpoBare extends React.Component<any, any> {
<KeyboardAvoidingView style={styles.container} enabled={true} behavior={'padding'}>
<SafeAreaView style={styles.container}>
<FlashMessage position="bottom" />
{!isConnected ?
<OfflinePage />
:
<NavigationContainer
ref={this.navigationRef} onReady={this.handleNavigationReady}
// ref={(ref) => {
@ -278,6 +299,7 @@ class ExpoBare extends React.Component<any, any> {
</Stack.Navigator>
</NavigationContainer>
}
</SafeAreaView>
</KeyboardAvoidingView>
)

View File

@ -38,7 +38,7 @@ class ForgotPassword extends React.Component<any, any>{
if (this.props.checkuser_data.hasOwnProperty('status')) {
if (this.props.checkuser_data.status) {
if(!this.props.isRedirected) {
this.props.navigation.navigate("otp", { action: 'forgot', username: this.state.username.value })
this.props.navigation.navigate("otp", { action: 'forgot', username: this.state.username.value, isEmailAuth: this.state.isEmailAuth })
}
}
}

View File

@ -21,6 +21,7 @@ class OTPVerification extends React.Component<any, any>{
inputs:any;
state = {
username: this.props.route.params.username,
isEmailAuth: this.props.route.params.isEmailAuth,
otp: { value: '', error: '', verified: null },
action: this.props.route.params.action,
otp1: false,
@ -192,15 +193,14 @@ class OTPVerification extends React.Component<any, any>{
}
render() {
const { otp1, otp2, otp3, otp4, otp5, otp6, inputotp } = this.state
const { otp1, otp2, otp3, otp4, otp5, otp6, inputotp, isEmailAuth } = this.state
return (<View style={AuthStyles.container}>
<View style={AuthStyles.stepMsgBarcontainer}>
<Text style={[AuthStyles.stepMsgBarcontainer, AuthStyles.stepMsgBarOtp]}></Text>
</View>
<Text style={[AuthStyles.subTextMsg, AuthStyles.stepMsg]}>STEP 2/3</Text>
<Text style={[BaseStyles.headerLabel, BaseStyles.font700Bold,]}>Verify your number</Text>
<Text style={[AuthStyles.subTextMsg, BaseStyles.font500Medium]}>Wel'll text you on {this.state.username}</Text>
<Text style={[BaseStyles.headerLabel, BaseStyles.font700Bold,]}>{isEmailAuth ? "Verify your Email" : "Verify your number"}</Text>
<Text style={[AuthStyles.subTextMsg, BaseStyles.font500Medium]}>We'll text you on {this.state.username}</Text>
<View style={{ flexDirection: 'row', }}>
{Array.from({ length: 6 }).map((_, index) => (

View File

@ -0,0 +1,39 @@
import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
interface OfflinePageProps {
}
class OfflinePage extends Component<any> {
render() {
return (
<View style={styles.container}>
<Text style={styles.title}>You're offline</Text>
<Text style={styles.message}>Please check your internet connection and try again.</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#f8f8f8',
},
title: {
fontSize: 24,
fontWeight: 'bold',
},
message: {
fontSize: 18,
marginVertical: 20,
textAlign: 'center'
},
});
export default OfflinePage;

View File

@ -25,7 +25,9 @@ class TakeQuizzes extends React.Component<any, any>{
scrollView: any;
token: any;
state: any = {
academicYear: ''
academicYear: '',
data: {},
info: {}
};
constructor(props: any) {
@ -35,6 +37,7 @@ class TakeQuizzes extends React.Component<any, any>{
async componentDidMount() {
const { navigation, route } = this.props;
const title = route.params?.data?.question_name || 'Quizzes';
this.setState({data: route.params?.data, info: route.params?.info })
navigation.setOptions({ title });
this.getCurrentAcademicYearData() //fetch the Current Academic year from Login Response
this.token = await AsyncStorage.getItem('token')
@ -103,8 +106,8 @@ class TakeQuizzes extends React.Component<any, any>{
}
onTakeQuizzes = (data: any) => {
const quizAdminparams: any = this.props.route.params.data
const classData = this.props.route.params.info
const quizAdminparams: any = this.state.data
const classData = this.state.info
if(quizAdminparams?.is_teacher_present && (classData?.is_attendance_taken || this.props.is_attendance_taken)){
const classDataInfo: any = JSON.parse(JSON.stringify(classData))
let studentList: any = []

View File

@ -14,6 +14,7 @@ import BaseColors from "@theme/Colors" //NOSONAR
import * as ImagePicker from 'expo-image-picker'
import Constants from "expo-constants"
import { RadioButton } from 'react-native-paper'
import DateTimePickerModal from 'react-native-modal-datetime-picker';
const Sepator = ({ style }: any) => <View style={[BaseStyles.separator, style]} />
@ -57,7 +58,8 @@ class StudentCreate extends React.Component<any, any>{
isImageUploaded: false,
image: '',
imagePreviewURL: '',
academicYear: ''
academicYear: '',
isDatePickerVisible: false,
};
token: any;
@ -221,6 +223,14 @@ class StudentCreate extends React.Component<any, any>{
}
}
showDatePicker = () => this.setState({ isDatePickerVisible: true });
hideDatePicker = () => this.setState({ isDatePickerVisible: false });
handleConfirm = (date: any, setFieldValue: any) => {
setFieldValue('date_of_birth', date.toISOString().split('T')[0]);
this.hideDatePicker();
};
render() {
return (<View style={[AppStyles.containerWoPadding, {}]}>
@ -283,6 +293,7 @@ class StudentCreate extends React.Component<any, any>{
email_id: '',
student_name: '',
gender:'',
date_of_birth: '',
}}
onSubmit={(values, actions) => this.onStudentSubmit(values, actions)}
>
@ -343,6 +354,22 @@ class StudentCreate extends React.Component<any, any>{
</View>
{(errors.parent_lastname && touched.parent_lastname) && <Text style={AppStyles.error}>{errors.parent_lastname}</Text>}
<Text style={[AppStyles.cardHeader, BaseStyles.marTop5]}> Date of Birth </Text>
<TouchableOpacity onPress={this.showDatePicker} style={[AppStyles.inputView, BaseStyles.marTop5]}>
<Text style={AppStyles.inputText}>
{values.date_of_birth ? values.date_of_birth : 'Select Date'}
</Text>
</TouchableOpacity>
{(errors.date_of_birth && touched.date_of_birth) && <Text style={AppStyles.error}>{errors.date_of_birth}</Text>}
<DateTimePickerModal
isVisible={this.state.isDatePickerVisible}
mode="date"
onConfirm={(date) => this.handleConfirm(date, setFieldValue)}
onCancel={this.hideDatePicker}
/>
<View style={[styles.container]}>
<View style={styles.btnItem}>
<TouchableOpacity style={[AppStyles.defaultBtn, { alignSelf: 'center' }]} onPress={this.onCancel} activeOpacity={0.8}>

View File

@ -291,7 +291,7 @@ class StudentProfile extends React.Component<any, any>{
<View style={[BaseStyles.padding10, AppStyles.diaryCard, BaseStyles.marTop20, { marginBottom: 0 }]}>
<Text style={[AppStyles.studentHeader, BaseStyles.marBottom20]}>Performance By Subjects</Text>
<View style={[{ flex: 1, flexDirection: "row", justifyContent: 'center' }, BaseStyles.marBottom20]}>
<Text style={[AppStyles.weakGoodTextColor1, BaseStyles.marRight10]}> Week 0%</Text>
<Text style={[AppStyles.weakGoodTextColor1, BaseStyles.marRight10]}> Weak 0%</Text>
<Text style={[AppStyles.performanceWidth, AppStyles.weakGoodColor1]}></Text>
<Text style={[AppStyles.performanceWidth, AppStyles.weakGoodColor3]}></Text>
<Text style={[AppStyles.performanceWidth, AppStyles.weakGoodColor5]}></Text>

View File

@ -198,7 +198,7 @@ class StudentReport extends React.Component<any, any>{
</View>}
<ScrollView style={{ marginVertical: 12, marginHorizontal: 15 }}>
<View style={{ flex: 1, flexDirection: "column", }}>
{this.props.studentsList.data &&
{this.props.studentsList.data && this.props.classes.data.status !== false &&
<Formik
validationSchema={perfomanceReportValidationSchema}
enableReinitialize={true}
@ -321,7 +321,7 @@ class StudentReport extends React.Component<any, any>{
{perfomanceReportByTopic.questions && perfomanceReportByTopic.questions.map((questionItem: any, questionIndex: any) => (
<View key={questionIndex} style={[AppStyles.diaryCard, BaseStyles.marTop10, { padding: 0 }]}>
<View style={[BaseStyles.flexRowStart, BaseStyles.padding10, { justifyContent: "space-between" }]}>
<View style={[BaseStyles.padding10, { justifyContent: "space-between" }]}>
<View style={[BaseStyles.flexColumnStart,]}>
<Text style={[AppStyles.nameLabel, BaseStyles.font18, BaseStyles.font700Bold, BaseStyles.marBottom5]}>{questionItem?.question_name}</Text>
</View>

View File

@ -14,6 +14,7 @@ import BaseColors from "@theme/Colors" //NOSONAR
import * as ImagePicker from 'expo-image-picker'
import Constants from "expo-constants"
import { RadioButton } from 'react-native-paper'
import DateTimePickerModal from 'react-native-modal-datetime-picker';
const Sepator = ({ style }: any) => <View style={[BaseStyles.separator, style]} />
@ -57,7 +58,8 @@ class StudentUpdate extends React.Component<any, any>{
isImageUploaded: false,
image: '',
imagePreviewURL: '',
academicYear: ''
academicYear: '',
isDatePickerVisible: false,
};
token: any;
@ -211,6 +213,14 @@ class StudentUpdate extends React.Component<any, any>{
}
}
showDatePicker = () => this.setState({ isDatePickerVisible: true });
hideDatePicker = () => this.setState({ isDatePickerVisible: false });
handleConfirm = (date: any, setFieldValue: any) => {
setFieldValue('date_of_birth', date.toISOString().split('T')[0]);
this.hideDatePicker();
};
render() {
let studentInfo: any = {}
@ -253,7 +263,8 @@ class StudentUpdate extends React.Component<any, any>{
phone_number: studentInfo?.phone_number,
email_id: studentInfo?.email_id,
student_name: studentInfo?.student_name,
gender: studentInfo?.gender
gender: studentInfo?.gender,
date_of_birth: studentInfo?.date_of_birth,
}}
onSubmit={(values, actions) => this.onStudentSubmit(values, actions)}
>
@ -348,6 +359,22 @@ class StudentUpdate extends React.Component<any, any>{
</View>
{(errors.parent_lastname && touched.parent_lastname) && <Text style={AppStyles.error}>{errors.parent_lastname}</Text>}
<Text style={[AppStyles.cardHeader, BaseStyles.marTop5]}> Date of Birth </Text>
<TouchableOpacity onPress={this.showDatePicker} style={[AppStyles.inputView, BaseStyles.marTop5]}>
<Text style={AppStyles.inputText}>
{values.date_of_birth ? values.date_of_birth : 'Select Date'}
</Text>
</TouchableOpacity>
{(errors.date_of_birth && touched.date_of_birth) && <Text style={AppStyles.error}>{errors.date_of_birth}</Text>}
<DateTimePickerModal
isVisible={this.state.isDatePickerVisible}
mode="date"
onConfirm={(date) => this.handleConfirm(date, setFieldValue)}
onCancel={this.hideDatePicker}
/>
<View style={[styles.container]}>
<View style={styles.btnItem}>
<TouchableOpacity style={[AppStyles.defaultBtn, { alignSelf: 'center' }]} onPress={this.onCancel} activeOpacity={0.8}>

View File

@ -8,6 +8,7 @@ import { connect } from "react-redux"
import { ActionCreators } from "@actions" //NOSONAR
import PropTypes from 'prop-types'
import AsyncStorage from "@react-native-async-storage/async-storage"
import DateTimePickerModal from 'react-native-modal-datetime-picker';
const teacherCreateValidationSchema = yup.object().shape({
firstname: yup
@ -35,7 +36,9 @@ const teacherCreateValidationSchema = yup.object().shape({
class TeacherCreate extends React.Component<any, any>{
formikActions: any;
static propTypes = {};
state = {};
state = {
isDatePickerVisible: false,
};
token: any;
constructor(props: any) {
@ -79,6 +82,14 @@ class TeacherCreate extends React.Component<any, any>{
this.props.createTeacher({ data, token: this.token })
}
showDatePicker = () => this.setState({ isDatePickerVisible: true });
hideDatePicker = () => this.setState({ isDatePickerVisible: false });
handleConfirm = (date: any, setFieldValue: any) => {
setFieldValue('date_of_birth', date.toISOString().split('T')[0]);
this.hideDatePicker();
};
render() {
return (<View style={[AppStyles.containerWoPadding, {}]}>
@ -95,7 +106,8 @@ class TeacherCreate extends React.Component<any, any>{
firstname: '',
lastname: '',
phone_number: '',
email_id: ''
email_id: '',
date_of_birth: ''
}}
onSubmit={(values, actions) => this.onTeacherSubmit(values, actions)}
>
@ -128,6 +140,23 @@ class TeacherCreate extends React.Component<any, any>{
value={values.email_id} keyboardType="default" />
</View>
{(errors.email_id && touched.email_id) && <Text style={AppStyles.error}>{errors.email_id}</Text>}
<Text style={[AppStyles.cardHeader, BaseStyles.marTop5]}> Date of Birth </Text>
<TouchableOpacity onPress={this.showDatePicker} style={[AppStyles.inputView, BaseStyles.marTop5]}>
<Text style={AppStyles.inputText}>
{values.date_of_birth ? values.date_of_birth : 'Select Date'}
</Text>
</TouchableOpacity>
{(errors.date_of_birth && touched.date_of_birth) && <Text style={AppStyles.error}>{errors.date_of_birth}</Text>}
<DateTimePickerModal
isVisible={this.state.isDatePickerVisible}
mode="date"
onConfirm={(date) => this.handleConfirm(date, setFieldValue)}
onCancel={this.hideDatePicker}
/>
<View style={[styles.container]}>
<View style={styles.btnItem}>
<TouchableOpacity style={[AppStyles.defaultBtn, { alignSelf: 'center' }]} onPress={this.onCancel} activeOpacity={0.8}>

View File

@ -8,6 +8,7 @@ import { connect } from "react-redux"
import { ActionCreators } from "@actions" //NOSONAR
import PropTypes from 'prop-types'
import AsyncStorage from "@react-native-async-storage/async-storage"
import DateTimePickerModal from 'react-native-modal-datetime-picker';
const teacherUpdateValidationSchema = yup.object().shape({
firstname: yup
@ -36,7 +37,8 @@ class TeacherUpdate extends React.Component<any, any>{
formikActions: any;
static propTypes = {};
state = {
id: this.props.route.teacher_id
id: this.props.route.teacher_id,
isDatePickerVisible: false,
};
token: any;
@ -86,6 +88,13 @@ class TeacherUpdate extends React.Component<any, any>{
this.props.updateTeacher({ teacher_id: this.props.route.params.teacher_id, data, token: this.token})
}
showDatePicker = () => this.setState({ isDatePickerVisible: true });
hideDatePicker = () => this.setState({ isDatePickerVisible: false });
handleConfirm = (date: any, setFieldValue: any) => {
setFieldValue('date_of_birth', date.toISOString().split('T')[0]);
this.hideDatePicker();
};
render() {
@ -94,6 +103,7 @@ class TeacherUpdate extends React.Component<any, any>{
let phoneNumber: any
let emailId: any
let imageInput: any
let date_of_birth: any
if (this.props.info.hasOwnProperty('status')) {
if (this.props.info.status) {
@ -101,7 +111,8 @@ class TeacherUpdate extends React.Component<any, any>{
lastname = this.props.route.params.data.lastname
phoneNumber = this.props.route.params.data.phone_number
emailId = this.props.route.params.data.email_id
imageInput = this.props.route.params.data.image
imageInput = this.props.route.params.data.image,
date_of_birth = this.props.route.params.data.date_of_birth
}
}
@ -121,11 +132,12 @@ class TeacherUpdate extends React.Component<any, any>{
lastname: lastname,
phone_number: phoneNumber,
email_id: emailId,
image:imageInput
image:imageInput,
date_of_birth: ''
}}
onSubmit={(values, actions) => this.onTeacherUpdate(values, actions)}
>
{({ handleChange, handleBlur, handleSubmit, values, errors, touched, isValid, dirty }) => (
{({ handleChange, handleBlur, handleSubmit, values, errors, touched, isValid, dirty, setFieldValue }) => (
<>
<Text style={[AppStyles.cardHeader, BaseStyles.marTop5]}>First Name<Text style={AppStyles.required}> *</Text></Text>
<View style={[AppStyles.inputView, BaseStyles.marTop5,]} >
@ -155,6 +167,22 @@ class TeacherUpdate extends React.Component<any, any>{
</View>
{(errors.email_id && touched.email_id) && <Text style={AppStyles.error}>{errors.email_id}</Text>}
<Text style={[AppStyles.cardHeader, BaseStyles.marTop5]}> Date of Birth </Text>
<TouchableOpacity onPress={this.showDatePicker} style={[AppStyles.inputView, BaseStyles.marTop5]}>
<Text style={AppStyles.inputText}>
{values.date_of_birth ? values.date_of_birth : 'Select Date'}
</Text>
</TouchableOpacity>
{(errors.date_of_birth && touched.date_of_birth) && <Text style={AppStyles.error}>{errors.date_of_birth}</Text>}
<DateTimePickerModal
isVisible={this.state.isDatePickerVisible}
mode="date"
onConfirm={(date) => this.handleConfirm(date, setFieldValue)}
onCancel={this.hideDatePicker}
/>
<View style={[styles.container]}>
<View style={styles.btnItem}>
<TouchableOpacity style={[AppStyles.defaultBtn, { alignSelf: 'center' }]} onPress={this.onCancel} activeOpacity={0.8}>

View File

@ -169,7 +169,7 @@ class ClassCreate extends React.Component<any, any>{
this.onSelectChange(itemValue, 'standard', setFieldValue)
}
placeholder={{
label: '--Select Standard--',
label: '--Select Section--',
value: null,
}}
useNativeAndroidPickerStyle={false}

View File

@ -398,7 +398,7 @@ export const AppStyles = StyleSheet.create({
// flex-grow: 1;
color: "white",
textAlignVertical:"center",
padding: 10,
padding: 5,
textAlign: "center",
margin:2,
width: 80,