mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 21:48:04 -05:00
Revert "feat: add transaction history"
This commit is contained in:
committed by
GitHub
parent
09d829a3ee
commit
3953be2b9e
@@ -37,7 +37,6 @@
|
|||||||
"@typescript-eslint/no-unused-vars": [
|
"@typescript-eslint/no-unused-vars": [
|
||||||
"error",
|
"error",
|
||||||
{ "ignoreRestSiblings": true }
|
{ "ignoreRestSiblings": true }
|
||||||
],
|
]
|
||||||
"react/prop-types": ["warn"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
import React, { useContext } from 'react';
|
|
||||||
import { useSelector } from '@xstate/react';
|
|
||||||
import { getVersion } from 'react-native-device-info';
|
|
||||||
|
|
||||||
import { selectBackendInfo } from '../machines/app';
|
|
||||||
import { GlobalContext } from '../shared/GlobalContext';
|
|
||||||
import { Column, Text } from './ui';
|
|
||||||
import { Colors } from './ui/styleUtils';
|
|
||||||
|
|
||||||
export const AppVersion: React.FC = () => {
|
|
||||||
const { appService } = useContext(GlobalContext);
|
|
||||||
const backendInfo = useSelector(appService, selectBackendInfo);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Column>
|
|
||||||
<VersionText>Version: {getVersion()}</VersionText>
|
|
||||||
{backendInfo.application.name !== '' ? (
|
|
||||||
<React.Fragment>
|
|
||||||
<VersionText>
|
|
||||||
{backendInfo.application.name}: {backendInfo.application.version}
|
|
||||||
</VersionText>
|
|
||||||
<VersionText>MOSIP: {backendInfo.config['mosip.host']}</VersionText>
|
|
||||||
</React.Fragment>
|
|
||||||
) : null}
|
|
||||||
</Column>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const VersionText: React.FC = (props) => (
|
|
||||||
<Text weight="semibold" align="center" size="smaller" color={Colors.Grey}>
|
|
||||||
{props.children}
|
|
||||||
</Text>
|
|
||||||
);
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
import {
|
|
||||||
MOSIPServiceHistoryItem,
|
|
||||||
MOSIPServiceHistoryItemEventStatus,
|
|
||||||
} from '../screens/Profile/TransactionHistoryScreenController';
|
|
||||||
import { Column, Row, Text } from './ui';
|
|
||||||
import { Colors } from './ui/styleUtils';
|
|
||||||
|
|
||||||
export const TransactionHistoryItem: React.FC<TransactionHistoryItemProps> = (
|
|
||||||
props
|
|
||||||
) => {
|
|
||||||
const { data } = props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Column style={styles.container}>
|
|
||||||
<Row margin={[0, 0, 8, 0]}>
|
|
||||||
<Column fill margin={[0, 8, 0, 0]}>
|
|
||||||
<Text size="small" weight="semibold" numLines={1}>
|
|
||||||
{data.eventId}
|
|
||||||
</Text>
|
|
||||||
<Text size="smaller" color={Colors.Grey}>
|
|
||||||
{new Date(data.timeStamp).toLocaleString()}
|
|
||||||
</Text>
|
|
||||||
</Column>
|
|
||||||
<Column crossAlign="flex-end">
|
|
||||||
<Text
|
|
||||||
size="smaller"
|
|
||||||
weight="semibold"
|
|
||||||
style={[statusStyles.base, statusStyles[data.eventStatus]]}>
|
|
||||||
{data.eventStatus}
|
|
||||||
</Text>
|
|
||||||
</Column>
|
|
||||||
</Row>
|
|
||||||
<Text size="small">{data.description.trim()}</Text>
|
|
||||||
</Column>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
interface TransactionHistoryItemProps {
|
|
||||||
data: MOSIPServiceHistoryItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
backgroundColor: Colors.White,
|
|
||||||
marginBottom: 8,
|
|
||||||
paddingHorizontal: 16,
|
|
||||||
paddingVertical: 8,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const statusStyles = StyleSheet.create({
|
|
||||||
base: {
|
|
||||||
borderRadius: 100,
|
|
||||||
color: Colors.White,
|
|
||||||
backgroundColor: Colors.Grey,
|
|
||||||
paddingHorizontal: 8,
|
|
||||||
paddingVertical: 2,
|
|
||||||
},
|
|
||||||
|
|
||||||
[MOSIPServiceHistoryItemEventStatus.Failed]: {
|
|
||||||
backgroundColor: Colors.Red,
|
|
||||||
},
|
|
||||||
|
|
||||||
[MOSIPServiceHistoryItemEventStatus.InProgress]: {
|
|
||||||
backgroundColor: Colors.Orange,
|
|
||||||
},
|
|
||||||
|
|
||||||
[MOSIPServiceHistoryItemEventStatus.Success]: {
|
|
||||||
backgroundColor: Colors.Green,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -69,13 +69,13 @@ PODS:
|
|||||||
- GoogleNetworkingUtilities (~> 1.2)
|
- GoogleNetworkingUtilities (~> 1.2)
|
||||||
- GoogleSymbolUtilities (~> 1.1)
|
- GoogleSymbolUtilities (~> 1.1)
|
||||||
- GoogleUtilitiesLegacy (~> 1.3)
|
- GoogleUtilitiesLegacy (~> 1.3)
|
||||||
- Permission-BluetoothPeripheral (3.6.1):
|
- Permission-BluetoothPeripheral (3.6.0):
|
||||||
- RNPermissions
|
- RNPermissions
|
||||||
- Permission-Camera (3.6.1):
|
- Permission-Camera (3.6.0):
|
||||||
- RNPermissions
|
- RNPermissions
|
||||||
- Permission-LocationAccuracy (3.6.1):
|
- Permission-LocationAccuracy (3.6.0):
|
||||||
- RNPermissions
|
- RNPermissions
|
||||||
- Permission-LocationWhenInUse (3.6.1):
|
- Permission-LocationWhenInUse (3.6.0):
|
||||||
- RNPermissions
|
- RNPermissions
|
||||||
- RCT-Folly (2020.01.13.00):
|
- RCT-Folly (2020.01.13.00):
|
||||||
- boost-for-react-native
|
- boost-for-react-native
|
||||||
@@ -340,24 +340,24 @@ PODS:
|
|||||||
- React-cxxreact (= 0.64.4)
|
- React-cxxreact (= 0.64.4)
|
||||||
- React-jsi (= 0.64.4)
|
- React-jsi (= 0.64.4)
|
||||||
- React-perflogger (= 0.64.4)
|
- React-perflogger (= 0.64.4)
|
||||||
- RNBluetoothStateManager (1.3.4):
|
- RNBluetoothStateManager (1.3.3):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNCAsyncStorage (1.15.17):
|
- RNCAsyncStorage (1.15.17):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNCPicker (2.2.1):
|
- RNCPicker (2.2.1):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNDeviceInfo (8.7.1):
|
- RNDeviceInfo (8.7.0):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNGestureHandler (2.1.3):
|
- RNGestureHandler (2.1.3):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNKeychain (8.0.0):
|
- RNKeychain (8.0.0):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNPermissions (3.6.1):
|
- RNPermissions (3.6.0):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNScreens (3.10.2):
|
- RNScreens (3.10.2):
|
||||||
- React-Core
|
- React-Core
|
||||||
- React-RCTImage
|
- React-RCTImage
|
||||||
- RNSecureRandom (1.0.1):
|
- RNSecureRandom (1.0.0):
|
||||||
- React
|
- React
|
||||||
- RNSVG (12.1.1):
|
- RNSVG (12.1.1):
|
||||||
- React
|
- React
|
||||||
@@ -613,7 +613,7 @@ SPEC CHECKSUMS:
|
|||||||
EXUpdates: a83e036243b0f6ece53a8c1cb883b6751c88a5f8
|
EXUpdates: a83e036243b0f6ece53a8c1cb883b6751c88a5f8
|
||||||
EXUpdatesInterface: a9814f422d3cd6e7cfd260d13c27786148ece20e
|
EXUpdatesInterface: a9814f422d3cd6e7cfd260d13c27786148ece20e
|
||||||
FBLazyVector: fa8275d5086566e22a26ddc385ab5772e7f9b1bd
|
FBLazyVector: fa8275d5086566e22a26ddc385ab5772e7f9b1bd
|
||||||
FBReactNativeSpec: c3dafd68550f3c95f009beee5c20ab07949ec4e4
|
FBReactNativeSpec: 7ead992e0bbaf608b93d456361caa6ccf6745df5
|
||||||
glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62
|
glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62
|
||||||
GoogleInterchangeUtilities: d5bc4d88d5b661ab72f9d70c58d02ca8c27ad1f7
|
GoogleInterchangeUtilities: d5bc4d88d5b661ab72f9d70c58d02ca8c27ad1f7
|
||||||
GoogleNetworkingUtilities: 3edd3a8161347494f2da60ea0deddc8a472d94cb
|
GoogleNetworkingUtilities: 3edd3a8161347494f2da60ea0deddc8a472d94cb
|
||||||
@@ -621,10 +621,10 @@ SPEC CHECKSUMS:
|
|||||||
GoogleUtilitiesLegacy: 5501bedec1646bd284286eb5fc9453f7e23a12f4
|
GoogleUtilitiesLegacy: 5501bedec1646bd284286eb5fc9453f7e23a12f4
|
||||||
mosip-inji-face-sdk: f0e765373b50324243d904e45eb3ce899db951ac
|
mosip-inji-face-sdk: f0e765373b50324243d904e45eb3ce899db951ac
|
||||||
NearbyMessages: bd9e88f2df7fbab78be58fed58580d5d5bd62cbf
|
NearbyMessages: bd9e88f2df7fbab78be58fed58580d5d5bd62cbf
|
||||||
Permission-BluetoothPeripheral: 67708853584bb9208c76d36d0e0ea4eafb97ea5b
|
Permission-BluetoothPeripheral: 2a5154a9dfdb1cfcf1d546650ced9671904a02af
|
||||||
Permission-Camera: bf6791b17c7f614b6826019fcfdcc286d3a107f6
|
Permission-Camera: 0a0fb4341f50ab242f496fb2f73380e0ec454fe7
|
||||||
Permission-LocationAccuracy: 76df17de5c6b8bc2eee34e61ee92cdd7a864c73d
|
Permission-LocationAccuracy: 13cbce13607e0738f1339447b4c5f51aa2c2b597
|
||||||
Permission-LocationWhenInUse: 3ba99e45c852763f730eabecec2870c2382b7bd4
|
Permission-LocationWhenInUse: 51aa065819cd582517e98e89b564e2465a4a83c6
|
||||||
RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c
|
RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c
|
||||||
RCTRequired: f85fa00af016059cf88b90b8f8ff9a6af9e4b6c3
|
RCTRequired: f85fa00af016059cf88b90b8f8ff9a6af9e4b6c3
|
||||||
RCTTypeSafety: 5279aaf0fb1ad715cbbbbee32d5c98c72598bc9c
|
RCTTypeSafety: 5279aaf0fb1ad715cbbbbee32d5c98c72598bc9c
|
||||||
@@ -651,15 +651,15 @@ SPEC CHECKSUMS:
|
|||||||
React-RCTVibration: 761849eea2a1abc99d5e4171bae17ab3da3143ac
|
React-RCTVibration: 761849eea2a1abc99d5e4171bae17ab3da3143ac
|
||||||
React-runtimeexecutor: 5b441857030bb6c3abaa7517f333cb01875ae499
|
React-runtimeexecutor: 5b441857030bb6c3abaa7517f333cb01875ae499
|
||||||
ReactCommon: b4a65d2d6e9eeffd4b32dde1245962b3f43907d0
|
ReactCommon: b4a65d2d6e9eeffd4b32dde1245962b3f43907d0
|
||||||
RNBluetoothStateManager: ae6a26260cbdf1827b58bd3bcc563527d61e6488
|
RNBluetoothStateManager: 4f2d73aecf081b97024116cba628e36c5b283791
|
||||||
RNCAsyncStorage: 6bd5a7ba3dde1c3facba418aa273f449bdc5437a
|
RNCAsyncStorage: 6bd5a7ba3dde1c3facba418aa273f449bdc5437a
|
||||||
RNCPicker: cb57c823d5ce8d2d0b5dfb45ad97b737260dc59e
|
RNCPicker: cb57c823d5ce8d2d0b5dfb45ad97b737260dc59e
|
||||||
RNDeviceInfo: aad3c663b25752a52bf8fce93f2354001dd185aa
|
RNDeviceInfo: 36286df381fcaf1933ff9d2d3c34ba2abeb2d8d8
|
||||||
RNGestureHandler: e1099204721a17a89c81fcd1cc2e92143dc040fb
|
RNGestureHandler: e1099204721a17a89c81fcd1cc2e92143dc040fb
|
||||||
RNKeychain: 4f63aada75ebafd26f4bc2c670199461eab85d94
|
RNKeychain: 4f63aada75ebafd26f4bc2c670199461eab85d94
|
||||||
RNPermissions: dcdb7b99796bbeda6975a6e79ad519c41b251b1c
|
RNPermissions: de7b7c3fe1680d974ac7a85e3e97aa539c0e68ea
|
||||||
RNScreens: d6da2b9e29cf523832c2542f47bf1287318b1868
|
RNScreens: d6da2b9e29cf523832c2542f47bf1287318b1868
|
||||||
RNSecureRandom: 07efbdf2cd99efe13497433668e54acd7df49fef
|
RNSecureRandom: 0dcee021fdb3d50cd5cee5db0ebf583c42f5af0e
|
||||||
RNSVG: 551acb6562324b1d52a4e0758f7ca0ec234e278f
|
RNSVG: 551acb6562324b1d52a4e0758f7ca0ec234e278f
|
||||||
RNVectorIcons: 31cebfcf94e8cf8686eb5303ae0357da64d7a5a4
|
RNVectorIcons: 31cebfcf94e8cf8686eb5303ae0357da64d7a5a4
|
||||||
smartshare-react-native: 133dca4c48dea0908649c680701f0948317378c5
|
smartshare-react-native: 133dca4c48dea0908649c680701f0948317378c5
|
||||||
|
|||||||
@@ -132,30 +132,24 @@
|
|||||||
"confirmPasscode": "Confirm your passcode",
|
"confirmPasscode": "Confirm your passcode",
|
||||||
"enterPasscode": "Enter your passcode"
|
"enterPasscode": "Enter your passcode"
|
||||||
},
|
},
|
||||||
"ProfileLayout": {
|
"Credits": {
|
||||||
"profile": "Profile",
|
"header": "Credits and legal notices",
|
||||||
"creditsScreen": {
|
"back": "Back"
|
||||||
"title": "Credits and legal notices"
|
},
|
||||||
},
|
"ProfileScreen": {
|
||||||
"revokeScreen": {
|
|
||||||
"title": "Revoke VID",
|
|
||||||
"revokingVids": "You are about to revoke ({{count}}) VIDs.",
|
|
||||||
"revokingVidsAfter": "This means you will no longer be able to use or view any of the IDs linked to those VID(s). \nAre you sure you want to proceed?",
|
|
||||||
"empty": "Empty",
|
|
||||||
"revokeSuccessful": "VID successfully revoked"
|
|
||||||
},
|
|
||||||
"transactionHistoryScreen": {
|
|
||||||
"title": "Transaction History",
|
|
||||||
"showingRecords": "Showing last {{numRecords}} records",
|
|
||||||
"noRecords": "No records found",
|
|
||||||
"fetchingRecords": "Fetching records..."
|
|
||||||
},
|
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"vcLabel": "VC Label",
|
"vcLabel": "VC Label",
|
||||||
"language": "Language",
|
"language": "Language",
|
||||||
"bioUnlock": "Biometric unlock",
|
"bioUnlock": "Biometric unlock",
|
||||||
"authFactorUnlock": "Unlock auth factor",
|
"authFactorUnlock": "Unlock auth factor",
|
||||||
"logout": "Log-out"
|
"credits": "Credits and legal notices",
|
||||||
|
"logout": "Log-out",
|
||||||
|
"revokeLabel": "Revoke VID",
|
||||||
|
"revokeHeader": "REVOKE VID",
|
||||||
|
"revokingVids": "You are about to revoke ({{count}}) VIDs.",
|
||||||
|
"revokingVidsAfter": "This means you will no longer be able to use or view any of the IDs linked to those VID(s). \nAre you sure you want to proceed?",
|
||||||
|
"empty": "Empty",
|
||||||
|
"revokeSuccessful": "VID successfully revoked"
|
||||||
},
|
},
|
||||||
"ReceiveVcScreen": {
|
"ReceiveVcScreen": {
|
||||||
"header": "{{vcLabel}} details",
|
"header": "{{vcLabel}} details",
|
||||||
|
|||||||
@@ -100,4 +100,4 @@
|
|||||||
"react": "17.0.1",
|
"react": "17.0.1",
|
||||||
"react-native": "0.64.4"
|
"react-native": "0.64.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,11 @@ import {
|
|||||||
BottomTabNavigationOptions,
|
BottomTabNavigationOptions,
|
||||||
BottomTabScreenProps,
|
BottomTabScreenProps,
|
||||||
} from '@react-navigation/bottom-tabs';
|
} from '@react-navigation/bottom-tabs';
|
||||||
|
|
||||||
import { HomeScreen } from '../screens/Home/HomeScreen';
|
import { HomeScreen } from '../screens/Home/HomeScreen';
|
||||||
|
import { ProfileScreen } from '../screens/Profile/ProfileScreen';
|
||||||
import { RootStackParamList } from './index';
|
import { RootStackParamList } from './index';
|
||||||
import { RequestLayout } from '../screens/Request/RequestLayout';
|
import { RequestLayout } from '../screens/Request/RequestLayout';
|
||||||
import { ScanLayout } from '../screens/Scan/ScanLayout';
|
import { ScanLayout } from '../screens/Scan/ScanLayout';
|
||||||
import { ProfileLayout } from '../screens/Profile/ProfileLayout';
|
|
||||||
|
|
||||||
export const mainRoutes: TabScreen[] = [
|
export const mainRoutes: TabScreen[] = [
|
||||||
{
|
{
|
||||||
@@ -34,11 +33,8 @@ export const mainRoutes: TabScreen[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Profile',
|
name: 'Profile',
|
||||||
component: ProfileLayout,
|
component: ProfileScreen,
|
||||||
icon: 'person',
|
icon: 'person',
|
||||||
options: {
|
|
||||||
headerShown: false,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
4
screens/Profile/Credits.strings.json
Normal file
4
screens/Profile/Credits.strings.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"header": "Credits and legal notices",
|
||||||
|
"back": "Back"
|
||||||
|
}
|
||||||
101
screens/Profile/Credits.tsx
Normal file
101
screens/Profile/Credits.tsx
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import {
|
||||||
|
Dimensions,
|
||||||
|
Image,
|
||||||
|
SafeAreaView,
|
||||||
|
StyleSheet,
|
||||||
|
View,
|
||||||
|
} from 'react-native';
|
||||||
|
import { Divider, Icon, ListItem, Overlay } from 'react-native-elements';
|
||||||
|
import Markdown from 'react-native-simple-markdown';
|
||||||
|
import { Button, Text, Row } from '../../components/ui';
|
||||||
|
import { Colors } from '../../components/ui/styleUtils';
|
||||||
|
import creditsContent from '../../Credits.md';
|
||||||
|
|
||||||
|
export const Credits: React.FC<CreditsProps> = (props) => {
|
||||||
|
const { t } = useTranslation('Credits');
|
||||||
|
const [isViewing, setIsViewing] = useState(false);
|
||||||
|
const images = {
|
||||||
|
'docs/images/newlogic_logo.png': require('../../docs/images/newlogic_logo.png'),
|
||||||
|
'docs/images/id_pass_logo.png': require('../../docs/images/id_pass_logo.png'),
|
||||||
|
};
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
buttonContainer: {
|
||||||
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
|
right: 'auto',
|
||||||
|
},
|
||||||
|
view: {
|
||||||
|
flex: 1,
|
||||||
|
width: Dimensions.get('screen').width,
|
||||||
|
},
|
||||||
|
markdownView: {
|
||||||
|
padding: 20,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const markdownStyles = {
|
||||||
|
heading1: {
|
||||||
|
fontSize: 24,
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
maxWidth: 150,
|
||||||
|
margin: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
image: {
|
||||||
|
react: (node, output, state) => (
|
||||||
|
<View key={`image-${state.key}`}>
|
||||||
|
<Image
|
||||||
|
style={{ maxWidth: 150, height: 100 }}
|
||||||
|
source={images[node.target]}
|
||||||
|
resizeMode="contain"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ListItem bottomDivider onPress={() => setIsViewing(true)}>
|
||||||
|
<ListItem.Content>
|
||||||
|
<ListItem.Title>
|
||||||
|
<Text>{props.label}</Text>
|
||||||
|
</ListItem.Title>
|
||||||
|
</ListItem.Content>
|
||||||
|
<Overlay
|
||||||
|
overlayStyle={{ padding: 24 }}
|
||||||
|
isVisible={isViewing}
|
||||||
|
onBackdropPress={() => setIsViewing(false)}>
|
||||||
|
<SafeAreaView>
|
||||||
|
<View style={styles.view}>
|
||||||
|
<Row align="center" crossAlign="center" margin="0 0 10 0">
|
||||||
|
<View style={styles.buttonContainer}>
|
||||||
|
<Button
|
||||||
|
type="clear"
|
||||||
|
icon={<Icon name="chevron-left" color={Colors.Orange} />}
|
||||||
|
title=""
|
||||||
|
onPress={() => setIsViewing(false)}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Text size="small">{t('header')}</Text>
|
||||||
|
</Row>
|
||||||
|
<Divider />
|
||||||
|
<View style={styles.markdownView}>
|
||||||
|
<Markdown rules={rules} styles={markdownStyles}>
|
||||||
|
{creditsContent}
|
||||||
|
</Markdown>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</SafeAreaView>
|
||||||
|
</Overlay>
|
||||||
|
</ListItem>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
interface CreditsProps {
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { Image, View } from 'react-native';
|
|
||||||
|
|
||||||
import Markdown from 'react-native-simple-markdown';
|
|
||||||
import { Column } from '../../components/ui';
|
|
||||||
import { Colors } from '../../components/ui/styleUtils';
|
|
||||||
import creditsContent from '../../Credits.md';
|
|
||||||
|
|
||||||
export const CreditsScreen: React.FC<CreditsProps> = () => {
|
|
||||||
const images = {
|
|
||||||
'docs/images/newlogic_logo.png': require('../../docs/images/newlogic_logo.png'),
|
|
||||||
'docs/images/id_pass_logo.png': require('../../docs/images/id_pass_logo.png'),
|
|
||||||
};
|
|
||||||
|
|
||||||
const markdownStyles = {
|
|
||||||
text: {
|
|
||||||
color: Colors.Black,
|
|
||||||
fontFamily: 'Poppins_400Regular',
|
|
||||||
},
|
|
||||||
heading: {
|
|
||||||
fontFamily: 'Poppins_600SemiBold',
|
|
||||||
fontWeight: '600',
|
|
||||||
},
|
|
||||||
image: {
|
|
||||||
maxWidth: 150,
|
|
||||||
margin: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const rules = {
|
|
||||||
image: {
|
|
||||||
react: (node, output, state) => (
|
|
||||||
<View key={`image-${state.key}`}>
|
|
||||||
<Image
|
|
||||||
style={{ maxWidth: 150, height: 100 }}
|
|
||||||
source={images[node.target]}
|
|
||||||
resizeMode="contain"
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Column fill safe backgroundColor={Colors.White} padding="20">
|
|
||||||
<Markdown rules={rules} styles={markdownStyles}>
|
|
||||||
{creditsContent}
|
|
||||||
</Markdown>
|
|
||||||
</Column>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
interface CreditsProps {
|
|
||||||
label: string;
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"profile": "Profile",
|
|
||||||
"creditsScreen": {
|
|
||||||
"title": "Credits and legal notices"
|
|
||||||
},
|
|
||||||
"revokeScreen": {
|
|
||||||
"title": "Revoke VID",
|
|
||||||
"revokingVids": "You are about to revoke ({{count}}) VIDs.",
|
|
||||||
"revokingVidsAfter": "This means you will no longer be able to use or view any of the IDs linked to those VID(s). \nAre you sure you want to proceed?",
|
|
||||||
"empty": "Empty",
|
|
||||||
"revokeSuccessful": "VID successfully revoked"
|
|
||||||
},
|
|
||||||
"transactionHistoryScreen": {
|
|
||||||
"title": "Transaction History",
|
|
||||||
"showingRecords": "Showing last {{numRecords}} records",
|
|
||||||
"noRecords": "No records found",
|
|
||||||
"fetchingRecords": "Fetching records..."
|
|
||||||
},
|
|
||||||
"name": "Name",
|
|
||||||
"vcLabel": "VC Label",
|
|
||||||
"language": "Language",
|
|
||||||
"bioUnlock": "Biometric unlock",
|
|
||||||
"authFactorUnlock": "Unlock auth factor",
|
|
||||||
"logout": "Log-out"
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import {
|
|
||||||
createNativeStackNavigator,
|
|
||||||
NativeStackNavigationOptions,
|
|
||||||
NativeStackScreenProps,
|
|
||||||
} from '@react-navigation/native-stack';
|
|
||||||
import { ProfileScreen } from './ProfileScreen';
|
|
||||||
import { TransactionHistoryScreen } from './TransactionHistoryScreen';
|
|
||||||
import { NavigationProp } from '@react-navigation/native';
|
|
||||||
import { MainBottomTabParamList } from '../../routes/main';
|
|
||||||
import { CreditsScreen } from './CreditsScreen';
|
|
||||||
import { RevokeScreen } from './RevokeScreen';
|
|
||||||
import { Icon } from 'react-native-elements';
|
|
||||||
import { Colors } from '../../components/ui/styleUtils';
|
|
||||||
import { Row } from '../../components/ui';
|
|
||||||
import { LanguageSelector } from '../../components/LanguageSelector';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
const ProfileStack = createNativeStackNavigator();
|
|
||||||
|
|
||||||
export type ProfileStackParamList = {
|
|
||||||
RevokeScreen: undefined;
|
|
||||||
ProfileScreen: undefined;
|
|
||||||
TransactionHistoryScreen: undefined;
|
|
||||||
CreditsScreen: undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ScanLayoutNavigation = NavigationProp<
|
|
||||||
ProfileStackParamList & MainBottomTabParamList
|
|
||||||
>;
|
|
||||||
|
|
||||||
export const ProfileLayout: React.FC<
|
|
||||||
NativeStackScreenProps<MainBottomTabParamList, 'Profile'>
|
|
||||||
> = (props) => {
|
|
||||||
const { t } = useTranslation('ProfileLayout');
|
|
||||||
const options: NativeStackNavigationOptions = {
|
|
||||||
headerLeft: () => (
|
|
||||||
<Row margin={[0, 16, 0, 0]}>
|
|
||||||
<Icon
|
|
||||||
name="chevron-left"
|
|
||||||
color={Colors.Orange}
|
|
||||||
onPress={() => props.navigation.pop()}
|
|
||||||
/>
|
|
||||||
</Row>
|
|
||||||
),
|
|
||||||
headerRight: () => (
|
|
||||||
<LanguageSelector
|
|
||||||
triggerComponent={<Icon name="language" color={Colors.Orange} />}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
headerTitleAlign: 'center',
|
|
||||||
title: t('profile').toUpperCase(),
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ProfileStack.Navigator
|
|
||||||
initialRouteName="ProfileScreen"
|
|
||||||
screenOptions={options}>
|
|
||||||
<ProfileStack.Screen name="ProfileScreen" component={ProfileScreen} />
|
|
||||||
<ProfileStack.Screen
|
|
||||||
name="TransactionHistoryScreen"
|
|
||||||
component={TransactionHistoryScreen}
|
|
||||||
options={{
|
|
||||||
title: t('transactionHistoryScreen.title'),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<ProfileStack.Screen
|
|
||||||
name="RevokeScreen"
|
|
||||||
component={RevokeScreen}
|
|
||||||
options={{
|
|
||||||
title: t('revokeScreen.title'),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<ProfileStack.Screen
|
|
||||||
name="CreditsScreen"
|
|
||||||
component={CreditsScreen}
|
|
||||||
options={{
|
|
||||||
title: t('creditsScreen.title'),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ProfileStack.Navigator>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
15
screens/Profile/ProfileScreen.strings.json
Normal file
15
screens/Profile/ProfileScreen.strings.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "Name",
|
||||||
|
"vcLabel": "VC Label",
|
||||||
|
"language": "Language",
|
||||||
|
"bioUnlock": "Biometric unlock",
|
||||||
|
"authFactorUnlock": "Unlock auth factor",
|
||||||
|
"credits": "Credits and legal notices",
|
||||||
|
"logout": "Log-out",
|
||||||
|
"revokeLabel": "Revoke VID",
|
||||||
|
"revokeHeader": "REVOKE VID",
|
||||||
|
"revokingVids": "You are about to revoke ({{count}}) VIDs.",
|
||||||
|
"revokingVidsAfter": "This means you will no longer be able to use or view any of the IDs linked to those VID(s). \nAre you sure you want to proceed?",
|
||||||
|
"empty": "Empty",
|
||||||
|
"revokeSuccessful": "VID successfully revoked"
|
||||||
|
}
|
||||||
@@ -1,110 +1,21 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { View } from 'react-native';
|
||||||
|
import { getVersion } from 'react-native-device-info';
|
||||||
import { ListItem, Switch } from 'react-native-elements';
|
import { ListItem, Switch } from 'react-native-elements';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
import i18next, { SUPPORTED_LANGUAGES } from '../../i18n';
|
|
||||||
import { Column, Text } from '../../components/ui';
|
import { Column, Text } from '../../components/ui';
|
||||||
import { Colors } from '../../components/ui/styleUtils';
|
import { Colors } from '../../components/ui/styleUtils';
|
||||||
|
import { MainRouteProps } from '../../routes/main';
|
||||||
import { EditableListItem } from '../../components/EditableListItem';
|
import { EditableListItem } from '../../components/EditableListItem';
|
||||||
import { MessageOverlay } from '../../components/MessageOverlay';
|
import { MessageOverlay } from '../../components/MessageOverlay';
|
||||||
import {
|
import { Credits } from './Credits';
|
||||||
ProfileScreenProps,
|
import { Revoke } from './Revoke';
|
||||||
useProfileScreen,
|
import { useProfileScreen } from './ProfileScreenController';
|
||||||
} from './ProfileScreenController';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { LanguageSelector } from '../../components/LanguageSelector';
|
import { LanguageSelector } from '../../components/LanguageSelector';
|
||||||
|
import i18next, { SUPPORTED_LANGUAGES } from '../../i18n';
|
||||||
export const ProfileScreen: React.FC<ProfileScreenProps> = (props) => {
|
|
||||||
const { t } = useTranslation('ProfileLayout');
|
|
||||||
const controller = useProfileScreen(props);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<Column fill padding="24 0" backgroundColor={Colors.LightGrey}>
|
|
||||||
<EditableListItem
|
|
||||||
label={t('name')}
|
|
||||||
value={controller.name}
|
|
||||||
onEdit={controller.UPDATE_NAME}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<EditableListItem
|
|
||||||
label={t('vcLabel')}
|
|
||||||
value={controller.vcLabel.singular}
|
|
||||||
onEdit={controller.UPDATE_VC_LABEL}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<LanguageSetting />
|
|
||||||
|
|
||||||
<ListItem
|
|
||||||
bottomDivider
|
|
||||||
onPress={() => props.navigation.navigate('RevokeScreen')}>
|
|
||||||
<ListItem.Content>
|
|
||||||
<ListItem.Title>
|
|
||||||
<Text>{t('revokeScreen.title')}</Text>
|
|
||||||
</ListItem.Title>
|
|
||||||
</ListItem.Content>
|
|
||||||
</ListItem>
|
|
||||||
|
|
||||||
<ListItem bottomDivider disabled={!controller.canUseBiometrics}>
|
|
||||||
<ListItem.Content>
|
|
||||||
<ListItem.Title>
|
|
||||||
<Text>{t('bioUnlock')}</Text>
|
|
||||||
</ListItem.Title>
|
|
||||||
</ListItem.Content>
|
|
||||||
<Switch
|
|
||||||
value={controller.isBiometricUnlockEnabled}
|
|
||||||
onValueChange={controller.useBiometrics}
|
|
||||||
color={Colors.Orange}
|
|
||||||
/>
|
|
||||||
</ListItem>
|
|
||||||
|
|
||||||
<ListItem
|
|
||||||
bottomDivider
|
|
||||||
onPress={() => props.navigation.navigate('TransactionHistoryScreen')}>
|
|
||||||
<ListItem.Content>
|
|
||||||
<ListItem.Title>
|
|
||||||
<Text>{t('transactionHistoryScreen.title')}</Text>
|
|
||||||
</ListItem.Title>
|
|
||||||
</ListItem.Content>
|
|
||||||
</ListItem>
|
|
||||||
|
|
||||||
<ListItem bottomDivider disabled>
|
|
||||||
<ListItem.Content>
|
|
||||||
<ListItem.Title>
|
|
||||||
<Text color={Colors.Grey}>{t('authFactorUnlock')}</Text>
|
|
||||||
</ListItem.Title>
|
|
||||||
</ListItem.Content>
|
|
||||||
</ListItem>
|
|
||||||
|
|
||||||
<ListItem
|
|
||||||
bottomDivider
|
|
||||||
onPress={() => props.navigation.navigate('CreditsScreen')}>
|
|
||||||
<ListItem.Content>
|
|
||||||
<ListItem.Title>
|
|
||||||
<Text>{t('creditsScreen.title')}</Text>
|
|
||||||
</ListItem.Title>
|
|
||||||
</ListItem.Content>
|
|
||||||
</ListItem>
|
|
||||||
|
|
||||||
<ListItem bottomDivider onPress={controller.LOGOUT}>
|
|
||||||
<ListItem.Content>
|
|
||||||
<ListItem.Title>
|
|
||||||
<Text>{t('logout')}</Text>
|
|
||||||
</ListItem.Title>
|
|
||||||
</ListItem.Content>
|
|
||||||
</ListItem>
|
|
||||||
</Column>
|
|
||||||
|
|
||||||
<MessageOverlay
|
|
||||||
isVisible={controller.alertMsg != ''}
|
|
||||||
onBackdropPress={controller.hideAlert}
|
|
||||||
title={controller.alertMsg}
|
|
||||||
/>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const LanguageSetting: React.FC = () => {
|
const LanguageSetting: React.FC = () => {
|
||||||
const { t } = useTranslation('ProfileLayout');
|
const { t } = useTranslation('ProfileScreen');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LanguageSelector
|
<LanguageSelector
|
||||||
@@ -123,3 +34,83 @@ const LanguageSetting: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ProfileScreen: React.FC<MainRouteProps> = (props) => {
|
||||||
|
const { t } = useTranslation('ProfileScreen');
|
||||||
|
const controller = useProfileScreen(props);
|
||||||
|
return (
|
||||||
|
<Column fill padding="24 0" backgroundColor={Colors.LightGrey}>
|
||||||
|
<MessageOverlay
|
||||||
|
isVisible={controller.alertMsg != ''}
|
||||||
|
onBackdropPress={controller.hideAlert}
|
||||||
|
title={controller.alertMsg}
|
||||||
|
/>
|
||||||
|
<EditableListItem
|
||||||
|
label={t('name')}
|
||||||
|
value={controller.name}
|
||||||
|
onEdit={controller.UPDATE_NAME}
|
||||||
|
/>
|
||||||
|
<EditableListItem
|
||||||
|
label={t('vcLabel')}
|
||||||
|
value={controller.vcLabel.singular}
|
||||||
|
onEdit={controller.UPDATE_VC_LABEL}
|
||||||
|
/>
|
||||||
|
<LanguageSetting />
|
||||||
|
<Revoke label={t('revokeLabel')} />
|
||||||
|
<ListItem bottomDivider disabled={!controller.canUseBiometrics}>
|
||||||
|
<ListItem.Content>
|
||||||
|
<ListItem.Title>
|
||||||
|
<Text>{t('bioUnlock')}</Text>
|
||||||
|
</ListItem.Title>
|
||||||
|
</ListItem.Content>
|
||||||
|
<Switch
|
||||||
|
value={controller.isBiometricUnlockEnabled}
|
||||||
|
onValueChange={controller.useBiometrics}
|
||||||
|
color={Colors.Orange}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem bottomDivider disabled>
|
||||||
|
<ListItem.Content>
|
||||||
|
<ListItem.Title>
|
||||||
|
<Text color={Colors.Grey}>{t('authFactorUnlock')}</Text>
|
||||||
|
</ListItem.Title>
|
||||||
|
</ListItem.Content>
|
||||||
|
</ListItem>
|
||||||
|
<Credits label={t('credits')} />
|
||||||
|
<ListItem bottomDivider onPress={controller.LOGOUT}>
|
||||||
|
<ListItem.Content>
|
||||||
|
<ListItem.Title>
|
||||||
|
<Text>{t('logout')}</Text>
|
||||||
|
</ListItem.Title>
|
||||||
|
</ListItem.Content>
|
||||||
|
</ListItem>
|
||||||
|
<Text
|
||||||
|
weight="semibold"
|
||||||
|
margin="32 0 0 0"
|
||||||
|
align="center"
|
||||||
|
size="smaller"
|
||||||
|
color={Colors.Grey}>
|
||||||
|
Version: {getVersion()}
|
||||||
|
</Text>
|
||||||
|
{controller.backendInfo.application.name !== '' ? (
|
||||||
|
<View>
|
||||||
|
<Text
|
||||||
|
weight="semibold"
|
||||||
|
align="center"
|
||||||
|
size="smaller"
|
||||||
|
color={Colors.Grey}>
|
||||||
|
{controller.backendInfo.application.name}:{' '}
|
||||||
|
{controller.backendInfo.application.version}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
weight="semibold"
|
||||||
|
align="center"
|
||||||
|
size="smaller"
|
||||||
|
color={Colors.Grey}>
|
||||||
|
MOSIP: {controller.backendInfo.config['mosip.host']}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
) : null}
|
||||||
|
</Column>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import * as LocalAuthentication from 'expo-local-authentication';
|
|
||||||
import { useContext, useEffect, useState } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { useMachine, useSelector } from '@xstate/react';
|
import { useMachine, useSelector } from '@xstate/react';
|
||||||
|
import { useContext, useEffect, useState } from 'react';
|
||||||
|
import * as LocalAuthentication from 'expo-local-authentication';
|
||||||
|
import { selectBackendInfo } from '../../machines/app';
|
||||||
import {
|
import {
|
||||||
AuthEvents,
|
AuthEvents,
|
||||||
selectBiometrics,
|
selectBiometrics,
|
||||||
@@ -14,18 +13,18 @@ import {
|
|||||||
selectVcLabel,
|
selectVcLabel,
|
||||||
SettingsEvents,
|
SettingsEvents,
|
||||||
} from '../../machines/settings';
|
} from '../../machines/settings';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
biometricsMachine,
|
biometricsMachine,
|
||||||
selectError,
|
selectError,
|
||||||
selectIsSuccess,
|
selectIsSuccess,
|
||||||
selectUnenrolledNotice,
|
selectUnenrolledNotice,
|
||||||
} from '../../machines/biometrics';
|
} from '../../machines/biometrics';
|
||||||
|
import { MainRouteProps } from '../../routes/main';
|
||||||
import { GlobalContext } from '../../shared/GlobalContext';
|
import { GlobalContext } from '../../shared/GlobalContext';
|
||||||
import { NativeStackScreenProps } from '@react-navigation/native-stack';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ProfileStackParamList } from './ProfileLayout';
|
|
||||||
import { RootStackParamList } from '../../routes';
|
|
||||||
|
|
||||||
export function useProfileScreen({ navigation }: ProfileScreenProps) {
|
export function useProfileScreen({ navigation }: MainRouteProps) {
|
||||||
const { appService } = useContext(GlobalContext);
|
const { appService } = useContext(GlobalContext);
|
||||||
const authService = appService.children.get('auth');
|
const authService = appService.children.get('auth');
|
||||||
const settingsService = appService.children.get('settings');
|
const settingsService = appService.children.get('settings');
|
||||||
@@ -94,7 +93,7 @@ export function useProfileScreen({ navigation }: ProfileScreenProps) {
|
|||||||
return {
|
return {
|
||||||
alertMsg,
|
alertMsg,
|
||||||
hideAlert,
|
hideAlert,
|
||||||
|
backendInfo: useSelector(appService, selectBackendInfo),
|
||||||
name: useSelector(settingsService, selectName),
|
name: useSelector(settingsService, selectName),
|
||||||
vcLabel: useSelector(settingsService, selectVcLabel),
|
vcLabel: useSelector(settingsService, selectVcLabel),
|
||||||
isBiometricUnlockEnabled: useSelector(
|
isBiometricUnlockEnabled: useSelector(
|
||||||
@@ -119,8 +118,3 @@ export function useProfileScreen({ navigation }: ProfileScreenProps) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProfileScreenProps = NativeStackScreenProps<
|
|
||||||
ProfileStackParamList & RootStackParamList,
|
|
||||||
'ProfileScreen'
|
|
||||||
>;
|
|
||||||
|
|||||||
@@ -6,19 +6,18 @@ import {
|
|||||||
StyleSheet,
|
StyleSheet,
|
||||||
View,
|
View,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { Divider, Icon, ListItem, Overlay } from 'react-native-elements';
|
import { Divider, Icon, ListItem, Overlay } from 'react-native-elements';
|
||||||
|
|
||||||
import { Button, Column, Centered, Row, Text } from '../../components/ui';
|
import { Button, Column, Centered, Row, Text } from '../../components/ui';
|
||||||
import { VidItem } from '../../components/VidItem';
|
import { VidItem } from '../../components/VidItem';
|
||||||
import { Colors } from '../../components/ui/styleUtils';
|
import { Colors } from '../../components/ui/styleUtils';
|
||||||
import { ToastItem } from '../../components/ui/ToastItem';
|
import { ToastItem } from '../../components/ui/ToastItem';
|
||||||
import { OIDcAuthenticationOverlay } from '../../components/OIDcAuthModal';
|
import { OIDcAuthenticationOverlay } from '../../components/OIDcAuthModal';
|
||||||
import { useRevokeScreen } from './RevokeScreenController';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useRevoke } from './RevokeController';
|
||||||
|
|
||||||
export const RevokeScreen: React.FC = () => {
|
export const Revoke: React.FC<RevokeScreenProps> = (props) => {
|
||||||
const controller = useRevokeScreen();
|
const controller = useRevoke();
|
||||||
const { t } = useTranslation('ProfileLayout');
|
const { t } = useTranslation('ProfileScreen');
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
buttonContainer: {
|
buttonContainer: {
|
||||||
@@ -53,10 +52,9 @@ export const RevokeScreen: React.FC = () => {
|
|||||||
<ListItem bottomDivider onPress={() => controller.setAuthenticating(true)}>
|
<ListItem bottomDivider onPress={() => controller.setAuthenticating(true)}>
|
||||||
<ListItem.Content>
|
<ListItem.Content>
|
||||||
<ListItem.Title>
|
<ListItem.Title>
|
||||||
<Text>{t('revokeLabel')}</Text>
|
<Text>{props.label}</Text>
|
||||||
</ListItem.Title>
|
</ListItem.Title>
|
||||||
</ListItem.Content>
|
</ListItem.Content>
|
||||||
|
|
||||||
<Overlay
|
<Overlay
|
||||||
overlayStyle={{ padding: 0 }}
|
overlayStyle={{ padding: 0 }}
|
||||||
isVisible={controller.isViewing}
|
isVisible={controller.isViewing}
|
||||||
@@ -185,3 +183,7 @@ export const RevokeScreen: React.FC = () => {
|
|||||||
</ListItem>
|
</ListItem>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface RevokeScreenProps {
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ import {
|
|||||||
|
|
||||||
import { ActorRefFrom } from 'xstate';
|
import { ActorRefFrom } from 'xstate';
|
||||||
|
|
||||||
export function useRevokeScreen() {
|
export function useRevoke() {
|
||||||
const { t } = useTranslation('ProfileScreen');
|
const { t } = useTranslation('ProfileScreen');
|
||||||
const { appService } = useContext(GlobalContext);
|
const { appService } = useContext(GlobalContext);
|
||||||
const vcService = appService.children.get('vc');
|
const vcService = appService.children.get('vc');
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { FlatList, RefreshControl } from 'react-native';
|
|
||||||
import { Icon, Overlay } from 'react-native-elements';
|
|
||||||
import { TransactionHistoryItem } from '../../components/TransactionHistoryItem';
|
|
||||||
|
|
||||||
import { Column, Row, Text } from '../../components/ui';
|
|
||||||
import { Colors } from '../../components/ui/styleUtils';
|
|
||||||
import { useTransactionHistoryScreen } from './TransactionHistoryScreenController';
|
|
||||||
|
|
||||||
export const TransactionHistoryScreen: React.FC = () => {
|
|
||||||
const controller = useTransactionHistoryScreen();
|
|
||||||
|
|
||||||
const numRecords = controller.transactionHistory.length;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<Column backgroundColor={Colors.Grey6} fill>
|
|
||||||
<Row margin="16">
|
|
||||||
<Column fill align="center">
|
|
||||||
<StatusText
|
|
||||||
isLoading={controller.isLoading}
|
|
||||||
numRecords={numRecords}
|
|
||||||
/>
|
|
||||||
</Column>
|
|
||||||
<Column>
|
|
||||||
<Icon
|
|
||||||
name="filter"
|
|
||||||
color={numRecords > 0 ? Colors.Orange : Colors.Grey}
|
|
||||||
onPress={() => numRecords > 0 && controller.SHOW_FILTERS()}
|
|
||||||
/>
|
|
||||||
</Column>
|
|
||||||
</Row>
|
|
||||||
<Column fill>
|
|
||||||
<FlatList
|
|
||||||
data={controller.transactionHistory}
|
|
||||||
keyExtractor={(item) => item.eventId}
|
|
||||||
renderItem={({ item }) => <TransactionHistoryItem data={item} />}
|
|
||||||
refreshControl={
|
|
||||||
<RefreshControl
|
|
||||||
refreshing={controller.isLoading}
|
|
||||||
onRefresh={controller.REFRESH}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Column>
|
|
||||||
</Column>
|
|
||||||
<Overlay
|
|
||||||
isVisible={controller.isShowingFilters}
|
|
||||||
onBackdropPress={controller.CANCEL}>
|
|
||||||
<Text>TODO: Filters Modal</Text>
|
|
||||||
{/* FILTERS */}
|
|
||||||
</Overlay>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const StatusText: React.FC<{ isLoading: boolean; numRecords: number }> = (
|
|
||||||
props
|
|
||||||
) => {
|
|
||||||
const { t } = useTranslation('ProfileLayout');
|
|
||||||
const { isLoading, numRecords } = props;
|
|
||||||
|
|
||||||
return isLoading ? (
|
|
||||||
<Text color={Colors.Grey} size="small">
|
|
||||||
{t('transactionHistoryScreen.fetchingRecords')}
|
|
||||||
</Text>
|
|
||||||
) : (
|
|
||||||
<Text color={Colors.Grey} size="small">
|
|
||||||
{numRecords > 0
|
|
||||||
? t('transactionHistoryScreen.showingRecords', {
|
|
||||||
numRecords,
|
|
||||||
})
|
|
||||||
: t('transactionHistoryScreen.noRecords')}
|
|
||||||
</Text>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
import { useInterpret, useSelector } from '@xstate/react';
|
|
||||||
import { useRef } from 'react';
|
|
||||||
import { assign, StateFrom } from 'xstate';
|
|
||||||
import { createModel } from 'xstate/lib/model';
|
|
||||||
import { request } from '../../shared/request';
|
|
||||||
|
|
||||||
export function useTransactionHistoryScreen() {
|
|
||||||
const machine = useRef(TransactionHistoryScreenMachine);
|
|
||||||
const service = useInterpret(machine.current, { devTools: __DEV__ });
|
|
||||||
|
|
||||||
return {
|
|
||||||
transactionHistory: useSelector(service, selectTransactionHistory),
|
|
||||||
|
|
||||||
isLoading: useSelector(service, selectIsLoading),
|
|
||||||
isShowingFilters: useSelector(service, selectIsShowingFilters),
|
|
||||||
|
|
||||||
REFRESH: () => service.send(TransactionHistoryScreenEvents.REFRESH()),
|
|
||||||
CANCEL: () => service.send(TransactionHistoryScreenEvents.CANCEL()),
|
|
||||||
SHOW_FILTERS: () =>
|
|
||||||
service.send(TransactionHistoryScreenEvents.SHOW_FILTERS()),
|
|
||||||
APPLY_FILTERS: (filters: TransactionHistoryFilters) =>
|
|
||||||
service.send(TransactionHistoryScreenEvents.APPLY_FILTERS(filters)),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const model = createModel(
|
|
||||||
{
|
|
||||||
items: [] as MOSIPServiceHistoryItem[],
|
|
||||||
error: '',
|
|
||||||
filters: {
|
|
||||||
pageStart: 0,
|
|
||||||
pageFetch: 50,
|
|
||||||
searchText: '',
|
|
||||||
sortType: 'DESC',
|
|
||||||
} as TransactionHistoryFilters,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
events: {
|
|
||||||
REFRESH: () => ({}),
|
|
||||||
CANCEL: () => ({}),
|
|
||||||
SHOW_FILTERS: () => ({}),
|
|
||||||
APPLY_FILTERS: (filters: TransactionHistoryFilters) => ({ filters }),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const TransactionHistoryScreenEvents = model.events;
|
|
||||||
|
|
||||||
export const TransactionHistoryScreenMachine = model.createMachine(
|
|
||||||
{
|
|
||||||
tsTypes:
|
|
||||||
{} as import('./TransactionHistoryScreenController.typegen').Typegen0,
|
|
||||||
id: 'TransactionHistoryScreen',
|
|
||||||
context: model.initialContext,
|
|
||||||
schema: {
|
|
||||||
services: {} as {
|
|
||||||
loadTransactionHistory: {
|
|
||||||
data: MOSIPServiceHistoryItem[];
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
initial: 'loading',
|
|
||||||
states: {
|
|
||||||
loading: {
|
|
||||||
invoke: {
|
|
||||||
src: 'loadTransactionHistory',
|
|
||||||
onDone: {
|
|
||||||
target: 'idle',
|
|
||||||
actions: 'setItems',
|
|
||||||
},
|
|
||||||
onError: {
|
|
||||||
target: 'idle',
|
|
||||||
actions: 'setError',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
idle: {
|
|
||||||
on: {
|
|
||||||
REFRESH: {
|
|
||||||
target: 'loading',
|
|
||||||
},
|
|
||||||
SHOW_FILTERS: {
|
|
||||||
target: 'showingFilters',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
showingFilters: {
|
|
||||||
on: {
|
|
||||||
CANCEL: {
|
|
||||||
target: 'idle',
|
|
||||||
},
|
|
||||||
APPLY_FILTERS: {
|
|
||||||
actions: 'setFilters',
|
|
||||||
target: 'idle',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
actions: {
|
|
||||||
setItems: assign({
|
|
||||||
items: (_context, event) => event.data,
|
|
||||||
}),
|
|
||||||
|
|
||||||
setError: assign({
|
|
||||||
error: (_context, event) => (event.data as Error).message,
|
|
||||||
}),
|
|
||||||
|
|
||||||
setFilters: assign({
|
|
||||||
filters: (_context, event) => event.filters,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
|
|
||||||
services: {
|
|
||||||
loadTransactionHistory: (context) => async () => {
|
|
||||||
const langCode = 'en-US';
|
|
||||||
console.log('a');
|
|
||||||
const query = toQueryParams(context.filters);
|
|
||||||
console.log('b', query);
|
|
||||||
|
|
||||||
const response = await request(
|
|
||||||
'GET',
|
|
||||||
`/req/service-history/${langCode}?${query}`
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log('c', response);
|
|
||||||
|
|
||||||
return response.response.data;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
type State = StateFrom<typeof TransactionHistoryScreenMachine>;
|
|
||||||
|
|
||||||
function selectTransactionHistory(state: State) {
|
|
||||||
return state.context.items;
|
|
||||||
}
|
|
||||||
|
|
||||||
function selectIsLoading(state: State) {
|
|
||||||
return state.matches('loading');
|
|
||||||
}
|
|
||||||
|
|
||||||
function selectIsShowingFilters(state: State) {
|
|
||||||
return state.matches('showingFilters');
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MOSIPServiceHistoryItem {
|
|
||||||
eventId: string;
|
|
||||||
description: string;
|
|
||||||
eventStatus: MOSIPServiceHistoryItemEventStatus;
|
|
||||||
timeStamp: string; // JSON Date
|
|
||||||
requestType: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum MOSIPServiceHistoryItemEventStatus {
|
|
||||||
Success = 'Success',
|
|
||||||
Failed = 'Failed',
|
|
||||||
InProgress = 'In-Progress',
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum MOSIPServiceHistoryItemType {
|
|
||||||
All = 'ALL',
|
|
||||||
AuthenticationRequest = 'AUTHENTICATION_REQUEST',
|
|
||||||
ServiceRequest = 'SERVICE_REQUEST',
|
|
||||||
DataUpdateRequest = 'DATA_UPDATE_REQUEST',
|
|
||||||
IdManagementRequest = 'ID_MANAGEMENT_REQUEST',
|
|
||||||
DataShareRequest = 'DATA_SHARE_REQUEST',
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TransactionHistoryFilters {
|
|
||||||
fromDateTime?: string;
|
|
||||||
toDateTime?: string;
|
|
||||||
pageFetch?: number;
|
|
||||||
pageStart?: number;
|
|
||||||
searchText?: string;
|
|
||||||
serviceType?: MOSIPServiceHistoryItemType;
|
|
||||||
sortType?: 'ASC' | 'DESC';
|
|
||||||
[key: string]: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toQueryParams(queryObj: Record<string, unknown>) {
|
|
||||||
return Object.entries(queryObj)
|
|
||||||
.map(([key, value]) => `${key}=${value}`)
|
|
||||||
.join('&');
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
// This file was automatically generated. Edits will be overwritten
|
|
||||||
|
|
||||||
export interface Typegen0 {
|
|
||||||
'@@xstate/typegen': true;
|
|
||||||
'internalEvents': {
|
|
||||||
'done.invoke.TransactionHistoryScreen.loading:invocation[0]': {
|
|
||||||
type: 'done.invoke.TransactionHistoryScreen.loading:invocation[0]';
|
|
||||||
data: unknown;
|
|
||||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
|
||||||
};
|
|
||||||
'error.platform.TransactionHistoryScreen.loading:invocation[0]': {
|
|
||||||
type: 'error.platform.TransactionHistoryScreen.loading:invocation[0]';
|
|
||||||
data: unknown;
|
|
||||||
};
|
|
||||||
'xstate.init': { type: 'xstate.init' };
|
|
||||||
};
|
|
||||||
'invokeSrcNameMap': {
|
|
||||||
loadTransactionHistory: 'done.invoke.TransactionHistoryScreen.loading:invocation[0]';
|
|
||||||
};
|
|
||||||
'missingImplementations': {
|
|
||||||
actions: never;
|
|
||||||
services: never;
|
|
||||||
guards: never;
|
|
||||||
delays: never;
|
|
||||||
};
|
|
||||||
'eventsCausingActions': {
|
|
||||||
setError: 'error.platform.TransactionHistoryScreen.loading:invocation[0]';
|
|
||||||
setFilters: 'APPLY_FILTERS';
|
|
||||||
setItems: 'done.invoke.TransactionHistoryScreen.loading:invocation[0]';
|
|
||||||
};
|
|
||||||
'eventsCausingServices': {
|
|
||||||
loadTransactionHistory: 'REFRESH' | 'xstate.init';
|
|
||||||
};
|
|
||||||
'eventsCausingGuards': {};
|
|
||||||
'eventsCausingDelays': {};
|
|
||||||
'matchesStates': 'idle' | 'loading' | 'showingFilters';
|
|
||||||
'tags': never;
|
|
||||||
}
|
|
||||||
4
types/globals/index.d.ts
vendored
4
types/globals/index.d.ts
vendored
@@ -1,4 +0,0 @@
|
|||||||
declare module '*.md' {
|
|
||||||
const content: string;
|
|
||||||
export default content;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user