* change apm url to portal url TP-25597 (#262)

* change apm url to portal url TP-25597

* fix config dev TP-25597

* enable sso TP-122 (#261)

* TP-24980 | Package version bump and submodule update

* enable sso TP-122

* TP-122 update rnUi

* fix crypto js failing issue TP-122

* error handling add TP-122

* change error text TP-122

* add disable button timer TP-122

* remove extra dispatch TP-122

* fix UI with design TP-122

* fix icon TP-122

* fix design nit picks and add google icon TP-122

* Revert "TP-25967 | Added Web Alias config + Updating NewAddressContainer  with alias (#266)" (#267)

This reverts commit c9fefc0309.

* move code back to AuthRouter TP-122

* foreground service notification title and config update TP-122

* fix package json TP-122

* emiBreakupBottomSheet formatting revert TP-122

* remoce disable function TP-122

Co-authored-by: Aman Chaturvedi <aman.chaturvedi@navi.com>
Co-authored-by: Himanshu Kansal <himanshu.kansal@navi.com>

* TP-122 bump package

Co-authored-by: Aman Chaturvedi <aman.chaturvedi@navi.com>
Co-authored-by: Himanshu Kansal <himanshu.kansal@navi.com>
This commit is contained in:
Aman Sethi
2023-04-20 21:43:07 +05:30
committed by GitHub Enterprise
parent f510b2d63e
commit 3249e55014
16 changed files with 356 additions and 260 deletions

View File

@@ -131,8 +131,8 @@ def reactNativeArchitectures() {
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
}
def VERSION_CODE = 52
def VERSION_NAME = "2.1.11"
def VERSION_CODE = 53
def VERSION_NAME = "2.1.12"
android {
ndkVersion rootProject.ext.ndkVersion

View File

@@ -4,4 +4,4 @@ export const JANUS_SERVICE_URL = 'https://dev-longhorn-portal.np.navi-tech.in/ap
export const ENV = 'dev';
export const IS_SSO_ENABLED = false;
export const APM_APP_NAME = 'cosmos-app';
export const APM_BASE_URL = 'https://apm-server.np.navi-tech.in';
export const APM_BASE_URL = 'https://dev-longhorn-portal.np.navi-tech.in/apm-events';

View File

@@ -2,6 +2,6 @@ export const BASE_AV_APP_URL = 'https://longhorn.navi.com/field-app';
export const SENTRY_DSN = 'https://5daa4832fade44b389b265de9b26c2fd@longhorn.navi.com/glitchtip-events/172';
export const JANUS_SERVICE_URL = 'https://longhorn.navi.com/api/events/json';
export const ENV = 'prod';
export const IS_SSO_ENABLED = false;
export const IS_SSO_ENABLED = true;
export const APM_APP_NAME = 'cosmos-app';
export const APM_BASE_URL = 'https://apm-server.prod.navi-tech.in';
export const APM_BASE_URL = 'https://longhorn.navi.com/apm-events';

View File

@@ -4,4 +4,4 @@ export const JANUS_SERVICE_URL = 'https://qa-longhorn-portal.np.navi-tech.in/api
export const ENV = 'qa';
export const IS_SSO_ENABLED = false;
export const APM_APP_NAME = 'cosmos-app';
export const APM_BASE_URL = 'https://apm-server.np.navi-tech.in';
export const APM_BASE_URL = 'https://qa-longhorn-portal.np.navi-tech.in/apm-events';

View File

@@ -1,6 +1,6 @@
{
"name": "AV_APP",
"version": "2.1.11",
"version": "2.1.12",
"private": true,
"scripts": {
"android:dev": "yarn move:dev && react-native run-android",
@@ -56,6 +56,7 @@
"react-native-device-info": "10.3.0",
"react-native-fast-image": "8.6.3",
"react-native-geolocation-service": "5.3.1",
"react-native-get-random-values": "^1.8.0",
"react-native-image-picker": "4.10.2",
"react-native-pager-view": "6.1.2",
"react-native-permissions": "3.6.1",

View File

@@ -1,3 +1,5 @@
import { ToastMessages } from './../screens/allCases/constants';
import 'react-native-get-random-values';
import crypto from 'crypto-js';
import { IUser, setAuthData } from '../reducer/userSlice';
import axiosInstance, { ApiKeys, API_STATUS_CODE, getApiUrl } from '../components/utlis/apiHelper';
@@ -19,7 +21,6 @@ import { toast } from '../../RN-UI-LIB/src/components/toast';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { clearAllAsyncStorage, setAsyncStorageItem } from '../components/utlis/commonFunctions';
import { logError } from '../components/utlis/errorUtils';
import { getUniqueId } from 'react-native-device-info';
import { Linking } from 'react-native';
export interface GenerateOTPPayload {
@@ -78,7 +79,6 @@ export const signInGoogle = () => async (dispatch: Dispatch) => {
await setAsyncStorageItem('codeVerifier', codeVerifier);
const state = crypto.lib.WordArray.random(16).toString();
const url = getApiUrl(ApiKeys.SIGN_IN_GOOGLE);
dispatch(setFormLoading(true));
const response = await axiosInstance.get(url, {
params: {
codeChallenge,
@@ -87,15 +87,14 @@ export const signInGoogle = () => async (dispatch: Dispatch) => {
headers: { donotHandleError: false },
});
if (response?.data?.signInUrl) {
Linking.openURL(response.data.signInUrl);
await Linking.openURL(response.data.signInUrl);
}
} catch (error) {
logError(error as Error);
toast({
text1: 'Error in google sign in',
type: 'error',
});
} finally {
dispatch(setFormLoading(false));
}
};
@@ -108,16 +107,12 @@ export const verifyGoogleSignIn =
return;
}
const parsedCodeVerify = JSON.parse(codeVerify);
const response = await axiosInstance.post(
url,
{
code,
state,
codeVerifier: parsedCodeVerify,
deviceId: deviceId,
},
{ headers: { donotHandleError: true } }
);
const response = await axiosInstance.post(url, {
code,
state,
codeVerifier: parsedCodeVerify,
deviceId: deviceId,
});
if (response?.data?.sessionDetails) {
const { sessionDetails, user } = response.data;
dispatch(
@@ -132,12 +127,17 @@ export const verifyGoogleSignIn =
}
} catch (error) {
logError(error as Error);
toast({
text1: 'error in google sign in',
type: 'error',
});
} finally {
() => dispatch(setFormLoading(false));
if (error?.response?.status === API_STATUS_CODE.NOT_FOUND) {
toast({
text1: ToastMessages.GENERIC_ERROR_TOAST,
type: 'error',
});
} else {
toast({
text1: error?.response?.data?.message ?? ToastMessages.SSO_SERVER_SIGN_IN_ERROR,
type: 'error',
});
}
}
};

View File

@@ -32,7 +32,11 @@ export const getNotifications =
const startTime = yesterday.getTime();
const url = getApiUrl(ApiKeys.NOTIFICATIONS, {}, { ...payload, startTime });
return axiosInstance
.get(url)
.get(url, {
headers: {
showInSpecificComponents: ['Notifications'],
},
})
.then((response) => {
const notifications = response?.data?.notificationResponse?.notifications;
const { totalElements, totalPages, totalUnreadElements } = response?.data;
@@ -66,9 +70,19 @@ export const getNotifications =
export const notificationAction = (payload: INotificationAction[]) => (dispatch: AppDispatch) => {
const url = getApiUrl(ApiKeys.NOTIFICATION_ACTION);
return axiosInstance.post(url, payload).then(() => {
dispatch(addActionToNotifications(payload));
});
return axiosInstance
.post(
url,
{
headers: {
showInSpecificComponents: ['Notifications'],
},
},
payload
)
.then(() => {
dispatch(addActionToNotifications(payload));
});
};
export const notificationDelivered = (payload: { ids: string[] }) => (dispatch: AppDispatch) => {

View File

@@ -0,0 +1,43 @@
import * as React from 'react';
import Svg, { Path } from 'react-native-svg';
function GoogleIcon(props) {
return (
<Svg
width={38}
height={38}
viewBox="0 0 38 38"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<Path d="M0 8a8 8 0 018-8h22a8 8 0 018 8v22a8 8 0 01-8 8H8a8 8 0 01-8-8V8z" fill="#fff" />
<Path
fillRule="evenodd"
clipRule="evenodd"
d="M27.64 19.204c0-.638-.057-1.252-.164-1.84H19v3.48h4.844a4.14 4.14 0 01-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z"
fill="#4285F4"
/>
<Path
fillRule="evenodd"
clipRule="evenodd"
d="M19 28c2.43 0 4.467-.805 5.956-2.18l-2.908-2.258c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711h-3.007v2.332A8.997 8.997 0 0019 28z"
fill="#34A853"
/>
<Path
fillRule="evenodd"
clipRule="evenodd"
d="M13.964 20.71a5.41 5.41 0 01-.282-1.71c0-.592.102-1.17.282-1.71V14.96h-3.007A8.996 8.996 0 0010 19.001c0 1.452.348 2.827.957 4.042l3.007-2.332z"
fill="#FBBC05"
/>
<Path
fillRule="evenodd"
clipRule="evenodd"
d="M19 13.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C23.463 10.891 21.426 10 19 10a8.996 8.996 0 00-8.043 4.958l3.007 2.332c.708-2.127 2.692-3.71 5.036-3.71z"
fill="#EA4335"
/>
</Svg>
);
}
export default GoogleIcon;

View File

@@ -4,4 +4,4 @@ export const JANUS_SERVICE_URL = 'https://qa-longhorn-portal.np.navi-tech.in/api
export const ENV = 'qa';
export const IS_SSO_ENABLED = false;
export const APM_APP_NAME = 'cosmos-app';
export const APM_BASE_URL = 'https://apm-server.np.navi-tech.in';
export const APM_BASE_URL = 'https://qa-longhorn-portal.np.navi-tech.in/apm-events';

View File

@@ -56,4 +56,6 @@ export const ToastMessages = {
OFFLINE_MESSAGE: 'You seem to be offline',
PAYMENT_LINK_NOT_GENERATED: 'Payment link could not be generated',
PAYMENT_LINK_RETRY: 'Please retry after an hour for this number',
GENERIC_ERROR_TOAST: 'Something went wrong',
SSO_SERVER_SIGN_IN_ERROR: 'Error while signing in to cosmos',
};

View File

@@ -16,79 +16,74 @@ interface IEmiBreakupBottomSheet {
emiItem: IEmiItem;
listNumber: number;
}
const EmiBreakupBottomSheet: React.FC<IEmiBreakupBottomSheet> = props => {
const EmiBreakupBottomSheet: React.FC<IEmiBreakupBottomSheet> = (props) => {
const { openBottomSheet, setOpenBottomSheet, emiItem, listNumber } = props;
return (
<BottomSheet
heightPercentage={40}
visible={openBottomSheet}
HeaderNode={() => (
<View style={[...row, GenericStyles.p16]}>
<Heading dark type="h4">
EMI {listNumber} breakup
</Heading>
<TouchableOpacity
activeOpacity={0.7}
onPress={() => setOpenBottomSheet(prev => !prev)}>
<CloseIcon color={COLORS.TEXT.LIGHT} />
</TouchableOpacity>
</View>
)}
setVisible={() => setOpenBottomSheet(prev => !prev)}>
<View style={[GenericStyles.p16]}>
<View style={[...row, GenericStyles.pb16]}>
<Text light>Principal</Text>
<Text dark>{formatAmount(emiItem?.totalUnpaidPrincipal ?? 0)}</Text>
</View>
<View style={[...row, GenericStyles.pb16]}>
<Text light>Interest</Text>
<Text dark bold>
{formatAmount(emiItem?.totalUnpaidInterest ?? 0)}
</Text>
</View>
{
emiItem?.totalUnpaidEmiPenaltyCharges ?
(
<>
<View style={[...row, GenericStyles.pb16]}>
<Text light>Interest</Text>
<Text dark bold>
{formatAmount(emiItem?.totalUnpaidEmiPenaltyCharges ?? 0)}
</Text>
</View>
</>
) :
(
<>
<View style={[...row, GenericStyles.pb16]}>
<Text light>Other fees</Text>
<Text dark bold>
{formatAmount(emiItem?.totalUnpaidOtherFees ?? 0)}
</Text>
</View>
</>
)
}
<View style={styles.horizontalLine} />
<View style={[...row, GenericStyles.pb16]}>
<Text dark bold>
Total Overdue Amount
</Text>
<Text style={{ color: COLORS.TEXT.RED }}>
{formatAmount(emiItem?.totalOverDueAmount ?? 0)}
</Text>
</View>
</View>
</BottomSheet>
<BottomSheet
heightPercentage={40}
visible={openBottomSheet}
HeaderNode={() => (
<View style={[...row, GenericStyles.p16]}>
<Heading dark type="h4">
EMI {listNumber} breakup
</Heading>
<TouchableOpacity activeOpacity={0.7} onPress={() => setOpenBottomSheet((prev) => !prev)}>
<CloseIcon color={COLORS.TEXT.LIGHT} />
</TouchableOpacity>
</View>
)}
setVisible={() => setOpenBottomSheet((prev) => !prev)}
>
<View style={[GenericStyles.p16]}>
<View style={[...row, GenericStyles.pb16]}>
<Text light>Principal</Text>
<Text dark>{formatAmount(emiItem?.totalUnpaidPrincipal ?? 0)}</Text>
</View>
<View style={[...row, GenericStyles.pb16]}>
<Text light>Interest</Text>
<Text dark bold>
{formatAmount(emiItem?.totalUnpaidInterest ?? 0)}
</Text>
</View>
{emiItem?.totalUnpaidEmiPenaltyCharges ? (
<>
<View style={[...row, GenericStyles.pb16]}>
<Text light>Interest</Text>
<Text dark bold>
{formatAmount(emiItem?.totalUnpaidEmiPenaltyCharges ?? 0)}
</Text>
</View>
</>
) : (
<>
<View style={[...row, GenericStyles.pb16]}>
<Text light>Other fees</Text>
<Text dark bold>
{formatAmount(emiItem?.totalUnpaidOtherFees ?? 0)}
</Text>
</View>
</>
)}
<View style={styles.horizontalLine} />
<View style={[...row, GenericStyles.pb16]}>
<Text dark bold>
Total Overdue Amount
</Text>
<Text style={{ color: COLORS.TEXT.RED }}>
{formatAmount(emiItem?.totalOverDueAmount ?? 0)}
</Text>
</View>
</View>
</BottomSheet>
);
};
const styles = StyleSheet.create({
horizontalLine: {
height: 1,
backgroundColor: COLORS.BORDER.PRIMARY,
width: '100%',
marginBottom: 16,
},
horizontalLine: {
height: 1,
backgroundColor: COLORS.BORDER.PRIMARY,
width: '100%',
marginBottom: 16,
},
});
export default EmiBreakupBottomSheet;

View File

@@ -13,140 +13,122 @@ import Tag from '../../../RN-UI-LIB/src/components/Tag';
import { formatAmount } from '../../../RN-UI-LIB/src/utlis/amount';
export interface IEmiItem {
status: 'SCHEDULED' | 'PAID' | 'UNPAID' | 'CANCELLED';
dueDate: string; //YYYY-MM-DD
totalOverDueAmount: number;
paidOnDate: string; //YYYY-MM-DD
totalUnpaidPrincipal: number;
totalUnpaidInterest: number;
totalUnpaidPenalInterest: number;
totalUnpaidLateFeeAmount: number;
totalUnpaidBounceFeeAmount: number;
totalUnpaidEmiPenaltyCharges: number;
totalUnpaidOtherFees?: number;
status: 'SCHEDULED' | 'PAID' | 'UNPAID' | 'CANCELLED';
dueDate: string; //YYYY-MM-DD
totalOverDueAmount: number;
paidOnDate: string; //YYYY-MM-DD
totalUnpaidPrincipal: number;
totalUnpaidInterest: number;
totalUnpaidPenalInterest: number;
totalUnpaidLateFeeAmount: number;
totalUnpaidBounceFeeAmount: number;
totalUnpaidEmiPenaltyCharges: number;
totalUnpaidOtherFees?: number;
}
interface IEmiScheduleItem {
listNumber: number;
emiItem: IEmiItem;
selectedTab: EmiSelectedTab;
listNumber: number;
emiItem: IEmiItem;
selectedTab: EmiSelectedTab;
}
const EmiScheduleItem: React.FC<IEmiScheduleItem> = ({
listNumber,
emiItem,
selectedTab,
}) => {
const [openBottomSheet, setOpenBottomSheet] = React.useState(false);
const EmiScheduleItem: React.FC<IEmiScheduleItem> = ({ listNumber, emiItem, selectedTab }) => {
const [openBottomSheet, setOpenBottomSheet] = React.useState(false);
return (
<View style={styles.container}>
<View style={styles.leftContainer}>
<Text
dark
style={[GenericStyles.pl12, GenericStyles.fontSize12]}>
{listNumber}
</Text>
<Text
light
style={[GenericStyles.pl12, GenericStyles.fontSize12]}>
EMI
</Text>
</View>
<View style={[...row, GenericStyles.fill, GenericStyles.p12]}>
<View>
<Text
style={
emiItem.status === 'UNPAID'
? {
color: COLORS.TEXT.RED,
}
: null
}>
{formatAmount(emiItem?.totalOverDueAmount)}
</Text>
<Text light>
{dateFormat(
new Date(emiItem.dueDate),
BUSINESS_DATE_FORMAT,
)}
</Text>
</View>
<View>
{emiItem.status === 'UNPAID' ? (
<>
{selectedTab === EmiSelectedTab.ALL ? (
<Tag variant="error" text="Unpaid" />
) : (
<Button
title="Breakup"
variant="primaryText"
onPress={() => setOpenBottomSheet(true)}
textStyle={{
fontSize: 12,
fontWeight: '500',
}}
/>
)}
</>
) : null}
{emiItem.status === 'PAID' ? (
<>
{selectedTab === EmiSelectedTab.ALL ? (
<Tag variant="success" text="Paid" />
) : (
<Text light style={[GenericStyles.fontSize12]}>
Paid on:{' '}
<Text
style={[
GenericStyles.fontSize12,
{
color: COLORS.TEXT.GREEN,
},
]}>
{dateFormat(
new Date(emiItem.paidOnDate),
BUSINESS_DATE_FORMAT,
)}
</Text>
</Text>
)}
</>
) : null}
{emiItem.status === 'SCHEDULED' ? (
<Tag variant="gray" text="Scheduled" />
) : null}
{emiItem.status === 'CANCELLED' ? (
<Tag variant="yellow" text="Cancelled" />
) : null}
</View>
</View>
<EmiBreakupBottomSheet
emiItem={emiItem}
openBottomSheet={openBottomSheet}
setOpenBottomSheet={setOpenBottomSheet}
listNumber={listNumber}
/>
return (
<View style={styles.container}>
<View style={styles.leftContainer}>
<Text dark style={[GenericStyles.pl12, GenericStyles.fontSize12]}>
{listNumber}
</Text>
<Text light style={[GenericStyles.pl12, GenericStyles.fontSize12]}>
EMI
</Text>
</View>
<View style={[...row, GenericStyles.fill, GenericStyles.p12]}>
<View>
<Text
style={
emiItem.status === 'UNPAID'
? {
color: COLORS.TEXT.RED,
}
: null
}
>
{formatAmount(emiItem?.totalOverDueAmount)}
</Text>
<Text light>{dateFormat(new Date(emiItem.dueDate), BUSINESS_DATE_FORMAT)}</Text>
</View>
);
<View>
{emiItem.status === 'UNPAID' ? (
<>
{selectedTab === EmiSelectedTab.ALL ? (
<Tag variant="error" text="Unpaid" />
) : (
<Button
title="Breakup"
variant="primaryText"
onPress={() => setOpenBottomSheet(true)}
textStyle={{
fontSize: 12,
fontWeight: '500',
}}
/>
)}
</>
) : null}
{emiItem.status === 'PAID' ? (
<>
{selectedTab === EmiSelectedTab.ALL ? (
<Tag variant="success" text="Paid" />
) : (
<Text light style={[GenericStyles.fontSize12]}>
Paid on:{' '}
<Text
style={[
GenericStyles.fontSize12,
{
color: COLORS.TEXT.GREEN,
},
]}
>
{dateFormat(new Date(emiItem.paidOnDate), BUSINESS_DATE_FORMAT)}
</Text>
</Text>
)}
</>
) : null}
{emiItem.status === 'SCHEDULED' ? <Tag variant="gray" text="Scheduled" /> : null}
{emiItem.status === 'CANCELLED' ? <Tag variant="yellow" text="Cancelled" /> : null}
</View>
</View>
<EmiBreakupBottomSheet
emiItem={emiItem}
openBottomSheet={openBottomSheet}
setOpenBottomSheet={setOpenBottomSheet}
listNumber={listNumber}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
borderWidth: 1,
borderColor: COLORS.BORDER.PRIMARY,
borderRadius: 4,
marginBottom: 12,
height: 68,
flexDirection: 'row',
alignContent: 'center',
},
leftContainer: {
alignContent: 'center',
justifyContent: 'center',
backgroundColor: COLORS.BACKGROUND.SILVER,
width: 43,
},
container: {
borderWidth: 1,
borderColor: COLORS.BORDER.PRIMARY,
borderRadius: 4,
marginBottom: 12,
height: 68,
flexDirection: 'row',
alignContent: 'center',
},
leftContainer: {
alignContent: 'center',
justifyContent: 'center',
backgroundColor: COLORS.BACKGROUND.SILVER,
width: 43,
},
});
export default EmiScheduleItem;

View File

@@ -2,6 +2,7 @@ import React, { useEffect } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useSelector } from 'react-redux';
import { StyleSheet, View } from 'react-native';
import Button from '../../../RN-UI-LIB/src/components/Button';
import Heading from '../../../RN-UI-LIB/src/components/Heading';
import Text from '../../../RN-UI-LIB/src/components/Text';
@@ -10,29 +11,39 @@ import { GenericStyles } from '../../../RN-UI-LIB/src/styles';
import NaviLogoIcon from '../../../RN-UI-LIB/src/Icons/NaviLogoIcon';
import {
generateOTP,
GenerateOTPPayload,
type GenerateOTPPayload,
signInGoogle,
} from '../../action/authActions';
import { useAppDispatch } from '../../hooks';
import { RootState } from '../../store/store';
import { type RootState } from '../../store/store';
import { addClickstreamEvent } from '../../services/clickstreamEventService';
import { CLICKSTREAM_EVENT_NAMES } from '../../common/Constants';
import { StyleSheet } from 'react-native';
import Layout from '../layout/Layout';
import { IS_SSO_ENABLED } from '../../constants/config';
import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
import GoogleIcon from '../../assets/icons/GoogleIcon';
interface ILoginForm {
phoneNumber: string;
}
const Login = () => {
function Login() {
const {
handleSubmit,
control,
getValues,
formState: { errors, isValid },
formState: { isValid },
} = useForm<ILoginForm>();
const dispatch = useAppDispatch();
const { phoneNumber, OTPError, isLoading, deviceId } = useSelector((state: RootState) => ({
deviceId: state.user.deviceId,
phoneNumber: state.loginInfo.phoneNumber,
OTPError: state.loginInfo.OTPError,
isLoading: state.loginInfo.isLoading,
}));
useEffect(() => {
isValid &&
@@ -45,13 +56,8 @@ const Login = () => {
useEffect(() => {
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_LOGIN_SCREEN_LOAD);
}, []);
const dispatch = useAppDispatch();
const { phoneNumber, OTPError, isLoading } = useSelector(
(state: RootState) => state.loginInfo,
);
const handleGenerateOTP = (data: GenerateOTPPayload) => {
addClickstreamEvent(
@@ -64,17 +70,18 @@ const Login = () => {
dispatch(signInGoogle());
}
return (
<Layout>
<SafeAreaView
style={[
GenericStyles.p16,
styles.container,
GenericStyles.whiteBackground,
GenericStyles.fill,
// GenericStyles.justifyContentCenter,
]}>
<NaviLogoIcon style={[GenericStyles.mb12, styles.mt84]} />
<Heading dark>Login to Cosmos</Heading>
<Heading style={styles.headingStyles} bold dark>Login to COSMOS</Heading>
<Text light style={[GenericStyles.mb24, GenericStyles.mt4]}>
Use your registered mobile number
</Text>
@@ -98,42 +105,77 @@ const Login = () => {
name="phoneNumber"
rules={{ required: true, minLength: 10, maxLength: 10 }}
/>
<Button
title="Get OTP"
onPress={handleSubmit(handleGenerateOTP)}
style={[GenericStyles.w100, GenericStyles.mt24]}
disabled={!isValid || isLoading}
showLoader={isLoading}
testID={'test_get_otp'}
testID="test_get_otp"
textStyle={
GenericStyles.fontSize16
}
/>
{IS_SSO_ENABLED ? <>
<Text
style={[
GenericStyles.centerAlignedText,
GenericStyles.mt24,
<View style={[GenericStyles.centerAlignedRow,
GenericStyles.mt24,]}>
<View style={styles.horizontalLine} />
<Text
style={[GenericStyles.mh12]}
bold
light>
or
</Text>
<View style={styles.horizontalLine} />
</View>
<Button
title="Log in with Google"
onPress={signInWithGoogle}
style={[GenericStyles.w100, GenericStyles.mt24,
]}
variant='secondary'
buttonStyle={styles.googleButton}
showLoader={isLoading}
testID="test_sso_login"
textStyle={[{
color: COLORS.TEXT.DARK,
},
GenericStyles.fontSize16
]}
bold
dark>
OR
</Text>
<Button
title="SSO login for Navi Employees"
onPress={signInWithGoogle}
style={[GenericStyles.w100, GenericStyles.mt24]}
showLoader={isLoading}
testID={'test_sso_login'}
/>
leftIcon={
<GoogleIcon />
}
/>
</>
: null }
</SafeAreaView>
</Layout>
);
};
}
const styles = StyleSheet.create({
mt84: {
marginTop: 84,
},
horizontalLine: {
backgroundColor: COLORS.BORDER.PRIMARY,
width: '38%',
height: 0.5,
},
googleButton: {
paddingBottom: 5,
paddingTop: 5,
},
container: {
padding: 32,
},
headingStyles: {
fontWeight: '600'
}
});
export default Login;

View File

@@ -22,12 +22,17 @@ class CosmosForegroundService {
if (!ForegroundService.is_running()) {
await ForegroundService.start({
id: FOREGROUND_SERVICE_ID,
title: 'Cosmos app',
message: 'Cosmos Service is running',
title: 'Tap to open Cosmos',
message: '',
icon: 'ic_launcher',
color: '#000000',
// @ts-ignore
setOnlyAlertOnce: true,
setOnlyAlertOnce: false,
priority: 'low',
visibility: 'hidden',
importance: 'low',
sound: null,
vibrate: null,
});
}
const { task, ...rest } = currentTask;

View File

@@ -4183,6 +4183,11 @@ fake-xml-http-request@^2.1.2:
resolved "https://registry.yarnpkg.com/fake-xml-http-request/-/fake-xml-http-request-2.1.2.tgz#f1786720cae50bbb46273035a0173414f3e85e74"
integrity sha512-HaFMBi7r+oEC9iJNpc3bvcW7Z7iLmM26hPDmlb0mFwyANSsOQAtJxbdWsXITKOzZUyMYK0zYCv3h5yDj9TsiXg==
fast-base64-decode@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz#b434a0dd7d92b12b43f26819300d2dafb83ee418"
integrity sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@@ -5994,7 +5999,7 @@ lines-and-columns@^1.1.6:
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
lint-staged@^13.2.1:
lint-staged@13.2.1:
version "13.2.1"
resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.2.1.tgz#9d30a14e3e42897ef417bc98556fb757f75cae87"
integrity sha512-8gfzinVXoPfga5Dz/ZOn8I2GOhf81Wvs+KwbEXQn/oWZAvCVS2PivrXfVbFJc93zD16uC0neS47RXHIjXKYZQw==
@@ -7605,6 +7610,13 @@ react-native-geolocation-service@5.3.1:
resolved "https://registry.yarnpkg.com/react-native-geolocation-service/-/react-native-geolocation-service-5.3.1.tgz#4ce1017789da6fdfcf7576eb6f59435622af4289"
integrity sha512-LTXPtPNmrdhx+yeWG47sAaCgQc3nG1z+HLLHlhK/5YfOgfLcAb9HAkhREPjQKPZOUx8pKZMIpdGFUGfJYtimXQ==
react-native-get-random-values@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/react-native-get-random-values/-/react-native-get-random-values-1.8.0.tgz#1cb4bd4bd3966a356e59697b8f372999fe97cb16"
integrity sha512-H/zghhun0T+UIJLmig3+ZuBCvF66rdbiWUfRSNS6kv5oDSpa1ZiVyvRWtuPesQpT8dXj+Bv7WJRQOUP+5TB1sA==
dependencies:
fast-base64-decode "^1.0.0"
react-native-gradle-plugin@^0.70.3:
version "0.70.3"
resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.70.3.tgz#cbcf0619cbfbddaa9128701aa2d7b4145f9c4fc8"