@janiscommerce/app-tracking-shift 1.2.0 → 1.4.0-beta.1

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.
package/README.md CHANGED
@@ -1 +1,298 @@
1
- # @janiscommerce/app-tracking-shift
1
+ # @janiscommerce/app-tracking-shift
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@janiscommerce/app-tracking-shift.svg)](https://www.npmjs.com/package/@janiscommerce/app-tracking-shift)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ A React Native library for managing work shifts and work logs in Janis Commerce applications. This package provides comprehensive shift tracking functionality with offline support and seamless integration with the Staff MS (Microservice).
7
+
8
+ ## Features
9
+
10
+ - 🕒 **Shift Management**: Open, close, and manage work shifts
11
+ - 📝 **Work Log Tracking**: Track work activities with start/end times
12
+ - 📱 **Offline Support**: Continue working even without internet connection
13
+ - 🔄 **Automatic Sync**: Sync pending work logs when connection is restored
14
+ - 🎯 **React Context Integration**: Easy state management with React Context
15
+ - 🛡️ **Authorization Control**: Built-in staff authorization validation
16
+ - ⚡ **Performance Optimized**: Uses MMKV for fast local storage
17
+ - 🔧 **Error Handling**: Comprehensive error reporting with Crashlytics integration
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @janiscommerce/app-tracking-shift
23
+ ```
24
+
25
+ ### Peer Dependencies
26
+
27
+ Make sure you have the following peer dependencies installed:
28
+
29
+ ```bash
30
+ npm install @janiscommerce/app-crashlytics@>=2.1.0
31
+ npm install @janiscommerce/app-request@>=2.0.0
32
+ npm install react@>=17.0.2
33
+ npm install react-native@>=0.67.5
34
+ ```
35
+
36
+ ## Quick Start
37
+
38
+ ### 1. Provider Setup
39
+
40
+ Wrap your app with the `ShiftTrackingProvider`:
41
+
42
+ ```jsx
43
+ import React from 'react';
44
+ import {ShiftTrackingProvider} from '@janiscommerce/app-tracking-shift';
45
+
46
+ const App = () => {
47
+ return (
48
+ <ShiftTrackingProvider onError={(error) => console.error(error)}>
49
+ {/* Your app components */}
50
+ </ShiftTrackingProvider>
51
+ );
52
+ };
53
+
54
+ export default App;
55
+ ```
56
+
57
+ ### 2. Using the Hook
58
+
59
+ Access shift data and methods using the `useShiftTracking` hook:
60
+
61
+ ```jsx
62
+ import React from 'react';
63
+ import {useShiftTracking} from '@janiscommerce/app-tracking-shift';
64
+
65
+ const MyComponent = () => {
66
+ const {
67
+ shiftId,
68
+ shiftStatus,
69
+ shiftData,
70
+ workLogTypes,
71
+ currentWorkLogData,
72
+ hasStaffAuthorization,
73
+ isShiftLoading,
74
+ error,
75
+ } = useShiftTracking();
76
+
77
+ return (
78
+ <div>
79
+ <p>Shift Status: {shiftStatus}</p>
80
+ <p>Shift ID: {shiftId}</p>
81
+ {/* Your component logic */}
82
+ </div>
83
+ );
84
+ };
85
+ ```
86
+
87
+ ### 3. Managing Shifts
88
+
89
+ Use the `Shift` class for shift operations:
90
+
91
+ ```jsx
92
+ import {Shift} from '@janiscommerce/app-tracking-shift';
93
+
94
+ // Open a shift
95
+ const handleOpenShift = async () => {
96
+ try {
97
+ const shiftId = await Shift.open();
98
+ console.log('Shift opened:', shiftId);
99
+ } catch (error) {
100
+ console.error('Error opening shift:', error);
101
+ }
102
+ };
103
+
104
+ // Close a shift
105
+ const handleCloseShift = async () => {
106
+ try {
107
+ const shiftId = await Shift.finish();
108
+ console.log('Shift closed:', shiftId);
109
+ } catch (error) {
110
+ console.error('Error closing shift:', error);
111
+ }
112
+ };
113
+ ```
114
+
115
+ ### 4. Work Log Management
116
+
117
+ ```jsx
118
+ // Open a work log
119
+ const handleOpenWorkLog = async () => {
120
+ const workLog = {
121
+ referenceId: 'task-123',
122
+ name: 'Customer Service',
123
+ type: 'work',
124
+ suggestedTime: 30, // minutes
125
+ };
126
+
127
+ try {
128
+ const workLogId = await Shift.openWorkLog(workLog);
129
+ console.log('Work log opened:', workLogId);
130
+ } catch (error) {
131
+ console.error('Error opening work log:', error);
132
+ }
133
+ };
134
+
135
+ // Finish a work log
136
+ const handleFinishWorkLog = async () => {
137
+ const workLog = {
138
+ referenceId: 'task-123',
139
+ };
140
+
141
+ try {
142
+ const workLogId = await Shift.finishWorkLog(workLog);
143
+ console.log('Work log finished:', workLogId);
144
+ } catch (error) {
145
+ console.error('Error finishing work log:', error);
146
+ }
147
+ };
148
+ ```
149
+
150
+ ## API Reference
151
+
152
+ ### ShiftTrackingProvider
153
+
154
+ The main provider component that manages shift state and initialization.
155
+
156
+ **Props:**
157
+
158
+ - `children` (ReactNode): Child components
159
+ - `onError` (function, optional): Error callback function
160
+
161
+ ### useShiftTracking Hook
162
+
163
+ Returns the current shift tracking state and data.
164
+
165
+ **Returns:**
166
+
167
+ - `shiftId` (string): Current shift ID
168
+ - `shiftStatus` (string): Current shift status ('opened', 'closed', 'paused')
169
+ - `shiftData` (object): Complete shift data
170
+ - `workLogTypes` (array): Available work log types
171
+ - `currentWorkLogData` (object): Current active work log data
172
+ - `currentWorkLogId` (string): Current work log ID
173
+ - `hasStaffAuthorization` (boolean): Staff authorization status
174
+ - `isShiftLoading` (boolean): Loading state
175
+ - `error` (object): Current error state
176
+
177
+ ### Shift Class
178
+
179
+ Main class for shift and work log operations.
180
+
181
+ #### Methods
182
+
183
+ **`open()`**
184
+
185
+ - Opens a new work shift
186
+ - Returns: `Promise<string>` - Shift ID
187
+
188
+ **`finish(params?)`**
189
+
190
+ - Closes the current shift
191
+ - Parameters: `{ date?: string }` - Optional closing date
192
+ - Returns: `Promise<string>` - Shift ID
193
+
194
+ **`openWorkLog(workLog)`**
195
+
196
+ - Opens a new work log
197
+ - Parameters: `{ referenceId, name, type, suggestedTime? }`
198
+ - Returns: `Promise<string>` - Work log ID
199
+
200
+ **`finishWorkLog(workLog)`**
201
+
202
+ - Finishes the current work log
203
+ - Parameters: `{ referenceId }`
204
+ - Returns: `Promise<string>` - Work log ID
205
+
206
+ **`getWorkLogs(shiftId?)`**
207
+
208
+ - Gets work logs for a shift
209
+ - Parameters: `shiftId` (optional) - Shift ID
210
+ - Returns: `Promise<Array>` - Array of work logs
211
+
212
+ **`fetchWorklogTypes()`**
213
+
214
+ - Fetches available work log types
215
+ - Returns: `Promise<Array>` - Array of work log types
216
+
217
+ **`sendPendingWorkLogs()`**
218
+
219
+ - Sends pending offline work logs
220
+ - Returns: `Promise<null>`
221
+
222
+ **`deleteShiftRegisters()`**
223
+
224
+ - Deletes all shift-related data
225
+ - Returns: `Promise<boolean>`
226
+
227
+ #### Properties
228
+
229
+ **`hasStaffAuthorize`** (getter)
230
+
231
+ - Returns: `boolean` - Staff authorization status
232
+
233
+ **`hasPendingData`** (getter)
234
+
235
+ - Returns: `boolean` - Pending offline data status
236
+
237
+ ### WithShiftTracking HOC
238
+
239
+ Higher-order component that provides shift tracking data to wrapped components.
240
+
241
+ ```jsx
242
+ import {WithShiftTracking} from '@janiscommerce/app-tracking-shift';
243
+
244
+ const MyComponent = ({shiftData}) => {
245
+ // Component logic
246
+ };
247
+
248
+ export default WithShiftTracking(MyComponent, {
249
+ pausedShiftComponent: <PausedShiftNotification />,
250
+ });
251
+ ```
252
+
253
+ ### Internal Work Logs
254
+
255
+ The package provides predefined internal work logs:
256
+
257
+ ```jsx
258
+ import {INTERNAL_WORKLOGS} from '@janiscommerce/app-tracking-shift';
259
+
260
+ // Available internal work logs:
261
+ // INTERNAL_WORKLOGS.PICKING_WORK
262
+ // INTERNAL_WORKLOGS.DELIVERY_WORK
263
+ ```
264
+
265
+ ## Offline Support
266
+
267
+ The library automatically handles offline scenarios:
268
+
269
+ 1. **Offline Storage**: Work logs are stored locally when offline
270
+ 2. **Automatic Sync**: Pending work logs are automatically synced when connection is restored
271
+ 3. **Data Persistence**: Uses MMKV for fast and reliable local storage
272
+ 4. **Error Recovery**: Graceful error handling for network issues
273
+
274
+ ## Error Handling
275
+
276
+ All errors are standardized and include:
277
+
278
+ - Descriptive error messages
279
+ - Error types for categorization
280
+ - Automatic Crashlytics reporting
281
+ - Promise rejection for proper error handling
282
+
283
+ ## Storage Keys
284
+
285
+ The library uses the following storage keys (managed automatically):
286
+
287
+ - `shift.id` - Current shift ID
288
+ - `shift.status` - Current shift status
289
+ - `shift.data` - Complete shift data
290
+ - `worklog.id` - Current work log ID
291
+ - `worklog.data` - Current work log data
292
+ - `worklogTypes.data` - Work log types cache
293
+ - `staff.authorization` - Staff authorization data
294
+ - `offline.data` - Offline work logs
295
+
296
+ ## Contributing
297
+
298
+ This package is maintained by Janis Commerce. For issues and feature requests, please use the [GitHub Issues](https://github.com/janis-commerce/app-tracking-shift/issues).
@@ -1,11 +1,10 @@
1
1
  import {OFFLINE_DATA} from './constant';
2
2
  import Storage from './db/StorageService';
3
3
  import {isArray, isEmptyArray} from './utils/helpers';
4
- import {setObject, getObject} from './utils/storage';
5
4
 
6
5
  class OfflineData {
7
6
  get hasData() {
8
- const offlineData = getObject(OFFLINE_DATA, []);
7
+ const offlineData = Storage.get(OFFLINE_DATA) || [];
9
8
  return offlineData.length > 0;
10
9
  }
11
10
 
@@ -18,9 +17,8 @@ class OfflineData {
18
17
 
19
18
  save(id, data) {
20
19
  try {
21
- const offlineData = getObject(OFFLINE_DATA, []);
20
+ const offlineData = Storage.get(OFFLINE_DATA) || [];
22
21
  const foundIdx = offlineData.findIndex((item) => item.storageId === id);
23
-
24
22
  if (foundIdx === -1) {
25
23
  offlineData.push({storageId: id, ...data});
26
24
  } else {
@@ -28,7 +26,7 @@ class OfflineData {
28
26
  offlineData[foundIdx] = {...storedData, ...data};
29
27
  }
30
28
 
31
- setObject(OFFLINE_DATA, offlineData);
29
+ Storage.set(OFFLINE_DATA, offlineData);
32
30
  } catch (error) {
33
31
  throw new Error(error);
34
32
  }
@@ -43,7 +41,7 @@ class OfflineData {
43
41
 
44
42
  get(id = null) {
45
43
  try {
46
- const offlineData = getObject(OFFLINE_DATA, []);
44
+ const offlineData = Storage.get(OFFLINE_DATA) || [];
47
45
 
48
46
  if (!isArray(id)) {
49
47
  id = [id].filter(Boolean);
@@ -57,22 +55,6 @@ class OfflineData {
57
55
  }
58
56
  }
59
57
 
60
- /**
61
- * Gets the last record from the offline data storage.
62
- *
63
- * @returns {Object} The last record from the storage.
64
- */
65
-
66
- getLastRecord() {
67
- try {
68
- const offlineData = this.get();
69
- const [lastRecord] = offlineData.slice(-1);
70
- return lastRecord;
71
- } catch (error) {
72
- throw new Error(error);
73
- }
74
- }
75
-
76
58
  /**
77
59
  * Deletes data from the offline data storage.
78
60
  *
@@ -81,7 +63,7 @@ class OfflineData {
81
63
 
82
64
  delete(id) {
83
65
  try {
84
- const offlineData = getObject(OFFLINE_DATA, []);
66
+ const offlineData = Storage.get(OFFLINE_DATA) || [];
85
67
 
86
68
  if (!isArray(id)) {
87
69
  id = [id].filter(Boolean);
@@ -91,7 +73,7 @@ class OfflineData {
91
73
 
92
74
  const filteredData = offlineData.filter((item) => !id.includes(item.storageId));
93
75
 
94
- setObject(OFFLINE_DATA, filteredData);
76
+ Storage.set(OFFLINE_DATA, filteredData);
95
77
  } catch (error) {
96
78
  throw new Error(error);
97
79
  }
@@ -103,7 +85,7 @@ class OfflineData {
103
85
 
104
86
  deleteAll() {
105
87
  try {
106
- Storage.delete(OFFLINE_DATA);
88
+ Storage.remove(OFFLINE_DATA);
107
89
  } catch (error) {
108
90
  throw new Error(error);
109
91
  }