diff --git a/ProtectedRouter.tsx b/ProtectedRouter.tsx index 308cbf9b..00ee44ef 100644 --- a/ProtectedRouter.tsx +++ b/ProtectedRouter.tsx @@ -16,6 +16,7 @@ import { setLoanIdToValue } from './src/reducer/paymentSlice'; import { setDeviceId } from './src/reducer/userSlice'; import AddressGeolocation from './src/screens/addressGeolocation'; import AllCasesMain from './src/screens/allCases'; +import CompletedCase from './src/screens/allCases/CompletedCase'; import CaseDetails from './src/screens/caseDetails/CaseDetails'; import CollectionCaseDetails from './src/screens/caseDetails/CollectionCaseDetail'; import interactionsHandler from './src/screens/caseDetails/interactionsHandler'; @@ -163,6 +164,16 @@ const ProtectedRouter = () => { }} listeners={getScreenFocusListenerObj} /> + null, + animation: 'slide_from_right', + animationDuration: ANIMATION_DURATION + }} + listeners={getScreenFocusListenerObj} + /> ) : ( <> diff --git a/src/action/authActions.ts b/src/action/authActions.ts index 8bba135e..73889d8c 100644 --- a/src/action/authActions.ts +++ b/src/action/authActions.ts @@ -16,8 +16,7 @@ import { navigateToScreen } from '../components/utlis/navigationUtlis'; import { AxiosResponse } from 'axios'; import { AppDispatch } from '../store/store'; import { setGlobalUserData } from '../constants/Global'; -import { resetCasesData, setCasesListData } from '../reducer/allCasesSlice'; -import { getAllCaseDetails } from './dataActions'; +import { resetCasesData } from '../reducer/allCasesSlice'; export interface GenerateOTPPayload { phoneNumber: string; diff --git a/src/assets/icons/EmptyPageCheckIcon.tsx b/src/assets/icons/EmptyPageCheckIcon.tsx index 1252b412..e678b343 100644 --- a/src/assets/icons/EmptyPageCheckIcon.tsx +++ b/src/assets/icons/EmptyPageCheckIcon.tsx @@ -2,164 +2,158 @@ import React from 'react'; import Svg, {Path} from 'react-native-svg'; const EmptyPageCheckIcon = () => ( - + + + + - - + - - - - - - - - + + + + + + + + + - - - ); export default EmptyPageCheckIcon; diff --git a/src/assets/icons/NoCasesFoundIcon.tsx b/src/assets/icons/NoCasesFoundIcon.tsx index 5fbd7ef2..bf79d847 100644 --- a/src/assets/icons/NoCasesFoundIcon.tsx +++ b/src/assets/icons/NoCasesFoundIcon.tsx @@ -1,111 +1,108 @@ import * as React from "react"; import Svg, { Path, Rect } from "react-native-svg"; const NoCasesFoundIcon = () => ( - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + ); export default NoCasesFoundIcon; diff --git a/src/reducer/allCasesSlice.ts b/src/reducer/allCasesSlice.ts index e3177a41..6d4c1f30 100644 --- a/src/reducer/allCasesSlice.ts +++ b/src/reducer/allCasesSlice.ts @@ -461,12 +461,27 @@ const allCasesSlice = createSlice({ toggleNewlyAddedCase: (state, action) => { state.caseDetails[action.payload].isNewlyAdded = false; }, - resetCasesData: (state) => { - state = { - ...initialState, - isOnboarded: state.isOnboarded - } - } + resetCasesData: state => { + state.casesList = []; + state.pinnedList = []; + state.casesListMap = {}; + state.intermediateTodoList = []; + state.intermediateTodoListMap = {}; + state.selectedTodoListCount = 0; + state.selectedTodoListMap = {}; + state.initialPinnedRankCount = 0; + state.pinnedRankCount = 0; + state.loading = false; + state.filterList = []; + state.newlyPinnedCases = 0; + state.completedCases = 0; + state.caseDetails = {}; + state.filters = {}; + state.searchQuery = ''; + state.selectedFilters = {}; + state.filterCount = 0; + state.isOnboarded = state.isOnboarded; + }, }, }); diff --git a/src/reducer/loginSlice.ts b/src/reducer/loginSlice.ts index bbb9995b..1eb2ce1c 100644 --- a/src/reducer/loginSlice.ts +++ b/src/reducer/loginSlice.ts @@ -38,7 +38,12 @@ const loginSlice = createSlice({ state.isLoading = action.payload; }, resetLoginForm: state => { - state = { ...initialState }; + state.phoneNumber = ''; + state.otpToken = ''; + state.OTPError = ''; + state.verifyOTPSuccess = ''; + state.verifyOTPError = ''; + state.isLoading = false; }, }, }); diff --git a/src/screens/Profile/index.tsx b/src/screens/Profile/index.tsx index 9b7d0e52..0ac1546c 100644 --- a/src/screens/Profile/index.tsx +++ b/src/screens/Profile/index.tsx @@ -7,13 +7,25 @@ import { addClickstreamEvent } from '../../services/clickstreamEventService'; import { CLICKSTREAM_EVENT_NAMES } from '../../common/Constants'; import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; import { logout } from '../../action/authActions'; -import { goBack } from '../../components/utlis/navigationUtlis'; -import { useAppDispatch } from '../../hooks'; -import AccountDetails from './AccountDetails'; +import { useAppDispatch, useAppSelector } from '../../hooks'; import Layout from '../layout/Layout'; +import { RootState } from '../../store/store'; +import { ICaseItem } from '../allCases/interface'; +import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; +import ListItem from '../allCases/ListItem'; +import Button from '../../../RN-UI-LIB/src/components/Button'; +import { navigateToScreen } from '../../components/utlis/navigationUtlis'; +import GroupIcon from '../../../RN-UI-LIB/src/Icons/groupIcon'; -const Profile: React.FC = () => { +interface IProfile { + completedCases: ICaseItem[]; +} + +const Profile: React.FC = ({completedCases = []}) => { const dispatch = useAppDispatch(); + const {phoneNumber, name} = useAppSelector( + (state: RootState) => state.user.user!!, + ); useEffect(() => { addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_PROFILE_PAGE_LOADED); @@ -49,21 +61,54 @@ const Profile: React.FC = () => { ]); }; + const handleViewAllCases = () => { + navigateToScreen('CompletedCases', {completedCases}) + } + + const numberOfCompletedCases = completedCases?.length || 0; + return ( - - - - + + + + + + + Completed cases ({numberOfCompletedCases}) + {numberOfCompletedCases + ? completedCases + .slice(0, 3) + .map(caseItem => ( + + )) + : null} + {numberOfCompletedCases > 3 ? ( + + ) : null} + + + style={[GenericStyles.row, GenericStyles.alignCenter]}> Logout @@ -77,7 +122,9 @@ export default Profile; const styles = StyleSheet.create({ logoutContainer: { - marginLeft: 10, + backgroundColor: COLORS.BACKGROUND.PRIMARY, + paddingVertical: 16, + paddingHorizontal: 34 }, logoutText: { marginLeft: 6, diff --git a/src/screens/allCases/CasesList.tsx b/src/screens/allCases/CasesList.tsx index 034a3b73..81e85cf4 100644 --- a/src/screens/allCases/CasesList.tsx +++ b/src/screens/allCases/CasesList.tsx @@ -95,19 +95,23 @@ const CasesList: React.FC = ({ casesList = [], isVisitPlan }) => { }) : filteredList; - const listEmptyComponent = - filterCount > 0 || searchQuery.length > 0 ? ( - - ) : ( - - ); + const isFilterApplied = filterCount > 0 || searchQuery.length > 0; + + const listEmptyComponent = ( + + ); return { filteredCasesList: filteredListAfterQuery, listEmptyComponent }; }, [casesList, caseDetails, filters, selectedFilters, searchQuery]); @@ -154,7 +158,7 @@ const CasesList: React.FC = ({ casesList = [], isVisitPlan }) => { headerLabel={ isVisitPlan ? "Today's visit plan" - : `My Cases (${casesList.length})` + : `My Cases (${filteredCasesList.length})` } showFilters={!!casesList.length} /> diff --git a/src/screens/allCases/CompletedCase.tsx b/src/screens/allCases/CompletedCase.tsx index 558f743c..3a6f2686 100644 --- a/src/screens/allCases/CompletedCase.tsx +++ b/src/screens/allCases/CompletedCase.tsx @@ -1,5 +1,4 @@ import { - RefreshControl, StyleSheet, View, VirtualizedList, @@ -8,45 +7,43 @@ import React from 'react'; import { ICaseItem } from './interface'; import ListItem from './ListItem'; import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; -import { useAppDispatch, useAppSelector } from '../../hooks'; -import { COMPLETED_STATUSES, EmptyListMessages } from './contants'; +import { EmptyListMessages } from './contants'; import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; import EmptyList from './EmptyList'; -import useRefresh from '../../hooks/useRefresh'; -import { getAllCases } from '../../action/dataActions'; -import { HEADER_HEIGHT_MIN, HEADER_SCROLL_DISTANCE } from '../../common/Constants'; +import NavigationHeader from '../../../RN-UI-LIB/src/components/NavigationHeader'; +import { goBack } from '../../components/utlis/navigationUtlis'; const getItem = (item: Array, index: number) => item[index]; -const CompletedCase = () => { - const { casesList, caseDetails } = useAppSelector(state => state.allCases); - const completed = casesList.filter(caseData => { - const detail = caseDetails[caseData.caseReferenceId]; - const { caseStatus } = detail; - return COMPLETED_STATUSES.includes(caseStatus); - }); +interface ICompletedCases { + route: { + params: { completedCases: ICaseItem[] }, + }, +} - const dispatch = useAppDispatch(); +const CompletedCase:React.FC = (props) => { + const { + route: { + params: { completedCases }, + }, + } = props; - const { refreshing, onRefresh } = useRefresh(() => dispatch(getAllCases())); + const handleBack = () => { + goBack(); + } return ( + - // } - data={completed} + data={completedCases} initialNumToRender={4} renderItem={row => ( - + )} keyExtractor={item => item.caseReferenceId} getItemCount={item => item.length} @@ -69,7 +66,6 @@ const styles = StyleSheet.create({ list: { marginHorizontal: 12, marginVertical: 10, - paddingTop: HEADER_HEIGHT_MIN - 50 }, seperator: { backgroundColor: COLORS.BORDER.PRIMARY, diff --git a/src/screens/allCases/EmptyList.tsx b/src/screens/allCases/EmptyList.tsx index dbebcb7f..5c97ece4 100644 --- a/src/screens/allCases/EmptyList.tsx +++ b/src/screens/allCases/EmptyList.tsx @@ -1,20 +1,21 @@ import { StyleSheet, View } from 'react-native'; import React from 'react'; -import EmptyPageWarnIcon from '../../assets/icons/EmptyPageWarnIcon'; import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; import Heading from '../../../RN-UI-LIB/src/components/Heading'; import EmptyPageCheckIcon from '../../assets/icons/EmptyPageCheckIcon'; -import EmptyListIcon from '../../../RN-UI-LIB/src/Icons/EmptyListIcon'; import Button from '../../../RN-UI-LIB/src/components/Button'; import { navigateToScreen } from '../../components/utlis/navigationUtlis'; +import NoCasesFoundIcon from '../../assets/icons/NoCasesFoundIcon'; +import Text from '../../../RN-UI-LIB/src/components/Text'; interface IEmptyList { message: string; - showWarnSign?: boolean; + subMessage?: string; isVisitPlan?: boolean; + isFilterApplied?: boolean; } -const EmptyList: React.FC = ({ showWarnSign, message, isVisitPlan }) => { +const EmptyList: React.FC = ({ message, isVisitPlan, isFilterApplied, subMessage }) => { const handleCreateVisitPlan = () => { navigateToScreen('Cases') @@ -23,11 +24,31 @@ const EmptyList: React.FC = ({ showWarnSign, message, isVisitPlan }) return ( - {isVisitPlan ? : showWarnSign ? : } - - {message} - - {isVisitPlan && ); @@ -38,7 +59,11 @@ const styles = StyleSheet.create({ height: '100%', justifyContent: 'center', alignItems: 'center', - paddingHorizontal: 4 + paddingHorizontal: 4, + }, + text: { + paddingHorizontal: 30, + width: '100%' }, }); diff --git a/src/screens/allCases/ListItem.tsx b/src/screens/allCases/ListItem.tsx index c3c97acf..43b942d1 100644 --- a/src/screens/allCases/ListItem.tsx +++ b/src/screens/allCases/ListItem.tsx @@ -33,15 +33,15 @@ interface IListItem { caseData: ICaseItem; // True if it's from the inside todo screen isTodoItem?: boolean; - compleatedList?: boolean; + isCompleted?: boolean; } const ListItem: React.FC = props => { - const { caseData, compleatedList, isTodoItem } = props; + const { caseData, isCompleted, isTodoItem } = props; const { caseReferenceId: caseId } = caseData; const dispatch = useAppDispatch(); - if (!compleatedList && caseData.caseStatus === CaseStatuses.CLOSED) { + if (!isCompleted && caseData.caseStatus === CaseStatuses.CLOSED) { return null; } @@ -126,7 +126,7 @@ const ListItem: React.FC = props => { }, ]}> - {!isTodoItem ? ( + {!isTodoItem && !isCompleted ? ( @@ -135,11 +135,14 @@ const ListItem: React.FC = props => { ) : null} - {detail?.caseType === CaseAllocationType.COLLECTION_CASE ? ( + {detail?.caseType === + CaseAllocationType.COLLECTION_CASE ? ( } /> @@ -148,7 +151,8 @@ const ListItem: React.FC = props => { variant="teal" text={ CaseTypeMap[ - CaseAllocationType.ADDRESS_VERIFICATION_CASE + CaseAllocationType + .ADDRESS_VERIFICATION_CASE ] } tagIcon={} @@ -158,26 +162,22 @@ const ListItem: React.FC = props => { {customerName} - {!compleatedList && ( - - {taskTitle ? ( - - {/* @ts-ignore */} - {TaskTitleUIMapping[taskTitle]} - {displayAddress - ? `: ${displayAddress}` - : null} - - ) : isCollection ? ( - {displayAddress} - ) : null} - - )} + + {taskTitle ? ( + + {/* @ts-ignore */} + {TaskTitleUIMapping[taskTitle]} + {displayAddress ? `: ${displayAddress}` : null} + + ) : isCollection ? ( + {displayAddress} + ) : null} + {detail?.caseType === CaseAllocationType.COLLECTION_CASE ? ( = props => { POS {formatAmount(detail.pos, false)} {' '}DPD bucket {detail.dpdBucket} - ) : compleatedList || caseStatus ? ( + ) : caseStatus ? ( - {!compleatedList && caseStatus && ( + {caseStatus ? ( {caseStatus.label} - )} - {compleatedList && ( - - {closedCaseStatus.label} - - )} + ): null} ) : null} diff --git a/src/screens/allCases/NoCasesFound.tsx b/src/screens/allCases/NoCasesFound.tsx deleted file mode 100644 index ae1a1787..00000000 --- a/src/screens/allCases/NoCasesFound.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react'; -import { StyleSheet, View } from 'react-native'; -import Heading from '../../../RN-UI-LIB/src/components/Heading'; -import Text from '../../../RN-UI-LIB/src/components/Text'; -import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; -import NoCasesFoundIcon from '../../assets/icons/NoCasesFoundIcon'; - -interface INoCasesFound { - message: string; - subMessage: string; -} - -const NoCasesFound: React.FC = ({ message, subMessage }) => { - return ( - - - - - - - {message} - - {subMessage} - - - - ); -}; - -const styles = StyleSheet.create({ - centerAbsolute: { - height: '100%', - justifyContent: 'center', - alignItems: 'center', - }, -}); - -export default NoCasesFound; \ No newline at end of file diff --git a/src/screens/allCases/contants.ts b/src/screens/allCases/contants.ts index 4f6d09ff..25d425dd 100644 --- a/src/screens/allCases/contants.ts +++ b/src/screens/allCases/contants.ts @@ -27,7 +27,7 @@ export const ListHeaderItems = { export const EmptyListMessages = { NO_COMPLETED_CASES: 'No case completed yet', - NO_PENDING_CASES: 'All cases completed', + NO_PENDING_CASES: 'Looks like you resolved all your cases for this allocation', NO_VISIT_PLANS: 'Plan your day by creating a visit plan', NO_CASES_FOUND: 'No results for the selected filters', NO_CASES_FOUND_SUB: 'Try removing or adding different filters', diff --git a/src/screens/allCases/index.tsx b/src/screens/allCases/index.tsx index 0b708058..5592d2b4 100644 --- a/src/screens/allCases/index.tsx +++ b/src/screens/allCases/index.tsx @@ -67,7 +67,7 @@ const AllCasesMain = () => { }, { name: 'Profile', - component: Profile, + component: () => , icon: ProfileIcon, }, ],