diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index bf557c5..5cd55d0 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -168,7 +168,7 @@ class Sidebar extends React.Component { {this.state.image && this.state.image !== '' ? - + : {this.state.name && this.state.name.charAt(0)} diff --git a/src/constants/Constants.tsx b/src/constants/Constants.tsx index 8b3f1d6..e0b7187 100644 --- a/src/constants/Constants.tsx +++ b/src/constants/Constants.tsx @@ -155,3 +155,8 @@ export const MONTHLIST = [ address: /^\S+(?: \S+)*$/, //NOSONAR } + export const imageFormat: any = { + MAX_FILE_SIZE: 6 * 1024 * 1024, + SUPPORTED_FORMATS: ['image/png', 'image/jpeg', 'image/jpg'] + } + diff --git a/src/core/utils.tsx b/src/core/utils.tsx index 806e603..b419eec 100644 --- a/src/core/utils.tsx +++ b/src/core/utils.tsx @@ -29,7 +29,7 @@ export const passwordStrengthValidator = (password:any) => { return 'Password cannot be empty.' } if (!re.test(password)) { - return 'Password atleast 8 character,one upper case, one lower case, one number and one special characters.' + return 'Password should be 8 to 12 characters with at least one upper case, one lower case, one number and one special character.' } return '' diff --git a/src/screens/Attendance/AttendanceDetailView.tsx b/src/screens/Attendance/AttendanceDetailView.tsx index accc93b..5703c0d 100644 --- a/src/screens/Attendance/AttendanceDetailView.tsx +++ b/src/screens/Attendance/AttendanceDetailView.tsx @@ -102,7 +102,7 @@ class AttendanceDetailView extends React.Component{ onPress={this.onStudentProfileCheck.bind(this, studentItem)}> {(studentItem.profile_picture !== '') ? - + : {studentItem?.card_id || '0'} @@ -134,7 +134,7 @@ class AttendanceDetailView extends React.Component{ {(studentItem.profile_picture !== '') ? - + : {studentItem?.card_id || ''} diff --git a/src/screens/Diary/DiaryCreate.tsx b/src/screens/Diary/DiaryCreate.tsx index 30cf6a8..70b5fb2 100644 --- a/src/screens/Diary/DiaryCreate.tsx +++ b/src/screens/Diary/DiaryCreate.tsx @@ -5,7 +5,7 @@ import { Formik } from 'formik' import * as yup from 'yup' import { Picker } from '@react-native-picker/picker' import AsyncStorage from "@react-native-async-storage/async-storage" -import { currentYear, UserRoles, currentAcademicYear, fetchBaseUrl } from '@constants/Constants' //NOSONAR +import { currentYear, UserRoles, currentAcademicYear, fetchBaseUrl, imageFormat } from '@constants/Constants' //NOSONAR import { connect } from "react-redux" import { ActionCreators } from "@actions" //NOSONAR import PropTypes, { array } from 'prop-types' @@ -16,6 +16,7 @@ import BaseColors from "@theme/Colors" //NOSONAR import * as ImagePicker from 'expo-image-picker' import Constants from "expo-constants" import RNPickerSelect from "react-native-picker-select" +import RNFS from 'react-native-fs'; const diaryValidationSchema = yup.object().shape({ diary_type: yup @@ -261,19 +262,35 @@ class DiaryCreate extends React.Component{ quality: 1, }) } - if (!result.cancelled) { - const fileNameURL = result.assets[0].uri - const index = fileNameURL.lastIndexOf('/') - const fileName = fileNameURL.substring(index + 1) - const fileExtensionType = fileName.split('.').pop() - const formData: any = new FormData() - formData.append('file', { - uri: result.assets[0].uri, - name: fileName, - type: `image/${fileExtensionType}`, - }) - this.setState({ isImageUploaded: false }) - this.props.setDiaryImage({ data: formData, token: this.token }) + // if (!result.cancelled) { + // const fileNameURL = result.assets[0].uri + // const index = fileNameURL.lastIndexOf('/') + // const fileName = fileNameURL.substring(index + 1) + // const fileExtensionType = fileName.split('.').pop() + // const formData: any = new FormData() + // formData.append('file', { + // uri: result.assets[0].uri, + // name: fileName, + // type: `image/${fileExtensionType}`, + // }) + // this.setState({ isImageUploaded: false }) + // this.props.setDiaryImage({ data: formData, token: this.token }) + // } + if (!result.canceled && result.assets && result.assets[0].uri) { + const fileUri = result.assets[0].uri; + const fileType = result.assets[0].mimeType; // MIME type + const fileStat = await RNFS.stat(fileUri); + const fileSize = fileStat.size; // File size in bytes + if (fileSize > imageFormat.MAX_FILE_SIZE) { + Alert.alert('Error', 'File size exceeds 6 MB.'); + return; + } + if (!imageFormat.SUPPORTED_FORMATS.includes(fileType)) { + Alert.alert('Error', 'Only PNG, JPEG, and JPG formats are allowed.'); + return; + } + const base64 = await RNFS.readFile(fileUri, 'base64'); + this.setState({ isImageUploaded: true, image: `data:image/jpeg;base64,${base64}`, imagePreviewURL: `data:image/jpeg;base64,${base64}` }) } } diff --git a/src/screens/Diary/DiaryView.tsx b/src/screens/Diary/DiaryView.tsx index c505394..7ea65bf 100644 --- a/src/screens/Diary/DiaryView.tsx +++ b/src/screens/Diary/DiaryView.tsx @@ -134,7 +134,7 @@ class DiaryView extends React.PureComponent { const images = [] if (data) { - images.push({ uri: `${this.imageBaseUrl + data}` }) + images.push({ uri: `${data}` }) this.setState({ isVisible: true, images: images }) } } @@ -284,7 +284,7 @@ class DiaryView extends React.PureComponent { {item?.images !== '' && this.imageBaseUrl !== '' && - + } diff --git a/src/screens/Home.tsx b/src/screens/Home.tsx index 807a65d..ffb70df 100644 --- a/src/screens/Home.tsx +++ b/src/screens/Home.tsx @@ -262,7 +262,7 @@ class Home extends React.Component { { item?.profile_picture ? - + : diff --git a/src/screens/InstantFeedback/InstantFeedbackDetail.tsx b/src/screens/InstantFeedback/InstantFeedbackDetail.tsx index 0cde013..5ff06be 100644 --- a/src/screens/InstantFeedback/InstantFeedbackDetail.tsx +++ b/src/screens/InstantFeedback/InstantFeedbackDetail.tsx @@ -87,7 +87,7 @@ class InstantFeedbackDetail extends React.Component{ {(studentItem.profile_picture !== '') ? - + : {studentItem?.card_id || '0'} diff --git a/src/screens/InstantFeedback/InstantFeedbackDetailView.tsx b/src/screens/InstantFeedback/InstantFeedbackDetailView.tsx index 5eb0077..37e4611 100644 --- a/src/screens/InstantFeedback/InstantFeedbackDetailView.tsx +++ b/src/screens/InstantFeedback/InstantFeedbackDetailView.tsx @@ -88,7 +88,7 @@ class InstantFeedbackDetailView extends React.Component{ {(studentItem.profile_picture !== '') ? - + : {studentItem?.card_id || '0'} diff --git a/src/screens/NoticeBoard/NoticeBoardView.tsx b/src/screens/NoticeBoard/NoticeBoardView.tsx index 8991565..9622493 100644 --- a/src/screens/NoticeBoard/NoticeBoardView.tsx +++ b/src/screens/NoticeBoard/NoticeBoardView.tsx @@ -108,7 +108,7 @@ class NoticeBoardView extends React.Component{ onImagePreview = (data: any) => { const images = [] if (data.url) { - images.push({ uri: `${this.imageBaseUrl + data.url}` }) + images.push({ uri: `${data.url}` }) this.setState({ isVisible: true, images: images }) } } @@ -217,7 +217,7 @@ class NoticeBoardView extends React.Component{ {item?.image && this.imageBaseUrl && item?.image.map((imageInfo: any, index: any) => ( - + ))} diff --git a/src/screens/Quizzes/QuizSummaryDetails.tsx b/src/screens/Quizzes/QuizSummaryDetails.tsx index b1b80f4..6b23f73 100644 --- a/src/screens/Quizzes/QuizSummaryDetails.tsx +++ b/src/screens/Quizzes/QuizSummaryDetails.tsx @@ -326,7 +326,7 @@ class QuizSummaryDetails extends React.Component{ onPress={this.onStudentProfileCheck.bind(this, studentItem)}> {(studentItem.profile !== '') ? - @@ -374,7 +374,7 @@ class QuizSummaryDetails extends React.Component{ onPress={this.onStudentProfileCheck.bind(this, studentItem)}> {(studentItem.profile !== '') ? - @@ -422,7 +422,7 @@ class QuizSummaryDetails extends React.Component{ onPress={this.onStudentProfileCheck.bind(this, studentItem)}> {(studentItem.profile !== '') ? - diff --git a/src/screens/Student/StudentCreate.tsx b/src/screens/Student/StudentCreate.tsx index b8e1665..0aa579d 100644 --- a/src/screens/Student/StudentCreate.tsx +++ b/src/screens/Student/StudentCreate.tsx @@ -3,7 +3,7 @@ import { StyleSheet, Text, View, TouchableOpacity, TextInput, ScrollView, Activi import { AppStyles, BaseStyles } from "@theme/BaseStyles" //NOSONAR import { Formik } from 'formik' import * as yup from 'yup' -import { formValidationPatten, currentYear, UserRoles, currentAcademicYear, fetchBaseUrl } from '@constants/Constants' //NOSONAR +import { formValidationPatten, currentYear, UserRoles, currentAcademicYear, fetchBaseUrl, imageFormat } from '@constants/Constants' //NOSONAR import { connect } from "react-redux" import { ActionCreators } from "@actions" //NOSONAR import PropTypes from 'prop-types' @@ -15,6 +15,7 @@ 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'; +import RNFS from 'react-native-fs'; const Sepator = ({ style }: any) => @@ -193,19 +194,35 @@ class StudentCreate extends React.Component{ quality: 1, }) } - if (!result.cancelled) { - const fileNameURL = result.assets[0].uri - const index = fileNameURL.lastIndexOf('/') - const fileName = fileNameURL.substring(index + 1) - const fileExtensionType = fileName.split('.').pop() - const formData: any = new FormData() - formData.append('file', { - uri: result.assets[0].uri, - name: fileName, - type: `image/${fileExtensionType}`, - }) - this.setState({ isImageUploaded: false }) - this.props.setStudentImage({ data: formData, token: this.token }) + // if (!result.cancelled) { + // const fileNameURL = result.assets[0].uri + // const index = fileNameURL.lastIndexOf('/') + // const fileName = fileNameURL.substring(index + 1) + // const fileExtensionType = fileName.split('.').pop() + // const formData: any = new FormData() + // formData.append('file', { + // uri: result.assets[0].uri, + // name: fileName, + // type: `image/${fileExtensionType}`, + // }) + // this.setState({ isImageUploaded: false }) + // this.props.setStudentImage({ data: formData, token: this.token }) + // } + if (!result.canceled && result.assets && result.assets[0].uri) { + const fileUri = result.assets[0].uri; + const fileType = result.assets[0].mimeType; // MIME type + const fileStat = await RNFS.stat(fileUri); + const fileSize = fileStat.size; // File size in bytes + if (fileSize > imageFormat.MAX_FILE_SIZE) { + Alert.alert('Error', 'File size exceeds 6 MB.'); + return; + } + if (!imageFormat.SUPPORTED_FORMATS.includes(fileType)) { + Alert.alert('Error', 'Only PNG, JPEG, and JPG formats are allowed.'); + return; + } + const base64 = await RNFS.readFile(fileUri, 'base64'); + this.setState({ isImageUploaded: true, image: `data:image/jpeg;base64,${base64}`, imagePreviewURL: `data:image/jpeg;base64,${base64}` }) } } diff --git a/src/screens/Student/StudentProfile.tsx b/src/screens/Student/StudentProfile.tsx index fcb26e1..b731b0d 100644 --- a/src/screens/Student/StudentProfile.tsx +++ b/src/screens/Student/StudentProfile.tsx @@ -208,7 +208,7 @@ class StudentProfile extends React.Component{ {(studentProfile?.profile_picture !== '') ? - + : {studentProfile?.card_id || '0'} diff --git a/src/screens/Student/StudentUpdate.tsx b/src/screens/Student/StudentUpdate.tsx index 6872ca8..1adef77 100644 --- a/src/screens/Student/StudentUpdate.tsx +++ b/src/screens/Student/StudentUpdate.tsx @@ -3,7 +3,7 @@ import { StyleSheet, Text, View, TouchableOpacity, TextInput, ScrollView, Activi import { AppStyles, BaseStyles } from "@theme/BaseStyles" //NOSONAR import { Formik } from 'formik' import * as yup from 'yup' -import { formValidationPatten, currentYear, currentAcademicYear, fetchBaseUrl } from '@constants/Constants' //NOSONAR +import { formValidationPatten, currentYear, currentAcademicYear, fetchBaseUrl, imageFormat } from '@constants/Constants' //NOSONAR import { connect } from "react-redux" import { ActionCreators } from "@actions" //NOSONAR import PropTypes from 'prop-types' @@ -15,6 +15,7 @@ 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'; +import RNFS from 'react-native-fs'; const Sepator = ({ style }: any) => @@ -183,19 +184,36 @@ class StudentUpdate extends React.Component{ quality: 1, }) } - if (!result.cancelled) { - const fileNameURL = result.assets[0].uri - const index = fileNameURL.lastIndexOf('/') - const fileName = fileNameURL.substring(index + 1) - const fileExtensionType = fileName.split('.').pop() - const formData: any = new FormData() - formData.append('file', { - uri: result.assets[0].uri, - name: fileName, - type: `image/${fileExtensionType}`, - }) - this.setState({ isImageUploaded: false }) - this.props.setStudentImage({ data: formData, token: this.token }) + // if (!result.cancelled) { + // const fileNameURL = result.assets[0].uri + // const index = fileNameURL.lastIndexOf('/') + // const fileName = fileNameURL.substring(index + 1) + // const fileExtensionType = fileName.split('.').pop() + // const formData: any = new FormData() + // formData.append('file', { + // uri: result.assets[0].uri, + // name: fileName, + // type: `image/${fileExtensionType}`, + // }) + // this.setState({ isImageUploaded: false }) + // this.props.setStudentImage({ data: formData, token: this.token }) + // } + + if (!result.canceled && result.assets && result.assets[0].uri) { + const fileUri = result.assets[0].uri; + const fileType = result.assets[0].mimeType; // MIME type + const fileStat = await RNFS.stat(fileUri); + const fileSize = fileStat.size; // File size in bytes + if (fileSize > imageFormat.MAX_FILE_SIZE) { + Alert.alert('Error', 'File size exceeds 6 MB.'); + return; + } + if (!imageFormat.SUPPORTED_FORMATS.includes(fileType)) { + Alert.alert('Error', 'Only PNG, JPEG, and JPG formats are allowed.'); + return; + } + const base64 = await RNFS.readFile(fileUri, 'base64'); + this.setState({ isImageUploaded: true, image: `data:image/jpeg;base64,${base64}`, imagePreviewURL: `data:image/jpeg;base64,${base64}` }) } } @@ -251,7 +269,7 @@ class StudentUpdate extends React.Component{ {this.state.isImageUploaded ? : - studentProfileInfo && } {(!studentProfileInfo && !this.state.isImageUploaded) && } diff --git a/src/screens/Student/StudentView.tsx b/src/screens/Student/StudentView.tsx index c87c46b..fb251ce 100644 --- a/src/screens/Student/StudentView.tsx +++ b/src/screens/Student/StudentView.tsx @@ -185,7 +185,7 @@ class StudentView extends React.Component{ { (this.imageBaseUrl && item?.studentclass_details?.profile_picture) ? - : diff --git a/src/screens/Teacher/TeacherProfile.tsx b/src/screens/Teacher/TeacherProfile.tsx index 6ff7c73..f971401 100644 --- a/src/screens/Teacher/TeacherProfile.tsx +++ b/src/screens/Teacher/TeacherProfile.tsx @@ -192,7 +192,7 @@ class TeacherProfile extends React.Component{ this.state.teacherInfo?.image ? - + : { { item?.image ? - + :