@suflon/rnmd-reporting 0.0.2 → 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.
package/package.json
CHANGED
|
@@ -19058,10 +19058,10 @@ index 0000000..5b11a80
|
|
|
19058
19058
|
+export default ReportingDetail;
|
|
19059
19059
|
diff --git a/node_modules/@suflon/native-ui/src/modules/Reporting/index.tsx b/node_modules/@suflon/native-ui/src/modules/Reporting/index.tsx
|
|
19060
19060
|
new file mode 100644
|
|
19061
|
-
index 0000000..
|
|
19061
|
+
index 0000000..98773be
|
|
19062
19062
|
--- /dev/null
|
|
19063
19063
|
+++ b/node_modules/@suflon/native-ui/src/modules/Reporting/index.tsx
|
|
19064
|
-
@@ -0,0 +1,
|
|
19064
|
+
@@ -0,0 +1,249 @@
|
|
19065
19065
|
+import React, { useEffect, useState, useMemo, useCallback } from 'react';
|
|
19066
19066
|
+import { ScrollView, TouchableOpacity, View, Text, SafeAreaView, useColorScheme } from 'react-native';
|
|
19067
19067
|
+import { useNavigation } from '@react-navigation/native';
|
|
@@ -19144,7 +19144,7 @@ index 0000000..9c355ad
|
|
|
19144
19144
|
+ const iconMutedColor = isDark ? '#9CA3AF' : themeColors.slate[400];
|
|
19145
19145
|
+
|
|
19146
19146
|
+ return (
|
|
19147
|
-
+ <SafeAreaView
|
|
19147
|
+
+ <SafeAreaView className="flex-1 bg-slate-50 dark:bg-background-lightBlack">
|
|
19148
19148
|
+ {/* Header Component */}
|
|
19149
19149
|
+ <Header
|
|
19150
19150
|
+ title="Reports Catalog"
|
|
@@ -19152,9 +19152,9 @@ index 0000000..9c355ad
|
|
|
19152
19152
|
+ showActionIcon={false}
|
|
19153
19153
|
+ />
|
|
19154
19154
|
+
|
|
19155
|
-
+ <ScrollView
|
|
19155
|
+
+ <ScrollView className="flex-1" contentContainerStyle={{ paddingBottom: 30 }}>
|
|
19156
19156
|
+ {/* Search Bar */}
|
|
19157
|
-
+ <View
|
|
19157
|
+
+ <View className="px-4 pt-3.5">
|
|
19158
19158
|
+ <SearchFilter
|
|
19159
19159
|
+ placeholder="Search reports or creator..."
|
|
19160
19160
|
+ value={searchQuery}
|
|
@@ -19164,12 +19164,12 @@ index 0000000..9c355ad
|
|
|
19164
19164
|
+
|
|
19165
19165
|
+ {/* Quick Access Featured Carousel */}
|
|
19166
19166
|
+ {featuredPicks.length > 0 && (
|
|
19167
|
-
+ <View
|
|
19168
|
-
+ <View
|
|
19169
|
-
+ <Text
|
|
19167
|
+
+ <View className="pt-4">
|
|
19168
|
+
+ <View className="px-4 flex-row justify-between items-center mb-2.5">
|
|
19169
|
+
+ <Text className="text-[11px] font-extrabold text-slate-400 dark:text-gray-400 tracking-wider">
|
|
19170
19170
|
+ FEATURED REPORTS
|
|
19171
19171
|
+ </Text>
|
|
19172
|
-
+ <Text
|
|
19172
|
+
+ <Text className="text-[11px] font-bold text-violet-600 dark:text-violet-400">
|
|
19173
19173
|
+ Swipe ➔
|
|
19174
19174
|
+ </Text>
|
|
19175
19175
|
+ </View>
|
|
@@ -19180,23 +19180,15 @@ index 0000000..9c355ad
|
|
|
19180
19180
|
+ key={pick.id || i}
|
|
19181
19181
|
+ onPress={() => handleReportPress(pick)}
|
|
19182
19182
|
+ activeOpacity={0.8}
|
|
19183
|
-
+
|
|
19184
|
-
+ width: 170,
|
|
19185
|
-
+ backgroundColor: isDark ? '#1C1C1E' : '#FFFFFF',
|
|
19186
|
-
+ borderColor: isDark ? '#2C2C2E' : '#E2E8F0',
|
|
19187
|
-
+ borderWidth: 1,
|
|
19188
|
-
+ borderRadius: 16,
|
|
19189
|
-
+ padding: 12,
|
|
19190
|
-
+ gap: 6,
|
|
19191
|
-
+ }}
|
|
19183
|
+
+ className="w-[170px] bg-white dark:bg-background-darkSecondaryBg rounded-2xl p-3 border border-slate-200 dark:border-gray-800 gap-1.5"
|
|
19192
19184
|
+ >
|
|
19193
|
-
+ <View
|
|
19185
|
+
+ <View className="w-7 h-7 rounded-lg bg-violet-50 dark:bg-violet-950/40 items-center justify-center">
|
|
19194
19186
|
+ <Icon name="bar-chart-2" type="Feather" size={16} color={iconBrandColor} />
|
|
19195
19187
|
+ </View>
|
|
19196
|
-
+ <Text
|
|
19188
|
+
+ <Text className="text-xs font-extrabold text-slate-900 dark:text-text-dark-primary" numberOfLines={1}>
|
|
19197
19189
|
+ {pick.name}
|
|
19198
19190
|
+ </Text>
|
|
19199
|
-
+ <Text
|
|
19191
|
+
+ <Text className="text-[9px] font-semibold text-slate-500 dark:text-gray-400" numberOfLines={1}>
|
|
19200
19192
|
+ {pick.sub_report_class ? SUB_CLASS_LABEL_MAP[pick.sub_report_class] || pick.sub_report_class : 'Report'}
|
|
19201
19193
|
+ </Text>
|
|
19202
19194
|
+ </TouchableOpacity>
|
|
@@ -19206,7 +19198,7 @@ index 0000000..9c355ad
|
|
|
19206
19198
|
+ )}
|
|
19207
19199
|
+
|
|
19208
19200
|
+ {/* Category Pills Switcher - Dynamic from response */}
|
|
19209
|
-
+ <View
|
|
19201
|
+
+ <View className="pt-4">
|
|
19210
19202
|
+ <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{ paddingHorizontal: 16, gap: 8 }}>
|
|
19211
19203
|
+ {categoryTabs.map((tab) => {
|
|
19212
19204
|
+ const isActive = activeTabId === tab.id;
|
|
@@ -19218,17 +19210,11 @@ index 0000000..9c355ad
|
|
|
19218
19210
|
+ key={tab.id}
|
|
19219
19211
|
+ onPress={() => setActiveTabId(tab.id)}
|
|
19220
19212
|
+ activeOpacity={0.8}
|
|
19221
|
-
+
|
|
19222
|
-
+
|
|
19223
|
-
+
|
|
19224
|
-
+
|
|
19225
|
-
+
|
|
19226
|
-
+ paddingHorizontal: 14,
|
|
19227
|
-
+ paddingVertical: 8,
|
|
19228
|
-
+ flexDirection: 'row',
|
|
19229
|
-
+ alignItems: 'center',
|
|
19230
|
-
+ gap: 6,
|
|
19231
|
-
+ }}
|
|
19213
|
+
+ className={`flex-row items-center gap-1.5 px-3.5 py-2 rounded-full border ${
|
|
19214
|
+
+ isActive
|
|
19215
|
+
+ ? 'bg-violet-600 border-violet-600'
|
|
19216
|
+
+ : 'bg-white dark:bg-background-darkSecondaryBg border-slate-200 dark:border-gray-800'
|
|
19217
|
+
+ }`}
|
|
19232
19218
|
+ >
|
|
19233
19219
|
+ <Icon
|
|
19234
19220
|
+ name={tab.icon}
|
|
@@ -19237,20 +19223,27 @@ index 0000000..9c355ad
|
|
|
19237
19223
|
+ color={isActive ? '#FFFFFF' : (isDark ? '#FFFFFF' : themeColors.slate[600])}
|
|
19238
19224
|
+ />
|
|
19239
19225
|
+ <Text
|
|
19240
|
-
+
|
|
19226
|
+
+ className={`text-[11px] font-bold ${
|
|
19227
|
+
+ isActive
|
|
19228
|
+
+ ? 'text-white'
|
|
19229
|
+
+ : 'text-slate-700 dark:text-gray-200'
|
|
19230
|
+
+ }`}
|
|
19241
19231
|
+ >
|
|
19242
19232
|
+ {tab.label}
|
|
19243
19233
|
+ </Text>
|
|
19244
19234
|
+ <View
|
|
19245
|
-
+
|
|
19246
|
-
+
|
|
19247
|
-
+
|
|
19248
|
-
+
|
|
19249
|
-
+
|
|
19250
|
-
+ }}
|
|
19235
|
+
+ className={`rounded-full px-1.5 py-0.5 ${
|
|
19236
|
+
+ isActive
|
|
19237
|
+
+ ? 'bg-white/25'
|
|
19238
|
+
+ : 'bg-slate-100 dark:bg-gray-800'
|
|
19239
|
+
+ }`}
|
|
19251
19240
|
+ >
|
|
19252
19241
|
+ <Text
|
|
19253
|
-
+
|
|
19242
|
+
+ className={`text-[9px] font-extrabold ${
|
|
19243
|
+
+ isActive
|
|
19244
|
+
+ ? 'text-white'
|
|
19245
|
+
+ : 'text-slate-600 dark:text-gray-300'
|
|
19246
|
+
+ }`}
|
|
19254
19247
|
+ >
|
|
19255
19248
|
+ {count}
|
|
19256
19249
|
+ </Text>
|
|
@@ -19262,14 +19255,14 @@ index 0000000..9c355ad
|
|
|
19262
19255
|
+ </View>
|
|
19263
19256
|
+
|
|
19264
19257
|
+ {/* Report Catalog List */}
|
|
19265
|
-
+ <View
|
|
19258
|
+
+ <View className="px-4 pt-3.5 gap-2.5">
|
|
19266
19259
|
+ {loading ? (
|
|
19267
|
-
+ <View
|
|
19260
|
+
+ <View className="py-10">
|
|
19268
19261
|
+ <Loader message="Loading reports catalog..." color={iconBrandColor} />
|
|
19269
19262
|
+ </View>
|
|
19270
19263
|
+ ) : filteredReports.length === 0 ? (
|
|
19271
|
-
+ <View
|
|
19272
|
-
+ <Text
|
|
19264
|
+
+ <View className="bg-white dark:bg-background-darkSecondaryBg p-8 rounded-2xl items-center mt-2.5 border border-slate-200 dark:border-gray-800">
|
|
19265
|
+
+ <Text className="text-slate-500 dark:text-gray-400 text-xs font-semibold">No reports match the selected category</Text>
|
|
19273
19266
|
+ </View>
|
|
19274
19267
|
+ ) : (
|
|
19275
19268
|
+ filteredReports.map((item) => (
|
|
@@ -19277,18 +19270,10 @@ index 0000000..9c355ad
|
|
|
19277
19270
|
+ key={item.id}
|
|
19278
19271
|
+ onPress={() => handleReportPress(item)}
|
|
19279
19272
|
+ activeOpacity={0.8}
|
|
19280
|
-
+
|
|
19281
|
-
+ backgroundColor: isDark ? '#1C1C1E' : '#FFFFFF',
|
|
19282
|
-
+ borderColor: isDark ? '#2C2C2E' : '#E2E8F0',
|
|
19283
|
-
+ borderWidth: 1,
|
|
19284
|
-
+ borderRadius: 16,
|
|
19285
|
-
+ padding: 14,
|
|
19286
|
-
+ flexDirection: 'row',
|
|
19287
|
-
+ alignItems: 'center',
|
|
19288
|
-
+ }}
|
|
19273
|
+
+ className="bg-white dark:bg-background-darkSecondaryBg rounded-2xl p-3.5 border border-slate-200 dark:border-gray-800 flex-row items-center"
|
|
19289
19274
|
+ >
|
|
19290
|
-
+ <View
|
|
19291
|
-
+ <View
|
|
19275
|
+
+ <View className="flex-row items-center gap-3 flex-1">
|
|
19276
|
+
+ <View className="w-10 h-10 rounded-xl bg-violet-50 dark:bg-violet-950/40 items-center justify-center">
|
|
19292
19277
|
+ <Icon
|
|
19293
19278
|
+ name={SUB_CLASS_ICON_MAP[item.sub_report_class] || (item.is_dynamic ? "pie-chart" : "file-text")}
|
|
19294
19279
|
+ type="Feather"
|
|
@@ -19297,23 +19282,23 @@ index 0000000..9c355ad
|
|
|
19297
19282
|
+ />
|
|
19298
19283
|
+ </View>
|
|
19299
19284
|
+
|
|
19300
|
-
+ <View
|
|
19301
|
-
+ <Text
|
|
19285
|
+
+ <View className="flex-1">
|
|
19286
|
+
+ <Text className="text-[13px] font-extrabold text-slate-900 dark:text-text-dark-primary" numberOfLines={1}>
|
|
19302
19287
|
+ {item.name}
|
|
19303
19288
|
+ </Text>
|
|
19304
|
-
+ <View
|
|
19305
|
-
+ <Text
|
|
19289
|
+
+ <View className="flex-row items-center gap-1.5 mt-0.5">
|
|
19290
|
+
+ <Text className="text-[10px] font-bold text-violet-600 dark:text-violet-400">
|
|
19306
19291
|
+ {SUB_CLASS_LABEL_MAP[item.sub_report_class] || item.sub_report_class || 'Report'}
|
|
19307
19292
|
+ </Text>
|
|
19308
|
-
+ <Text
|
|
19309
|
-
+ <Text
|
|
19293
|
+
+ <Text className="text-[10px] text-slate-400 dark:text-gray-500">•</Text>
|
|
19294
|
+
+ <Text className="text-[10px] font-semibold text-slate-500 dark:text-gray-400">
|
|
19310
19295
|
+ {item.report_type || 'LISTING'}
|
|
19311
19296
|
+ </Text>
|
|
19312
19297
|
+ </View>
|
|
19313
19298
|
+ </View>
|
|
19314
19299
|
+ </View>
|
|
19315
19300
|
+
|
|
19316
|
-
+ <View
|
|
19301
|
+
+ <View className="flex-row items-center gap-1.5">
|
|
19317
19302
|
+ <Icon name="chevron-right" type="Feather" size={18} color={iconMutedColor} />
|
|
19318
19303
|
+ </View>
|
|
19319
19304
|
+ </TouchableOpacity>
|
|
@@ -21410,15 +21395,17 @@ index 0000000..5af6cc6
|
|
|
21410
21395
|
+
|
|
21411
21396
|
+export default NewConnectionModal;
|
|
21412
21397
|
diff --git a/node_modules/@suflon/native-ui/src/services/ApiService.ts b/node_modules/@suflon/native-ui/src/services/ApiService.ts
|
|
21413
|
-
index 7613a70..
|
|
21398
|
+
index 7613a70..abaa6f6 100644
|
|
21414
21399
|
--- a/node_modules/@suflon/native-ui/src/services/ApiService.ts
|
|
21415
21400
|
+++ b/node_modules/@suflon/native-ui/src/services/ApiService.ts
|
|
21416
|
-
@@ -1,118 +1,
|
|
21401
|
+
@@ -1,118 +1,44 @@
|
|
21417
21402
|
-import axios, { AxiosRequestConfig } from 'axios';
|
|
21418
21403
|
-import type { AxiosRequestHeaders } from 'axios';
|
|
21419
21404
|
-import { useAuthStore } from '../store/auth.store';
|
|
21420
21405
|
-import { getData } from '../utils/AsyncStorageUtils';
|
|
21421
|
-
|
|
21406
|
+
+import { axiosInstance } from './api';
|
|
21407
|
+
+import { saveData, getData } from '@/utils/AsyncStorageUtils';
|
|
21408
|
+
|
|
21422
21409
|
-/** Default API origin when the host has not called {@link setBaseUrl} yet. Host apps should call `setBaseUrl` at startup (from env or config). */
|
|
21423
21410
|
-const DEFAULT_BASE_URL =
|
|
21424
21411
|
- 'https://api-local.woctor.com';
|
|
@@ -21466,8 +21453,12 @@ index 7613a70..b549dc4 100644
|
|
|
21466
21453
|
- const base_url = apiBaseUrl;
|
|
21467
21454
|
-
|
|
21468
21455
|
- return { token, company_id, region_id, staff_id, user_id, base_url };
|
|
21469
|
-
|
|
21470
|
-
|
|
21456
|
+
+export const setBaseUrl = async (url: string) => {
|
|
21457
|
+
+ const cleanUrl = url ? url.trim().replace(/\/+$/, '') : '';
|
|
21458
|
+
+ await saveData('api_base_url', cleanUrl);
|
|
21459
|
+
+ axiosInstance.defaults.baseURL = cleanUrl;
|
|
21460
|
+
};
|
|
21461
|
+
|
|
21471
21462
|
-axiosInstance.interceptors.request.use(
|
|
21472
21463
|
- async config => {
|
|
21473
21464
|
- const { token, region_id, company_id, user_id, staff_id, base_url } = await resolveAuthContext();
|
|
@@ -21506,8 +21497,10 @@ index 7613a70..b549dc4 100644
|
|
|
21506
21497
|
- data: body,
|
|
21507
21498
|
- });
|
|
21508
21499
|
- return response.data as T;
|
|
21509
|
-
|
|
21510
|
-
+
|
|
21500
|
+
+export const getBaseUrl = async (): Promise<string> => {
|
|
21501
|
+
+ const stored = await getData<string>('api_base_url');
|
|
21502
|
+
+ return stored || axiosInstance.defaults.baseURL || '';
|
|
21503
|
+
};
|
|
21511
21504
|
|
|
21512
21505
|
export const ApiService = {
|
|
21513
21506
|
- get: <T = any>(url: string, config?: AxiosRequestConfig) =>
|
|
@@ -21522,6 +21515,14 @@ index 7613a70..b549dc4 100644
|
|
|
21522
21515
|
- handleRequest<T>('delete', url, undefined, config),
|
|
21523
21516
|
- fetchList: <T = any>(url: string, config?: AxiosRequestConfig) =>
|
|
21524
21517
|
- handleRequest<T>('get', url, undefined, config),
|
|
21518
|
+
-};
|
|
21519
|
+
-
|
|
21520
|
+
-export const getBaseUrl = () => apiBaseUrl;
|
|
21521
|
+
-export const setBaseUrl = (url: string) => {
|
|
21522
|
+
- const normalized = String(url || '').trim().replace(/\/+$/, '');
|
|
21523
|
+
- if (!normalized) return;
|
|
21524
|
+
- apiBaseUrl = normalized;
|
|
21525
|
+
- axiosInstance.defaults.baseURL = normalized;
|
|
21525
21526
|
+ get: async (url: string, paramsOrConfig?: Record<string, any>) => {
|
|
21526
21527
|
+ let config: { params?: Record<string, any> } = {};
|
|
21527
21528
|
+ if (paramsOrConfig) {
|
|
@@ -21549,16 +21550,9 @@ index 7613a70..b549dc4 100644
|
|
|
21549
21550
|
+ return ApiService.get(url, params);
|
|
21550
21551
|
+ },
|
|
21551
21552
|
};
|
|
21552
|
-
|
|
21553
|
-
-export const getBaseUrl = () => apiBaseUrl;
|
|
21554
|
-
-export const setBaseUrl = (url: string) => {
|
|
21555
|
-
- const normalized = String(url || '').trim().replace(/\/+$/, '');
|
|
21556
|
-
- if (!normalized) return;
|
|
21557
|
-
- apiBaseUrl = normalized;
|
|
21558
|
-
- axiosInstance.defaults.baseURL = normalized;
|
|
21559
|
-
-};
|
|
21560
|
-
-
|
|
21553
|
+
|
|
21561
21554
|
-export default axiosInstance;
|
|
21555
|
+
+export { axiosInstance };
|
|
21562
21556
|
diff --git a/node_modules/@suflon/native-ui/src/services/ConnectionService.ts b/node_modules/@suflon/native-ui/src/services/ConnectionService.ts
|
|
21563
21557
|
new file mode 100644
|
|
21564
21558
|
index 0000000..b7e3f15
|
|
@@ -25467,7 +25461,7 @@ index 221e5d1..352ad70 100644
|
|
|
25467
25461
|
),
|
|
25468
25462
|
);
|
|
25469
25463
|
diff --git a/node_modules/@suflon/native-ui/src/store/package.store.ts b/node_modules/@suflon/native-ui/src/store/package.store.ts
|
|
25470
|
-
index bee9382..
|
|
25464
|
+
index bee9382..f1ccdef 100644
|
|
25471
25465
|
--- a/node_modules/@suflon/native-ui/src/store/package.store.ts
|
|
25472
25466
|
+++ b/node_modules/@suflon/native-ui/src/store/package.store.ts
|
|
25473
25467
|
@@ -4,6 +4,8 @@ import { IPackage } from '@utils/index';
|
|
@@ -25479,7 +25473,7 @@ index bee9382..21f88e2 100644
|
|
|
25479
25473
|
interface IPackageState {
|
|
25480
25474
|
/* flags & data */
|
|
25481
25475
|
loading: boolean;
|
|
25482
|
-
@@ -12,
|
|
25476
|
+
@@ -12,196 +14,231 @@ interface IPackageState {
|
|
25483
25477
|
packages: IPackage[];
|
|
25484
25478
|
package: IPackage | null;
|
|
25485
25479
|
|
|
@@ -25494,13 +25488,19 @@ index bee9382..21f88e2 100644
|
|
|
25494
25488
|
/* writes */
|
|
25495
25489
|
createPackage: (data: Partial<IPackage>) => Promise<IPackage | null>;
|
|
25496
25490
|
updatePackage: (id: number, data: Partial<IPackage>) => Promise<IPackage | null>;
|
|
25491
|
+
+ updatePackageDetail: (detailId: number, payload: Record<string, any>) => Promise<any>;
|
|
25497
25492
|
addPackageGroup: (packageId: number, groups: any[]) => Promise<any>;
|
|
25498
25493
|
- // updatePackageDetail: (detailId: number, payload: Record<string, any>) => Promise<any>;
|
|
25499
25494
|
- // updatePackageDetail: (detailId: number, payload: Record<string, any>) => Promise<any>;
|
|
25500
25495
|
}
|
|
25501
25496
|
|
|
25502
25497
|
/* ─────────────────────────────
|
|
25503
|
-
|
|
25498
|
+
- Endpoint root
|
|
25499
|
+
+ Endpoint root (Content service)
|
|
25500
|
+
────────────────────────────── */
|
|
25501
|
+
-const serviceUrl = `/billing/api/online/catalogue/package`;
|
|
25502
|
+
+const serviceUrl = `/content/api/online/catalogue/package`;
|
|
25503
|
+
|
|
25504
25504
|
/* ─────────────────────────────
|
|
25505
25505
|
Store
|
|
25506
25506
|
────────────────────────────── */
|
|
@@ -25535,27 +25535,6 @@ index bee9382..21f88e2 100644
|
|
|
25535
25535
|
- // Only include company_id for COMPANY source, not for GENERIC
|
|
25536
25536
|
- if (!isGeneric && company_id) {
|
|
25537
25537
|
- urlObj.searchParams.append('company_id', String(company_id));
|
|
25538
|
-
- }
|
|
25539
|
-
-
|
|
25540
|
-
- // Add optional parameters
|
|
25541
|
-
- if (params?.package_type) {
|
|
25542
|
-
- urlObj.searchParams.append('package_type', params.package_type);
|
|
25543
|
-
- }
|
|
25544
|
-
- if (params?.source) {
|
|
25545
|
-
- urlObj.searchParams.append('source', params.source);
|
|
25546
|
-
- }
|
|
25547
|
-
- if (params?.search_query) {
|
|
25548
|
-
- urlObj.searchParams.append('search_query', params.search_query);
|
|
25549
|
-
- }
|
|
25550
|
-
-
|
|
25551
|
-
- const url = urlObj.toString();
|
|
25552
|
-
-
|
|
25553
|
-
- // ✅ Debug logging for search verification
|
|
25554
|
-
- console.log('[PackageStore] Fetching packages with URL:', url);
|
|
25555
|
-
-
|
|
25556
|
-
- const res = await ApiService.get(url);
|
|
25557
|
-
- if (!Array.isArray(res)) {
|
|
25558
|
-
- set({ error: 'Unexpected API response', errorStatus: null, packages: [] });
|
|
25559
25538
|
+export const usePackageStore = create<IPackageState>()((set, get) => {
|
|
25560
25539
|
+ registerStore('package', get, set);
|
|
25561
25540
|
+
|
|
@@ -25587,36 +25566,34 @@ index bee9382..21f88e2 100644
|
|
|
25587
25566
|
+ // Check if source is GENERIC (generic packages don't use company_id)
|
|
25588
25567
|
+ const isGeneric = params?.source === 'GENERIC';
|
|
25589
25568
|
+
|
|
25590
|
-
+
|
|
25591
|
-
+ const urlObj = new URL(serviceUrl + '/');
|
|
25569
|
+
+ const queryParams: Record<string, any> = {};
|
|
25592
25570
|
+
|
|
25593
25571
|
+ // Always include region_id
|
|
25594
25572
|
+ if (region_id) {
|
|
25595
|
-
+
|
|
25573
|
+
+ queryParams.region_id = region_id;
|
|
25596
25574
|
+ }
|
|
25597
25575
|
+
|
|
25598
25576
|
+ // Only include company_id for COMPANY source, not for GENERIC
|
|
25599
25577
|
+ if (!isGeneric && company_id) {
|
|
25600
|
-
+
|
|
25578
|
+
+ queryParams.company_id = company_id;
|
|
25601
25579
|
+ }
|
|
25602
25580
|
+
|
|
25603
25581
|
+ // Add optional parameters
|
|
25604
25582
|
+ if (params?.package_type) {
|
|
25605
|
-
+
|
|
25583
|
+
+ queryParams.package_type = params.package_type;
|
|
25606
25584
|
+ }
|
|
25607
25585
|
+ if (params?.source) {
|
|
25608
|
-
+
|
|
25586
|
+
+ queryParams.source = params.source;
|
|
25609
25587
|
+ }
|
|
25610
25588
|
+ if (params?.search_query) {
|
|
25611
|
-
+
|
|
25589
|
+
+ queryParams.search_query = params.search_query;
|
|
25612
25590
|
+ }
|
|
25613
25591
|
+
|
|
25614
|
-
+ const url =
|
|
25592
|
+
+ const url = `${serviceUrl}/`;
|
|
25615
25593
|
+
|
|
25616
|
-
+
|
|
25617
|
-
+ console.log('[PackageStore] Fetching packages with URL:', url);
|
|
25594
|
+
+ console.log('[PackageStore] Fetching packages with URL:', url, 'params:', queryParams);
|
|
25618
25595
|
+
|
|
25619
|
-
+ const res = await ApiService.get(url);
|
|
25596
|
+
+ const res = await ApiService.get(url, queryParams);
|
|
25620
25597
|
+ if (!Array.isArray(res)) {
|
|
25621
25598
|
+ throw new Error('Unexpected API response');
|
|
25622
25599
|
+ }
|
|
@@ -25631,7 +25608,131 @@ index bee9382..21f88e2 100644
|
|
|
25631
25608
|
+ } catch (err: any) {
|
|
25632
25609
|
+ const status = err?.response?.status || null;
|
|
25633
25610
|
+ set({ error: err.response?.data?.detail || err.message || 'An error occurred', errorStatus: status });
|
|
25634
|
-
|
|
25611
|
+
+ return null;
|
|
25612
|
+
+ } finally {
|
|
25613
|
+
+ set({ loading: false });
|
|
25614
|
+
}
|
|
25615
|
+
-
|
|
25616
|
+
- // Add optional parameters
|
|
25617
|
+
- if (params?.package_type) {
|
|
25618
|
+
- urlObj.searchParams.append('package_type', params.package_type);
|
|
25619
|
+
+ },
|
|
25620
|
+
+
|
|
25621
|
+
+ getPackageById: async (id: number, source: string = 'COMPANY') => {
|
|
25622
|
+
+ try {
|
|
25623
|
+
+ set({ loading: true, error: null, errorStatus: null });
|
|
25624
|
+
+
|
|
25625
|
+
+ let url: string;
|
|
25626
|
+
+ if (source === 'GENERIC') {
|
|
25627
|
+
+ url = `${serviceUrl}/generic/${id}`;
|
|
25628
|
+
+ } else {
|
|
25629
|
+
+ url = `${serviceUrl}/${id}`;
|
|
25630
|
+
+ }
|
|
25631
|
+
+
|
|
25632
|
+
+ const res = await ApiService.get(url);
|
|
25633
|
+
+ set({ package: res });
|
|
25634
|
+
+
|
|
25635
|
+
+ return res;
|
|
25636
|
+
+ } catch (err: any) {
|
|
25637
|
+
+ const status = err?.response?.status || null;
|
|
25638
|
+
+ set({ error: err.message || 'An error occurred', errorStatus: status });
|
|
25639
|
+
+ return null;
|
|
25640
|
+
+ } finally {
|
|
25641
|
+
+ set({ loading: false });
|
|
25642
|
+
}
|
|
25643
|
+
- if (params?.source) {
|
|
25644
|
+
- urlObj.searchParams.append('source', params.source);
|
|
25645
|
+
+ },
|
|
25646
|
+
+
|
|
25647
|
+
+ /* ---------- WRITES ---------- */
|
|
25648
|
+
+ createPackage: async (data) => {
|
|
25649
|
+
+ try {
|
|
25650
|
+
+ set({ loading: true, error: null, errorStatus: null });
|
|
25651
|
+
+ const res: IPackage = await ApiService.post(`${serviceUrl}/create`, data);
|
|
25652
|
+
+ if (res) {
|
|
25653
|
+
+ const currentPkgs = get().packages || [];
|
|
25654
|
+
+ const updatedPkgs = [res, ...currentPkgs.filter((p) => p.id !== res.id)];
|
|
25655
|
+
+ set({ package: res, packages: updatedPkgs });
|
|
25656
|
+
+
|
|
25657
|
+
+ injectIntoCache({
|
|
25658
|
+
+ get,
|
|
25659
|
+
+ set,
|
|
25660
|
+
+ listPrefix: 'getPackages',
|
|
25661
|
+
+ detailPrefix: 'getPackageById:',
|
|
25662
|
+
+ item: res,
|
|
25663
|
+
+ });
|
|
25664
|
+
+ }
|
|
25665
|
+
+ return res;
|
|
25666
|
+
+ } catch (err: any) {
|
|
25667
|
+
+ const status = err?.response?.status || null;
|
|
25668
|
+
+ set({ error: err.message || 'An error occurred', errorStatus: status });
|
|
25669
|
+
+ return null;
|
|
25670
|
+
+ } finally {
|
|
25671
|
+
+ set({ loading: false });
|
|
25672
|
+
}
|
|
25673
|
+
- if (params?.search_query) {
|
|
25674
|
+
- urlObj.searchParams.append('search_query', params.search_query);
|
|
25675
|
+
+ },
|
|
25676
|
+
+
|
|
25677
|
+
+ /** PATCH the *meta* (top-card) of a package */
|
|
25678
|
+
+ updatePackage: async (id, data) => {
|
|
25679
|
+
+ try {
|
|
25680
|
+
+ set({ loading: true, error: null, errorStatus: null });
|
|
25681
|
+
+ const endpoint = `${serviceUrl}/update/${id}`;
|
|
25682
|
+
+
|
|
25683
|
+
+ const res: IPackage = await ApiService.patch(endpoint, data);
|
|
25684
|
+
+ if (res) {
|
|
25685
|
+
+ const currentPkgs = get().packages || [];
|
|
25686
|
+
+ const updatedPkgs = currentPkgs.map((p) => p.id === id ? { ...p, ...res } : p);
|
|
25687
|
+
+ set({ package: res, packages: updatedPkgs });
|
|
25688
|
+
+
|
|
25689
|
+
+ updateInCache({
|
|
25690
|
+
+ get,
|
|
25691
|
+
+ set,
|
|
25692
|
+
+ listPrefix: 'getPackages',
|
|
25693
|
+
+ detailPrefix: 'getPackageById:',
|
|
25694
|
+
+ item: { id, ...data, ...res },
|
|
25695
|
+
+ });
|
|
25696
|
+
+ }
|
|
25697
|
+
+ return res;
|
|
25698
|
+
+ } catch (err: any) {
|
|
25699
|
+
+ const status = err?.response?.status || null;
|
|
25700
|
+
+ const errorMsg = err?.response?.data?.detail || err?.response?.data?.message || err?.message || 'Update failed';
|
|
25701
|
+
+ set({ error: errorMsg, errorStatus: status });
|
|
25702
|
+
+ throw err; // Re-throw to allow component to handle
|
|
25703
|
+
+ } finally {
|
|
25704
|
+
+ set({ loading: false });
|
|
25705
|
+
}
|
|
25706
|
+
-
|
|
25707
|
+
- const url = urlObj.toString();
|
|
25708
|
+
-
|
|
25709
|
+
- // ✅ Debug logging for search verification
|
|
25710
|
+
- console.log('[PackageStore] Fetching packages with URL:', url);
|
|
25711
|
+
-
|
|
25712
|
+
- const res = await ApiService.get(url);
|
|
25713
|
+
- if (!Array.isArray(res)) {
|
|
25714
|
+
- set({ error: 'Unexpected API response', errorStatus: null, packages: [] });
|
|
25715
|
+
- return null;
|
|
25716
|
+
+ },
|
|
25717
|
+
+
|
|
25718
|
+
+ /** PATCH a single detail row (service) */
|
|
25719
|
+
+ updatePackageDetail: async (detailId: number, payload: Record<string, any>) => {
|
|
25720
|
+
+ try {
|
|
25721
|
+
+ set({ loading: true, error: null, errorStatus: null });
|
|
25722
|
+
+ const res = await ApiService.patch(
|
|
25723
|
+
+ `${serviceUrl}/update_detail/${detailId}`,
|
|
25724
|
+
+ payload,
|
|
25725
|
+
+ );
|
|
25726
|
+
+
|
|
25727
|
+
+ /* If backend returns parent id refresh local state */
|
|
25728
|
+
+ const pkgId = res?.package_id;
|
|
25729
|
+
+ if (typeof pkgId === 'number') await get().getPackageById(pkgId);
|
|
25730
|
+
+
|
|
25731
|
+
+ return res;
|
|
25732
|
+
+ } catch (err: any) {
|
|
25733
|
+
+ const status = err?.response?.status || null;
|
|
25734
|
+
+ set({ error: err.message || 'Detail update failed', errorStatus: status });
|
|
25735
|
+
+ throw err;
|
|
25635
25736
|
+ } finally {
|
|
25636
25737
|
+ set({ loading: false });
|
|
25637
25738
|
}
|
|
@@ -25646,60 +25747,134 @@ index bee9382..21f88e2 100644
|
|
|
25646
25747
|
- set({ loading: false });
|
|
25647
25748
|
- }
|
|
25648
25749
|
- },
|
|
25750
|
+
-
|
|
25751
|
+
- getPackageById: async (id: number, source: string = 'COMPANY') => {
|
|
25752
|
+
- try {
|
|
25753
|
+
- set({ loading: true, error: null, errorStatus: null });
|
|
25754
|
+
-
|
|
25755
|
+
- let url: string;
|
|
25756
|
+
- if (source === 'GENERIC') {
|
|
25757
|
+
- url = `/billing/api/online/catalogue/package/generic/${id}`;
|
|
25758
|
+
- } else {
|
|
25759
|
+
- url = `${serviceUrl}/${id}`;
|
|
25649
25760
|
+ },
|
|
25650
|
-
|
|
25651
|
-
getPackageById: async (id: number, source: string = 'COMPANY') => {
|
|
25652
|
-
try {
|
|
25653
|
-
@@ -128,7 +146,19 @@ export const usePackageStore = create<IPackageState>((set, get) => ({
|
|
25654
|
-
try {
|
|
25655
|
-
set({ loading: true, error: null, errorStatus: null });
|
|
25656
|
-
const res: IPackage = await ApiService.post(`${serviceUrl}/create`, data);
|
|
25657
|
-
- set({ package: res });
|
|
25658
|
-
+ if (res) {
|
|
25659
|
-
+ const currentPkgs = get().packages || [];
|
|
25660
|
-
+ const updatedPkgs = [res, ...currentPkgs.filter((p) => p.id !== res.id)];
|
|
25661
|
-
+ set({ package: res, packages: updatedPkgs });
|
|
25662
25761
|
+
|
|
25663
|
-
+
|
|
25664
|
-
+
|
|
25665
|
-
+
|
|
25666
|
-
+
|
|
25667
|
-
+
|
|
25668
|
-
+
|
|
25669
|
-
+
|
|
25670
|
-
+
|
|
25671
|
-
|
|
25672
|
-
|
|
25673
|
-
|
|
25674
|
-
|
|
25675
|
-
|
|
25676
|
-
|
|
25677
|
-
|
|
25762
|
+
+ /** POST new groups to an existing package */
|
|
25763
|
+
+ addPackageGroup: async (packageId, groups) => {
|
|
25764
|
+
+ try {
|
|
25765
|
+
+ set({ loading: true, error: null, errorStatus: null });
|
|
25766
|
+
+ const res = await ApiService.post(
|
|
25767
|
+
+ `${serviceUrl}/add_group/${packageId}`,
|
|
25768
|
+
+ groups,
|
|
25769
|
+
+ );
|
|
25770
|
+
+ // Refresh package data after adding groups
|
|
25771
|
+
+ await get().getPackageById(packageId);
|
|
25772
|
+
+ return res;
|
|
25773
|
+
+ } catch (err: any) {
|
|
25774
|
+
+ const status = err?.response?.status || null;
|
|
25775
|
+
+ set({ error: err.message || 'Adding group failed', errorStatus: status });
|
|
25776
|
+
+ throw err;
|
|
25777
|
+
+ } finally {
|
|
25778
|
+
+ set({ loading: false });
|
|
25779
|
+
}
|
|
25780
|
+
-
|
|
25781
|
+
- const res = await ApiService.get(url);
|
|
25782
|
+
- set({ package: res });
|
|
25783
|
+
-
|
|
25784
|
+
-
|
|
25785
|
+
- return res;
|
|
25786
|
+
- } catch (err: any) {
|
|
25787
|
+
- const status = err?.response?.status || null;
|
|
25788
|
+
- set({ error: err.message || 'An error occurred', errorStatus: status });
|
|
25789
|
+
- return null;
|
|
25790
|
+
- } finally {
|
|
25791
|
+
- set({ loading: false });
|
|
25792
|
+
- }
|
|
25793
|
+
- },
|
|
25794
|
+
-
|
|
25795
|
+
- /* ---------- WRITES ---------- */
|
|
25796
|
+
- createPackage: async (data) => {
|
|
25797
|
+
- try {
|
|
25798
|
+
- set({ loading: true, error: null, errorStatus: null });
|
|
25799
|
+
- const res: IPackage = await ApiService.post(`${serviceUrl}/create`, data);
|
|
25800
|
+
- set({ package: res });
|
|
25801
|
+
- return res;
|
|
25802
|
+
- } catch (err: any) {
|
|
25803
|
+
- const status = err?.response?.status || null;
|
|
25804
|
+
- set({ error: err.message || 'An error occurred', errorStatus: status });
|
|
25805
|
+
- return null;
|
|
25806
|
+
- } finally {
|
|
25807
|
+
- set({ loading: false });
|
|
25808
|
+
- }
|
|
25809
|
+
- },
|
|
25810
|
+
-
|
|
25811
|
+
- /** PATCH the *meta* (top-card) of a package */
|
|
25812
|
+
- updatePackage: async (id, data) => {
|
|
25813
|
+
- try {
|
|
25814
|
+
- set({ loading: true, error: null, errorStatus: null });
|
|
25815
|
+
- const endpoint = `${serviceUrl}/update/${id}`;
|
|
25816
|
+
-
|
|
25817
|
+
- const res: IPackage = await ApiService.patch(endpoint, data);
|
|
25678
25818
|
-
|
|
25679
25819
|
- set({ package: res }); // keep local copy fresh
|
|
25680
|
-
|
|
25681
|
-
|
|
25682
|
-
|
|
25683
|
-
|
|
25684
|
-
|
|
25685
|
-
|
|
25686
|
-
|
|
25687
|
-
|
|
25688
|
-
|
|
25689
|
-
|
|
25690
|
-
|
|
25691
|
-
|
|
25692
|
-
|
|
25693
|
-
|
|
25694
|
-
|
|
25695
|
-
|
|
25696
|
-
|
|
25697
|
-
|
|
25698
|
-
|
|
25699
|
-
|
|
25820
|
+
- return res;
|
|
25821
|
+
- } catch (err: any) {
|
|
25822
|
+
-
|
|
25823
|
+
- const status = err?.response?.status || null;
|
|
25824
|
+
- const errorMsg = err?.response?.data?.detail || err?.response?.data?.message || err?.message || 'Update failed';
|
|
25825
|
+
- set({ error: errorMsg, errorStatus: status });
|
|
25826
|
+
- throw err; // Re-throw to allow component to handle
|
|
25827
|
+
- } finally {
|
|
25828
|
+
- set({ loading: false });
|
|
25829
|
+
- }
|
|
25830
|
+
- },
|
|
25831
|
+
-
|
|
25832
|
+
- /** PATCH a single detail row (service) */
|
|
25833
|
+
- updatePackageDetail: async (detailId: number, payload: Record<string, any>) => {
|
|
25834
|
+
- try {
|
|
25835
|
+
- set({ loading: true, error: null, errorStatus: null });
|
|
25836
|
+
- const res = await ApiService.patch(
|
|
25837
|
+
- `${serviceUrl}/update_detail/${detailId}`,
|
|
25838
|
+
- payload,
|
|
25839
|
+
- );
|
|
25840
|
+
-
|
|
25841
|
+
- /* If backend returns parent id refresh local state */
|
|
25842
|
+
- const pkgId = res?.package_id;
|
|
25843
|
+
- if (typeof pkgId === 'number') await get().getPackageById(pkgId);
|
|
25844
|
+
-
|
|
25845
|
+
- return res;
|
|
25846
|
+
- } catch (err: any) {
|
|
25847
|
+
- const status = err?.response?.status || null;
|
|
25848
|
+
- set({ error: err.message || 'Detail update failed', errorStatus: status });
|
|
25849
|
+
- throw err;
|
|
25850
|
+
- } finally {
|
|
25851
|
+
- set({ loading: false });
|
|
25852
|
+
- }
|
|
25853
|
+
- },
|
|
25854
|
+
-
|
|
25855
|
+
- /** POST new groups to an existing package */
|
|
25856
|
+
- addPackageGroup: async (packageId, groups) => {
|
|
25857
|
+
- try {
|
|
25858
|
+
- set({ loading: true, error: null, errorStatus: null });
|
|
25859
|
+
- const res = await ApiService.post(
|
|
25860
|
+
- `${serviceUrl}/add_group/${packageId}`,
|
|
25861
|
+
- groups,
|
|
25862
|
+
- );
|
|
25863
|
+
- // Refresh package data after adding groups
|
|
25864
|
+
- await get().getPackageById(packageId);
|
|
25865
|
+
- return res;
|
|
25866
|
+
- } catch (err: any) {
|
|
25867
|
+
- const status = err?.response?.status || null;
|
|
25868
|
+
- set({ error: err.message || 'Adding group failed', errorStatus: status });
|
|
25869
|
+
- throw err;
|
|
25870
|
+
- } finally {
|
|
25871
|
+
- set({ loading: false });
|
|
25872
|
+
- }
|
|
25873
|
+
- },
|
|
25700
25874
|
-
|
|
25701
25875
|
-
|
|
25702
25876
|
-}));
|
|
25877
|
+
+ },
|
|
25703
25878
|
+ };
|
|
25704
25879
|
+});
|
|
25705
25880
|
diff --git a/node_modules/@suflon/native-ui/src/store/patient.store.ts b/node_modules/@suflon/native-ui/src/store/patient.store.ts
|
|
@@ -88,7 +88,8 @@ const Reporting = ({ onBackPress }: { onBackPress?: () => void } = {}) => {
|
|
|
88
88
|
showActionIcon={false}
|
|
89
89
|
/>
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
{/* Fixed Top Controls */}
|
|
92
|
+
<View>
|
|
92
93
|
{/* Search Bar */}
|
|
93
94
|
<View className="px-4 pt-3.5">
|
|
94
95
|
<SearchFilter
|
|
@@ -134,7 +135,7 @@ const Reporting = ({ onBackPress }: { onBackPress?: () => void } = {}) => {
|
|
|
134
135
|
)}
|
|
135
136
|
|
|
136
137
|
{/* Category Pills Switcher - Dynamic from response */}
|
|
137
|
-
<View className="
|
|
138
|
+
<View className="py-4">
|
|
138
139
|
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{ paddingHorizontal: 16, gap: 8 }}>
|
|
139
140
|
{categoryTabs.map((tab) => {
|
|
140
141
|
const isActive = activeTabId === tab.id;
|
|
@@ -189,58 +190,58 @@ const Reporting = ({ onBackPress }: { onBackPress?: () => void } = {}) => {
|
|
|
189
190
|
})}
|
|
190
191
|
</ScrollView>
|
|
191
192
|
</View>
|
|
193
|
+
</View>
|
|
192
194
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
195
|
+
{/* Scrollable Report Catalog List ONLY */}
|
|
196
|
+
<ScrollView className="flex-1" contentContainerStyle={{ paddingHorizontal: 16, paddingBottom: 30, gap: 10 }}>
|
|
197
|
+
{loading ? (
|
|
198
|
+
<View className="py-10">
|
|
199
|
+
<Loader message="Loading reports catalog..." color={iconBrandColor} />
|
|
200
|
+
</View>
|
|
201
|
+
) : filteredReports.length === 0 ? (
|
|
202
|
+
<View className="bg-white dark:bg-background-darkSecondaryBg p-8 rounded-2xl items-center mt-2.5 border border-slate-200 dark:border-gray-800">
|
|
203
|
+
<Text className="text-slate-500 dark:text-gray-400 text-xs font-semibold">No reports match the selected category</Text>
|
|
204
|
+
</View>
|
|
205
|
+
) : (
|
|
206
|
+
filteredReports.map((item) => (
|
|
207
|
+
<TouchableOpacity
|
|
208
|
+
key={item.id}
|
|
209
|
+
onPress={() => handleReportPress(item)}
|
|
210
|
+
activeOpacity={0.8}
|
|
211
|
+
className="bg-white dark:bg-background-darkSecondaryBg rounded-2xl p-3.5 border border-slate-200 dark:border-gray-800 flex-row items-center"
|
|
212
|
+
>
|
|
213
|
+
<View className="flex-row items-center gap-3 flex-1">
|
|
214
|
+
<View className="w-10 h-10 rounded-xl bg-violet-50 dark:bg-violet-950/40 items-center justify-center">
|
|
215
|
+
<Icon
|
|
216
|
+
name={SUB_CLASS_ICON_MAP[item.sub_report_class] || (item.is_dynamic ? "pie-chart" : "file-text")}
|
|
217
|
+
type="Feather"
|
|
218
|
+
size={20}
|
|
219
|
+
color={iconBrandColor}
|
|
220
|
+
/>
|
|
221
|
+
</View>
|
|
220
222
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
223
|
+
<View className="flex-1">
|
|
224
|
+
<Text className="text-[13px] font-extrabold text-slate-900 dark:text-text-dark-primary" numberOfLines={1}>
|
|
225
|
+
{item.name}
|
|
226
|
+
</Text>
|
|
227
|
+
<View className="flex-row items-center gap-1.5 mt-0.5">
|
|
228
|
+
<Text className="text-[10px] font-bold text-violet-600 dark:text-violet-400">
|
|
229
|
+
{SUB_CLASS_LABEL_MAP[item.sub_report_class] || item.sub_report_class || 'Report'}
|
|
230
|
+
</Text>
|
|
231
|
+
<Text className="text-[10px] text-slate-400 dark:text-gray-500">•</Text>
|
|
232
|
+
<Text className="text-[10px] font-semibold text-slate-500 dark:text-gray-400">
|
|
233
|
+
{item.report_type || 'LISTING'}
|
|
224
234
|
</Text>
|
|
225
|
-
<View className="flex-row items-center gap-1.5 mt-0.5">
|
|
226
|
-
<Text className="text-[10px] font-bold text-violet-600 dark:text-violet-400">
|
|
227
|
-
{SUB_CLASS_LABEL_MAP[item.sub_report_class] || item.sub_report_class || 'Report'}
|
|
228
|
-
</Text>
|
|
229
|
-
<Text className="text-[10px] text-slate-400 dark:text-gray-500">•</Text>
|
|
230
|
-
<Text className="text-[10px] font-semibold text-slate-500 dark:text-gray-400">
|
|
231
|
-
{item.report_type || 'LISTING'}
|
|
232
|
-
</Text>
|
|
233
|
-
</View>
|
|
234
235
|
</View>
|
|
235
236
|
</View>
|
|
237
|
+
</View>
|
|
236
238
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
</View>
|
|
239
|
+
<View className="flex-row items-center gap-1.5">
|
|
240
|
+
<Icon name="chevron-right" type="Feather" size={18} color={iconMutedColor} />
|
|
241
|
+
</View>
|
|
242
|
+
</TouchableOpacity>
|
|
243
|
+
))
|
|
244
|
+
)}
|
|
244
245
|
</ScrollView>
|
|
245
246
|
</SafeAreaView>
|
|
246
247
|
);
|
|
@@ -85,7 +85,7 @@ const DEV_STRINGS: Record<LanguageCode, Record<string, string>> = {
|
|
|
85
85
|
|
|
86
86
|
// Default dev values
|
|
87
87
|
const DEFAULT_VALUES = {
|
|
88
|
-
authToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
|
|
88
|
+
authToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwiZXhwIjoxOTQxNzEwNzI5LCJ0aWQiOiJka2t3Ynd1ZyIsImNsdCI6IldFQiIsInNjb3BlIjoiQ09NUEFOWSIsImNvbXBhbnlfaWQiOjIsInJlZ2lvbl9pZCI6MSwic3RhZmZfaWQiOjF9.hPQC0_-uFfHU253gvJi-eJD1HnM8fGWA0lG3IRVs09I',
|
|
89
89
|
companyId: '2',
|
|
90
90
|
regionId: '1',
|
|
91
91
|
staffId: '1',
|