@imksh/create 1.0.31 → 1.0.32
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 +2 -0
- package/package.json +1 -1
- package/src/commands/create.js +2 -0
- package/src/index.js +1 -1
- package/templates/layers/next/javascript/package.json +8 -2
- package/templates/layers/next/typescript/.eslintrc.json +12 -0
- package/templates/layers/next/typescript/package.json +14 -3
- package/templates/layers/next/typescript/src/components/common/Loading.tsx +1 -1
- package/templates/layers/next/typescript/src/components/common/LottieIcon.tsx +2 -2
- package/templates/layers/next/typescript/src/components/common/Table.tsx +4 -4
- package/templates/layers/next/typescript/src/components/modals/ConfirmModal.tsx +2 -1
- package/templates/layers/next/typescript/src/components/ui/Header.tsx +2 -2
- package/templates/layers/next/typescript/src/hooks/usePwaInstall.ts +10 -4
- package/templates/layers/next/typescript/src/services/authService.ts +1 -1
- package/templates/layers/next/typescript/src/store/useAuthStore.ts +24 -9
- package/templates/layers/node/javascript/.env.example +3 -1
- package/templates/layers/node/javascript/package.json +12 -3
- package/templates/layers/node/javascript/src/app.js +2 -1
- package/templates/layers/node/javascript/src/controllers/auth.controller.js +106 -168
- package/templates/layers/node/javascript/src/controllers/push.controller.js +51 -58
- package/templates/layers/node/javascript/src/controllers/upload.controller.js +12 -19
- package/templates/layers/node/javascript/src/middleware/auth.middleware.js +5 -11
- package/templates/layers/node/javascript/src/middleware/errorHandler.js +6 -4
- package/templates/layers/node/javascript/src/routes/auth.route.js +2 -0
- package/templates/layers/node/javascript/src/services/auth.service.js +159 -164
- package/templates/layers/node/javascript/src/utils/ApiError.js +20 -0
- package/templates/layers/node/javascript/src/utils/SuccessResponse.js +15 -0
- package/templates/layers/node/javascript/src/utils/apiResponse.js +4 -0
- package/templates/layers/node/javascript/src/utils/asyncHandler.js +5 -0
- package/templates/layers/node/typescript/.env.example +3 -1
- package/templates/layers/node/typescript/.eslintrc.cjs +28 -0
- package/templates/layers/node/typescript/package.json +16 -2
- package/templates/layers/node/typescript/src/app.ts +3 -2
- package/templates/layers/node/typescript/src/config/db.ts +3 -2
- package/templates/layers/node/typescript/src/config/socket.ts +5 -4
- package/templates/layers/node/typescript/src/controllers/auth.controller.ts +104 -132
- package/templates/layers/node/typescript/src/controllers/push.controller.ts +52 -59
- package/templates/layers/node/typescript/src/controllers/upload.controller.ts +12 -19
- package/templates/layers/node/typescript/src/middleware/auth.middleware.ts +13 -7
- package/templates/layers/node/typescript/src/middleware/errorHandler.ts +18 -5
- package/templates/layers/node/typescript/src/middleware/rateLimiter.ts +2 -2
- package/templates/layers/node/typescript/src/routes/auth.route.ts +2 -0
- package/templates/layers/node/typescript/src/services/auth.service.ts +86 -43
- package/templates/layers/node/typescript/src/types/express.d.ts +5 -3
- package/templates/layers/node/typescript/src/utils/ApiError.ts +25 -0
- package/templates/layers/node/typescript/src/utils/SuccessResponse.ts +17 -0
- package/templates/layers/node/typescript/src/utils/apiResponse.ts +4 -0
- package/templates/layers/node/typescript/src/utils/asyncHandler.ts +13 -0
- package/templates/layers/node/typescript/src/utils/cloudinaryUpload.ts +18 -7
- package/templates/layers/node/typescript/src/utils/expoNotification.ts +1 -1
- package/templates/layers/node/typescript/src/utils/genOtpToken.ts +7 -1
- package/templates/layers/node/typescript/src/utils/jwt.ts +8 -2
- package/templates/layers/node/typescript/src/utils/logger.ts +2 -1
- package/templates/layers/node/typescript/src/utils/pushHelper.ts +13 -9
- package/templates/layers/node-prisma/javascript/.env.example +3 -1
- package/templates/layers/node-prisma/javascript/package.json +11 -2
- package/templates/layers/node-prisma/javascript/src/app.js +2 -1
- package/templates/layers/node-prisma/javascript/src/controllers/auth.controller.js +90 -135
- package/templates/layers/node-prisma/javascript/src/controllers/push.controller.js +64 -76
- package/templates/layers/node-prisma/javascript/src/controllers/upload.controller.js +12 -19
- package/templates/layers/node-prisma/javascript/src/middleware/auth.middleware.js +5 -4
- package/templates/layers/node-prisma/javascript/src/middleware/errorHandler.js +6 -4
- package/templates/layers/node-prisma/javascript/src/routes/auth.route.js +2 -0
- package/templates/layers/node-prisma/javascript/src/services/auth.service.js +145 -122
- package/templates/layers/node-prisma/javascript/src/utils/ApiError.js +20 -0
- package/templates/layers/node-prisma/javascript/src/utils/SuccessResponse.js +15 -0
- package/templates/layers/node-prisma/javascript/src/utils/apiResponse.js +4 -0
- package/templates/layers/node-prisma/javascript/src/utils/asyncHandler.js +5 -0
- package/templates/layers/node-prisma/typescript/.env.example +3 -1
- package/templates/layers/node-prisma/typescript/.eslintrc.cjs +28 -0
- package/templates/layers/node-prisma/typescript/package.json +19 -5
- package/templates/layers/node-prisma/typescript/src/app.ts +3 -2
- package/templates/layers/node-prisma/typescript/src/config/prisma.ts +3 -2
- package/templates/layers/node-prisma/typescript/src/config/socket.ts +5 -4
- package/templates/layers/node-prisma/typescript/src/controllers/auth.controller.ts +89 -105
- package/templates/layers/node-prisma/typescript/src/controllers/push.controller.ts +67 -83
- package/templates/layers/node-prisma/typescript/src/controllers/upload.controller.ts +12 -19
- package/templates/layers/node-prisma/typescript/src/middleware/auth.middleware.ts +9 -13
- package/templates/layers/node-prisma/typescript/src/middleware/errorHandler.ts +18 -5
- package/templates/layers/node-prisma/typescript/src/middleware/rateLimiter.ts +2 -2
- package/templates/layers/node-prisma/typescript/src/routes/auth.route.ts +2 -0
- package/templates/layers/node-prisma/typescript/src/services/auth.service.ts +83 -31
- package/templates/layers/node-prisma/typescript/src/types/express.d.ts +5 -3
- package/templates/layers/node-prisma/typescript/src/utils/ApiError.ts +25 -0
- package/templates/layers/node-prisma/typescript/src/utils/SuccessResponse.ts +17 -0
- package/templates/layers/node-prisma/typescript/src/utils/apiResponse.ts +4 -0
- package/templates/layers/node-prisma/typescript/src/utils/asyncHandler.ts +13 -0
- package/templates/layers/node-prisma/typescript/src/utils/cloudinaryUpload.ts +18 -7
- package/templates/layers/node-prisma/typescript/src/utils/genOtpToken.ts +7 -1
- package/templates/layers/node-prisma/typescript/src/utils/jwt.ts +8 -2
- package/templates/layers/node-prisma/typescript/src/utils/logger.ts +2 -1
- package/templates/layers/node-prisma/typescript/src/utils/pushHelper.ts +10 -6
- package/templates/layers/prisma/javascript/package.json +8 -0
- package/templates/layers/prisma/typescript/package.json +14 -1
- package/templates/layers/prisma/typescript/src/config/db.ts +3 -2
- package/templates/layers/react/javascript/package.json +6 -0
- package/templates/layers/react/typescript/.eslintrc.cjs +20 -0
- package/templates/layers/react/typescript/package.json +11 -2
- package/templates/layers/react/typescript/src/components/common/Table.tsx +4 -4
- package/templates/layers/react/typescript/src/components/ui/Sidebar.tsx +1 -1
- package/templates/layers/react/typescript/src/main.tsx +11 -11
- package/templates/layers/react/typescript/src/services/authService.ts +1 -1
- package/templates/layers/react/typescript/src/store/useAuthStore.ts +24 -9
- package/templates/layers/react-native/base/app.json +9 -22
- package/templates/layers/react-native/base/eslint.config.js +5 -1
- package/templates/layers/react-native/base/package.json +11 -1
- package/templates/layers/react-native/base/src/app/(auth)/edit-profile.tsx +7 -7
- package/templates/layers/react-native/base/src/app/(auth)/login.tsx +31 -7
- package/templates/layers/react-native/base/src/app/(tabs)/_layout.tsx +3 -3
- package/templates/layers/react-native/base/src/app/(tabs)/index.tsx +6 -5
- package/templates/layers/react-native/base/src/app/_layout.tsx +3 -3
- package/templates/layers/react-native/base/src/app/doc-viewer.tsx +3 -3
- package/templates/layers/react-native/base/src/components/common/ConfirmationToast.tsx +58 -40
- package/templates/layers/react-native/base/src/components/common/GoogleAuthButton.tsx +144 -0
- package/templates/layers/react-native/base/src/components/common/LocationLoader.tsx +64 -9
- package/templates/layers/react-native/base/src/components/common/Typography.tsx +54 -19
- package/templates/layers/react-native/base/src/components/ui/ClassicTabBar.tsx +15 -12
- package/templates/layers/react-native/base/src/components/ui/CustomTabBar.tsx +84 -90
- package/templates/layers/react-native/base/src/components/ui/Drawer.tsx +344 -0
- package/templates/layers/react-native/base/src/components/ui/Sidebar.tsx +4 -4
- package/templates/layers/react-native/base/src/components/ui/buttons/Button.tsx +29 -6
- package/templates/layers/react-native/base/src/components/ui/data-display/Accordion.tsx +2 -2
- package/templates/layers/react-native/base/src/components/ui/data-display/Badge.tsx +1 -2
- package/templates/layers/react-native/base/src/components/ui/data-display/Image.tsx +3 -3
- package/templates/layers/react-native/base/src/components/ui/data-display/SwipeableRow.tsx +28 -7
- package/templates/layers/react-native/base/src/components/ui/feedback/GestureWrapper.tsx +11 -4
- package/templates/layers/react-native/base/src/components/ui/inputs/DatePicker.tsx +3 -3
- package/templates/layers/react-native/base/src/components/ui/inputs/ImagePickerModal.tsx +45 -19
- package/templates/layers/react-native/base/src/components/ui/inputs/Input.tsx +28 -9
- package/templates/layers/react-native/base/src/components/ui/inputs/SearchablePicker.tsx +199 -0
- package/templates/layers/react-native/base/src/components/ui/inputs/Switch.tsx +7 -7
- package/templates/layers/react-native/base/src/components/ui/inputs/WebLocationPicker.tsx +146 -72
- package/templates/layers/react-native/base/src/config/api.ts +5 -5
- package/templates/layers/react-native/base/src/services/auth.service.ts +3 -1
- package/templates/layers/react-native/base/src/services/permission.service.ts +0 -2
- package/templates/layers/react-native/base/src/services/socket.service.ts +0 -7
- package/templates/layers/react-native/base/src/store/useAuthStore.ts +61 -16
- package/templates/layers/react-native/base/src/store/useNotificationStore.ts +36 -42
- package/templates/layers/react-native/base/src/types/images.d.ts +7 -5
- package/templates/layers/react-native/base/src/utils/fileDownload.ts +206 -0
- package/templates/layers/react-native/base/src/utils/storage.ts +1 -1
- package/templates/presets/production-fullstack/overrides/client/package.json +9 -0
- package/templates/presets/production-fullstack/overrides/mobile/app.json +2 -15
- package/templates/presets/production-fullstack/overrides/mobile/package.json +11 -1
- package/templates/presets/production-fullstack/overrides/mobile/src/app/_layout.tsx +3 -3
- package/templates/presets/production-fullstack/overrides/mobile/src/components/ui/Drawer.tsx +344 -0
- package/templates/presets/production-fullstack/overrides/mobile/src/components/ui/inputs/DatePicker.tsx +3 -3
- package/templates/presets/production-fullstack/overrides/mobile/src/components/ui/inputs/ImagePickerModal.tsx +3 -3
- package/templates/presets/production-fullstack/overrides/server/package.json +11 -2
- package/templates/layers/react-native/base/src/components/ui/BottomModal.tsx +0 -176
- package/templates/presets/production-fullstack/overrides/mobile/src/components/ui/BottomModal.tsx +0 -159
- /package/templates/layers/react-native/base/assets/images/logo/{logoWithBg.png → icon.png} +0 -0
|
@@ -1,24 +1,26 @@
|
|
|
1
|
+
import type { ImageSourcePropType } from "react-native";
|
|
2
|
+
|
|
1
3
|
declare module "*.png" {
|
|
2
|
-
const value:
|
|
4
|
+
const value: ImageSourcePropType;
|
|
3
5
|
export default value;
|
|
4
6
|
}
|
|
5
7
|
|
|
6
8
|
declare module "*.jpg" {
|
|
7
|
-
const value:
|
|
9
|
+
const value: ImageSourcePropType;
|
|
8
10
|
export default value;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
declare module "*.jpeg" {
|
|
12
|
-
const value:
|
|
14
|
+
const value: ImageSourcePropType;
|
|
13
15
|
export default value;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
declare module "*.gif" {
|
|
17
|
-
const value:
|
|
19
|
+
const value: ImageSourcePropType;
|
|
18
20
|
export default value;
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
declare module "*.svg" {
|
|
22
|
-
const value:
|
|
24
|
+
const value: ImageSourcePropType;
|
|
23
25
|
export default value;
|
|
24
26
|
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { Platform } from "react-native";
|
|
2
|
+
import { toast } from "./toast";
|
|
3
|
+
import * as FileSystem from "expo-file-system/legacy";
|
|
4
|
+
import * as Sharing from "expo-sharing";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Downloads a string or base64 data to a file.
|
|
8
|
+
* - On Web: triggers browser download via an anchor element and Blob.
|
|
9
|
+
* - On Android: saves to user-selected folder via StorageAccessFramework.
|
|
10
|
+
* - On iOS: writes to app document directory and opens native iOS Share/Save sheet.
|
|
11
|
+
*/
|
|
12
|
+
export const downloadFileString = async (
|
|
13
|
+
content: string,
|
|
14
|
+
filename: string,
|
|
15
|
+
mimeType: string,
|
|
16
|
+
isBase64: boolean = false
|
|
17
|
+
): Promise<boolean> => {
|
|
18
|
+
if (Platform.OS === "web") {
|
|
19
|
+
try {
|
|
20
|
+
let blob: Blob;
|
|
21
|
+
if (isBase64) {
|
|
22
|
+
const byteCharacters = atob(content);
|
|
23
|
+
const byteArrays: Uint8Array[] = [];
|
|
24
|
+
for (let offset = 0; offset < byteCharacters.length; offset += 512) {
|
|
25
|
+
const slice = byteCharacters.slice(offset, offset + 512);
|
|
26
|
+
const byteNumbers = new Array(slice.length);
|
|
27
|
+
for (let i = 0; i < slice.length; i++) {
|
|
28
|
+
byteNumbers[i] = slice.charCodeAt(i);
|
|
29
|
+
}
|
|
30
|
+
const byteArray = new Uint8Array(byteNumbers);
|
|
31
|
+
byteArrays.push(byteArray);
|
|
32
|
+
}
|
|
33
|
+
blob = new Blob(byteArrays, { type: mimeType });
|
|
34
|
+
} else {
|
|
35
|
+
blob = new Blob([content], { type: mimeType });
|
|
36
|
+
}
|
|
37
|
+
const link = document.createElement("a");
|
|
38
|
+
const url = URL.createObjectURL(blob);
|
|
39
|
+
link.setAttribute("href", url);
|
|
40
|
+
link.setAttribute("download", filename);
|
|
41
|
+
link.style.visibility = "hidden";
|
|
42
|
+
document.body.appendChild(link);
|
|
43
|
+
link.click();
|
|
44
|
+
document.body.removeChild(link);
|
|
45
|
+
URL.revokeObjectURL(url);
|
|
46
|
+
return true;
|
|
47
|
+
} catch (error: unknown) {
|
|
48
|
+
const err = error as Error;
|
|
49
|
+
toast.error("Error", err.message || `Failed to download ${filename}`);
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const encoding = isBase64
|
|
56
|
+
? FileSystem.EncodingType.Base64
|
|
57
|
+
: FileSystem.EncodingType.UTF8;
|
|
58
|
+
|
|
59
|
+
if (Platform.OS === "android") {
|
|
60
|
+
const permissions =
|
|
61
|
+
await FileSystem.StorageAccessFramework.requestDirectoryPermissionsAsync();
|
|
62
|
+
if (!permissions.granted) {
|
|
63
|
+
toast.info("Cancelled", "Directory permission was not granted.");
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const createdFileUri =
|
|
68
|
+
await FileSystem.StorageAccessFramework.createFileAsync(
|
|
69
|
+
permissions.directoryUri,
|
|
70
|
+
filename,
|
|
71
|
+
mimeType
|
|
72
|
+
);
|
|
73
|
+
await FileSystem.writeAsStringAsync(createdFileUri, content, {
|
|
74
|
+
encoding,
|
|
75
|
+
});
|
|
76
|
+
toast.success("Success", `${filename} saved successfully!`);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// iOS and other native platforms
|
|
81
|
+
const baseDir =
|
|
82
|
+
FileSystem.documentDirectory ?? FileSystem.cacheDirectory ?? "";
|
|
83
|
+
const fileUri = `${baseDir}${filename}`;
|
|
84
|
+
await FileSystem.writeAsStringAsync(fileUri, content, { encoding });
|
|
85
|
+
|
|
86
|
+
const isSharingAvailable = await Sharing.isAvailableAsync();
|
|
87
|
+
if (isSharingAvailable) {
|
|
88
|
+
await Sharing.shareAsync(fileUri, {
|
|
89
|
+
mimeType,
|
|
90
|
+
dialogTitle: `Save ${filename}`,
|
|
91
|
+
UTI: mimeType,
|
|
92
|
+
});
|
|
93
|
+
toast.success("Success", "File ready to save or share.");
|
|
94
|
+
return true;
|
|
95
|
+
} else {
|
|
96
|
+
toast.error("Error", "Sharing is not available on this device.");
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
} catch (error: unknown) {
|
|
100
|
+
const err = error as Error;
|
|
101
|
+
toast.error("Error", err.message || `Failed to download ${filename}`);
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Downloads a CSV string as a .csv file.
|
|
108
|
+
*/
|
|
109
|
+
export const downloadCsvString = async (
|
|
110
|
+
csvString: string,
|
|
111
|
+
filename: string = "export.csv"
|
|
112
|
+
): Promise<boolean> => {
|
|
113
|
+
return downloadFileString(csvString, filename, "text/csv;charset=utf-8;");
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Downloads JSON data as a formatted .json file.
|
|
118
|
+
*/
|
|
119
|
+
export const downloadJson = async (
|
|
120
|
+
data: unknown,
|
|
121
|
+
filename: string = "export.json"
|
|
122
|
+
): Promise<boolean> => {
|
|
123
|
+
const jsonString = JSON.stringify(data, null, 2);
|
|
124
|
+
return downloadFileString(jsonString, filename, "application/json");
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Downloads a file from a remote URL.
|
|
129
|
+
* - On Web: triggers browser download.
|
|
130
|
+
* - On Mobile: downloads to local filesystem, then prompts to save on Android
|
|
131
|
+
* via StorageAccessFramework or opens iOS Share sheet.
|
|
132
|
+
*/
|
|
133
|
+
export const downloadFileFromUrl = async (
|
|
134
|
+
url: string,
|
|
135
|
+
filename: string,
|
|
136
|
+
mimeType: string = "application/octet-stream"
|
|
137
|
+
): Promise<boolean> => {
|
|
138
|
+
if (Platform.OS === "web") {
|
|
139
|
+
try {
|
|
140
|
+
const link = document.createElement("a");
|
|
141
|
+
link.href = url;
|
|
142
|
+
link.download = filename;
|
|
143
|
+
link.target = "_blank";
|
|
144
|
+
link.style.visibility = "hidden";
|
|
145
|
+
document.body.appendChild(link);
|
|
146
|
+
link.click();
|
|
147
|
+
document.body.removeChild(link);
|
|
148
|
+
return true;
|
|
149
|
+
} catch (error: unknown) {
|
|
150
|
+
const err = error as Error;
|
|
151
|
+
toast.error("Error", err.message || `Failed to download ${filename}`);
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
const baseDir =
|
|
158
|
+
FileSystem.cacheDirectory ?? FileSystem.documentDirectory ?? "";
|
|
159
|
+
const localUri = `${baseDir}${filename}`;
|
|
160
|
+
const result = await FileSystem.downloadAsync(url, localUri);
|
|
161
|
+
|
|
162
|
+
if (Platform.OS === "android") {
|
|
163
|
+
const permissions =
|
|
164
|
+
await FileSystem.StorageAccessFramework.requestDirectoryPermissionsAsync();
|
|
165
|
+
if (!permissions.granted) {
|
|
166
|
+
toast.info("Cancelled", "Directory permission was not granted.");
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const fileBase64 = await FileSystem.readAsStringAsync(result.uri, {
|
|
171
|
+
encoding: FileSystem.EncodingType.Base64,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const createdFileUri =
|
|
175
|
+
await FileSystem.StorageAccessFramework.createFileAsync(
|
|
176
|
+
permissions.directoryUri,
|
|
177
|
+
filename,
|
|
178
|
+
mimeType
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
await FileSystem.writeAsStringAsync(createdFileUri, fileBase64, {
|
|
182
|
+
encoding: FileSystem.EncodingType.Base64,
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
toast.success("Success", `${filename} saved successfully!`);
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const isSharingAvailable = await Sharing.isAvailableAsync();
|
|
190
|
+
if (isSharingAvailable) {
|
|
191
|
+
await Sharing.shareAsync(result.uri, {
|
|
192
|
+
mimeType,
|
|
193
|
+
dialogTitle: `Save ${filename}`,
|
|
194
|
+
});
|
|
195
|
+
toast.success("Success", "File ready to save or share.");
|
|
196
|
+
return true;
|
|
197
|
+
} else {
|
|
198
|
+
toast.error("Error", "Sharing is not available on this device.");
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
} catch (error: unknown) {
|
|
202
|
+
const err = error as Error;
|
|
203
|
+
toast.error("Error", err.message || `Failed to download ${filename}`);
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
2
2
|
|
|
3
3
|
// Save data
|
|
4
|
-
export const save = async (key: string, value:
|
|
4
|
+
export const save = async (key: string, value: unknown) => {
|
|
5
5
|
if (!key || !value) return;
|
|
6
6
|
try {
|
|
7
7
|
const jsonValue = JSON.stringify(value);
|
|
@@ -7,6 +7,12 @@
|
|
|
7
7
|
"dev": "vite",
|
|
8
8
|
"build": "tsc && vite build",
|
|
9
9
|
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
10
|
+
"lint:fix": "eslint . --ext ts,tsx --fix",
|
|
11
|
+
"format": "prettier --write \"src/**/*.{ts,tsx,css,json}\"",
|
|
12
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx,css,json}\"",
|
|
13
|
+
"circular-check": "dpdm --circular --no-warning --no-tree --exit-code circular:1 \"src/**/*.{ts,tsx}\"",
|
|
14
|
+
"ts-prune": "ts-prune",
|
|
15
|
+
"ts-purns": "ts-prune",
|
|
10
16
|
"preview": "vite preview"
|
|
11
17
|
},
|
|
12
18
|
"dependencies": {
|
|
@@ -37,10 +43,13 @@
|
|
|
37
43
|
"@typescript-eslint/eslint-plugin": "^6.10.0",
|
|
38
44
|
"@typescript-eslint/parser": "^6.10.0",
|
|
39
45
|
"@vitejs/plugin-react": "^4.2.0",
|
|
46
|
+
"dpdm": "^3.14.0",
|
|
40
47
|
"eslint": "^8.53.0",
|
|
41
48
|
"eslint-plugin-react": "^7.33.2",
|
|
42
49
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
43
50
|
"eslint-plugin-react-refresh": "^0.4.4",
|
|
51
|
+
"prettier": "^3.4.2",
|
|
52
|
+
"ts-prune": "^0.10.3",
|
|
44
53
|
"typescript": "^5.2.2",
|
|
45
54
|
"vite": "^5.0.0"
|
|
46
55
|
}
|
|
@@ -22,16 +22,8 @@
|
|
|
22
22
|
"package": "com.anonymous.mobile",
|
|
23
23
|
"permissions": [
|
|
24
24
|
"android.permission.CAMERA",
|
|
25
|
-
"android.permission.RECORD_AUDIO",
|
|
26
25
|
"android.permission.ACCESS_FINE_LOCATION",
|
|
27
|
-
"android.permission.ACCESS_COARSE_LOCATION"
|
|
28
|
-
"android.permission.READ_CONTACTS",
|
|
29
|
-
"android.permission.READ_CALENDAR",
|
|
30
|
-
"android.permission.READ_EXTERNAL_STORAGE",
|
|
31
|
-
"android.permission.WRITE_EXTERNAL_STORAGE",
|
|
32
|
-
"android.permission.BLUETOOTH_CONNECT",
|
|
33
|
-
"android.permission.BLUETOOTH_SCAN",
|
|
34
|
-
"android.permission.CALL_PHONE"
|
|
26
|
+
"android.permission.ACCESS_COARSE_LOCATION"
|
|
35
27
|
]
|
|
36
28
|
},
|
|
37
29
|
"web": {
|
|
@@ -58,14 +50,9 @@
|
|
|
58
50
|
{
|
|
59
51
|
"iosPermissions": [
|
|
60
52
|
"Camera",
|
|
61
|
-
"Microphone",
|
|
62
|
-
"LocationAlways",
|
|
63
53
|
"LocationWhenInUse",
|
|
64
54
|
"Notifications",
|
|
65
|
-
"PhotoLibrary"
|
|
66
|
-
"Contacts",
|
|
67
|
-
"Calendars",
|
|
68
|
-
"BluetoothPeripheral"
|
|
55
|
+
"PhotoLibrary"
|
|
69
56
|
]
|
|
70
57
|
}
|
|
71
58
|
]
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
"expo-blur": "~57.0.2",
|
|
19
19
|
"expo-constants": "~57.0.6",
|
|
20
20
|
"expo-device": "~57.0.1",
|
|
21
|
+
"expo-file-system": "~18.0.7",
|
|
22
|
+
"expo-sharing": "~13.0.1",
|
|
21
23
|
"expo-font": "~57.0.1",
|
|
22
24
|
"expo-glass-effect": "~57.0.1",
|
|
23
25
|
"expo-image": "~57.0.1",
|
|
@@ -61,9 +63,12 @@
|
|
|
61
63
|
"devDependencies": {
|
|
62
64
|
"@types/react": "~19.2.2",
|
|
63
65
|
"babel-plugin-inline-import": "^3.0.0",
|
|
66
|
+
"dpdm": "^3.14.0",
|
|
64
67
|
"drizzle-kit": "^0.31.10",
|
|
65
68
|
"eslint": "^9.0.0",
|
|
66
69
|
"eslint-config-expo": "~57.0.0",
|
|
70
|
+
"prettier": "^3.4.2",
|
|
71
|
+
"ts-prune": "^0.10.3",
|
|
67
72
|
"typescript": "~6.0.3"
|
|
68
73
|
},
|
|
69
74
|
"scripts": {
|
|
@@ -74,7 +79,12 @@
|
|
|
74
79
|
"ios": "expo run:ios",
|
|
75
80
|
"web": "expo start --web",
|
|
76
81
|
"lint": "expo lint",
|
|
77
|
-
"
|
|
82
|
+
"lint:fix": "expo lint --fix",
|
|
83
|
+
"format": "prettier --write \"src/**/*.{ts,tsx,json}\"",
|
|
84
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx,json}\"",
|
|
85
|
+
"circular-check": "dpdm --circular --no-warning --no-tree --exit-code circular:1 \"src/**/*.{ts,tsx}\"",
|
|
86
|
+
"ts-prune": "ts-prune",
|
|
87
|
+
"ts-purns": "ts-prune",
|
|
78
88
|
"ts:check": "tsc --noEmit",
|
|
79
89
|
"build": "eas build",
|
|
80
90
|
"build:android": "eas build -p android",
|
|
@@ -63,8 +63,8 @@ export default function RootLayout() {
|
|
|
63
63
|
if (!user && !inAuthGroup) {
|
|
64
64
|
// Redirect to the auth group
|
|
65
65
|
router.replace("/(auth)/login");
|
|
66
|
-
} else if (user && inAuthGroup) {
|
|
67
|
-
// Redirect away from auth
|
|
66
|
+
} else if (user && (inAuthGroup || !segments[0])) {
|
|
67
|
+
// Redirect away from auth or root to main app tabs
|
|
68
68
|
router.replace("/(tabs)");
|
|
69
69
|
}
|
|
70
70
|
}, [user, isCheckingAuth, segments]);
|
|
@@ -94,8 +94,8 @@ export default function RootLayout() {
|
|
|
94
94
|
options={{ headerShown: false, animation: "fade" }}
|
|
95
95
|
/>
|
|
96
96
|
</Stack>
|
|
97
|
-
<Toast />
|
|
98
97
|
</PaperProvider>
|
|
98
|
+
<Toast />
|
|
99
99
|
</GestureHandlerRootView>
|
|
100
100
|
</QueryClientProvider>
|
|
101
101
|
);
|