diff --git a/src/Routes/Public/StackScreen.js b/src/Routes/Public/StackScreen.js
index 22f33866..44b8dfe9 100644
--- a/src/Routes/Public/StackScreen.js
+++ b/src/Routes/Public/StackScreen.js
@@ -32,6 +32,8 @@ import DashboardStack from './DashboardStack';
import SCPUserTabScreen from '../SCPUser/SCPUserTabScreen';
import YouthNetTabScreen from '../Youthnet/YouthNetTabScreen';
import UnauthorizedScreen from '../../screens/Unauthorized/UnauthorizedScreen';
+import PlpWebViewScreen from '../../screens/PlpWebViewScreen/PlpWebViewScreen';
+import ProgramsScreen from '../../screens/ProgramsScreen/ProgramsScreen';
const StackScreen = () => {
const Stack = createNativeStackNavigator();
@@ -270,6 +272,16 @@ const StackScreen = () => {
component={UnauthorizedScreen}
options={{ headerShown: false, lazy: true }}
/>
+
+
);
};
diff --git a/src/Routes/Public/TabScreen.js b/src/Routes/Public/TabScreen.js
index f2473658..f95ac227 100644
--- a/src/Routes/Public/TabScreen.js
+++ b/src/Routes/Public/TabScreen.js
@@ -8,6 +8,7 @@ import {
Platform,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
+import { useFocusEffect } from '@react-navigation/native';
import { useTranslation } from '../../context/LanguageContext';
import {
useTabBarStyle,
@@ -35,12 +36,14 @@ import explore_UNFILLED from '@src/assets/images/png/explore_UNFILLED.png';
const Tab = createBottomTabNavigator();
const WalkthroughableView = walkthroughable(View); // Wrap Image component
-const TabScreen = () => {
+ const TabScreen = () => {
+ console.log('###### TabScreen----yyyyy');
const { t } = useTranslation();
const [contentShow, setContentShow] = useState(true);
const [CopilotStarted, setCopilotStarted] = useState(false);
const [CopilotStopped, setCopilotStopped] = useState(false);
const [isVolunteer, setIsVolunteer] = useState(false);
+ const [userType, setUserType] = useState('');
const { start, goToNth, unregisterStep, copilotEvents } = useCopilot();
const insets = useSafeAreaInsets();
const tabBarStyle = useTabBarStyle();
@@ -58,28 +61,48 @@ const TabScreen = () => {
// copilotEvents.on('stop', () => setCopilotStopped(true));
// }, [start, copilotEvents]);
- useEffect(() => {
- const fetchData = async () => {
- let userType = await getDataFromStorage('userType');
- const result = JSON.parse(await getDataFromStorage('profileData'));
- console.log(
- '########## getUserDetails',
- result?.getUserDetails?.[0]?.customFields
- );
- const volunteer = result?.getUserDetails?.[0]?.customFields.filter(
- (item) => item?.label === 'IS_VOLUNTEER'
- );
- console.log('###### volunteer', volunteer);
- const isVolunteer = volunteer?.[0]?.selectedValues?.[0];
- console.log('###### isVolunteer', isVolunteer);
- setIsVolunteer(isVolunteer);
- if (userType === 'youthnet') {
- setContentShow(false);
- }
- };
+ // Use useFocusEffect to re-run when screen comes into focus
+ // This will trigger when userType changes in storage
+ useFocusEffect(
+ React.useCallback(() => {
+ const fetchData = async () => {
+ try {
+ let currentUserType = await getDataFromStorage('userType');
+ console.log('###### Fetched userType:', currentUserType);
+
+ const result = JSON.parse(await getDataFromStorage('profileData'));
+ console.log(
+ '########## getUserDetails',
+ result?.getUserDetails?.[0]?.customFields
+ );
+
+ const volunteer = result?.getUserDetails?.[0]?.customFields.filter(
+ (item) => item?.label === 'IS_VOLUNTEER'
+ );
+ console.log('###### volunteer', volunteer);
+
+ const isVolunteerValue = volunteer?.[0]?.selectedValues?.[0];
+ console.log('###### isVolunteer', isVolunteerValue);
+
+ setIsVolunteer(isVolunteerValue);
+ setUserType(currentUserType);
+
+ // Update contentShow based on userType
+ if (currentUserType === 'youthnet') {
+ console.log('###### youthnetTab - hiding content, showing explore');
+ setContentShow(false);
+ } else {
+ console.log('###### regularTab - showing content, hiding explore');
+ setContentShow(true);
+ }
+ } catch (error) {
+ console.error('###### Error fetching data:', error);
+ }
+ };
- fetchData();
- }, []);
+ fetchData();
+ }, [])
+ );
return (
{
const navigation = useNavigation();
const { setLanguage, language, t } = useTranslation();
const [selectedIndex, setSelectedIndex] = useState();
const [value, setValue] = useState();
+ const [userType, setUserType] = useState('');
+ const [userId, setUserId] = useState('');
+ const [showProgramSwitch, setShowProgramSwitch] = useState(false);
useEffect(() => {
// Set the initial value based on the current language
@@ -30,8 +38,32 @@ const SecondaryHeader = ({ logo }) => {
setSelectedIndex(new IndexPath(currentLanguageIndex));
setValue(language);
}
+
+ // Fetch userType and userId from AsyncStorage
+ fetchUserTypeAndId();
}, [language]); // Include language as a dependency
+ // Add focus effect to refresh data when returning from other screens
+ useFocusEffect(
+ React.useCallback(() => {
+ // Reset modal state when screen comes into focus
+ setShowProgramSwitch(false);
+ // Refresh user data
+ fetchUserTypeAndId();
+ }, [])
+ );
+
+ const fetchUserTypeAndId = async () => {
+ try {
+ const storedUserType = await getDataFromStorage('userType');
+ const storedUserId = await getDataFromStorage('userId');
+ setUserType(storedUserType || '');
+ setUserId(storedUserId || '');
+ } catch (error) {
+ console.error('Error fetching userType or userId:', error);
+ }
+ };
+
const onSelect = (index) => {
//setSelectedIndex(index);
const selectedValue = languages[index.row].value;
@@ -39,6 +71,16 @@ const SecondaryHeader = ({ logo }) => {
setLanguage(selectedValue);
};
+ const handleProgramSwitchToggle = () => {
+ setShowProgramSwitch(!showProgramSwitch);
+ };
+
+ const handleProgramSwitchClose = () => {
+ setShowProgramSwitch(false);
+ // Refresh userType after switching
+ fetchUserTypeAndId();
+ };
+
return (
{
/>
) : (
-
+
+ {userType && (
+
+
+ {userType ==="scp" ? "Second Chance Program" : userType ==="youthnet" ? "Vocational Traning" : userType }
+
+
+
+
+ )}
)}
+
+ {/* ProgramSwitch Modal */}
+
+
+
+
+
+ Switch Program
+
+
+
+
+
+ {showProgramSwitch && (
+ {
+ console.log('Program switched successfully:', userData);
+ // handleProgramSwitchClose();
+ }}
+ onError={(error) => {
+ console.error('Program switch error:', error);
+ }}
+ onClose={handleProgramSwitchClose}
+ />
+ )}
+
+
+
);
};
@@ -105,16 +199,63 @@ const styles = StyleSheet.create({
select: {
width: 100,
},
- center: {
+ centerContainer: {
alignItems: 'center',
+ flexDirection: 'row',
},
image: {
height: 50,
width: 50,
},
+ userTypeContainer: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ marginLeft: 12,
+ paddingHorizontal: 12,
+ paddingVertical: 6,
+ backgroundColor: '#F5F5F5',
+ borderRadius: 20,
+ borderWidth: 1,
+ borderColor: '#E5E5E5',
+ },
+ userTypeText: {
+ fontSize: 14,
+ color: '#4D4639',
+ fontFamily: 'Poppins-Medium',
+ marginRight: 4,
+ },
+ dropdownIcon: {
+ marginLeft: 2,
+ },
icon: {
marginLeft: 20,
},
+ modalOverlay: {
+ flex: 1,
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
+ justifyContent: 'flex-end',
+ },
+ modalContainer: {
+ backgroundColor: '#FFFFFF',
+ borderTopLeftRadius: 20,
+ borderTopRightRadius: 20,
+ height: '90%',
+ },
+ modalHeader: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ paddingHorizontal: 20,
+ paddingVertical: 15,
+ borderBottomWidth: 1,
+ borderBottomColor: '#E5E5E5',
+ },
+ modalTitle: {
+ fontSize: 20,
+ color: '#000',
+ fontFamily: 'Poppins-Bold',
+ fontWeight: '600',
+ },
});
SecondaryHeader.propTypes = {
diff --git a/src/components/ProgramSwitch/ProgramSwitch.js b/src/components/ProgramSwitch/ProgramSwitch.js
new file mode 100644
index 00000000..86bedb22
--- /dev/null
+++ b/src/components/ProgramSwitch/ProgramSwitch.js
@@ -0,0 +1,809 @@
+import React, { useState, useEffect } from 'react';
+import {
+ View,
+ StyleSheet,
+ ActivityIndicator,
+ Alert,
+ TouchableOpacity,
+ ScrollView,
+} from 'react-native';
+import PropTypes from 'prop-types';
+import GlobalText from '@components/GlobalText/GlobalText';
+import Ionicons from 'react-native-vector-icons/Ionicons';
+import { useNavigation, useFocusEffect, CommonActions } from '@react-navigation/native';
+
+import {
+ getCohort,
+ getProfileDetails,
+ getProgramDetails,
+ getUserDetails,
+ setAcademicYear,
+ notificationSubscribe,
+ telemetryTrackingData,
+} from '../../utils/API/AuthService';
+import {
+ deleteSavedItem,
+ getActiveCohortData,
+ getActiveCohortIds,
+ getDataFromStorage,
+ getDeviceId,
+ getuserDetails,
+ logEventFunction,
+ saveAccessToken,
+ saveRefreshToken,
+ setDataInStorage,
+ storeUsername,
+} from '../../utils/JsHelper/Helper';
+import moment from 'moment';
+import { TENANT_DATA } from '../../utils/Constants/app-constants';
+import { NotificationUnsubscribe } from '../../utils/Helper/JSHelper';
+const ProgramSwitch = ({ userId, onSuccess, onError, onClose }) => {
+ const [loading, setLoading] = useState(false);
+ const [currentUserType, setCurrentUserType] = useState('');
+ const [enrolledPrograms, setEnrolledPrograms] = useState([]);
+ const [tenantData, setTenantData] = useState([]);
+ const navigation = useNavigation();
+
+ useEffect(() => {
+ if (userId) {
+ fetchUserDetails();
+ getCurrentUserType();
+ }
+ }, [userId]);
+
+ // Refetch data when component comes into focus (e.g., after program switch)
+ useFocusEffect(
+ React.useCallback(() => {
+ if (userId) {
+ getCurrentUserType();
+ fetchUserDetails();
+ }
+ }, [userId])
+ );
+
+ const getCurrentUserType = async () => {
+ try {
+ const userType = await getDataFromStorage('userType');
+ setCurrentUserType(userType || '');
+ } catch (error) {
+ console.error('Error getting userType:', error);
+ }
+ };
+
+ const fetchUserDetails = async () => {
+ try {
+ setLoading(true);
+
+ // Get current tenant ID to exclude it from the list
+ const currentTenantId = await getDataFromStorage('userTenantid');
+ console.log('Current tenant ID:', currentTenantId);
+
+ // Call getUserDetails API
+ const response = await getUserDetails({ user_id: userId });
+ console.log(
+ 'User details fetched successfully:',
+ JSON.stringify(response?.userData?.tenantData)
+ );
+
+ if (response?.userData?.tenantData) {
+ const allTenantData = response.userData.tenantData;
+ setTenantData(allTenantData);
+
+ // Filter tenants where role is "Learner" and status is "active" or "pending"
+ // AND exclude the current program
+ const filteredPrograms = allTenantData.filter((tenant) => {
+ const hasLearnerRole = tenant.roles?.some(
+ (role) => role.roleName?.toLowerCase() === 'learner'
+ );
+ const isActiveOrPending =
+ tenant.tenantStatus === 'active' || tenant.tenantStatus === 'pending';
+ const isNotCurrentProgram = tenant.tenantId !== currentTenantId;
+
+ return hasLearnerRole && isActiveOrPending && isNotCurrentProgram;
+ });
+
+ setEnrolledPrograms(filteredPrograms);
+
+ // Store userId in localStorage (AsyncStorage)
+ await setDataInStorage('userId', userId);
+
+ console.log('Current program excluded. Other enrolled programs:', filteredPrograms);
+
+ // Call success callback if provided
+ if (onSuccess) {
+ onSuccess(response.userData);
+ }
+ } else {
+ throw new Error('Failed to fetch user details');
+ }
+ } catch (error) {
+ console.error('Error fetching user details:', error);
+ Alert.alert('Error', 'Failed to fetch user details. Please try again.');
+
+ // Call error callback if provided
+ if (onError) {
+ onError(error);
+ }
+ } finally {
+ setLoading(false);
+ }
+ };
+ const handleProgramLogin = async(tenant) => {
+ try {
+ setLoading(true);
+ const tenantId = tenant?.tenantId;
+ const tenantName = tenant?.tenantName;
+
+ console.log('#### Starting program switch for:', tenantName, tenantId);
+
+ // Get user_id from storage
+ const user_id = await getDataFromStorage('userId');
+
+ if (!user_id) {
+ Alert.alert('Error', 'User ID not found. Please login again.');
+ setLoading(false);
+ return;
+ }
+
+ // Get user details from storage
+ const userDetails = await getuserDetails();
+
+ if (!userDetails || !userDetails.tenantData) {
+ Alert.alert('Error', 'User details not found. Please login again.');
+ setLoading(false);
+ return;
+ }
+
+ const selectedTenantData = [
+ userDetails?.tenantData?.find((t) => t.tenantId === tenantId),
+ ];
+ const uiConfig = selectedTenantData?.[0]?.params?.uiConfig;
+ await setDataInStorage('uiConfig', JSON.stringify(uiConfig));
+ console.log('#### loginmultirole uiConfig', JSON.stringify(uiConfig));
+ console.log('#### loginmultirole selectedTenantData', selectedTenantData);
+
+ if (!selectedTenantData[0]) {
+ Alert.alert('Error', 'Program data not found. Please try again.');
+ setLoading(false);
+ return;
+ }
+
+ const enrollmentId = userDetails?.enrollmentId;
+ await setDataInStorage('tenantData', JSON.stringify(selectedTenantData || {}));
+ await setDataInStorage('userId', user_id || '');
+ await setDataInStorage('enrollmentId', enrollmentId || '');
+
+ //store dynamic templateId
+ const templateId = selectedTenantData?.[0]?.templateId;
+ await setDataInStorage('templateId', templateId || '');
+
+ const academicyear = await setAcademicYear({ tenantid: tenantId });
+ const academicYearId = academicyear?.[0]?.id;
+ await setDataInStorage('academicYearId', academicYearId || '');
+ await setDataInStorage('userTenantid', tenantId || '');
+
+ const cohort = await getCohort({
+ user_id,
+ tenantid: tenantId,
+ academicYearId,
+ });
+ console.log('#### loginmultirole cohort', cohort);
+
+ let cohort_id;
+ if (cohort.params?.status !== 'failed') {
+ const getActiveCohort = await getActiveCohortData(cohort);
+ const getActiveCohortId = await getActiveCohortIds(cohort);
+ await setDataInStorage(
+ 'cohortData',
+ JSON.stringify(getActiveCohort?.[0]) || ''
+ );
+ cohort_id = getActiveCohortId?.[0];
+ }
+
+ const profileData = await getProfileDetails({
+ userId: user_id,
+ });
+ console.log('#### loginmultirole profileData', profileData);
+
+ await setDataInStorage('profileData', JSON.stringify(profileData));
+ await setDataInStorage(
+ 'Username',
+ profileData?.getUserDetails?.[0]?.username || ''
+ );
+ await storeUsername(profileData?.getUserDetails?.[0]?.username);
+
+ await setDataInStorage(
+ 'cohortId',
+ cohort_id || '00000000-0000-0000-0000-000000000000'
+ );
+
+ const tenantDetails = (await getProgramDetails()) || [];
+
+ const MatchedTenant = tenantDetails.filter(
+ (item) => item?.tenantId === tenantId
+ );
+
+ await setDataInStorage(
+ 'contentFilter',
+ JSON.stringify(MatchedTenant?.[0]?.contentFilter || {})
+ );
+
+ // Get tenant IDs for each program type
+ const youthnetTenantIds = tenantDetails
+ ?.filter((item) => item?.name === TENANT_DATA.YOUTHNET)
+ ?.map((item) => item?.tenantId);
+
+ const scpTenantIds = tenantDetails
+ ?.filter((item) => item?.name === TENANT_DATA.SECOND_CHANCE_PROGRAM)
+ ?.map((item) => item?.tenantId);
+
+ const campToClubTenantIds = tenantDetails
+ ?.filter((item) => item?.name === TENANT_DATA.CAMP_TO_CLUB)
+ ?.map((item) => item?.tenantId);
+
+ console.log('#### All tenant details:', JSON.stringify(tenantDetails));
+ console.log('#### Tenant IDs - SCP:', scpTenantIds, 'Youthnet:', youthnetTenantIds, 'Camp to Club:', campToClubTenantIds);
+ console.log('#### Selected Tenant Name:', selectedTenantData?.[0]?.tenantName);
+ console.log('#### Looking for tenant with ID:', tenantId);
+
+ // Also check by tenant name directly from selectedTenantData
+ const selectedTenantName = selectedTenantData?.[0]?.tenantName;
+ console.log('#### Comparing tenant name:', selectedTenantName, 'with constants');
+
+ // Device notification subscription
+ try {
+ const deviceId = await getDeviceId();
+ const action = 'add';
+ await notificationSubscribe({ deviceId, user_id, action });
+ } catch (notifError) {
+ console.log('#### Notification subscribe error (non-critical):', notifError);
+ }
+
+ // Telemetry tracking
+ try {
+ const now = moment();
+ const telemetryPayloadData = {
+ event: 'login',
+ type: 'click',
+ ets: now.unix(),
+ };
+ await telemetryTrackingData({
+ telemetryPayloadData,
+ });
+ } catch (telemetryError) {
+ console.log('#### Telemetry tracking error (non-critical):', telemetryError);
+ }
+
+ // Close the modal BEFORE navigation
+ if (onClose && typeof onClose === 'function') {
+ onClose();
+ }
+
+ // Small delay to ensure modal closes and storage is written
+ await new Promise(resolve => setTimeout(resolve, 200));
+
+ // Navigate based on program type
+ setLoading(false);
+
+ // Use selectedTenantName already declared above
+ if (scpTenantIds?.includes(tenantId)) {
+ console.log('#### Navigating to SCP (matched by tenant ID)');
+ await setDataInStorage('userType', 'scp');
+ navigation.reset({
+ index: 0,
+ routes: [{ name: 'SCPUserTabScreen' }],
+ });
+ } else if (selectedTenantName === TENANT_DATA.SECOND_CHANCE_PROGRAM) {
+ console.log('#### Navigating to SCP (matched by tenant name)');
+ await setDataInStorage('userType', 'scp');
+ navigation.reset({
+ index: 0,
+ routes: [{ name: 'SCPUserTabScreen' }],
+ });
+ } else if (youthnetTenantIds?.includes(tenantId)) {
+ console.log('#### Navigating to Youthnet/Vocational Training (matched by tenant ID)');
+ await setDataInStorage('userType', 'youthnet');
+ navigation.reset({
+ index: 0,
+ routes: [{ name: 'Dashboard' }],
+ });
+ } else if (selectedTenantName === TENANT_DATA.YOUTHNET) {
+ console.log('#### Navigating to Youthnet/Vocational Training (matched by tenant name)');
+ await setDataInStorage('userType', 'youthnet');
+ navigation.reset({
+ index: 0,
+ routes: [{ name: 'Dashboard' }],
+ });
+ } else if (campToClubTenantIds?.includes(tenantId)) {
+ console.log('#### Navigating to Camp to Club (matched by tenant ID)');
+ await setDataInStorage('userType', TENANT_DATA.CAMP_TO_CLUB);
+ navigation.reset({
+ index: 0,
+ routes: [{ name: 'Dashboard' }],
+ });
+ } else if (selectedTenantName === TENANT_DATA.CAMP_TO_CLUB) {
+ console.log('#### Navigating to Camp to Club (matched by tenant name)');
+ await setDataInStorage('userType', TENANT_DATA.CAMP_TO_CLUB);
+ navigation.reset({
+ index: 0,
+ routes: [{ name: 'Dashboard' }],
+ });
+ } else {
+ // Default: use tenant name as userType
+ console.log('#### Navigating to Default Dashboard with userType:', selectedTenantName);
+ await setDataInStorage('userType', selectedTenantName || 'default');
+ navigation.reset({
+ index: 0,
+ routes: [{ name: 'Dashboard' }],
+ });
+ }
+
+ } catch (error) {
+ console.error('#### Error in handleProgramLogin:', error);
+ console.error('#### Error details:', JSON.stringify(error));
+ setLoading(false);
+
+ // Close modal on error too
+ if (onClose && typeof onClose === 'function') {
+ onClose();
+ }
+
+ Alert.alert(
+ 'Error',
+ `Failed to switch program: ${error.message || 'Please try again.'}`,
+ [
+ {
+ text: 'OK',
+ onPress: () => {
+ if (onError && typeof onError === 'function') {
+ onError(error);
+ }
+ }
+ }
+ ]
+ );
+ }
+ };
+ // const handleProgramLogin = async(tenant) => {
+ // try {
+ // setLoading(true);
+ // const tenantId = tenant?.tenantId;
+
+ // // Get user details from storage
+ // const userDetails = await getuserDetails();
+ // const roleName = "Learner";
+
+ // // Get userId properly from storage (await the promise)
+ // const user_id = await getDataFromStorage('userId');
+
+ // if (!user_id) {
+ // Alert.alert('Error', 'User ID not found. Please login again.');
+ // setLoading(false);
+ // return;
+ // }
+
+ // const selectedTenantData = [
+ // userDetails?.tenantData?.find((t) => t.tenantId === tenantId),
+ // ];
+ // console.log('#### loginmultirole selectedTenantData', selectedTenantData);
+
+ // if (!selectedTenantData[0]) {
+ // Alert.alert('Error', 'Program data not found. Please try again.');
+ // setLoading(false);
+ // return;
+ // }
+
+ // const enrollmentId = userDetails?.enrollmentId;
+ // await setDataInStorage('tenantData', JSON.stringify(selectedTenantData || {}));
+ // await setDataInStorage('userId', user_id || '');
+ // await setDataInStorage('enrollmentId', enrollmentId || '');
+
+ // //store dynamic templateId
+ // const templateId = selectedTenantData?.[0]?.templateId;
+ // await setDataInStorage('templateId', templateId || '');
+
+ // const academicyear = await setAcademicYear({ tenantid: tenantId });
+ // const academicYearId = academicyear?.[0]?.id;
+ // await setDataInStorage('academicYearId', academicYearId || '');
+ // await setDataInStorage('userTenantid', tenantId || '');
+
+ // const cohort = await getCohort({
+ // user_id,
+ // tenantid: tenantId,
+ // academicYearId,
+ // });
+ // console.log('#### loginmultirole cohort', cohort);
+
+ // let cohort_id;
+ // if (cohort.params?.status !== 'failed') {
+ // const getActiveCohort = await getActiveCohortData(cohort);
+ // const getActiveCohortId = await getActiveCohortIds(cohort);
+ // await setDataInStorage(
+ // 'cohortData',
+ // JSON.stringify(getActiveCohort?.[0]) || ''
+ // );
+ // cohort_id = getActiveCohortId?.[0];
+ // }
+
+ // const profileData = await getProfileDetails({
+ // userId: user_id,
+ // });
+ // console.log('#### loginmultirole profileData', profileData);
+
+ // await setDataInStorage('profileData', JSON.stringify(profileData));
+ // await setDataInStorage(
+ // 'Username',
+ // profileData?.getUserDetails?.[0]?.username || ''
+ // );
+ // await storeUsername(profileData?.getUserDetails?.[0]?.username);
+
+ // await setDataInStorage(
+ // 'cohortId',
+ // cohort_id || '00000000-0000-0000-0000-000000000000'
+ // );
+
+ // const tenantDetails = (await getProgramDetails()) || [];
+
+ // const MatchedTenant = tenantDetails.filter(
+ // (item) => item?.tenantId === tenantId
+ // );
+
+ // await setDataInStorage(
+ // 'contentFilter',
+ // JSON.stringify(MatchedTenant?.[0]?.contentFilter || {})
+ // );
+
+ // // Get tenant IDs for each program type
+ // const youthnetTenantIds = tenantDetails
+ // ?.filter((item) => item?.name === TENANT_DATA.YOUTHNET)
+ // ?.map((item) => item?.tenantId);
+
+ // const scpTenantIds = tenantDetails
+ // ?.filter((item) => item?.name === TENANT_DATA.SECOND_CHANCE_PROGRAM)
+ // ?.map((item) => item?.tenantId);
+
+ // const campToClubTenantIds = tenantDetails
+ // ?.filter((item) => item?.name === TENANT_DATA.CAMP_TO_CLUB)
+ // ?.map((item) => item?.tenantId);
+
+ // console.log('#### Tenant IDs - SCP:', scpTenantIds, 'Youthnet:', youthnetTenantIds, 'Camp to Club:', campToClubTenantIds);
+ // console.log('#### Selected Tenant Name:', selectedTenantData?.[0]?.tenantName);
+
+ // // Navigate based on program type
+ // if (scpTenantIds?.includes(tenantId)) {
+ // console.log('#### Navigating to SCP');
+ // await setDataInStorage('userType', 'scp');
+ // setLoading(false);
+ // navigation.navigate('SCPUserTabScreen');
+ // } else if (youthnetTenantIds?.includes(tenantId)) {
+ // console.log('#### Navigating to Youthnet/Vocational Training');
+ // await setDataInStorage('userType', 'youthnet');
+ // setLoading(false);
+ // navigation.navigate('Dashboard');
+ // } else if (campToClubTenantIds?.includes(tenantId)) {
+ // console.log('#### Navigating to Camp to Club');
+ // await setDataInStorage('userType', TENANT_DATA.CAMP_TO_CLUB);
+ // setLoading(false);
+ // navigation.navigate('Dashboard');
+ // } else {
+ // // Default: use tenant name as userType
+ // console.log('#### Navigating to Default Dashboard with userType:', selectedTenantData?.[0]?.tenantName);
+ // await setDataInStorage('userType', selectedTenantData?.[0]?.tenantName || 'default');
+ // setLoading(false);
+ // navigation.navigate('Dashboard');
+ // }
+
+ // // Close the modal/dialog if onClose is provided
+ // if (onClose) {
+ // onClose();
+ // }
+
+ // } catch (error) {
+ // console.error('Error in handleProgramLogin:', error);
+ // setLoading(false);
+ // Alert.alert(
+ // 'Error',
+ // 'Failed to switch program. Please try again.',
+ // [
+ // {
+ // text: 'OK',
+ // onPress: () => {
+ // if (onError) {
+ // onError(error);
+ // }
+ // }
+ // }
+ // ]
+ // );
+ // }
+ // };
+ const handleProgramSwitch = async (tenant) => {
+ try {
+ // Store the selected tenant information
+ await setDataInStorage('userTenantid', tenant.tenantId);
+ await setDataInStorage('userType', tenant.tenantName);
+
+ console.log('Switched to program:', tenant.tenantName);
+ Alert.alert('Success', `Switched to ${tenant.tenantName}`, [
+ {
+ text: 'OK',
+ onPress: () => {
+ if (onSuccess) {
+ onSuccess(tenant);
+ }
+ },
+ },
+ ]);
+ } catch (error) {
+ console.error('Error switching program:', error);
+ Alert.alert('Error', 'Failed to switch program. Please try again.');
+ }
+ };
+
+ const handleShowAllPrograms = () => {
+ console.log('All tenant data:', tenantData);
+ // Navigate to Programs screen
+ navigation.navigate('ProgramsScreen');
+ };
+ const logoutEvent = async () => {
+ const obj = {
+ eventName: 'logout_Event',
+ method: 'button-click',
+ screenName: 'ProgramSwitch',
+ };
+ await logEventFunction(obj);
+ };
+ const handleLogout = () => {
+ Alert.alert('Logout', 'Are you sure you want to logout?', [
+ { text: 'Cancel', style: 'cancel' },
+ {
+ text: 'Logout',
+ style: 'destructive',
+ onPress: async() => {
+ const fetchData = async () => {
+ await NotificationUnsubscribe();
+ await deleteSavedItem('refreshToken');
+ await deleteSavedItem('Accesstoken');
+ await deleteSavedItem('userId');
+ await deleteSavedItem('cohortId');
+ await deleteSavedItem('cohortData');
+ await deleteSavedItem('weightedProgress');
+ await deleteSavedItem('courseTrackData');
+ await deleteSavedItem('profileData');
+ await deleteSavedItem('tenantData');
+ await deleteSavedItem('academicYearId');
+ await deleteSavedItem('userType');
+ logoutEvent();
+ // Reset the navigation stack and navigate to LoginSignUpScreen
+ navigation.dispatch(
+ CommonActions.reset({
+ index: 0,
+ routes: [{ name: 'LoginScreen' }],
+ })
+ );
+ const now = moment();
+ const telemetryPayloadData = {
+ event: 'logout',
+ type: 'click',
+ ets: now.unix(),
+ };
+ await telemetryTrackingData({
+ telemetryPayloadData,
+ });
+ };
+
+ fetchData(); // Add your logout logic here
+ },
+ },
+ ]);
+ };
+
+
+
+
+
+ return (
+
+ {loading ? (
+
+
+ Loading programs...
+
+ ) : (
+
+ {/* Current Program Header */}
+
+
+ {currentUserType ==="scp" ? "Second Chance Program" : currentUserType ==="youthnet" ? "Vocational Traning" : currentUserType }
+
+
+
+ {/* Other Programs Section */}
+
+
+ Other programs you are enrolled in
+
+
+ {enrolledPrograms.length > 0 ? (
+ enrolledPrograms.map((program, index) => (
+ handleProgramLogin(program)}
+ >
+
+ {program.tenantName}
+
+
+
+ ))
+ ) : (
+
+ No other programs available
+
+ )}
+
+
+ {/* Action Buttons */}
+
+
+
+ Home
+
+
+
+
+ Show All Programs
+
+
+
+
+
+ Logout
+
+
+
+
+
+ )}
+
+ );
+};
+
+ProgramSwitch.propTypes = {
+ userId: PropTypes.string.isRequired,
+ onSuccess: PropTypes.func,
+ onError: PropTypes.func,
+ onClose: PropTypes.func,
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: '#FFFFFF',
+ },
+ scrollContent: {
+ paddingBottom: 20,
+ },
+ loadingContainer: {
+ justifyContent: 'center',
+ alignItems: 'center',
+ padding: 40,
+ },
+ loadingText: {
+ marginTop: 10,
+ fontSize: 16,
+ color: '#4D4639',
+ fontFamily: 'Poppins-Regular',
+ },
+ headerContainer: {
+ paddingVertical: 20,
+ paddingHorizontal: 20,
+ backgroundColor: '#FFFFFF',
+ borderBottomWidth: 1,
+ borderBottomColor: '#E5E5E5',
+ },
+ currentProgramTitle: {
+ fontSize: 22,
+ color: '#000',
+ fontFamily: 'Poppins-Bold',
+ fontWeight: '600',
+ },
+ sectionContainer: {
+ paddingTop: 20,
+ paddingHorizontal: 20,
+ },
+ sectionTitle: {
+ fontSize: 14,
+ color: '#666',
+ fontFamily: 'Poppins-Regular',
+ marginBottom: 15,
+ },
+ programCard: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ paddingVertical: 18,
+ paddingHorizontal: 15,
+ backgroundColor: '#FFFFFF',
+ borderRadius: 12,
+ borderWidth: 1,
+ borderColor: '#E5E5E5',
+ marginBottom: 12,
+ shadowColor: '#000',
+ shadowOffset: {
+ width: 0,
+ height: 1,
+ },
+ shadowOpacity: 0.05,
+ shadowRadius: 2,
+ elevation: 1,
+ },
+ programName: {
+ fontSize: 16,
+ color: '#000',
+ fontFamily: 'Poppins-Medium',
+ flex: 1,
+ },
+ buttonContainer: {
+ paddingHorizontal: 20,
+ paddingTop: 30,
+ paddingBottom: 20,
+ },
+ button: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
+ paddingVertical: 14,
+ paddingHorizontal: 20,
+ backgroundColor: '#FFFFFF',
+ borderRadius: 25,
+ borderWidth: 1,
+ borderColor: '#D0C5B4',
+ marginBottom: 12,
+ shadowColor: '#000',
+ shadowOffset: {
+ width: 0,
+ height: 1,
+ },
+ shadowOpacity: 0.05,
+ shadowRadius: 2,
+ elevation: 1,
+ },
+ logoutButton: {
+ borderColor: '#F6931E',
+ borderWidth: 1.5,
+ },
+ buttonText: {
+ fontSize: 16,
+ color: '#000',
+ fontFamily: 'Poppins-Medium',
+ marginHorizontal: 8,
+ },
+ logoutText: {
+ color: '#F6931E',
+ },
+ emptyText: {
+ fontSize: 14,
+ color: '#999',
+ fontFamily: 'Poppins-Regular',
+ textAlign: 'center',
+ paddingVertical: 20,
+ },
+});
+
+export default ProgramSwitch;
+
diff --git a/src/components/ProgramSwitch/index.js b/src/components/ProgramSwitch/index.js
new file mode 100644
index 00000000..336b9a33
--- /dev/null
+++ b/src/components/ProgramSwitch/index.js
@@ -0,0 +1,2 @@
+export { default } from './ProgramSwitch';
+
diff --git a/src/components/ZoomWebView/index.ts b/src/components/ZoomWebView/index.ts
new file mode 100644
index 00000000..89fb4f55
--- /dev/null
+++ b/src/components/ZoomWebView/index.ts
@@ -0,0 +1,2 @@
+export { default } from './ZoomWebView';
+export { default as ZoomWebView } from './ZoomWebView';
diff --git a/src/context/Languages.js b/src/context/Languages.js
index f343fcd9..e98dc821 100644
--- a/src/context/Languages.js
+++ b/src/context/Languages.js
@@ -11,30 +11,30 @@ export const languages = [
title: 'marathi',
value: 'ma',
},
- // {
- // title: 'odia',
- // value: 'odia',
- // },
+ {
+ title: 'odia',
+ value: 'odia',
+ },
// {
// title: 'bengali',
// value: 'ba',
// },
- // {
- // title: 'telugu',
- // value: 'te',
- // },
- // {
- // title: 'kannada',
- // value: 'ka',
- // },
- // {
- // title: 'tamil',
- // value: 'ta',
- // },
- // {
- // title: 'gujarati',
- // value: 'gu',
- // },
+ {
+ title: 'telugu',
+ value: 'te',
+ },
+ {
+ title: 'kannada',
+ value: 'ka',
+ },
+ {
+ title: 'tamil',
+ value: 'ta',
+ },
+ {
+ title: 'gujarati',
+ value: 'gu',
+ },
// {
// title: 'urdu',
// value: 'ur',
diff --git a/src/screens/LanguageScreen/LanguageScreen.js b/src/screens/LanguageScreen/LanguageScreen.js
index 948ffe6a..9d0733b7 100644
--- a/src/screens/LanguageScreen/LanguageScreen.js
+++ b/src/screens/LanguageScreen/LanguageScreen.js
@@ -295,7 +295,7 @@ const LanguageScreen = () => {
);
const handlethis = () => {
- navigation.navigate('LoginSignUpScreen');
+ navigation.navigate('PlpWebViewScreen');
};
if (loading) {
diff --git a/src/screens/LoginScreen/LoginScreen.js b/src/screens/LoginScreen/LoginScreen.js
index 3f8169a5..ffa2f28d 100644
--- a/src/screens/LoginScreen/LoginScreen.js
+++ b/src/screens/LoginScreen/LoginScreen.js
@@ -1,24 +1,455 @@
-import {
- View,
- TouchableOpacity,
- StyleSheet,
- Image,
- // SafeAreaView,
- Pressable,
- ScrollView,
- StatusBar,
-} from 'react-native';
+// import {
+// View,
+// TouchableOpacity,
+// StyleSheet,
+// Image,
+// // SafeAreaView,
+// Pressable,
+// ScrollView,
+// StatusBar,
+// } from 'react-native';
+// import SafeAreaWrapper from '../../components/SafeAreaWrapper/SafeAreaWrapper';
+// import { useState, React, useEffect } from 'react';
+// import PrimaryButton from '../../components/PrimaryButton/PrimaryButton';
+// import { useNavigation } from '@react-navigation/native';
+// import {
+// getCohort,
+// getProfileDetails,
+// getProgramDetails,
+// login,
+// notificationSubscribe,
+// setAcademicYear,
+// telemetryTrackingData,
+// } from '../../utils/API/AuthService';
+// import {
+// getActiveCohortData,
+// getActiveCohortIds,
+// getDataFromStorage,
+// getDeviceId,
+// getuserDetails,
+// saveAccessToken,
+// saveRefreshToken,
+// setDataInStorage,
+// storeUsername,
+// } from '../../utils/JsHelper/Helper';
+// import LoginTextField from '../../components/LoginTextField/LoginTextField';
+// import UserNameField from '../../components/LoginTextField/UserNameField';
+// import { useTranslation } from '../../context/LanguageContext';
+// import ActiveLoading from '../LoadingScreen/ActiveLoading';
+// import Logo from '../../assets/images/png/logo.png';
+// import globalStyles from '../../utils/Helper/Style';
+// import { useInternet } from '../../context/NetworkContext';
+// import NetworkAlert from '../../components/NetworkError/NetworkAlert';
+// import GlobalText from '@components/GlobalText/GlobalText';
+// import moment from 'moment';
+// import { TENANT_DATA } from '../../utils/Constants/app-constants';
+// import SwitchAccountDialog from '../../utils/SwitchAccount/SwitchAccount';
+
+// const LoginScreen = () => {
+// const navigation = useNavigation();
+// const { t } = useTranslation();
+// const { isConnected } = useInternet();
+// const [userName, setUserName] = useState('');
+// const [password, setPassword] = useState('');
+// const [acceptTerms] = useState(false);
+// const [isDisabled, setIsDisabled] = useState(true);
+// const [errmsg, setErrmsg] = useState('');
+// const [loading, setLoading] = useState(false);
+// const [networkstatus, setNetworkstatus] = useState(true);
+// const [usernames, setUsernames] = useState([]);
+
+// const onChangeText = (e) => {
+// setUserName(e.trim());
+// };
+// const onChangePassword = (e) => {
+// setPassword(e.trim());
+// };
+
+// const handleLogin = async () => {
+// if (isConnected) {
+// setNetworkstatus(true);
+// setLoading(true);
+// const payload = {
+// username: userName,
+// password: password,
+// };
+// const data = await login(payload);
+
+// if (data?.access_token) {
+// await saveRefreshToken(data?.refresh_token || '');
+// await saveAccessToken(data?.access_token || '');
+
+// const userDetails = await getuserDetails();
+
+// console.log('#### loginmultirole userDetails', userDetails);
+
+// setUserDetails(userDetails);
+
+// setSwitchDialogOpen(true);
+
+// setLoading(false);
+// } else {
+// setLoading(false);
+// setErrmsg(data?.params?.errmsg.toLowerCase().replace(/ /g, '_'));
+// }
+// } else {
+// setNetworkstatus(false);
+// }
+// };
+
+// const [switchDialogOpen, setSwitchDialogOpen] = useState(false);
+// const [userDetails, setUserDetails] = useState(null);
+// const [tenantId, setTenantId] = useState('');
+// const [tenantName, setTenantName] = useState('');
+// const [roleId, setRoleId] = useState('');
+// const [roleName, setRoleName] = useState('');
+
+// const callBackSwitchDialog = async (
+// tenantId,
+// tenantName,
+// roleId,
+// roleName
+// ) => {
+// setLoading(true);
+// setSwitchDialogOpen(false);
+
+// // Set the state values
+// setTenantId(tenantId);
+// setTenantName(tenantName);
+// setRoleId(roleId);
+// setRoleName(roleName);
+
+// const tenantid = tenantId;
+
+// console.log('#### loginmultirole tenantId', tenantId);
+// console.log('#### loginmultirole tenantName', tenantName);
+// console.log('#### loginmultirole roleId', roleId);
+// console.log('#### loginmultirole roleName', roleName);
+
+// console.log('#### loginmultirole userDetails', userDetails);
+// const user_id = userDetails?.userId;
+// const tenantData = [
+// userDetails?.tenantData?.find((tenant) => tenant.tenantId === tenantId),
+// ];
+// console.log('#### loginmultirole tenantData', tenantData);
+
+// const enrollmentId = userDetails?.enrollmentId;
+// await setDataInStorage('tenantData', JSON.stringify(tenantData || {}));
+// await setDataInStorage('userId', user_id || '');
+// await setDataInStorage('enrollmentId', enrollmentId || '');
+
+// //store dynamci templateId
+// const templateId = tenantData?.[0]?.templateId;
+// await setDataInStorage('templateId', templateId || '');
+
+// const academicyear = await setAcademicYear({ tenantid });
+// const academicYearId = academicyear?.[0]?.id;
+// await setDataInStorage('academicYearId', academicYearId || '');
+// await setDataInStorage('userTenantid', tenantId || '');
+// const cohort = await getCohort({ user_id, tenantid, academicYearId });
+// console.log('#### loginmultirole cohort', cohort);
+// let cohort_id;
+// if (cohort.params?.status !== 'failed') {
+// const getActiveCohort = await getActiveCohortData(cohort);
+// const getActiveCohortId = await getActiveCohortIds(cohort);
+// await setDataInStorage(
+// 'cohortData',
+// JSON.stringify(getActiveCohort?.[0]) || ''
+// );
+// cohort_id = getActiveCohortId?.[0];
+// }
+
+// const profileData = await getProfileDetails({
+// userId: user_id,
+// });
+// console.log('#### loginmultirole profileData', profileData);
+
+// await setDataInStorage('profileData', JSON.stringify(profileData));
+// await setDataInStorage(
+// 'Username',
+// profileData?.getUserDetails?.[0]?.username || ''
+// );
+// await storeUsername(profileData?.getUserDetails?.[0]?.username);
+
+// await setDataInStorage(
+// 'cohortId',
+// cohort_id || '00000000-0000-0000-0000-000000000000'
+// );
+// const tenantDetails = (await getProgramDetails()) || [];
+
+// const MatchedTenant = tenantDetails.filter(
+// (item) => item?.tenantId === tenantId
+// );
+
+// // console.log('tenantDetails===>', JSON.stringify(tenantDetails));
+// // console.log(
+// // 'MatchedTenant===>',
+// // JSON.stringify(MatchedTenant?.[0]?.contentFilter)
+// // );
+
+// await setDataInStorage(
+// 'contentFilter',
+// JSON.stringify(MatchedTenant?.[0]?.contentFilter || {})
+// );
+
+// const youthnetTenantIds = tenantDetails
+// ?.filter((item) => item?.name === TENANT_DATA.YOUTHNET)
+// ?.map((item) => item?.tenantId);
+
+// const scp = tenantDetails
+// ?.filter((item) => item.name === 'Second Chance Program')
+// ?.map((item) => item.tenantId);
+
+// const role = roleName;
+
+// if (role == 'Learner' || role == 'Student') {
+// console.log('#### loginmultirole role', role);
+
+// if (tenantId === scp?.[0]) {
+// console.log('####loginintoscp', scp);
+// await setDataInStorage('userType', 'scp');
+// navigation.navigate('SCPUserTabScreen');
+
+// // if (cohort_id) {
+// // navigation.navigate('SCPUserTabScreen');
+// // } else {
+// // navigation.navigate('Dashboard');
+// // }
+// } else {
+// if (tenantId === youthnetTenantIds?.[0]) {
+// await setDataInStorage('userType', 'youthnet');
+// // navigation.navigate('YouthNetTabScreen');
+// navigation.navigate('Dashboard');
+// } else {
+// // await setDataInStorage('userType', 'pragyanpath');
+// await setDataInStorage('userType', tenantData?.[0]?.tenantName);
+// navigation.navigate('Dashboard');
+// }
+// }
+// const deviceId = await getDeviceId();
+// const action = 'add';
+
+// await notificationSubscribe({ deviceId, user_id, action });
+// } else {
+// setErrmsg('invalid_username_or_password');
+// }
+// const now = moment();
+
+// const telemetryPayloadData = {
+// event: 'login',
+// type: 'click',
+// ets: now.unix(),
+// };
+// await telemetryTrackingData({
+// telemetryPayloadData,
+// });
+
+// setLoading(false);
+// };
+
+// const callBackError = () => {
+// setErrmsg('invalid_username_or_password');
+// };
+
+// // const handleLogin = async () => {
+// // navigation.navigate('Dashboard');
+// // };
+
+// useEffect(() => {
+// if (userName.length > 0 && password.length > 0 && acceptTerms) {
+// setIsDisabled(false);
+// } else {
+// setIsDisabled(true);
+// }
+// }, [userName, password, acceptTerms]);
+
+// useEffect(() => {
+// const fetchData = async () => {
+// const data = JSON.parse(await getDataFromStorage('usernames')) || [];
+// const filteredSuggestions = data.filter((item) => item != null);
+
+// setUsernames(filteredSuggestions);
+// };
+// fetchData();
+// }, []);
+
+// return (
+//
+// {loading ? (
+//
+// ) : (
+//
+//
+//
+
+// {/* {
+// navigation.navigate('LoginSignUpScreen');
+// }}
+// >
+//
+//
+// {t('back')}
+//
+// */}
+//
+//
+// {t('login')}
+//
+// {/*
+// {t('login_with_the_cred')}
+// */}
+//
+//
+//
+//
+//
+//
+
+// {errmsg !== '' && (
+//
+// {t(errmsg || 'invalid_username_or_password')}
+//
+// )}
+//
+// {
+// navigation.navigate('ForgotPassword', { enableLogin: true });
+// }}
+// style={{ paddingLeft: 20, marginBottom: 30, zIndex: -1 }}
+// >
+//
+// {t('forgot_password')}?
+//
+//
+// {/*
+//
+//
+// {t('remember_me')}
+//
+// */}
+// {/*
+//
+//
+//
+//
+//
+// {t('Read_T_&_C')}
+//
+// {
+// navigation.navigate('TermsAndCondition');
+// }}
+// >
+//
+// {t('terms_and_conditions2')}
+//
+//
+//
+// */}
+//
+//
+//
+// {
+// navigation.navigate('RegisterStart');
+// }}
+// style={{ alignItems: 'center', padding: 20 }}
+// >
+//
+// {t('dont_have_account')}
+//
+//
+//
+// )}
+
+// {
+// setNetworkstatus(!networkstatus);
+// }}
+// />
+// setSwitchDialogOpen(false)}
+// callbackFunction={callBackSwitchDialog}
+// authResponse={userDetails?.tenantData}
+// callBackError={callBackError}
+// />
+//
+// );
+// };
+// const styles = StyleSheet.create({
+// scrollView: {
+// flex: 1,
+// },
+// textfieldbox: {
+// marginTop: 20,
+// },
+// });
+// export default LoginScreen;
+import React, { useState, useRef, useEffect } from 'react';
+import { View, ActivityIndicator, StyleSheet, Alert, BackHandler } from 'react-native';
+import WebView from 'react-native-webview';
import SafeAreaWrapper from '../../components/SafeAreaWrapper/SafeAreaWrapper';
-import { useState, React, useEffect } from 'react';
-import PrimaryButton from '../../components/PrimaryButton/PrimaryButton';
-import { useNavigation } from '@react-navigation/native';
+import BackHeader from '../../components/Layout/BackHeader';
+import { useNavigation, useIsFocused } from '@react-navigation/native';
import {
getCohort,
getProfileDetails,
getProgramDetails,
- login,
- notificationSubscribe,
setAcademicYear,
+ notificationSubscribe,
telemetryTrackingData,
} from '../../utils/API/AuthService';
import {
@@ -32,409 +463,348 @@ import {
setDataInStorage,
storeUsername,
} from '../../utils/JsHelper/Helper';
-import LoginTextField from '../../components/LoginTextField/LoginTextField';
-import UserNameField from '../../components/LoginTextField/UserNameField';
-import { useTranslation } from '../../context/LanguageContext';
-import ActiveLoading from '../LoadingScreen/ActiveLoading';
-import Logo from '../../assets/images/png/logo.png';
-import globalStyles from '../../utils/Helper/Style';
-import { useInternet } from '../../context/NetworkContext';
-import NetworkAlert from '../../components/NetworkError/NetworkAlert';
-import GlobalText from '@components/GlobalText/GlobalText';
import moment from 'moment';
import { TENANT_DATA } from '../../utils/Constants/app-constants';
-import SwitchAccountDialog from '../../utils/SwitchAccount/SwitchAccount';
+import Config from 'react-native-config';
const LoginScreen = () => {
- const navigation = useNavigation();
- const { t } = useTranslation();
- const { isConnected } = useInternet();
- const [userName, setUserName] = useState('');
- const [password, setPassword] = useState('');
- const [acceptTerms] = useState(false);
- const [isDisabled, setIsDisabled] = useState(true);
+ const [loading, setLoading] = useState(true);
const [errmsg, setErrmsg] = useState('');
- const [loading, setLoading] = useState(false);
- const [networkstatus, setNetworkstatus] = useState(true);
- const [usernames, setUsernames] = useState([]);
-
- const onChangeText = (e) => {
- setUserName(e.trim());
- };
- const onChangePassword = (e) => {
- setPassword(e.trim());
- };
-
- const handleLogin = async () => {
- if (isConnected) {
- setNetworkstatus(true);
- setLoading(true);
- const payload = {
- username: userName,
- password: password,
- };
- const data = await login(payload);
-
- if (data?.access_token) {
- await saveRefreshToken(data?.refresh_token || '');
- await saveAccessToken(data?.access_token || '');
-
- const userDetails = await getuserDetails();
-
- console.log('#### loginmultirole userDetails', userDetails);
+ const [canGoBack, setCanGoBack] = useState(false);
+ const navigation = useNavigation();
+ const isFocused = useIsFocused();
+ const webViewRef = useRef(null);
+ const url = `${Config.LEARNER_PLP_LINK}/login`
- setUserDetails(userDetails);
+ // Handle hardware back button
+ useEffect(() => {
+ const backAction = () => {
+ if (canGoBack && webViewRef.current) {
+ // Navigate back in WebView
+ webViewRef.current.goBack();
+ return true; // Prevent default behavior (exit app)
+ }
+ // Let default behavior happen (go back in navigation)
+ return false;
+ };
- setSwitchDialogOpen(true);
+ const backHandler = BackHandler.addEventListener(
+ 'hardwareBackPress',
+ backAction
+ );
- setLoading(false);
- } else {
- setLoading(false);
- setErrmsg(data?.params?.errmsg.toLowerCase().replace(/ /g, '_'));
+ return () => backHandler.remove();
+ }, [canGoBack]);
+
+ // Injected JavaScript to set isAndroidApp in localStorage
+ // This runs before page content loads
+ const injectedJavaScriptBeforeContentLoaded = `
+ (function() {
+ try {
+ window.localStorage.setItem('isAndroidApp', 'yes');
+ console.log('[BeforeLoad] isAndroidApp set to yes in localStorage');
+ } catch (error) {
+ console.error('[BeforeLoad] Error setting isAndroidApp:', error);
}
- } else {
- setNetworkstatus(false);
- }
- };
-
- const [switchDialogOpen, setSwitchDialogOpen] = useState(false);
- const [userDetails, setUserDetails] = useState(null);
- const [tenantId, setTenantId] = useState('');
- const [tenantName, setTenantName] = useState('');
- const [roleId, setRoleId] = useState('');
- const [roleName, setRoleName] = useState('');
-
- const callBackSwitchDialog = async (
- tenantId,
- tenantName,
- roleId,
- roleName
- ) => {
- setLoading(true);
- setSwitchDialogOpen(false);
-
- // Set the state values
- setTenantId(tenantId);
- setTenantName(tenantName);
- setRoleId(roleId);
- setRoleName(roleName);
-
- const tenantid = tenantId;
-
- console.log('#### loginmultirole tenantId', tenantId);
- console.log('#### loginmultirole tenantName', tenantName);
- console.log('#### loginmultirole roleId', roleId);
- console.log('#### loginmultirole roleName', roleName);
-
- console.log('#### loginmultirole userDetails', userDetails);
- const user_id = userDetails?.userId;
- const tenantData = [
- userDetails?.tenantData?.find((tenant) => tenant.tenantId === tenantId),
- ];
- console.log('#### loginmultirole tenantData', tenantData);
-
- const enrollmentId = userDetails?.enrollmentId;
- await setDataInStorage('tenantData', JSON.stringify(tenantData || {}));
- await setDataInStorage('userId', user_id || '');
- await setDataInStorage('enrollmentId', enrollmentId || '');
-
- //store dynamci templateId
- const templateId = tenantData?.[0]?.templateId;
- await setDataInStorage('templateId', templateId || '');
-
- const academicyear = await setAcademicYear({ tenantid });
+ })();
+ true;
+ `;
+
+ // This runs after page content loads
+ const injectedJavaScript = `
+ (function() {
+ try {
+ window.localStorage.setItem('isAndroidApp', 'yes');
+ console.log('[AfterLoad] isAndroidApp set to yes in localStorage');
+
+ // Send confirmation back to React Native
+ if (window.ReactNativeWebView) {
+ window.ReactNativeWebView.postMessage(JSON.stringify({
+ type: 'ANDROID_APP_FLAG_SET',
+ value: window.localStorage.getItem('isAndroidApp')
+ }));
+ }
+ } catch (error) {
+ console.error('[AfterLoad] Error setting isAndroidApp:', error);
+ }
+ })();
+ true;
+ `;
+
+ const handleProgramLogin = async(tenantId, userId, token, refreshToken) => {
+ await saveAccessToken(token || '');
+ await saveRefreshToken(refreshToken || '')
+ const userDetails = await getuserDetails();
+ const roleName = "Learner";
+
+ const user_id = userId;
+ const tenantData = [
+ userDetails?.tenantData?.find((tenant) => tenant.tenantId === tenantId),
+ ];
+ const uiConfig = tenantData?.[0]?.params?.uiConfig;
+ await setDataInStorage('uiConfig', JSON.stringify(uiConfig));
+ console.log('#### loginmultirole uiConfig', JSON.stringify(uiConfig));
+ console.log('#### loginmultirole tenantData', tenantData);
+
+ const enrollmentId = userDetails?.enrollmentId;
+ await setDataInStorage('tenantData', JSON.stringify(tenantData || {}));
+ await setDataInStorage('userId', user_id || '');
+ await setDataInStorage('enrollmentId', enrollmentId || '');
+
+ //store dynamic templateId
+ const templateId = tenantData?.[0]?.templateId;
+ await setDataInStorage('templateId', templateId || '');
+
+ const academicyear = await setAcademicYear({ tenantid: tenantId });
const academicYearId = academicyear?.[0]?.id;
await setDataInStorage('academicYearId', academicYearId || '');
await setDataInStorage('userTenantid', tenantId || '');
- const cohort = await getCohort({ user_id, tenantid, academicYearId });
- console.log('#### loginmultirole cohort', cohort);
- let cohort_id;
- if (cohort.params?.status !== 'failed') {
- const getActiveCohort = await getActiveCohortData(cohort);
- const getActiveCohortId = await getActiveCohortIds(cohort);
- await setDataInStorage(
- 'cohortData',
- JSON.stringify(getActiveCohort?.[0]) || ''
- );
- cohort_id = getActiveCohortId?.[0];
- }
-
- const profileData = await getProfileDetails({
- userId: user_id,
+ const cohort = await getCohort({
+ user_id,
+ tenantid: tenantId,
+ academicYearId,
});
- console.log('#### loginmultirole profileData', profileData);
-
- await setDataInStorage('profileData', JSON.stringify(profileData));
+ console.log('#### loginmultirole cohort', cohort);
+ let cohort_id;
+ if (cohort.params?.status !== 'failed') {
+ const getActiveCohort = await getActiveCohortData(cohort);
+ const getActiveCohortId = await getActiveCohortIds(cohort);
await setDataInStorage(
- 'Username',
- profileData?.getUserDetails?.[0]?.username || ''
+ 'cohortData',
+ JSON.stringify(getActiveCohort?.[0]) || ''
);
- await storeUsername(profileData?.getUserDetails?.[0]?.username);
+ cohort_id = getActiveCohortId?.[0];
+ }
+
+ const profileData = await getProfileDetails({
+ userId: user_id,
+ });
+ console.log('#### loginmultirole profileData', profileData);
+
+ await setDataInStorage('profileData', JSON.stringify(profileData));
+ await setDataInStorage(
+ 'Username',
+ profileData?.getUserDetails?.[0]?.username || ''
+ );
+ await storeUsername(profileData?.getUserDetails?.[0]?.username);
- await setDataInStorage(
- 'cohortId',
- cohort_id || '00000000-0000-0000-0000-000000000000'
- );
- const tenantDetails = (await getProgramDetails()) || [];
+ await setDataInStorage(
+ 'cohortId',
+ cohort_id || '00000000-0000-0000-0000-000000000000'
+ );
+ const tenantDetails = (await getProgramDetails()) || [];
- const MatchedTenant = tenantDetails.filter(
- (item) => item?.tenantId === tenantId
- );
+ const MatchedTenant = tenantDetails.filter(
+ (item) => item?.tenantId === tenantId
+ );
- // console.log('tenantDetails===>', JSON.stringify(tenantDetails));
- // console.log(
- // 'MatchedTenant===>',
- // JSON.stringify(MatchedTenant?.[0]?.contentFilter)
- // );
+ // console.log('tenantDetails===>', JSON.stringify(tenantDetails));
+ // console.log(
+ // 'MatchedTenant===>',
+ // JSON.stringify(MatchedTenant?.[0]?.contentFilter)
+ // );
- await setDataInStorage(
- 'contentFilter',
- JSON.stringify(MatchedTenant?.[0]?.contentFilter || {})
- );
+ await setDataInStorage(
+ 'contentFilter',
+ JSON.stringify(MatchedTenant?.[0]?.contentFilter || {})
+ );
- const youthnetTenantIds = tenantDetails
- ?.filter((item) => item?.name === TENANT_DATA.YOUTHNET)
- ?.map((item) => item?.tenantId);
+ const youthnetTenantIds = tenantDetails
+ ?.filter((item) => item?.name === TENANT_DATA.YOUTHNET)
+ ?.map((item) => item?.tenantId);
- const scp = tenantDetails
- ?.filter((item) => item.name === 'Second Chance Program')
- ?.map((item) => item.tenantId);
+ const scp = tenantDetails
+ ?.filter((item) => item.name === 'Second Chance Program')
+ ?.map((item) => item.tenantId);
- const role = roleName;
+ // const role = roleName;
- if (role == 'Learner' || role == 'Student') {
- console.log('#### loginmultirole role', role);
+ {
+ // console.log('#### loginmultirole role', role);
- if (tenantId === scp?.[0]) {
- console.log('####loginintoscp', scp);
- await setDataInStorage('userType', 'scp');
- navigation.navigate('SCPUserTabScreen');
+ if (tenantId === scp?.[0]) {
+ console.log('####loginintoscp', scp);
+ await setDataInStorage('userType', 'scp');
+ navigation.navigate('SCPUserTabScreen');
- // if (cohort_id) {
- // navigation.navigate('SCPUserTabScreen');
- // } else {
- // navigation.navigate('Dashboard');
- // }
+ // if (cohort_id) {
+ // navigation.navigate('SCPUserTabScreen');
+ // } else {
+ // navigation.navigate('Dashboard');
+ // }
+ } else {
+ if (tenantId === youthnetTenantIds?.[0]) {
+ await setDataInStorage('userType', 'youthnet');
+ // navigation.navigate('YouthNetTabScreen');
+ navigation.navigate('Dashboard');
} else {
- if (tenantId === youthnetTenantIds?.[0]) {
- await setDataInStorage('userType', 'youthnet');
- // navigation.navigate('YouthNetTabScreen');
- navigation.navigate('Dashboard');
- } else {
- // await setDataInStorage('userType', 'pragyanpath');
- await setDataInStorage('userType', tenantData?.[0]?.tenantName);
- navigation.navigate('Dashboard');
- }
+ // await setDataInStorage('userType', 'pragyanpath');
+ await setDataInStorage('userType', tenantData?.[0]?.tenantName);
+ navigation.navigate('Dashboard');
}
- const deviceId = await getDeviceId();
- const action = 'add';
-
- await notificationSubscribe({ deviceId, user_id, action });
- } else {
- setErrmsg('invalid_username_or_password');
}
- const now = moment();
-
- const telemetryPayloadData = {
- event: 'login',
- type: 'click',
- ets: now.unix(),
- };
- await telemetryTrackingData({
- telemetryPayloadData,
- });
-
- setLoading(false);
+ const deviceId = await getDeviceId();
+ const action = 'add';
+
+ await notificationSubscribe({ deviceId, user_id, action });
+ }
+
+ const now = moment();
+
+ const telemetryPayloadData = {
+ event: 'login',
+ type: 'click',
+ ets: now.unix(),
};
+ await telemetryTrackingData({
+ telemetryPayloadData,
+ });
- const callBackError = () => {
- setErrmsg('invalid_username_or_password');
};
- // const handleLogin = async () => {
- // navigation.navigate('Dashboard');
- // };
-
- useEffect(() => {
- if (userName.length > 0 && password.length > 0 && acceptTerms) {
- setIsDisabled(false);
- } else {
- setIsDisabled(true);
+ const handleWebViewMessage = async (event) => {
+ try {
+ const message = JSON.parse(event.nativeEvent.data);
+ console.log('Received from web:', message);
+
+ // Log when Android flag is confirmed set
+ if (message.type === 'ANDROID_APP_FLAG_SET') {
+ console.log('✓ isAndroidApp confirmed in localStorage:', message.value);
+ return;
+ }
+
+ if (message.type === 'ENROLL_PROGRAM_EVENT') {
+ const tenantId = message.data.tenantId;
+ const userId = message.data.userId;
+ const token = message.data.token;
+ const refreshToken = message.data.refreshToken;
+ await handleProgramLogin(tenantId, userId, token, refreshToken);
+
+ // Handle the event
+ console.log('User data:', message.data);
+ }
+
+ if (message.type === 'ACCESS_PROGRAM_EVENT') {
+ console.log("Hellooooo")
+ const tenantId = message.data.tenantId;
+ const userId = message.data.userId;
+ const token = message.data.token;
+ const refreshToken = message.data.refreshToken;
+ await handleProgramLogin(tenantId, userId, token, refreshToken);
+
+ console.log('Access Program data:', message.data);
+ }
+
+ if (message.type === 'LOGIN_INTO_ONLY_ONE_PROGRAM_EVENT') {
+ const tenantId = message.data.tenantId;
+ const userId = message.data.userId;
+ const token = message.data.token;
+ const refreshToken = message.data.refreshToken;
+ console.log('Login into Only One Program data:', message.data);
+
+
+
+ await handleProgramLogin(tenantId, userId, token, refreshToken);
+ // const refreshToken = ""
+ }
+ } catch (error) {
+ console.error('Error handling WebView message:', error);
}
- }, [userName, password, acceptTerms]);
-
- useEffect(() => {
- const fetchData = async () => {
- const data = JSON.parse(await getDataFromStorage('usernames')) || [];
- const filteredSuggestions = data.filter((item) => item != null);
-
- setUsernames(filteredSuggestions);
- };
- fetchData();
- }, []);
+ };
return (
-
- {loading ? (
-
- ) : (
-
-
-
-
- {/* {
- navigation.navigate('LoginSignUpScreen');
+
+
+
+ {loading && (
+
+
+
+ )}
+ {
+ setLoading(false);
+ // Re-inject the localStorage value after page loads
+ if (webViewRef.current) {
+ webViewRef.current.injectJavaScript(injectedJavaScript);
+ }
}}
- >
-
-
- {t('back')}
-
- */}
-
-
- {t('login')}
-
- {/* {
+ // Update canGoBack state
+ setCanGoBack(navState.canGoBack);
- style={[globalStyles.subHeading, { marginVertical: 5 }]}
- >
- {t('login_with_the_cred')}
- */}
-
-
-
-
-
-
-
- {errmsg !== '' && (
-
- {t(errmsg || 'invalid_username_or_password')}
-
- )}
-
- {
- navigation.navigate('ForgotPassword', { enableLogin: true });
+ // Re-inject on every navigation to ensure it persists
+ if (webViewRef.current) {
+ webViewRef.current.injectJavaScript(injectedJavaScript);
+ }
+ console.log('WebView Path Changed:', navState.url);
+ console.log('Can Go Back:', navState.canGoBack);
+ // if (navState.url === 'https://qa-plp.prathamdigital.org/login') {
+ // // Only navigate when screen is focused to prevent redirect loop
+ // if (isFocused) {
+ // navigation.navigate('LoginScreen');
+ // // Go back in WebView history so it's not on /login when user returns
+ // if (navState.canGoBack && webViewRef.current) {
+ // webViewRef.current.goBack();
+ // }
+ // }
+ // }
}}
- style={{ paddingLeft: 20, marginBottom: 30, zIndex: -1 }}
- >
-
- {t('forgot_password')}?
-
-
- {/*
-
-
- {t('remember_me')}
-
- */}
- {/*
-
-
-
-
-
- {t('Read_T_&_C')}
-
- {
- navigation.navigate('TermsAndCondition');
- }}
- >
-
- {t('terms_and_conditions2')}
-
-
-
- */}
-
-
-
- {
- navigation.navigate('RegisterStart');
+ onShouldStartLoadWithRequest={(request) => {
+ // if (request.url === 'https://qa-plp.prathamdigital.org/login') {
+ // if (isFocused) {
+ // navigation.navigate('LoginScreen');
+ // }
+ // return false;
+ // }
+ return true;
}}
- style={{ alignItems: 'center', padding: 20 }}
- >
-
- {t('dont_have_account')}
-
-
-
- )}
-
- {
- setNetworkstatus(!networkstatus);
- }}
- />
- setSwitchDialogOpen(false)}
- callbackFunction={callBackSwitchDialog}
- authResponse={userDetails?.tenantData}
- callBackError={callBackError}
- />
-
+ onMessage={handleWebViewMessage}
+ style={styles.webview}
+ startInLoadingState={true}
+ domStorageEnabled={true}
+ javaScriptEnabled={true}
+ renderLoading={() => (
+
+
+
+ )}
+ />
+
+
+
);
};
+
const styles = StyleSheet.create({
- scrollView: {
+ container: {
flex: 1,
+ backgroundColor: 'white',
+ marginTop: 40,
},
- textfieldbox: {
- marginTop: 20,
+ webviewContainer: {
+ flex: 1,
+ },
+ loader: {
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ right: 0,
+ bottom: 0,
+ justifyContent: 'center',
+ alignItems: 'center',
+ backgroundColor: 'white',
+ zIndex: 1,
+ },
+ webview: {
+ flex: 1,
},
});
+
export default LoginScreen;
+
+
diff --git a/src/screens/PlpWebViewScreen/PlpWebViewScreen.js b/src/screens/PlpWebViewScreen/PlpWebViewScreen.js
new file mode 100644
index 00000000..8999d143
--- /dev/null
+++ b/src/screens/PlpWebViewScreen/PlpWebViewScreen.js
@@ -0,0 +1,431 @@
+import React, { useState, useRef, useEffect } from 'react';
+import { View, ActivityIndicator, StyleSheet, Alert, BackHandler } from 'react-native';
+import WebView from 'react-native-webview';
+import SafeAreaWrapper from '../../components/SafeAreaWrapper/SafeAreaWrapper';
+import BackHeader from '../../components/Layout/BackHeader';
+import { useNavigation, useIsFocused } from '@react-navigation/native';
+import {
+ getCohort,
+ getProfileDetails,
+ getProgramDetails,
+ setAcademicYear,
+ notificationSubscribe,
+ telemetryTrackingData,
+} from '../../utils/API/AuthService';
+import {
+ getActiveCohortData,
+ getActiveCohortIds,
+ getDataFromStorage,
+ getDeviceId,
+ getuserDetails,
+ saveAccessToken,
+ saveRefreshToken,
+ setDataInStorage,
+ storeUsername,
+} from '../../utils/JsHelper/Helper';
+import moment from 'moment';
+import { TENANT_DATA } from '../../utils/Constants/app-constants';
+import Config from 'react-native-config';
+import { useTranslation } from '../../context/LanguageContext';
+
+const PlpWebViewScreen = () => {
+ const [loading, setLoading] = useState(true);
+ const [errmsg, setErrmsg] = useState('');
+ const [canGoBack, setCanGoBack] = useState(false);
+ const navigation = useNavigation();
+ const isFocused = useIsFocused();
+ const webViewRef = useRef(null);
+ const { t, setLanguage, language } = useTranslation();
+ console.log("#### language", language);
+
+ const url = Config.LEARNER_PLP_LINK
+
+ // Handle hardware back button
+ useEffect(() => {
+ const backAction = () => {
+ if (canGoBack && webViewRef.current) {
+ // Navigate back in WebView
+ webViewRef.current.goBack();
+ return true; // Prevent default behavior (exit app)
+ }
+ // Let default behavior happen (go back in navigation)
+ return false;
+ };
+
+ const backHandler = BackHandler.addEventListener(
+ 'hardwareBackPress',
+ backAction
+ );
+
+ return () => backHandler.remove();
+ }, [canGoBack]);
+
+ // Injected JavaScript to set isAndroidApp in localStorage
+ // This runs before page content loads
+ const injectedJavaScriptBeforeContentLoaded = `
+ (function() {
+ try {
+ window.localStorage.setItem('isAndroidApp', 'yes');
+ if('${language}' === 'ma')
+ {
+ window.localStorage.setItem('lang', 'mr');
+ }
+ else if('${language}' === 'te')
+ {
+ window.localStorage.setItem('lang', 'tel');
+
+ }
+ else if('${language}' === 'gu')
+ {
+ window.localStorage.setItem('lang', 'guj');
+ }
+ else if('${language}' === 'ta')
+ {
+ window.localStorage.setItem('lang', 'tam');
+ }
+ else if('${language}' === 'ka')
+ {
+ window.localStorage.setItem('lang', 'kan');
+ }
+ else if('${language}' === 'odia')
+ {
+ window.localStorage.setItem('lang', 'odi');
+ }
+ else
+ {
+ window.localStorage.setItem('lang', '${language}');
+ }
+ console.log('[BeforeLoad] isAndroidApp set to yes in localStorage');
+ } catch (error) {
+ console.error('[BeforeLoad] Error setting isAndroidApp:', error);
+ }
+ })();
+ true;
+ `;
+
+ // This runs after page content loads
+ const injectedJavaScript = `
+ (function() {
+ try {
+ window.localStorage.setItem('isAndroidApp', 'yes');
+ console.log('[AfterLoad] isAndroidApp set to yes in localStorage');
+
+ // Send confirmation back to React Native
+ if (window.ReactNativeWebView) {
+ window.ReactNativeWebView.postMessage(JSON.stringify({
+ type: 'ANDROID_APP_FLAG_SET',
+ value: window.localStorage.getItem('isAndroidApp')
+ }));
+ }
+ } catch (error) {
+ console.error('[AfterLoad] Error setting isAndroidApp:', error);
+ }
+ })();
+ true;
+ `;
+
+ const handleProgramLogin = async(tenantId, userId, token, refreshToken) => {
+ await saveAccessToken(token || '');
+ await saveRefreshToken(refreshToken || '')
+ const userDetails = await getuserDetails();
+ const roleName = "Learner";
+
+ const user_id = userId;
+ const tenantData = [
+ userDetails?.tenantData?.find((tenant) => tenant.tenantId === tenantId),
+ ];
+ const uiConfig = tenantData?.[0]?.params?.uiConfig;
+ await setDataInStorage('uiConfig', JSON.stringify(uiConfig));
+ console.log('#### loginmultirole uiConfig', JSON.stringify(uiConfig));
+ console.log('#### loginmultirole tenantData', tenantData);
+
+ const enrollmentId = userDetails?.enrollmentId;
+ await setDataInStorage('tenantData', JSON.stringify(tenantData || {}));
+ await setDataInStorage('userId', user_id || '');
+ await setDataInStorage('enrollmentId', enrollmentId || '');
+
+ //store dynamic templateId
+ const templateId = tenantData?.[0]?.templateId;
+ await setDataInStorage('templateId', templateId || '');
+
+ const academicyear = await setAcademicYear({ tenantid: tenantId });
+ const academicYearId = academicyear?.[0]?.id;
+ await setDataInStorage('academicYearId', academicYearId || '');
+ await setDataInStorage('userTenantid', tenantId || '');
+ const cohort = await getCohort({
+ user_id,
+ tenantid: tenantId,
+ academicYearId,
+ });
+ console.log('#### loginmultirole cohort', cohort);
+ let cohort_id;
+ if (cohort.params?.status !== 'failed') {
+ const getActiveCohort = await getActiveCohortData(cohort);
+ const getActiveCohortId = await getActiveCohortIds(cohort);
+ await setDataInStorage(
+ 'cohortData',
+ JSON.stringify(getActiveCohort?.[0]) || ''
+ );
+ cohort_id = getActiveCohortId?.[0];
+ }
+
+ const profileData = await getProfileDetails({
+ userId: user_id,
+ });
+ console.log('#### loginmultirole profileData', profileData);
+
+ await setDataInStorage('profileData', JSON.stringify(profileData));
+ await setDataInStorage(
+ 'Username',
+ profileData?.getUserDetails?.[0]?.username || ''
+ );
+ await storeUsername(profileData?.getUserDetails?.[0]?.username);
+
+ await setDataInStorage(
+ 'cohortId',
+ cohort_id || '00000000-0000-0000-0000-000000000000'
+ );
+ const tenantDetails = (await getProgramDetails()) || [];
+
+ const MatchedTenant = tenantDetails.filter(
+ (item) => item?.tenantId === tenantId
+ );
+
+ // console.log('tenantDetails===>', JSON.stringify(tenantDetails));
+ // console.log(
+ // 'MatchedTenant===>',
+ // JSON.stringify(MatchedTenant?.[0]?.contentFilter)
+ // );
+
+ await setDataInStorage(
+ 'contentFilter',
+ JSON.stringify(MatchedTenant?.[0]?.contentFilter || {})
+ );
+
+ const youthnetTenantIds = tenantDetails
+ ?.filter((item) => item?.name === TENANT_DATA.YOUTHNET)
+ ?.map((item) => item?.tenantId);
+
+ const scp = tenantDetails
+ ?.filter((item) => item.name === 'Second Chance Program')
+ ?.map((item) => item.tenantId);
+
+ // const role = roleName;
+
+ {
+ // console.log('#### loginmultirole role', role);
+
+ if (tenantId === scp?.[0]) {
+ console.log('####loginintoscp', scp);
+ await setDataInStorage('userType', 'scp');
+ navigation.navigate('SCPUserTabScreen');
+
+ // if (cohort_id) {
+ // navigation.navigate('SCPUserTabScreen');
+ // } else {
+ // navigation.navigate('Dashboard');
+ // }
+ } else {
+ if (tenantId === youthnetTenantIds?.[0]) {
+ await setDataInStorage('userType', 'youthnet');
+ // navigation.navigate('YouthNetTabScreen');
+ navigation.navigate('Dashboard');
+ } else {
+ // await setDataInStorage('userType', 'pragyanpath');
+ await setDataInStorage('userType', tenantData?.[0]?.tenantName);
+ navigation.navigate('Dashboard');
+ }
+ }
+ const deviceId = await getDeviceId();
+ const action = 'add';
+
+ await notificationSubscribe({ deviceId, user_id, action });
+ }
+
+ const now = moment();
+
+ const telemetryPayloadData = {
+ event: 'login',
+ type: 'click',
+ ets: now.unix(),
+ };
+ await telemetryTrackingData({
+ telemetryPayloadData,
+ });
+
+ };
+
+ const handleWebViewMessage = async (event) => {
+ try {
+ const message = JSON.parse(event.nativeEvent.data);
+ console.log('Received from web:', message);
+
+ // Log when Android flag is confirmed set
+ if (message.type === 'ANDROID_APP_FLAG_SET') {
+ console.log('✓ isAndroidApp confirmed in localStorage:', message.value);
+ return;
+ }
+ if (message.type === 'LANGUAGE_CHANGE_EVENT') {
+ console.log("Language changed to:", message.data);
+ if(message.data.language === 'mr')
+ {
+ setLanguage('ma');
+ }
+ else if(message.data.language === 'tel')
+ {
+ setLanguage('te');
+ }
+ else if(message.data.language === 'guj')
+ {
+ setLanguage('gu');
+ }
+ else if(message.data.language === 'tam')
+ {
+ setLanguage('ta');
+ }
+ else if(message.data.language === 'kan')
+ {
+ setLanguage('ka');
+ }
+ else if(message.data.language === 'odi')
+ {
+ setLanguage('odia');
+ }
+ else
+ setLanguage(message.data.language);
+ }
+
+ if (message.type === 'ENROLL_PROGRAM_EVENT') {
+ const tenantId = message.data.tenantId;
+ const userId = message.data.userId;
+ const token = message.data.token;
+ const refreshToken = message.data.refreshToken;
+ await handleProgramLogin(tenantId, userId, token, refreshToken);
+
+ // Handle the event
+ console.log('User data:', message.data);
+ }
+
+ if (message.type === 'ACCESS_PROGRAM_EVENT') {
+ console.log("Hellooooo")
+ const tenantId = message.data.tenantId;
+ const userId = message.data.userId;
+ const token = message.data.token;
+ const refreshToken = message.data.refreshToken;
+ await handleProgramLogin(tenantId, userId, token, refreshToken);
+
+ console.log('Access Program data:', message.data);
+ }
+
+ if (message.type === 'LOGIN_INTO_ONLY_ONE_PROGRAM_EVENT') {
+ const tenantId = message.data.tenantId;
+ const userId = message.data.userId;
+ const token = message.data.token;
+ const refreshToken = message.data.refreshToken;
+ console.log('Login into Only One Program data:', message.data);
+
+
+
+ await handleProgramLogin(tenantId, userId, token, refreshToken);
+ // const refreshToken = ""
+ }
+ } catch (error) {
+ console.error('Error handling WebView message:', error);
+ }
+ };
+
+ return (
+
+
+
+ {loading && (
+
+
+
+ )}
+ {
+ setLoading(false);
+ // Re-inject the localStorage value after page loads
+ if (webViewRef.current) {
+ webViewRef.current.injectJavaScript(injectedJavaScript);
+ }
+ }}
+ onNavigationStateChange={(navState) => {
+ // Update canGoBack state
+ setCanGoBack(navState.canGoBack);
+
+ // Re-inject on every navigation to ensure it persists
+ if (webViewRef.current) {
+ webViewRef.current.injectJavaScript(injectedJavaScript);
+ }
+ console.log('WebView Path Changed:', navState.url);
+ console.log('Can Go Back:', navState.canGoBack);
+ // if (navState.url === 'https://qa-plp.prathamdigital.org/login') {
+ // // Only navigate when screen is focused to prevent redirect loop
+ // if (isFocused) {
+ // navigation.navigate('LoginScreen');
+ // // Go back in WebView history so it's not on /login when user returns
+ // if (navState.canGoBack && webViewRef.current) {
+ // webViewRef.current.goBack();
+ // }
+ // }
+ // }
+ }}
+ onShouldStartLoadWithRequest={(request) => {
+ // if (request.url === 'https://qa-plp.prathamdigital.org/login') {
+ // if (isFocused) {
+ // navigation.navigate('LoginScreen');
+ // }
+ // return false;
+ // }
+ return true;
+ }}
+ onMessage={handleWebViewMessage}
+ style={styles.webview}
+ startInLoadingState={true}
+ domStorageEnabled={true}
+ javaScriptEnabled={true}
+ renderLoading={() => (
+
+
+
+ )}
+ />
+
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: 'white',
+ marginTop: 40,
+ },
+ webviewContainer: {
+ flex: 1,
+ },
+ loader: {
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ right: 0,
+ bottom: 0,
+ justifyContent: 'center',
+ alignItems: 'center',
+ backgroundColor: 'white',
+ zIndex: 1,
+ },
+ webview: {
+ flex: 1,
+ },
+});
+
+export default PlpWebViewScreen;
+
diff --git a/src/screens/Profile/OtherSettings.js b/src/screens/Profile/OtherSettings.js
index 13ef0ce3..43146e25 100644
--- a/src/screens/Profile/OtherSettings.js
+++ b/src/screens/Profile/OtherSettings.js
@@ -45,6 +45,7 @@ const OtherSettings = ({ route }) => {
const [isModalVisible, setModalVisible] = useState(false);
const [userType, setUserType] = useState();
const [cohortId, setCohortId] = useState();
+ const [isEditProfileEnabled, setIsEditProfileEnabled] = useState(false);
const { isConnected } = useInternet();
const { t } = useTranslation();
@@ -53,10 +54,38 @@ const OtherSettings = ({ route }) => {
const fetchData = async () => {
const userTypes = await getDataFromStorage('userType');
const getCohortId = await getDataFromStorage('cohortId');
+ // Try both possible keys for uiConfig
+ let uiConfig = await getDataFromStorage('uiConfig');
+ if (!uiConfig) {
+ uiConfig = await getDataFromStorage('uiconfig');
+ }
+
+ console.log('uiConfig from storage:', uiConfig);
+ console.log('uiConfig type:', typeof uiConfig);
+
setUserType(userTypes);
setCohortId(getCohortId);
+
+ // Parse uiconfig and check if isEditProfile is true
+ if (uiConfig) {
+ try {
+ const parsedConfig = typeof uiConfig === 'string' ? JSON.parse(uiConfig) : uiConfig;
+ console.log('Parsed uiConfig:', parsedConfig);
+ console.log('isEditProfile value:', parsedConfig?.isEditProfile);
+ const shouldShowEditProfile = parsedConfig?.isEditProfile === true;
+ console.log('Should show edit profile:', shouldShowEditProfile);
+ setIsEditProfileEnabled(shouldShowEditProfile);
+ } catch (error) {
+ console.log('Error parsing uiconfig:', error);
+ setIsEditProfileEnabled(false);
+ }
+ } else {
+ console.log('uiConfig is null or undefined');
+ setIsEditProfileEnabled(false);
+ }
};
console.log('cohortId', cohortId);
+ console.log('isEditProfileEnabled state:', isEditProfileEnabled);
useFocusEffect(
useCallback(() => {
@@ -187,98 +216,91 @@ const OtherSettings = ({ route }) => {
/>
- {(userType === 'scp' &&
- cohortId !== '00000000-0000-0000-0000-000000000000') ||
- !isConnected ? (
- <>>
- ) : (
- <>
- {userType !== 'pragyanpath' && (
- {
- navigation.navigate('ProfileUpdateScreen');
- }}
+
+ {isEditProfileEnabled && (
+ {
+ navigation.navigate('ProfileUpdateScreen');
+ }}
+ >
+
+
-
-
- {t('edit_profile')}
-
-
-
-
- )}
+ {t('edit_profile')}
+
+
+
+
+ )}
{/*
- {
- navigation.navigate('ResetUsername');
- }}
+ {
+ navigation.navigate('ResetUsername');
+ }}
+ >
+
+
-
-
- {t('change_username')}
-
-
-
- */}
- {
- navigation.navigate('ResetPassword');
- }}
+ {t('change_username')}
+
+
+
+ */}
+ {
+ navigation.navigate('ResetPassword');
+ }}
+ >
+
+
-
-
- {t('change_password')}
-
-
-
-
- >
- )}
+ {t('change_password')}
+
+
+
+
{
+ const [loading, setLoading] = useState(true);
+ const [errmsg, setErrmsg] = useState('');
+ const [canGoBack, setCanGoBack] = useState(false);
+ const navigation = useNavigation();
+ const isFocused = useIsFocused();
+ const webViewRef = useRef(null);
+ const url = `${Config.LEARNER_PLP_LINK}/programs`
+
+ // Handle hardware back button
+ useEffect(() => {
+ const backAction = () => {
+ if (canGoBack && webViewRef.current) {
+ // Navigate back in WebView
+ webViewRef.current.goBack();
+ return true; // Prevent default behavior (exit app)
+ }
+ // Let default behavior happen (go back in navigation)
+ return false;
+ };
+
+ const backHandler = BackHandler.addEventListener(
+ 'hardwareBackPress',
+ backAction
+ );
+
+ return () => backHandler.remove();
+ }, [canGoBack]);
+
+ // Injected JavaScript to set isAndroidApp in localStorage
+ // This runs before page content loads
+ const injectedJavaScriptBeforeContentLoaded = `
+ (function() {
+ try {
+ window.localStorage.setItem('isAndroidApp', 'yes');
+ console.log('[BeforeLoad] isAndroidApp set to yes in localStorage');
+ } catch (error) {
+ console.error('[BeforeLoad] Error setting isAndroidApp:', error);
+ }
+ })();
+ true;
+ `;
+
+ // This runs after page content loads
+ const injectedJavaScript = `
+ (function() {
+ try {
+ window.localStorage.setItem('isAndroidApp', 'yes');
+ console.log('[AfterLoad] isAndroidApp set to yes in localStorage');
+
+ // Send confirmation back to React Native
+ if (window.ReactNativeWebView) {
+ window.ReactNativeWebView.postMessage(JSON.stringify({
+ type: 'ANDROID_APP_FLAG_SET',
+ value: window.localStorage.getItem('isAndroidApp')
+ }));
+ }
+ } catch (error) {
+ console.error('[AfterLoad] Error setting isAndroidApp:', error);
+ }
+ })();
+ true;
+ `;
+
+
+ const handleProgramLogin = async(tenantId, userId, token, refreshToken) => {
+ await saveAccessToken(token || '');
+ await saveRefreshToken(refreshToken || '')
+ const userDetails = await getuserDetails();
+ const roleName = "Learner";
+
+ const user_id = userId;
+ const tenantData = [
+ userDetails?.tenantData?.find((tenant) => tenant.tenantId === tenantId),
+ ];
+ const uiConfig = tenantData[0]?.params?.uiConfig;
+ await setDataInStorage('uiConfig', JSON.stringify(uiConfig));
+ console.log('#### loginmultirole uiConfig', JSON.stringify(uiConfig));
+ console.log('#### loginmultirole tenantData', tenantData);
+
+ const enrollmentId = userDetails?.enrollmentId;
+ await setDataInStorage('tenantData', JSON.stringify(tenantData || {}));
+ await setDataInStorage('userId', user_id || '');
+ await setDataInStorage('enrollmentId', enrollmentId || '');
+
+ //store dynamic templateId
+ const templateId = tenantData?.[0]?.templateId;
+ await setDataInStorage('templateId', templateId || '');
+
+ const academicyear = await setAcademicYear({ tenantid: tenantId });
+ const academicYearId = academicyear?.[0]?.id;
+ await setDataInStorage('academicYearId', academicYearId || '');
+ await setDataInStorage('userTenantid', tenantId || '');
+ const cohort = await getCohort({
+ user_id,
+ tenantid: tenantId,
+ academicYearId,
+ });
+ console.log('#### loginmultirole cohort', cohort);
+ let cohort_id;
+ if (cohort.params?.status !== 'failed') {
+ const getActiveCohort = await getActiveCohortData(cohort);
+ const getActiveCohortId = await getActiveCohortIds(cohort);
+ await setDataInStorage(
+ 'cohortData',
+ JSON.stringify(getActiveCohort?.[0]) || ''
+ );
+ cohort_id = getActiveCohortId?.[0];
+ }
+
+ const profileData = await getProfileDetails({
+ userId: user_id,
+ });
+ console.log('#### loginmultirole profileData', profileData);
+
+ await setDataInStorage('profileData', JSON.stringify(profileData));
+ await setDataInStorage(
+ 'Username',
+ profileData?.getUserDetails?.[0]?.username || ''
+ );
+ await storeUsername(profileData?.getUserDetails?.[0]?.username);
+
+ await setDataInStorage(
+ 'cohortId',
+ cohort_id || '00000000-0000-0000-0000-000000000000'
+ );
+ const tenantDetails = (await getProgramDetails()) || [];
+
+ const MatchedTenant = tenantDetails.filter(
+ (item) => item?.tenantId === tenantId
+ );
+
+ // console.log('tenantDetails===>', JSON.stringify(tenantDetails));
+ // console.log(
+ // 'MatchedTenant===>',
+ // JSON.stringify(MatchedTenant?.[0]?.contentFilter)
+ // );
+
+ await setDataInStorage(
+ 'contentFilter',
+ JSON.stringify(MatchedTenant?.[0]?.contentFilter || {})
+ );
+
+ const youthnetTenantIds = tenantDetails
+ ?.filter((item) => item?.name === TENANT_DATA.YOUTHNET)
+ ?.map((item) => item?.tenantId);
+
+ const scp = tenantDetails
+ ?.filter((item) => item.name === 'Second Chance Program')
+ ?.map((item) => item.tenantId);
+
+ // const role = roleName;
+
+ {
+ // console.log('#### loginmultirole role', role);
+
+ if (tenantId === scp?.[0]) {
+ console.log('####loginintoscp', scp);
+ await setDataInStorage('userType', 'scp');
+ navigation.navigate('SCPUserTabScreen');
+
+ // if (cohort_id) {
+ // navigation.navigate('SCPUserTabScreen');
+ // } else {
+ // navigation.navigate('Dashboard');
+ // }
+ } else {
+ if (tenantId === youthnetTenantIds?.[0]) {
+ // console.log('#### loginintodefault tenant@@@@@@@', tenantData?.[0]?.tenantName);
+
+ await setDataInStorage('userType', 'youthnet');
+ // navigation.navigate('YouthNetTabScreen');
+ navigation.navigate('Dashboard');
+ } else {
+ console.log('#### loginintodefault tenant??????', tenantData?.[0]?.tenantName);
+ // await setDataInStorage('userType', 'pragyanpath');
+ await setDataInStorage('userType', tenantData?.[0]?.tenantName);
+ navigation.navigate('Dashboard');
+ }
+ }
+ const deviceId = await getDeviceId();
+ const action = 'add';
+
+ await notificationSubscribe({ deviceId, user_id, action });
+ }
+
+ const now = moment();
+
+ const telemetryPayloadData = {
+ event: 'login',
+ type: 'click',
+ ets: now.unix(),
+ };
+ await telemetryTrackingData({
+ telemetryPayloadData,
+ });
+
+ };
+
+ const handleWebViewMessage = async (event) => {
+ try {
+ const message = JSON.parse(event.nativeEvent.data);
+ console.log('Received from web:', message);
+
+ // Log when Android flag is confirmed set
+ if (message.type === 'ANDROID_APP_FLAG_SET') {
+ console.log('✓ isAndroidApp confirmed in localStorage:', message.value);
+ return;
+ }
+
+ if (message.type === 'ENROLL_PROGRAM_EVENT') {
+ const tenantId = message.data.tenantId;
+ const userId = message.data.userId;
+ const token = message.data.token;
+ const refreshToken = message.data.refreshToken;
+ await handleProgramLogin(tenantId, userId, token, refreshToken);
+
+ // Handle the event
+ console.log('User data:', message.data);
+ }
+
+ if (message.type === 'ACCESS_PROGRAM_EVENT') {
+ console.log("Hellooooo")
+ const tenantId = message.data.tenantId;
+ const userId = message.data.userId;
+ const token = message.data.token;
+ const refreshToken = message.data.refreshToken;
+ await handleProgramLogin(tenantId, userId, token, refreshToken);
+
+ console.log('Access Program data:', message.data);
+ }
+
+ if (message.type === 'LOGIN_INTO_ONLY_ONE_PROGRAM_EVENT') {
+ const tenantId = message.data.tenantId;
+ const userId = message.data.userId;
+ const token = message.data.token;
+ const refreshToken = message.data.refreshToken;
+ console.log('Login into Only One Program data:', message.data);
+
+
+
+ await handleProgramLogin(tenantId, userId, token, refreshToken);
+ // const refreshToken = ""
+ }
+ } catch (error) {
+ console.error('Error handling WebView message:', error);
+ }
+ };
+
+ return (
+
+
+
+ {loading && (
+
+
+
+ )}
+ {
+ setLoading(false);
+ // Re-inject the localStorage value after page loads
+ if (webViewRef.current) {
+ webViewRef.current.injectJavaScript(injectedJavaScript);
+ }
+ }}
+ onNavigationStateChange={(navState) => {
+ // Update canGoBack state
+ setCanGoBack(navState.canGoBack);
+
+ // Re-inject on every navigation to ensure it persists
+ if (webViewRef.current) {
+ webViewRef.current.injectJavaScript(injectedJavaScript);
+ }
+ console.log('WebView Path Changed:', navState.url);
+ console.log('Can Go Back:', navState.canGoBack);
+ // if (navState.url === 'https://qa-plp.prathamdigital.org/login') {
+ // // Only navigate when screen is focused to prevent redirect loop
+ // if (isFocused) {
+ // navigation.navigate('LoginScreen');
+ // // Go back in WebView history so it's not on /login when user returns
+ // if (navState.canGoBack && webViewRef.current) {
+ // webViewRef.current.goBack();
+ // }
+ // }
+ // }
+ }}
+ onShouldStartLoadWithRequest={(request) => {
+ // if (request.url === 'https://qa-plp.prathamdigital.org/login') {
+ // if (isFocused) {
+ // navigation.navigate('LoginScreen');
+ // }
+ // return false;
+ // }
+ return true;
+ }}
+ onMessage={handleWebViewMessage}
+ style={styles.webview}
+ startInLoadingState={true}
+ domStorageEnabled={true}
+ javaScriptEnabled={true}
+ renderLoading={() => (
+
+
+
+ )}
+ />
+
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: 'white',
+ marginTop: 40,
+ },
+ webviewContainer: {
+ flex: 1,
+ },
+ loader: {
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ right: 0,
+ bottom: 0,
+ justifyContent: 'center',
+ alignItems: 'center',
+ backgroundColor: 'white',
+ zIndex: 1,
+ },
+ webview: {
+ flex: 1,
+ },
+});
+
+export default PlpWebViewScreen;
+
diff --git a/src/screens/ProgramsScreen/index.js b/src/screens/ProgramsScreen/index.js
new file mode 100644
index 00000000..f069e37a
--- /dev/null
+++ b/src/screens/ProgramsScreen/index.js
@@ -0,0 +1,2 @@
+export { default } from './ProgramsScreen';
+
diff --git a/src/utils/API/AuthService.js b/src/utils/API/AuthService.js
index 23d4cee5..88f52d42 100644
--- a/src/utils/API/AuthService.js
+++ b/src/utils/API/AuthService.js
@@ -982,6 +982,25 @@ export const getProfileDetails = async (params = {}) => {
}
};
+export const getUserDetails = async (params = {}) => {
+ try {
+ const url = `${EndUrls.userDetails}/${params?.user_id}`; // Define the URL
+ const headers = await getHeaders();
+ const result = await get(url, {
+ headers: headers || {},
+ });
+ if (result) {
+ return result?.data?.result;
+ } else {
+ return {};
+ }
+ }
+ catch (e) {
+ console.log(e)
+ }
+};
+
+
export const getAssessmentStatus = async (params = {}) => {
try {
const url = `${EndUrls.AssessmentStatus}`; // Define the URL
diff --git a/src/utils/API/EndUrls.js b/src/utils/API/EndUrls.js
index d4902cfb..4c4dae41 100644
--- a/src/utils/API/EndUrls.js
+++ b/src/utils/API/EndUrls.js
@@ -87,6 +87,7 @@ const EndUrls = {
//ATM
atmAssessment: `${API_URL}/interface/v1/tracking/ai-assessment/search`,
atmAssessment_status: `${API_URL}/interface/v1/tracking/assessment/offline-assessment-status`,
+ userDetails: `${API_URL}/interface/v1/user/read`,
};