@pagamio/frontend-commons-lib 0.8.196 → 0.8.198
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
|
@@ -39,6 +39,21 @@ yarn add pagamio-frontend-commons-lib
|
|
|
39
39
|
|
|
40
40
|
`import { DateInput, TextInput } from 'pagamio-frontend-commons-lib';`
|
|
41
41
|
|
|
42
|
+
### :gear: Environment Variables
|
|
43
|
+
|
|
44
|
+
Some utilities (for example the `useImageUpload` hook and `ImageUploader` component) require an API endpoint that issues presigned upload URLs. Make sure your host application exposes the following public environment variable before using those helpers:
|
|
45
|
+
|
|
46
|
+
| Variable | Description |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| `NEXT_PUBLIC_UPLOAD_URL_ENDPOINT` | HTTP endpoint that returns presigned URLs for file uploads. |
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# .env (per app)
|
|
52
|
+
NEXT_PUBLIC_UPLOAD_URL_ENDPOINT=https://<your-upload-service>/upload-url
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
This value is resolved at runtime;
|
|
56
|
+
|
|
42
57
|
## :shield: **RBAC Module**
|
|
43
58
|
|
|
44
59
|
The Role-Based Access Control (RBAC) module provides a flexible system for implementing permission-based access control in your applications.
|
|
@@ -4,8 +4,7 @@ import { Image as ImageIcon, Loader2, Upload, X } from 'lucide-react';
|
|
|
4
4
|
import { useDropzone } from 'react-dropzone';
|
|
5
5
|
import { useCallback, useState } from 'react';
|
|
6
6
|
import { Button, cn, useToast } from '../..';
|
|
7
|
-
import {
|
|
8
|
-
import { uploadFileWithXHR } from '../../shared/utils/functionHelper';
|
|
7
|
+
import { useImageUpload } from '../../shared/hooks/useImageUpload';
|
|
9
8
|
import { Progress } from './Progress';
|
|
10
9
|
const ImageUploader = ({ project, env, onUploadSuccess, onError, className, disabled = false, maxFileSize = 5 * 1024 * 1024, // 5MB default
|
|
11
10
|
acceptedFileTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'], placeholder = 'Click to upload or drag and drop an image', showPreview = true, value, onChange, }) => {
|
|
@@ -14,53 +13,7 @@ acceptedFileTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'], plac
|
|
|
14
13
|
const [uploadProgress, setUploadProgress] = useState(0);
|
|
15
14
|
const [error, setError] = useState(null);
|
|
16
15
|
const { addToast } = useToast();
|
|
17
|
-
const
|
|
18
|
-
const timestamp = Date.now();
|
|
19
|
-
const randomString = generateSecureRandomString();
|
|
20
|
-
const extension = originalName.split('.').pop() || 'jpg';
|
|
21
|
-
return `${timestamp}_${randomString}.${extension}`;
|
|
22
|
-
};
|
|
23
|
-
const getPresignedUrl = async (fileName, contentType) => {
|
|
24
|
-
// This should be configurable or injected, but for now using a default endpoint
|
|
25
|
-
const endpoint = process.env.NEXT_PUBLIC_UPLOAD_URL_ENDPOINT ||
|
|
26
|
-
'https://faas-ams3-2a2df116.doserverless.co/api/v1/web/fn-2c9f1cfc-1296-4367-89d8-12409763dae6/default/upload-url';
|
|
27
|
-
const response = await fetch(endpoint, {
|
|
28
|
-
method: 'POST',
|
|
29
|
-
headers: {
|
|
30
|
-
'Content-Type': 'application/json',
|
|
31
|
-
},
|
|
32
|
-
body: JSON.stringify({
|
|
33
|
-
project,
|
|
34
|
-
env,
|
|
35
|
-
fileName,
|
|
36
|
-
contentType,
|
|
37
|
-
}),
|
|
38
|
-
});
|
|
39
|
-
if (!response.ok) {
|
|
40
|
-
throw new Error(`Failed to get upload URL: ${response.statusText}`);
|
|
41
|
-
}
|
|
42
|
-
// --- FIX: unwrap .data if present ---
|
|
43
|
-
const json = await response.json();
|
|
44
|
-
const data = json.data || json;
|
|
45
|
-
return {
|
|
46
|
-
uploadURL: data.uploadURL,
|
|
47
|
-
publicURL: data.publicURL,
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
const uploadFile = async (file) => {
|
|
51
|
-
const fileName = generateFileName(file.name);
|
|
52
|
-
try {
|
|
53
|
-
// Get pre-signed URL
|
|
54
|
-
const { uploadURL, publicURL } = await getPresignedUrl(fileName, file.type);
|
|
55
|
-
// Upload file using XMLHttpRequest
|
|
56
|
-
await uploadFileWithXHR(uploadURL, file);
|
|
57
|
-
return publicURL;
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
console.error('Upload error:', error);
|
|
61
|
-
throw error;
|
|
62
|
-
}
|
|
63
|
-
};
|
|
16
|
+
const { uploadFile } = useImageUpload({ project, env });
|
|
64
17
|
const handleFileUpload = async (file) => {
|
|
65
18
|
if (disabled)
|
|
66
19
|
return;
|
|
@@ -7,7 +7,7 @@ export interface UseImageUploadProps {
|
|
|
7
7
|
env: 'dev' | 'uat' | 'prod';
|
|
8
8
|
endpoint?: string;
|
|
9
9
|
}
|
|
10
|
-
export declare const useImageUpload: ({ project, env, endpoint
|
|
10
|
+
export declare const useImageUpload: ({ project, env, endpoint }: UseImageUploadProps) => {
|
|
11
11
|
getPresignedUrl: (fileName: string, contentType: string) => Promise<UploadResponse>;
|
|
12
12
|
uploadFile: (file: File) => Promise<string>;
|
|
13
13
|
isLoading: boolean;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { useCallback, useState } from 'react';
|
|
2
2
|
import { generateSecureRandomString, uploadFileWithXHR } from '../utils/functionHelper';
|
|
3
|
-
export const useImageUpload = ({ project, env, endpoint
|
|
4
|
-
|
|
3
|
+
export const useImageUpload = ({ project, env, endpoint }) => {
|
|
4
|
+
const resolvedEndpoint = endpoint ?? process.env.NEXT_PUBLIC_UPLOAD_URL_ENDPOINT;
|
|
5
|
+
if (!resolvedEndpoint) {
|
|
6
|
+
throw new Error('NEXT_PUBLIC_UPLOAD_URL_ENDPOINT is not configured.');
|
|
7
|
+
}
|
|
5
8
|
const [isLoading, setIsLoading] = useState(false);
|
|
6
9
|
const [error, setError] = useState(null);
|
|
7
10
|
const getPresignedUrl = useCallback(async (fileName, contentType) => {
|
|
8
11
|
setIsLoading(true);
|
|
9
12
|
setError(null);
|
|
10
13
|
try {
|
|
11
|
-
const response = await fetch(
|
|
14
|
+
const response = await fetch(resolvedEndpoint, {
|
|
12
15
|
method: 'POST',
|
|
13
16
|
headers: {
|
|
14
17
|
'Content-Type': 'application/json',
|
|
@@ -39,7 +42,7 @@ export const useImageUpload = ({ project, env, endpoint = process.env.NEXT_PUBLI
|
|
|
39
42
|
finally {
|
|
40
43
|
setIsLoading(false);
|
|
41
44
|
}
|
|
42
|
-
}, [project, env,
|
|
45
|
+
}, [project, env, resolvedEndpoint]);
|
|
43
46
|
const uploadFile = useCallback(async (file) => {
|
|
44
47
|
const timestamp = Date.now();
|
|
45
48
|
const randomString = generateSecureRandomString();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagamio/frontend-commons-lib",
|
|
3
3
|
"description": "Pagamio library for Frontend reusable components like the form engine and table container",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.198",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
7
7
|
"provenance": false
|