diff --git a/src/components/SwipeableContainer/index.tsx b/src/components/SwipeableContainer/index.tsx
new file mode 100644
index 00000000..e2cbbef8
--- /dev/null
+++ b/src/components/SwipeableContainer/index.tsx
@@ -0,0 +1,109 @@
+import React, {useState} from 'react';
+import {
+ View,
+ Text,
+ StyleSheet,
+ Animated,
+ Dimensions,
+ PanResponder,
+} from 'react-native';
+
+const {width} = Dimensions.get('window');
+const gestureDelay = -35;
+
+const SwipeableContainer = (props: any) => {
+ const [position, setPosition] = useState(new Animated.ValueXY());
+
+ let scrollViewEnabled = true;
+ const panResponder = PanResponder.create({
+ onStartShouldSetPanResponder: (evt, gestureState) => false,
+ onMoveShouldSetPanResponder: (evt, gestureState) => true,
+ onPanResponderTerminationRequest: (evt, gestureState) => false,
+ onPanResponderMove: (evt, gestureState) => {
+ if (gestureState.dx < 0) {
+ setScrollViewEnabled(false);
+ let newX = gestureState.dx + gestureDelay;
+ position.setValue({x: newX, y: 0});
+ }
+ },
+ onPanResponderRelease: (evt, gestureState) => {
+ if (gestureState.dx > -50) {
+ Animated.timing(position, {
+ toValue: {x: 0, y: 0},
+ duration: 150,
+ useNativeDriver: false,
+ }).start(() => {
+ setScrollViewEnabled(true);
+ });
+ } else {
+ Animated.timing(position, {
+ toValue: {x: -100, y: 0},
+ duration: 300,
+ useNativeDriver: false,
+ }).start(() => {
+ // props.success(props.text);
+ setScrollViewEnabled(true);
+ });
+ }
+ },
+ });
+
+ // this.panResponder = panResponder;
+ // this.state = {position};
+
+ const setScrollViewEnabled = (enabled: boolean) => {
+ if (scrollViewEnabled !== enabled) {
+ // props.setScrollEnabled(enabled);
+ scrollViewEnabled = enabled;
+ }
+ };
+
+ return (
+
+
+
+ {props.children}
+
+
+ DELETE
+
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ listItem: {
+ height: 80,
+ marginRight: -100,
+ justifyContent: 'center',
+ backgroundColor: 'red',
+ position: 'relative'
+ },
+ absoluteCell: {
+ position: 'absolute',
+ // top: 0,
+ // bottom: 0,
+ right: 0,
+ width: 100,
+ flexDirection: 'row',
+ // justifyContent: 'flex-end',
+ alignItems: 'center',
+ },
+ absoluteCellText: {
+ margin: 16,
+ color: '#FFF',
+ },
+ innerCell: {
+ // width: width + 100,
+ height: 80,
+ marginRight: 100,
+ backgroundColor: 'yellow',
+ // justifyContent: 'center',
+ // alignItems: 'center',
+ },
+});
+
+export default SwipeableContainer;
diff --git a/src/components/screens/allCases/AllCases.tsx b/src/components/screens/allCases/AllCases.tsx
index 5eed666c..a0a20b5a 100644
--- a/src/components/screens/allCases/AllCases.tsx
+++ b/src/components/screens/allCases/AllCases.tsx
@@ -1,49 +1,63 @@
import TextInput from '../../../../RN-UI-LIB/src/components/TextInput';
import React, {useEffect} from 'react';
import {
- ListRenderItemInfo, StyleSheet,
+ ListRenderItemInfo,
+ StyleSheet,
View,
- VirtualizedList
+ VirtualizedList,
} from 'react-native';
-import { useDispatch, useSelector } from 'react-redux';
+import {useDispatch, useSelector} from 'react-redux';
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 { COLORS } from '../../../../RN-UI-LIB/src/styles/colors';
+import {GenericStyles} from '../../../../RN-UI-LIB/src/styles';
+import {COLORS} from '../../../../RN-UI-LIB/src/styles/colors';
import data from '../../../data/cases.json';
-import { RootState } from '../../../store/store';
-import { setCasesListData } from './allCasesSlice';
-import { caseStatus, caseVerdict, Data, taskStatus, Type } from './interface';
+import {RootState} from '../../../store/store';
+import {resetTodoList, setCasesListData, setCasesListMapData, setIntermediateTodoList} from './allCasesSlice';
+import {caseStatus, Data, Type} from './interface';
import ListItem from './ListItem';
import SearchIcon from '../../../../RN-UI-LIB/src/Icons/SearchIcon';
-import InfoIcon from '../../../../RN-UI-LIB/src/Icons/InfoIcon';
-
+import Button from '../../../../RN-UI-LIB/src/components/Button';
+import { navigateToScreen } from '../../utlis/navigationUtlis';
interface IItem {
data: ListRenderItemInfo;
todoList: Array;
}
-const Item: React.FC = (props) => {
+const Item: React.FC = props => {
const propData = props.data.item;
const todoList = props.todoList;
let completedCount = 0;
- todoList.forEach(todo =>{
- if(todo.caseStatus === caseStatus.CLOSED){
+ todoList.forEach(todo => {
+ if (todo.caseStatus === caseStatus.CLOSED) {
completedCount++;
}
});
switch (propData.type) {
case Type.FILTER:
return (
-
- } placeholder='Search by name, address' />
+
+ }
+ placeholder="Search by name, address"
+ />
);
case Type.CASES_HEADER:
return (
-
+
Other cases
@@ -51,7 +65,12 @@ const Item: React.FC = (props) => {
);
case Type.TODO_HEADER:
return (
-
+
Today's to do list
@@ -74,37 +93,65 @@ const Item: React.FC = (props) => {
);
default:
- return ;
+ return ;
}
};
-const Seperator = () => ;
+export const Seperator = () => ;
-const getItem = (item: Array, index: number) => item[index];
+export const getItem = (item: Array, index: number) => item[index];
const AllCases = () => {
-
- const {compiledList, todoList} = useSelector((state: RootState) => state.allCases);
+ const {casesList, compiledList, todoList, newlyPinnedCases} = useSelector(
+ (state: RootState) => state.allCases,
+ );
const dispatch = useDispatch();
useEffect(() => {
- dispatch(setCasesListData(data.allCases));
+ dispatch(setCasesListData(data.allCases))
}, [])
+ useEffect(() => {
+ dispatch(setCasesListMapData(casesList));
+ }, [casesList]);
+
+ const handleTodoProceedClick = () => {
+ dispatch(setIntermediateTodoList());
+ }
+
+ const handleCancelTodoList = () => {
+ dispatch(resetTodoList());
+ }
+
return (
-
+
}
stickyHeaderIndices={[0]}
initialNumToRender={4}
- renderItem={row => (
-
- )}
+ renderItem={row => }
keyExtractor={item => item.caseId}
getItemCount={item => item.length}
getItem={getItem}
ItemSeparatorComponent={}
/>
+ {newlyPinnedCases ? (
+
+
+
+ ): null}
);
};
@@ -123,6 +170,17 @@ const styles = StyleSheet.create({
borderRadius: 2.5,
backgroundColor: COLORS.TEXT.LIGHT,
},
+ actionBtns: {
+ borderTopColor: COLORS.BORDER.PRIMARY,
+ backgroundColor: COLORS.BACKGROUND.PRIMARY,
+ borderTopWidth: 1,
+ },
+ br8: {
+ borderRadius: 8,
+ },
+ fb45: {
+ flexBasis: '45%',
+ },
});
export default AllCases;
diff --git a/src/components/screens/allCases/ListItem.tsx b/src/components/screens/allCases/ListItem.tsx
index a7ee8b27..eacfb448 100644
--- a/src/components/screens/allCases/ListItem.tsx
+++ b/src/components/screens/allCases/ListItem.tsx
@@ -18,11 +18,12 @@ import RoundCheckIcon from '../../../icons/RoundCheckIcon';
interface IListItem {
caseData: Data;
+ isTodoItem?: boolean;
compleatedList?: boolean;
}
const ListItem: React.FC = props => {
- const {caseData, compleatedList} = props;
+ const {caseData, compleatedList, isTodoItem} = props;
const {type, caseId} = caseData;
const dispatch = useDispatch();
@@ -30,19 +31,25 @@ const ListItem: React.FC = props => {
return null;
}
- const {casesListMap} = useSelector((state: RootState) => state.allCases);
+ const {intermediateTodoListMap} = useSelector(
+ (state: RootState) => state.allCases,
+ );
const handleAvatarClick = () => {
- if (!type) {
- dispatch(setPinnedRank(caseId));
+ if (
+ !isTodoItem &&
+ type === Type.CASE &&
+ caseData.caseStatus !== caseStatus.CLOSED
+ ) {
+ dispatch(setPinnedRank(caseData));
}
};
const handleCaseClick = () => {
- alert('case clicked')
- }
+ alert('case clicked');
+ };
- const caseSelected = casesListMap?.[caseId].pinnedRank;
+ const caseSelected = !isTodoItem && intermediateTodoListMap?.[caseId];
return (
// Todo kunal to add the page switching logic
diff --git a/src/components/screens/allCases/allCasesSlice.ts b/src/components/screens/allCases/allCasesSlice.ts
index a835ac0b..c86b1764 100644
--- a/src/components/screens/allCases/allCasesSlice.ts
+++ b/src/components/screens/allCases/allCasesSlice.ts
@@ -1,6 +1,7 @@
import {_map} from '@components/utlis/common';
import {createSlice} from '@reduxjs/toolkit';
-import {caseStatus, caseVerdict, Data, taskStatus, Type} from './interface';
+import {navigateToScreen} from '../../utlis/navigationUtlis';
+import {caseStatus, Data, Type} from './interface';
type ICasesMap = {[key: string]: Data};
@@ -9,9 +10,14 @@ interface IAllCasesSlice {
todoList: Data[];
otherCasesList: Data[];
compiledList: Data[];
- casesListMap: ICasesMap | null;
+ casesListMap: ICasesMap;
+ intermediateTodoList: Data[];
+ intermediateTodoListMap: ICasesMap;
+ initialPinnedRankCount: number;
pinnedRankCount: number;
loading: boolean;
+ newlyPinnedCases: number;
+ completedCases: number;
}
const initialState: IAllCasesSlice = {
@@ -19,9 +25,14 @@ const initialState: IAllCasesSlice = {
todoList: [],
otherCasesList: [],
compiledList: [],
- casesListMap: null,
+ casesListMap: {},
+ intermediateTodoList: [],
+ intermediateTodoListMap: {},
+ initialPinnedRankCount: 0,
pinnedRankCount: 0,
loading: false,
+ newlyPinnedCases: 0,
+ completedCases: 0,
};
const allCasesSlice = createSlice({
@@ -29,21 +40,38 @@ const allCasesSlice = createSlice({
initialState,
reducers: {
setCasesListData: (state, action) => {
+ state.casesList = action.payload;
+ },
+ setCasesListMapData: (state, action) => {
const todoList: Data[] = [];
const otherCasesList: Data[] = [];
+ let completedCasesCount = 0;
const list: ICasesMap = action.payload.reduce(
(acc: ICasesMap, caseItem: Data) => {
- acc[caseItem.caseId] = caseItem;
+ const caseId = caseItem.caseId;
+ if (caseItem.caseStatus === caseStatus.CLOSED) {
+ completedCasesCount++;
+ }
+ acc[caseId] = caseItem;
+ // acc[caseItem.caseId] = caseItem;
if (caseItem.pinnedRank) {
- todoList.push(caseItem);
+ const caseItemTypeTodo = {...caseItem, type: Type.TODO};
+ // caseItem.type = Type.TODO;
+ todoList.push(caseItemTypeTodo);
} else {
- otherCasesList.push(caseItem);
+ const caseItemTypeCase = {...caseItem, type: Type.CASE};
+ // caseItem.type = Type.CASE;
+ otherCasesList.push(caseItemTypeCase);
}
return acc;
},
{},
);
+ state.initialPinnedRankCount = todoList.length;
+ state.pinnedRankCount = todoList.length;
+ state.completedCases = completedCasesCount;
if (todoList.length) {
+ todoList.sort((caseItemA, caseItemB) => caseItemA.pinnedRank - caseItemB.pinnedRank);
todoList.unshift({
type: Type.TODO_HEADER,
caseId: -2,
@@ -64,25 +92,60 @@ const allCasesSlice = createSlice({
...otherCasesList,
];
state.casesListMap = list;
- state.casesList = action.payload;
+ // state.casesList = action.payload;
state.otherCasesList = action.payload;
},
setPinnedRank: (state, action) => {
- if (!state.casesListMap) {
- return;
- }
- const caseId = action.payload;
- const pinnedRank = state.casesListMap[caseId].pinnedRank;
- if (pinnedRank) {
- delete state.casesListMap[caseId].pinnedRank;
+ const caseId = action.payload.caseId;
+ const isCasePresent = state.intermediateTodoListMap[caseId];
+ if (isCasePresent) {
+ delete state.intermediateTodoListMap[caseId];
+ state.newlyPinnedCases--;
} else {
state.pinnedRankCount++;
- state.casesListMap[caseId].pinnedRank = state.pinnedRankCount;
+ state.newlyPinnedCases++;
+ const selectedCase = {...action.payload};
+ selectedCase.pinnedRank = state.pinnedRankCount;
+ state.intermediateTodoListMap[caseId] = selectedCase;
}
},
+ setIntermediateTodoList: state => {
+ const list = Object.values(state.intermediateTodoListMap);
+ state.intermediateTodoList = list;
+ navigateToScreen('OTP');
+ },
+ resetTodoList: state => {
+ state.intermediateTodoList = [];
+ state.intermediateTodoListMap = {};
+ state.newlyPinnedCases = 0;
+ state.pinnedRankCount = state.initialPinnedRankCount;
+ },
+ setTodoList: state => {
+ state.newlyPinnedCases = 0;
+ const list = state.casesList.map(caseItem => {
+ const todoItem =
+ state.intermediateTodoListMap[caseItem.caseId];
+ return {
+ ...caseItem,
+ pinnedRank: todoItem ? todoItem.pinnedRank : caseItem.pinnedRank,
+ };
+ });
+ state.casesList = list;
+ state.intermediateTodoList = [];
+ state.intermediateTodoListMap = {};
+ state.newlyPinnedCases = 0;
+ navigateToScreen('Login');
+ },
},
});
-export const {setCasesListData, setPinnedRank} = allCasesSlice.actions;
+export const {
+ setCasesListData,
+ setCasesListMapData,
+ setPinnedRank,
+ setIntermediateTodoList,
+ setTodoList,
+ resetTodoList,
+} = allCasesSlice.actions;
export default allCasesSlice.reducer;
diff --git a/src/components/screens/allCases/interface.ts b/src/components/screens/allCases/interface.ts
index 299c885c..15717f5f 100644
--- a/src/components/screens/allCases/interface.ts
+++ b/src/components/screens/allCases/interface.ts
@@ -4,6 +4,8 @@ export enum Type {
TODO_HEADER,
CASES_HEADER,
FILTER,
+ TODO,
+ CASE
}
export enum caseVerdict {
diff --git a/src/components/screens/todoList/TodoList.tsx b/src/components/screens/todoList/TodoList.tsx
new file mode 100644
index 00000000..d5caddbe
--- /dev/null
+++ b/src/components/screens/todoList/TodoList.tsx
@@ -0,0 +1,110 @@
+import {
+ View,
+ StyleSheet,
+ VirtualizedList,
+ ListRenderItemInfo,
+ TouchableOpacity,
+} from 'react-native';
+import React, {useMemo} from 'react';
+import {GenericStyles} from '../../../../RN-UI-LIB/src/styles';
+import CloseIcon from '../../../../RN-UI-LIB/src/Icons/CloseIcon';
+import {COLORS} from '../../../../RN-UI-LIB/src/styles/colors';
+import Heading from '../../../../RN-UI-LIB/src/components/Heading';
+import Text from '../../../../RN-UI-LIB/src/components/Text';
+import {useDispatch, useSelector} from 'react-redux';
+import {RootState} from '../../../store/store';
+import {Data} from '../allCases/interface';
+import ListItem from '../allCases/ListItem';
+import {getItem, Seperator} from '../allCases/AllCases';
+import Button from '../../../../RN-UI-LIB/src/components/Button';
+import {resetTodoList, setTodoList} from '../allCases/allCasesSlice';
+import {navigateToScreen} from '../../utlis/navigationUtlis';
+import SwipeableContainer from '../../SwipeableContainer';
+
+const TodoList = () => {
+ const {intermediateTodoList} = useSelector(
+ (state: RootState) => state.allCases,
+ );
+
+ const dispatch = useDispatch();
+
+ const handleCreateTodoList = () => {
+ dispatch(setTodoList());
+ };
+
+ const handleCancelTodoList = () => {
+ dispatch(resetTodoList());
+ navigateToScreen('Login');
+ };
+
+ return (
+
+
+
+
+
+
+ Sharing a message of your visit
+
+
+ The selected customer(s) will recieve a message about your
+ visit. Are you sure you want to proceed?
+
+
+ }
+ initialNumToRender={4}
+ renderItem={(row: ListRenderItemInfo) => (
+
+
+
+ )}
+ keyExtractor={item => item.caseId}
+ getItemCount={item => item.length}
+ getItem={getItem}
+ ItemSeparatorComponent={}
+ />
+
+
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ todoListContainer: {
+ backgroundColor: COLORS.BACKGROUND.PRIMARY,
+ },
+ header: {
+ borderBottomWidth: 1,
+ borderBottomColor: COLORS.BORDER.PRIMARY,
+ },
+ headingText: {
+ marginTop: 16,
+ marginBottom: 8,
+ },
+ separator: {
+ backgroundColor: COLORS.BORDER.PRIMARY,
+ height: 2,
+ },
+ actionBtns: {
+ borderTopColor: COLORS.BORDER.PRIMARY,
+ backgroundColor: COLORS.BACKGROUND.PRIMARY,
+ borderTopWidth: 1,
+ },
+});
+
+export default TodoList;
diff --git a/src/store/store.ts b/src/store/store.ts
index d23ec274..d9b1ccd9 100644
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@ -28,7 +28,7 @@ const persistConfig = {
key: 'root',
version: 1,
storage: AsyncStorage,
- whitelist: ['case', 'common'],
+ whitelist: ['case', 'common', 'allCases'],
};
const persistedReducer = persistReducer(persistConfig, rootReducer);