@jescon-technologies/react-native-ui-kit 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/index.js +70 -0
  2. package/package.json +25 -3
  3. package/src/Alerts/AAlert.js +1 -1
  4. package/src/HOC/ConfirmOverlay.js +192 -0
  5. package/src/HOC/HAbsolute.js +56 -0
  6. package/src/HOC/HDiscontinue.js +105 -0
  7. package/src/HOC/HHeading.js +70 -0
  8. package/src/HOC/HMoreButton.js +88 -0
  9. package/src/HOC/HNatureHeading.js +402 -0
  10. package/src/HOC/HOCIcons.js +80 -0
  11. package/src/HOC/HOverlay.js +99 -0
  12. package/src/HOC/HOverlayCentered.js +140 -0
  13. package/src/HOC/HShadowButton.js +45 -0
  14. package/src/HOC/HShadowCountButton.js +82 -0
  15. package/src/HOC/OptionOverlay.js +48 -0
  16. package/src/Media/AudioScreen.js +347 -0
  17. package/src/Media/BarcodeScan.js +145 -0
  18. package/src/Media/CAudioPlay.js +228 -0
  19. package/src/Media/CCaptureImageWithoutEdit.js +330 -0
  20. package/src/Media/CImageGallery.js +289 -0
  21. package/src/Media/CImageZoom.js +82 -0
  22. package/src/Media/CSingleImage.js +391 -0
  23. package/src/Media/CSketchCanvas.js +76 -0
  24. package/src/Media/CVideoPlay.js +31 -0
  25. package/src/Media/DocumentScreen.js +367 -0
  26. package/src/Media/DrawingScreen.js +582 -0
  27. package/src/Media/ImageScreen.js +313 -0
  28. package/src/Media/RecordAudio.js +250 -0
  29. package/src/Media/RecordVideo.js +223 -0
  30. package/src/Media/VideoScreen.js +383 -0
  31. package/src/StaticComponents/SAlphabet.js +47 -0
  32. package/src/StaticComponents/SCheckBox.js +42 -0
  33. package/src/StaticComponents/SDatePicker.js +208 -0
  34. package/src/StaticComponents/SDatePickerLabel.js +253 -0
  35. package/src/StaticComponents/SDatePickerNew.js +258 -0
  36. package/src/StaticComponents/SDateTimePickerNew.js +381 -0
  37. package/src/StaticComponents/SDropDownGenerate.js +450 -0
  38. package/src/StaticComponents/SDropDownHoc.js +636 -0
  39. package/src/StaticComponents/SDropDownIcon.js +500 -0
  40. package/src/StaticComponents/SMenuBox.js +131 -0
  41. package/src/StaticComponents/SOverlay.js +177 -0
  42. package/src/StaticComponents/SOverlayTextInput.js +109 -0
  43. package/src/StaticComponents/SSearch.js +438 -0
  44. package/src/StaticComponents/SSearchBar.js +53 -0
  45. package/src/StaticComponents/SSpeedDial.js +303 -0
  46. package/src/StaticComponents/STextInput.js +289 -0
  47. package/src/StaticComponents/STextInputProps.js +36 -0
  48. package/src/StaticComponents/STimePicker.js +171 -0
  49. package/src/StaticComponents/STimingDropDownNew.js +1589 -0
  50. package/src/StaticComponents/STimingSwitch.js +34 -0
  51. package/src/layout/CContainerView.js +21 -0
  52. package/src/layout/CDetailView.js +81 -0
  53. package/src/layout/FooterBlock.js +0 -3
  54. package/src/layout/HeaderBlock.js +353 -0
  55. package/src/index.js +0 -15
  56. package/src/screens/ForgotPassword.js +0 -346
  57. package/src/screens/Login.js +0 -328
  58. package/src/screens/Splash.js +0 -788
  59. /package/src/{components → layout}/Loader.js +0 -0
@@ -0,0 +1,313 @@
1
+ import React, { useContext, useEffect, useState } from 'react';
2
+ import {
3
+ StyleSheet,
4
+ FlatList,
5
+ Dimensions,
6
+ Text,
7
+ View,
8
+ TouchableOpacity,
9
+ ActivityIndicator,
10
+ PermissionsAndroid,
11
+ RefreshControl,
12
+ Platform,
13
+ Image,
14
+ } from 'react-native';
15
+ import Fontisto from 'react-native-vector-icons/Fontisto';
16
+ import CImageZoom from '../Media/CImageZoom';
17
+ import AntDesign from 'react-native-vector-icons/AntDesign';
18
+ import { APIURL, imageURLHIS } from '../Common/apiConstants';
19
+ import DocumentPicker from 'react-native-document-picker';
20
+ import { normalize } from '../CommonStyle/componentStyle';
21
+ import { useNavigation } from '../Navigation/useNavigation';
22
+
23
+ import { notifyMessage } from '../CommonStyle/ComponentFunctions';
24
+ import PhotoEditor from 'react-native-photo-editor';
25
+ import ReactNativeBlobUtil from 'react-native-blob-util';
26
+ import { Global } from '../Common/Global';
27
+ import NetworkServiceCall from '../Common/NetworkServiceCall';
28
+ import SSpeedDial from '../StaticComponents/SSpeedDial';
29
+ import EmrResponseComponentContext from '../Handlers/emrResponseComponentContext';
30
+
31
+ /*---------------------------------------------------------------------------------------*/
32
+ function ImageScreen(props) {
33
+ const { responseJSON, setResponseJSON } = useContext(EmrResponseComponentContext);
34
+ const navigation = useNavigation();
35
+ const windowWidth = Dimensions.get('window').width;
36
+ const windowHeight = Dimensions.get('window').height;
37
+
38
+ const [data, setData] = useState(props.data?.savedimages || []);
39
+ const [isImageShow, setImageShow] = useState(false);
40
+ const [mediaUrlLink, setMediaUrlLink] = useState(false);
41
+ const [refreshCount, setrefreshCount] = useState(1);
42
+ const [pulltorefresh, setPullToRefresh] = useState(false);
43
+ const [deleteImage, setDeleteImage] = useState(false);
44
+ const [loading, setLoading] = useState(false);
45
+
46
+ useEffect(() => {
47
+ props.setData(data);
48
+ }, [data]);
49
+
50
+ /*---------------------------------------------------------------------------------------*/
51
+ function deleteSelectedImage() {
52
+ const updated = data.filter(item => !item.deletestatus);
53
+ setData(updated);
54
+ props.editStatus(1);
55
+ setDeleteImage(false);
56
+ setrefreshCount(refreshCount + 1);
57
+ }
58
+
59
+ function changeStatus(renderdata) {
60
+ renderdata.item.deletestatus = !renderdata.item.deletestatus;
61
+ setrefreshCount(refreshCount + 1);
62
+ }
63
+
64
+ function renderImage(renderdata) {
65
+ const image = imageURLHIS + renderdata.item;
66
+
67
+ return (
68
+ <View>
69
+ <TouchableOpacity
70
+ style={styles.imageBox(windowHeight, windowWidth)}
71
+ onPress={() =>
72
+ navigation.navigate('CImageGallery', {
73
+ savedimages: data,
74
+ index: renderdata.index,
75
+ })
76
+ }
77
+ onLongPress={() => setDeleteImage(true)}
78
+ >
79
+ <Image
80
+ style={styles.fastImage}
81
+ source={{
82
+ uri:
83
+ renderdata.item && renderdata.item !== null
84
+ ? image
85
+ : 'https://icon-library.com/images/no-image-icon/no-image-icon-0.jpg',
86
+ headers: { Authorization: `Bearer ${Global.JWTToken}` },
87
+ priority: FastImage.priority.high,
88
+ cache: FastImage.cacheControl.web,
89
+ }}
90
+ />
91
+ </TouchableOpacity>
92
+
93
+ {isImageShow && (
94
+ <CImageZoom
95
+ image={mediaUrlLink}
96
+ navigation={navigation}
97
+ visibility={val => (val ? setImageShow(val) : null)}
98
+ mediaupload={Media_Upload}
99
+ />
100
+ )}
101
+
102
+ {deleteImage && (
103
+ <TouchableOpacity onPress={() => changeStatus(renderdata)}>
104
+ <View style={styles.checkboxContainer}>
105
+ <Fontisto
106
+ name={!renderdata.item.deletestatus ? 'checkbox-passive' : 'checkbox-active'}
107
+ size={25}
108
+ color={!renderdata.item.deletestatus ? 'lightgrey' : 'blue'}
109
+ />
110
+ </View>
111
+ </TouchableOpacity>
112
+ )}
113
+ </View>
114
+ );
115
+ }
116
+
117
+ /*---------------------------------------------------------------------------------------*/
118
+ const getResolvedPath = async (uri, filen) => {
119
+ const fileBase64 = await ReactNativeBlobUtil.fs.readFile(uri, 'base64');
120
+ const relativePath = ReactNativeBlobUtil.fs.dirs.CacheDir;
121
+ const path = `${relativePath}/${filen}`;
122
+ await ReactNativeBlobUtil.fs.writeFile(path, fileBase64, 'base64');
123
+ return { relativePath, fileName: filen, path };
124
+ };
125
+
126
+ /*---------------------------------------------------------------------------------------*/
127
+ const firebasebrowse = async () => {
128
+ try {
129
+ const fileDetails = await DocumentPicker.pick({
130
+ type: [DocumentPicker.types.images],
131
+ });
132
+
133
+ const picked = fileDetails[0];
134
+ const extension = picked.name.split('.').pop().toLowerCase();
135
+ const mimeType =
136
+ picked.type ||
137
+ (extension === 'png' ? 'image/png' : 'image/jpeg');
138
+
139
+ const { path } = await getResolvedPath(picked.uri, picked.name);
140
+
141
+ const dataset = {
142
+ fileid: data.length + 1,
143
+ uri: 'file://' + path,
144
+ filename: picked.name,
145
+ filetype: mimeType,
146
+ uritype: false,
147
+ };
148
+
149
+ PhotoEditor.Edit({
150
+ path: path,
151
+ hiddenControls: ['sticker', 'save'],
152
+ onDone: () => Media_Upload(dataset),
153
+ });
154
+ } catch (error) {
155
+ notifyMessage(
156
+ DocumentPicker.isCancel(error) ? 'Canceled' : 'Unknown Error: ' + JSON.stringify(error),
157
+ 2
158
+ );
159
+ }
160
+ };
161
+
162
+ /*---------------------------------------------------------------------------------------*/
163
+ async function Media_Upload(image) {
164
+ setLoading(true);
165
+
166
+ const dataset2 = {
167
+ fileid: data.length + 1,
168
+ filename: image.filename,
169
+ filetype: image.filetype,
170
+ uri: image.uri,
171
+ uritype: false,
172
+ };
173
+
174
+ if (!dataset2.uritype && dataset2.uri) {
175
+ const formData = new FormData();
176
+ formData.append('file', {
177
+ uri: dataset2.uri,
178
+ type: dataset2.filetype,
179
+ name: dataset2.filename,
180
+ });
181
+
182
+ try {
183
+ const responsedata = await NetworkServiceCall(
184
+ 'multiform',
185
+ APIURL + 'invfile/fileupload/emr/image',
186
+ formData
187
+ );
188
+
189
+ if (responsedata.httpstatus === 200) {
190
+ dataset2.filename = responsedata.data.fileuri;
191
+
192
+ setData(prev => [...prev, dataset2.filename]);
193
+ responseJSON.consultationEdit.editStatus = true;
194
+
195
+ props.editStatus(1);
196
+ props.data.usertype =
197
+ Global.PatientDetails?.usertype ?? 'Z';
198
+ props.data.suuser = Global.userData?.suuser ?? 0;
199
+ }
200
+ } catch (error) {
201
+ console.log('Upload error:', error);
202
+ } finally {
203
+ setLoading(false);
204
+ }
205
+ }
206
+ }
207
+
208
+ /*---------------------------------------------------------------------------------------*/
209
+ function CaptureImageWithoutEdit() {
210
+ navigation.navigate('CCaptureImageWithoutEdit', { onSelect: Media_Upload });
211
+ }
212
+
213
+ /*---------------------------------------------------------------------------------------*/
214
+ return (
215
+ <View style={{ flex: 1 }}>
216
+ <View style={styles.itemContainer}>
217
+ {deleteImage && (
218
+ <TouchableOpacity
219
+ style={{ alignItems: 'center', padding: 10 }}
220
+ onPress={deleteSelectedImage}
221
+ >
222
+ <AntDesign name="delete" size={30} color={'red'} />
223
+ </TouchableOpacity>
224
+ )}
225
+
226
+ <FlatList
227
+ data={data}
228
+ contentContainerStyle={{ alignItems: 'center', marginTop: 10 }}
229
+ renderItem={renderImage}
230
+ keyExtractor={(item, index) => index.toString()}
231
+ numColumns={3}
232
+ removeClippedSubviews={true}
233
+ initialNumToRender={50}
234
+ maxToRenderPerBatch={10}
235
+ refreshControl={
236
+ <RefreshControl
237
+ refreshing={pulltorefresh}
238
+ size={'large'}
239
+ tintColor={'blue'}
240
+ colors={['red', 'green', 'cyan', 'black']}
241
+ progressBackgroundColor={'white'}
242
+ onRefresh={() => setrefreshCount(refreshCount + 1)}
243
+ />
244
+ }
245
+ />
246
+
247
+ <View style={{ alignSelf: 'center' }}>
248
+ <Text style={{ fontSize: normalize(16) }}>
249
+ {data?.length > 0 ? `${data.length} IMAGE(S)` : null}
250
+ </Text>
251
+ </View>
252
+
253
+ {loading && (
254
+ <View style={styles.loadingBox}>
255
+ <ActivityIndicator size="large" color="#0000ff" />
256
+ </View>
257
+ )}
258
+
259
+ <SSpeedDial
260
+ buttons={[
261
+ { functionid: 1, color: 'darkblue', iconname: 'add', title: 'Browse' },
262
+ { functionid: 2, color: 'darkblue', iconname: 'camera', title: 'Capture & edit' },
263
+ ]}
264
+ callBack={val => (val ? getFunctions(val) : null)}
265
+ />
266
+ </View>
267
+ </View>
268
+ );
269
+
270
+ /*---------------------------------------------------------------------------------------*/
271
+ function getFunctions(key) {
272
+ switch (key) {
273
+ case 1:
274
+ firebasebrowse();
275
+ break;
276
+ case 2:
277
+ CaptureImageWithoutEdit();
278
+ break;
279
+ }
280
+ }
281
+ }
282
+
283
+ /*---------------------------------------------------------------------------------------*/
284
+ const styles = StyleSheet.create({
285
+ itemContainer: {
286
+ flex: 1,
287
+ backgroundColor: 'transparent',
288
+ },
289
+ imageBox: (windowHeight, windowWidth) => ({
290
+ height: windowHeight * 0.15,
291
+ width: windowWidth * 0.3,
292
+ margin: 5,
293
+ backgroundColor: '#e1e4e8',
294
+ borderRadius: 5,
295
+ }),
296
+ fastImage: {
297
+ width: '100%',
298
+ height: '100%',
299
+ borderRadius: normalize(10),
300
+ },
301
+ checkboxContainer: {
302
+ justifyContent: 'center',
303
+ alignItems: 'center',
304
+ },
305
+ loadingBox: {
306
+ flex: 1,
307
+ backgroundColor: '#fff',
308
+ alignItems: 'center',
309
+ padding: 10,
310
+ },
311
+ });
312
+ /*---------------------------------------------------------------------------------------*/
313
+ export default ImageScreen;
@@ -0,0 +1,250 @@
1
+
2
+ import React from 'react';
3
+ import {
4
+ AppRegistry,
5
+ StyleSheet,
6
+ Text,
7
+ TouchableOpacity,
8
+ View,
9
+ ActivityIndicator,
10
+ Dimensions,
11
+ KeyboardAvoidingView,
12
+ TouchableHighlight,
13
+ Image, Platform, PermissionsAndroid,
14
+ } from 'react-native';
15
+ // import AudioRecorderPlayer from 'react-native-audio-recorder-player';
16
+ import Ionicons from 'react-native-vector-icons/Ionicons';
17
+ import { AudioRecorder, AudioUtils } from 'react-native-audio';
18
+ import { Stopwatch, Timer } from 'react-native-stopwatch-timer';
19
+ import FontAwesome from 'react-native-vector-icons/FontAwesome';
20
+ // const audioRecorderPlayer = new AudioRecorderPlayer();
21
+ export default class RecordAudio extends React.Component {
22
+ constructor(props) {
23
+ super(props);
24
+ this.state = {
25
+ recordSecs: null,
26
+ recordTime: null,
27
+ currentPositionSec: null,
28
+ currentDurationSec: null,
29
+ playTime: null,
30
+ duration: null,//startAudio: false,playAudio:false,
31
+
32
+ messages: [],
33
+ startAudio: false,
34
+ hasPermission: false,
35
+ audioPath: `${
36
+ AudioUtils.DocumentDirectoryPath
37
+ }/${this.messageIdGenerator()}test.aac`,
38
+ playAudio: false,
39
+ fetchChats: false,
40
+ audioFile: '',
41
+ AudFileName: null,
42
+ audioSettings: {
43
+ SampleRate: 22050,
44
+ Channels: 1,
45
+ AudioQuality: 'Low',
46
+ AudioEncoding: 'aac',
47
+ MeteringEnabled: true,
48
+ IncludeBase64: true,
49
+ AudioEncodingBitRate: 32000,
50
+ },
51
+
52
+ stopwatchStart: false,
53
+ stopwatchReset: false,
54
+ };
55
+ this.toggleStopwatch = this.toggleStopwatch.bind(this);
56
+ this.resetStopwatch = this.resetStopwatch.bind(this);
57
+ }
58
+ componentWillMount() {
59
+
60
+ }
61
+ componentDidMount() {
62
+ this.checkPermission().then(async hasPermission => {
63
+ this.setState({ hasPermission });
64
+ if (!hasPermission) {return;}
65
+ await AudioRecorder.prepareRecordingAtPath(
66
+ this.state.audioPath,
67
+ this.state.audioSettings
68
+ );
69
+ AudioRecorder.onProgress = data => {
70
+
71
+ };
72
+ AudioRecorder.onFinished = data => {
73
+ let fileName = data.audioFileURL.substr(data.audioFileURL.lastIndexOf('/') + 1);
74
+ this.props.navigation.goBack();
75
+ this.props.route.params.onSelect({
76
+ // uri: data.audioFileURL,
77
+ uri: data.audioFileURL,
78
+ filename: fileName,
79
+ type: 'audio/mpeg',
80
+ });
81
+ };
82
+ });
83
+ }
84
+ componentWillUnmount() {
85
+ this.setState({
86
+ messages: [],
87
+ });
88
+ }
89
+ checkPermission() {
90
+ if (Platform.OS !== 'android') {
91
+ return Promise.resolve(true);
92
+ }
93
+ const rationale = {
94
+ title: 'Microphone Permission',
95
+ message:
96
+ 'AudioExample needs access to your microphone so you can record audio.',
97
+ };
98
+ return PermissionsAndroid.request(
99
+ PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
100
+ rationale
101
+ ).then(result => {
102
+
103
+ return result === true || result === PermissionsAndroid.RESULTS.GRANTED;
104
+ });
105
+ }
106
+
107
+
108
+
109
+ handleAvatarPress = props => {
110
+ // add navigation to user's profile
111
+ };
112
+ handleAudio = async () => {
113
+ this.setState({ stopwatchStart: !this.state.stopwatchStart, stopwatchReset: false });
114
+ const { user } = this.props;
115
+ if (!this.state.startAudio) {
116
+ this.setState({
117
+ startAudio: true,
118
+ });
119
+ await AudioRecorder.startRecording();
120
+ } else {
121
+ this.setState({ startAudio: false });
122
+ await AudioRecorder.stopRecording();
123
+ const { audioPath } = this.state;
124
+ const fileName = `${this.messageIdGenerator()}.aac`;
125
+ const file = {
126
+ uri: audioPath,// Platform.OS === "ios" ? audioPath : `file://${audioPath}`,
127
+ name: fileName,
128
+ type: 'audio/aac',
129
+ };
130
+ this.setState({ audioFile: file.uri, AudFileName: file.name });
131
+ }
132
+ };
133
+ messageIdGenerator() {
134
+ // generates uuid.
135
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
136
+ let r = (Math.random() * 16) | 0,
137
+ v = c == 'x' ? r : (r & 0x3) | 0x8;
138
+ return v.toString(16);
139
+ });
140
+ }
141
+
142
+ renderAndroidMicrophone() {
143
+ if (Platform.OS === 'android') {
144
+ return (
145
+ <Ionicons
146
+ name="ios-mic"
147
+ size={35}
148
+ hitSlop={{ top: 20, bottom: 20, left: 50, right: 50 }}
149
+ color={this.state.startAudio ? 'red' : 'black'}
150
+ style={{
151
+ bottom: 50,
152
+ right: Dimensions.get('window').width / 2,
153
+ position: 'absolute',
154
+ shadowColor: '#000',
155
+ shadowOffset: { width: 0, height: 0 },
156
+ shadowOpacity: 0.5,
157
+ zIndex: 2,
158
+ backgroundColor: 'transparent',
159
+ }}
160
+ onPress={this.handleAudio}
161
+ />
162
+ );
163
+ }
164
+ }
165
+ renderLoading() {
166
+ if (!this.state.messages.length && !this.state.fetchChats) {
167
+ return (
168
+ <View style={{ marginTop: 100 }}>
169
+ {/* <ActivityIndicator color="black" animating size="large" /> */}
170
+ </View>
171
+ );
172
+ }
173
+ }
174
+ toggleStopwatch() {
175
+ this.setState({ stopwatchStart: !this.state.stopwatchStart, stopwatchReset: false });
176
+ }
177
+
178
+ resetStopwatch() {
179
+ this.setState({ stopwatchStart: false, stopwatchReset: true });
180
+ }
181
+
182
+ render() {
183
+ return (
184
+ <TouchableOpacity style={layoutstyles.main_container}
185
+ onPress={() => this.props.navigation.goBack()}
186
+ >
187
+ <TouchableOpacity style={layoutstyles.child_container}>
188
+ {this.state.stopwatchStart ?
189
+ <View style={layoutstyles.stop_watch_container}>
190
+ <Stopwatch laps msecs start={this.state.stopwatchStart}
191
+ reset={this.state.stopwatchReset}
192
+ options={options}
193
+ />
194
+ </View>
195
+ : null
196
+ }
197
+ <View style={layoutstyles.start_or_stop_container}>
198
+ <TouchableHighlight underlayColor={'transparent'} onPress={this.handleAudio}>
199
+ {!this.state.stopwatchStart ?
200
+ <View style={layoutstyles.start_or_stop_icon}>
201
+ <FontAwesome name="circle" size={70} color={'red'} />
202
+ <Text>START</Text>
203
+ </View>
204
+ :
205
+ <View style={layoutstyles.start_or_stop_icon}>
206
+ <FontAwesome name="stop" size={60} color={'black'} />
207
+ <Text>STOP</Text>
208
+ </View>
209
+ }
210
+ </TouchableHighlight>
211
+ </View>
212
+ </TouchableOpacity>
213
+ </TouchableOpacity>
214
+ );
215
+ }
216
+ }
217
+ const options = {
218
+ text: {
219
+ fontSize: 40,
220
+ color: '#000',
221
+ },
222
+ };
223
+ const layoutstyles = StyleSheet.create({
224
+ main_container: {
225
+ flex: 1,
226
+ backgroundColor: 'rgba(0,0,0,0.50)',
227
+ justifyContent: 'center', alignItems: 'center',
228
+ },
229
+ stop_watch_container: {
230
+ flex: 2,
231
+ width: '100%',
232
+ height: 200,
233
+ justifyContent: 'center',
234
+ alignItems: 'center',
235
+ },
236
+
237
+ child_container: {
238
+ flex: 0.25,// 0.3
239
+ backgroundColor: '#fff', width: '100%',
240
+ borderRadius: 7, borderWidth: 0.5, borderColor: 'black',
241
+ },
242
+ start_or_stop_container: {
243
+ flex: 3, width: '100%', height: 200,
244
+ justifyContent: 'center', alignItems: 'center',
245
+ },
246
+ start_or_stop_icon: {
247
+ justifyContent: 'center',
248
+ alignItems: 'center',
249
+ },
250
+ });