@tradly/asset 1.0.2 → 1.0.4
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/dist/components/FileUpload.js +155 -0
- package/dist/components/Icons.js +32 -0
- package/dist/components/ImagesSkeleton.js +14 -0
- package/dist/components/MediaGallery.js +144 -0
- package/dist/components/MediaPopup.js +97 -0
- package/dist/components/MediaTab.js +132 -0
- package/dist/components/Pagination.js +134 -0
- package/dist/components/VideosGallery.js +144 -0
- package/dist/services/apiService.js +373 -0
- package/package.json +17 -5
- package/EXAMPLE_USAGE.jsx +0 -128
- package/MIGRATION_GUIDE.md +0 -249
- package/STYLING_GUIDE.md +0 -219
- package/src/components/FileUpload.jsx +0 -114
- package/src/components/Icons.jsx +0 -23
- package/src/components/ImagesSkeleton.jsx +0 -18
- package/src/components/MediaGallery.jsx +0 -125
- package/src/components/MediaPopup.jsx +0 -101
- package/src/components/MediaTab.jsx +0 -152
- package/src/components/Pagination.jsx +0 -175
- package/src/components/VideosGallery.jsx +0 -121
- package/src/services/apiService.js +0 -270
- /package/{src → dist}/index.js +0 -0
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
2
|
-
import { CameraIcon } from './Icons'
|
|
3
|
-
|
|
4
|
-
const FileUpload = ({
|
|
5
|
-
loadMedia,
|
|
6
|
-
accept,
|
|
7
|
-
title,
|
|
8
|
-
apiService,
|
|
9
|
-
onUploadStart,
|
|
10
|
-
onUploadComplete,
|
|
11
|
-
onUploadError,
|
|
12
|
-
// Styling props
|
|
13
|
-
className,
|
|
14
|
-
buttonClassName,
|
|
15
|
-
iconContainerClassName,
|
|
16
|
-
titleClassName,
|
|
17
|
-
loadingClassName,
|
|
18
|
-
}) => {
|
|
19
|
-
const [files, setFiles] = useState([])
|
|
20
|
-
const [isLoading, setISLoading] = useState(false)
|
|
21
|
-
const [length, setLength] = useState(0)
|
|
22
|
-
|
|
23
|
-
// Upload files
|
|
24
|
-
const uploadFiles = async (fileList) => {
|
|
25
|
-
if (onUploadStart) {
|
|
26
|
-
onUploadStart(fileList)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
setISLoading(true)
|
|
30
|
-
setLength(fileList.length)
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
// Use the API service to upload files
|
|
34
|
-
// The apiService.uploadMedia handles:
|
|
35
|
-
// 1. Generate S3 signed URLs via tradly.app.generateS3ImageURL
|
|
36
|
-
// 2. Upload files to S3
|
|
37
|
-
// 3. Save media metadata to API
|
|
38
|
-
const uploadedUrls = await apiService.uploadMedia(fileList, apiService.authKey)
|
|
39
|
-
|
|
40
|
-
if (onUploadComplete) {
|
|
41
|
-
onUploadComplete(uploadedUrls)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
setLength(0)
|
|
45
|
-
if (loadMedia) {
|
|
46
|
-
loadMedia()
|
|
47
|
-
}
|
|
48
|
-
} catch (error) {
|
|
49
|
-
console.error('Upload error:', error)
|
|
50
|
-
if (onUploadError) {
|
|
51
|
-
onUploadError(error)
|
|
52
|
-
}
|
|
53
|
-
} finally {
|
|
54
|
-
setISLoading(false)
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Default classes with customization support
|
|
59
|
-
const defaultContainerClass = 'min-w-40 h-40'
|
|
60
|
-
const defaultButtonClass =
|
|
61
|
-
'w-full h-full flex flex-col justify-center items-center text-sm border border-primary border-dashed rounded-lg hover:bg-gray-50 transition-colors'
|
|
62
|
-
const defaultIconContainerClass = 'p-[10px] bg-primary rounded-full'
|
|
63
|
-
const defaultTitleClass = 'mt-2'
|
|
64
|
-
const defaultLoadingClass =
|
|
65
|
-
'flex items-center justify-center h-40 bg-gray-200 rounded-lg shadow-md animate-pulse'
|
|
66
|
-
|
|
67
|
-
return (
|
|
68
|
-
<>
|
|
69
|
-
<div className={className || defaultContainerClass}>
|
|
70
|
-
<input
|
|
71
|
-
required
|
|
72
|
-
id={`media_select_${files?.length}`}
|
|
73
|
-
type="file"
|
|
74
|
-
className="hidden"
|
|
75
|
-
accept={accept}
|
|
76
|
-
placeholder=""
|
|
77
|
-
onChange={async (e) => {
|
|
78
|
-
e.stopPropagation()
|
|
79
|
-
const all_files = Array.from(e.target.files)
|
|
80
|
-
if (all_files?.length > 0) {
|
|
81
|
-
await uploadFiles(all_files)
|
|
82
|
-
}
|
|
83
|
-
// Reset input
|
|
84
|
-
e.target.value = ''
|
|
85
|
-
}}
|
|
86
|
-
multiple={true}
|
|
87
|
-
/>
|
|
88
|
-
|
|
89
|
-
<button
|
|
90
|
-
type="button"
|
|
91
|
-
className={buttonClassName || defaultButtonClass}
|
|
92
|
-
onClick={() => document.getElementById(`media_select_${files?.length}`).click()}
|
|
93
|
-
disabled={isLoading}
|
|
94
|
-
>
|
|
95
|
-
<span className={iconContainerClassName || defaultIconContainerClass}>
|
|
96
|
-
<CameraIcon />
|
|
97
|
-
</span>
|
|
98
|
-
<span className={titleClassName || defaultTitleClass}>{title}</span>
|
|
99
|
-
</button>
|
|
100
|
-
</div>
|
|
101
|
-
|
|
102
|
-
{isLoading &&
|
|
103
|
-
Array.from({ length: length }).map((_, index) => {
|
|
104
|
-
return (
|
|
105
|
-
<div key={index} className={loadingClassName || defaultLoadingClass}>
|
|
106
|
-
File Uploading... {index + 1}/{length}
|
|
107
|
-
</div>
|
|
108
|
-
)
|
|
109
|
-
})}
|
|
110
|
-
</>
|
|
111
|
-
)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export default FileUpload
|
package/src/components/Icons.jsx
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
|
-
export const CloseIcon = ({ className = 'w-8 h-8' }) => (
|
|
4
|
-
<svg
|
|
5
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
-
fill="none"
|
|
7
|
-
viewBox="0 0 24 24"
|
|
8
|
-
strokeWidth="1.5"
|
|
9
|
-
stroke="currentColor"
|
|
10
|
-
className={className}
|
|
11
|
-
>
|
|
12
|
-
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
|
|
13
|
-
</svg>
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
export const CameraIcon = () => (
|
|
17
|
-
<svg width="22" height="18" viewBox="0 0 22 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
18
|
-
<path
|
|
19
|
-
d="M7.75033 0.166672L5.76783 2.33334H2.33366C1.14199 2.33334 0.166992 3.30834 0.166992 4.50001V17.5C0.166992 18.6917 1.14199 19.6667 2.33366 19.6667H19.667C20.8587 19.6667 21.8337 18.6917 21.8337 17.5V4.50001C21.8337 3.30834 20.8587 2.33334 19.667 2.33334H16.2328L14.2503 0.166672H7.75033ZM11.0003 16.4167C8.01033 16.4167 5.58366 13.99 5.58366 11C5.58366 8.01001 8.01033 5.58334 11.0003 5.58334C13.9903 5.58334 16.417 8.01001 16.417 11C16.417 13.99 13.9903 16.4167 11.0003 16.4167Z"
|
|
20
|
-
fill="white"
|
|
21
|
-
/>
|
|
22
|
-
</svg>
|
|
23
|
-
)
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
|
-
const ImagesSkeleton = ({ per_page = 30 }) => {
|
|
4
|
-
const gridItems = []
|
|
5
|
-
|
|
6
|
-
for (let i = 0; i < per_page; i++) {
|
|
7
|
-
gridItems.push(
|
|
8
|
-
<div
|
|
9
|
-
key={i}
|
|
10
|
-
className="w-full min-h-[160px] bg-[#3B3269] bg-opacity-[20%] rounded-card animate-pulse"
|
|
11
|
-
></div>
|
|
12
|
-
)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
return gridItems
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export default ImagesSkeleton
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect } from 'react'
|
|
2
|
-
import FileUpload from './FileUpload'
|
|
3
|
-
import ImagesSkeleton from './ImagesSkeleton'
|
|
4
|
-
import Pagination from './Pagination'
|
|
5
|
-
|
|
6
|
-
const IMAGE_MIME_TYPES = [
|
|
7
|
-
'image/png',
|
|
8
|
-
'image/jpeg',
|
|
9
|
-
'image/webp',
|
|
10
|
-
'image/svg+xml',
|
|
11
|
-
'image/gif',
|
|
12
|
-
'image/avif',
|
|
13
|
-
'image/x-icon',
|
|
14
|
-
'image/vnd.microsoft.icon',
|
|
15
|
-
'image/heic',
|
|
16
|
-
'image/heif',
|
|
17
|
-
]
|
|
18
|
-
|
|
19
|
-
const ImagesGallery = ({
|
|
20
|
-
update_data,
|
|
21
|
-
closePopup,
|
|
22
|
-
apiService,
|
|
23
|
-
onError,
|
|
24
|
-
// Styling props
|
|
25
|
-
className,
|
|
26
|
-
gridClassName,
|
|
27
|
-
imageItemClassName,
|
|
28
|
-
paginationContainerClassName,
|
|
29
|
-
}) => {
|
|
30
|
-
const [images, setImages] = useState([])
|
|
31
|
-
const [total_count, setTotalCount] = useState(0)
|
|
32
|
-
const [currentPage, setCurrentPage] = useState(1)
|
|
33
|
-
const [isLoading, setISLoading] = useState(false)
|
|
34
|
-
|
|
35
|
-
// Fetch images
|
|
36
|
-
useEffect(() => {
|
|
37
|
-
loadMedia()
|
|
38
|
-
}, [])
|
|
39
|
-
|
|
40
|
-
const loadMedia = async (page_number = 1) => {
|
|
41
|
-
try {
|
|
42
|
-
const response = await apiService.fetchMedia({
|
|
43
|
-
mimeTypes: IMAGE_MIME_TYPES,
|
|
44
|
-
page: page_number,
|
|
45
|
-
setISLoading,
|
|
46
|
-
isLoading,
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
// Handle different response formats
|
|
50
|
-
// Response might be: { media: [...], count: ... } or { data: { media: [...], count: ... } } or directly [...]
|
|
51
|
-
const mediaData = response?.media || response?.data?.media || response?.data || response || []
|
|
52
|
-
const count = response?.count || response?.data?.count || response?.total || 0
|
|
53
|
-
|
|
54
|
-
setImages(Array.isArray(mediaData) ? mediaData : [])
|
|
55
|
-
setTotalCount(count)
|
|
56
|
-
setCurrentPage(page_number)
|
|
57
|
-
} catch (error) {
|
|
58
|
-
console.error('Error loading media:', error)
|
|
59
|
-
if (onError) {
|
|
60
|
-
onError(error)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const handleImageClick = (image) => {
|
|
66
|
-
if (update_data) {
|
|
67
|
-
update_data(image.url || image)
|
|
68
|
-
}
|
|
69
|
-
if (closePopup) {
|
|
70
|
-
closePopup()
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Default classes with customization support
|
|
75
|
-
const defaultContainerClass = 'h-full flex flex-col justify-between'
|
|
76
|
-
const defaultGridClass = 'grid grid-cols-[repeat(auto-fill,minmax(calc(160px),1fr))] gap-5'
|
|
77
|
-
const defaultImageItemClass =
|
|
78
|
-
'cursor-pointer w-full h-40 object-contain p-3 overflow-hidden bg-white rounded-md shadow-md hover:shadow-lg transition-shadow'
|
|
79
|
-
const defaultPaginationContainerClass = 'mb-4 bg-gray-100/90 p-4 sticky bottom-0'
|
|
80
|
-
|
|
81
|
-
return (
|
|
82
|
-
<div className={className || defaultContainerClass}>
|
|
83
|
-
<div className={gridClassName || defaultGridClass}>
|
|
84
|
-
<FileUpload
|
|
85
|
-
loadMedia={loadMedia}
|
|
86
|
-
accept="image/*"
|
|
87
|
-
title="Add Image"
|
|
88
|
-
apiService={apiService}
|
|
89
|
-
onUploadError={onError}
|
|
90
|
-
/>
|
|
91
|
-
|
|
92
|
-
{isLoading ? (
|
|
93
|
-
<ImagesSkeleton />
|
|
94
|
-
) : (
|
|
95
|
-
images?.map((image, index) => {
|
|
96
|
-
const imageUrl = typeof image === 'string' ? image : image.url
|
|
97
|
-
const imageKey = image.id || image.url || index
|
|
98
|
-
|
|
99
|
-
return (
|
|
100
|
-
<img
|
|
101
|
-
key={imageKey}
|
|
102
|
-
onClick={() => handleImageClick(image)}
|
|
103
|
-
className={imageItemClassName || defaultImageItemClass}
|
|
104
|
-
src={imageUrl}
|
|
105
|
-
alt={image.name || 'Media item'}
|
|
106
|
-
/>
|
|
107
|
-
)
|
|
108
|
-
})
|
|
109
|
-
)}
|
|
110
|
-
</div>
|
|
111
|
-
|
|
112
|
-
<div className={paginationContainerClassName || defaultPaginationContainerClass}>
|
|
113
|
-
{total_count > 0 && (
|
|
114
|
-
<Pagination
|
|
115
|
-
nextPage={(value) => loadMedia(value)}
|
|
116
|
-
pageCount={Math.ceil(total_count / 30)}
|
|
117
|
-
current_page={currentPage}
|
|
118
|
-
/>
|
|
119
|
-
)}
|
|
120
|
-
</div>
|
|
121
|
-
</div>
|
|
122
|
-
)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export default ImagesGallery
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { createPortal } from 'react-dom'
|
|
3
|
-
import MediaTab from './MediaTab'
|
|
4
|
-
import { CloseIcon } from './Icons'
|
|
5
|
-
|
|
6
|
-
const MediaPopup = ({
|
|
7
|
-
isOpen,
|
|
8
|
-
onClose,
|
|
9
|
-
onSelect,
|
|
10
|
-
currentData,
|
|
11
|
-
options = ['image'],
|
|
12
|
-
apiService,
|
|
13
|
-
onError,
|
|
14
|
-
title = 'Media Gallery',
|
|
15
|
-
// Styling props
|
|
16
|
-
className,
|
|
17
|
-
overlayClassName,
|
|
18
|
-
containerClassName,
|
|
19
|
-
headerClassName,
|
|
20
|
-
titleClassName,
|
|
21
|
-
closeButtonClassName,
|
|
22
|
-
// Pass-through styling props for child components
|
|
23
|
-
tabListClassName,
|
|
24
|
-
tabButtonClassName,
|
|
25
|
-
tabButtonActiveClassName,
|
|
26
|
-
tabButtonInactiveClassName,
|
|
27
|
-
tabPanelClassName,
|
|
28
|
-
gridClassName,
|
|
29
|
-
imageItemClassName,
|
|
30
|
-
videoItemClassName,
|
|
31
|
-
paginationContainerClassName,
|
|
32
|
-
}) => {
|
|
33
|
-
if (!isOpen) return null
|
|
34
|
-
|
|
35
|
-
const handleUpdate = (data) => {
|
|
36
|
-
if (onSelect) {
|
|
37
|
-
onSelect(data)
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const handleClose = () => {
|
|
42
|
-
if (onClose) {
|
|
43
|
-
onClose()
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Default classes with customization support
|
|
48
|
-
const defaultOverlayClass = 'fixed inset-0 w-screen h-screen bg-black opacity-10'
|
|
49
|
-
const defaultContainerClass =
|
|
50
|
-
'origin-top-right z-[9999] absolute inset-0 max-w-3xl mx-auto my-auto min-h-[200px] h-[600px] bg-white rounded shadow-inner cursor-auto p-6'
|
|
51
|
-
const defaultHeaderClass = 'flex items-center justify-between gap-4'
|
|
52
|
-
const defaultTitleClass = 'text-[#000] font-bold text-2xl'
|
|
53
|
-
const defaultCloseButtonClass =
|
|
54
|
-
'bg-transparent rounded-full hover:bg-gray-100 p-1 transition-colors'
|
|
55
|
-
|
|
56
|
-
return createPortal(
|
|
57
|
-
<>
|
|
58
|
-
<div
|
|
59
|
-
className={overlayClassName || defaultOverlayClass}
|
|
60
|
-
style={{ zIndex: 9998 }}
|
|
61
|
-
onClick={handleClose}
|
|
62
|
-
/>
|
|
63
|
-
<div className={containerClassName || defaultContainerClass} style={{ zIndex: 9999 }}>
|
|
64
|
-
{/* Header */}
|
|
65
|
-
<div className={headerClassName || defaultHeaderClass}>
|
|
66
|
-
<p className={titleClassName || defaultTitleClass}>{title}</p>
|
|
67
|
-
<button
|
|
68
|
-
className={closeButtonClassName || defaultCloseButtonClass}
|
|
69
|
-
type="button"
|
|
70
|
-
onClick={handleClose}
|
|
71
|
-
aria-label="Close"
|
|
72
|
-
>
|
|
73
|
-
<CloseIcon />
|
|
74
|
-
</button>
|
|
75
|
-
</div>
|
|
76
|
-
<MediaTab
|
|
77
|
-
imagePopup={isOpen}
|
|
78
|
-
update_data={handleUpdate}
|
|
79
|
-
current_data={currentData}
|
|
80
|
-
closePopup={handleClose}
|
|
81
|
-
options={options}
|
|
82
|
-
apiService={apiService}
|
|
83
|
-
onError={onError}
|
|
84
|
-
// Pass styling props through
|
|
85
|
-
tabListClassName={tabListClassName}
|
|
86
|
-
tabButtonClassName={tabButtonClassName}
|
|
87
|
-
tabButtonActiveClassName={tabButtonActiveClassName}
|
|
88
|
-
tabButtonInactiveClassName={tabButtonInactiveClassName}
|
|
89
|
-
tabPanelClassName={tabPanelClassName}
|
|
90
|
-
gridClassName={gridClassName}
|
|
91
|
-
imageItemClassName={imageItemClassName}
|
|
92
|
-
videoItemClassName={videoItemClassName}
|
|
93
|
-
paginationContainerClassName={paginationContainerClassName}
|
|
94
|
-
/>
|
|
95
|
-
</div>
|
|
96
|
-
</>,
|
|
97
|
-
document.body
|
|
98
|
-
)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export default MediaPopup
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
2
|
-
import { Tab } from '@headlessui/react'
|
|
3
|
-
import ImagesGallery from './MediaGallery'
|
|
4
|
-
import VideosGallery from './VideosGallery'
|
|
5
|
-
|
|
6
|
-
function classNames(...classes) {
|
|
7
|
-
return classes.filter(Boolean).join(' ')
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const MediaTab = ({
|
|
11
|
-
imagePopup,
|
|
12
|
-
current_data,
|
|
13
|
-
update_data,
|
|
14
|
-
closePopup,
|
|
15
|
-
options,
|
|
16
|
-
apiService,
|
|
17
|
-
onError,
|
|
18
|
-
// Styling props
|
|
19
|
-
className,
|
|
20
|
-
tabListClassName,
|
|
21
|
-
tabButtonClassName,
|
|
22
|
-
tabButtonActiveClassName,
|
|
23
|
-
tabButtonInactiveClassName,
|
|
24
|
-
tabPanelClassName,
|
|
25
|
-
// Pass-through styling props for gallery components
|
|
26
|
-
gridClassName,
|
|
27
|
-
imageItemClassName,
|
|
28
|
-
videoItemClassName,
|
|
29
|
-
paginationContainerClassName,
|
|
30
|
-
}) => {
|
|
31
|
-
const [selectedIndex, setSelectedIndex] = useState(0)
|
|
32
|
-
|
|
33
|
-
// Default classes with customization support
|
|
34
|
-
const defaultTabGroupClass = 'h-[520px] overflow-y-auto scrollbar-none'
|
|
35
|
-
const defaultTabListClass = 'sticky top-0 z-30 bg-white w-full flex border-b-2 border-gray-200'
|
|
36
|
-
const defaultTabButtonBaseClass =
|
|
37
|
-
'rounded-lg py-2.5 px-8 text-base font-medium leading-5 flex flex-col md:flex-row items-center justify-center gap-3 ring-0 focus:outline-none'
|
|
38
|
-
const defaultTabButtonActiveClass =
|
|
39
|
-
'relative text-primary after:content-[""] after:h-1 after:w-full after:block after:absolute after:-bottom-0.5 after:bg-primary after:rounded-card'
|
|
40
|
-
const defaultTabButtonInactiveClass = 'text-[#4F4F4F]'
|
|
41
|
-
const defaultTabPanelClass = 'h-full py-4 relative'
|
|
42
|
-
|
|
43
|
-
return (
|
|
44
|
-
<Tab.Group
|
|
45
|
-
as="div"
|
|
46
|
-
key={selectedIndex}
|
|
47
|
-
className={className || defaultTabGroupClass}
|
|
48
|
-
onChange={setSelectedIndex}
|
|
49
|
-
selectedIndex={selectedIndex}
|
|
50
|
-
>
|
|
51
|
-
<Tab.List className={tabListClassName || defaultTabListClass}>
|
|
52
|
-
{options.includes('image') && (
|
|
53
|
-
<Tab
|
|
54
|
-
as="p"
|
|
55
|
-
id="image-tab-button"
|
|
56
|
-
className={({ selected }) =>
|
|
57
|
-
classNames(
|
|
58
|
-
tabButtonClassName || defaultTabButtonBaseClass,
|
|
59
|
-
selected
|
|
60
|
-
? tabButtonActiveClassName || defaultTabButtonActiveClass
|
|
61
|
-
: tabButtonInactiveClassName || defaultTabButtonInactiveClass
|
|
62
|
-
)
|
|
63
|
-
}
|
|
64
|
-
>
|
|
65
|
-
<span>Images</span>
|
|
66
|
-
</Tab>
|
|
67
|
-
)}
|
|
68
|
-
{options.includes('video') && (
|
|
69
|
-
<Tab
|
|
70
|
-
as="p"
|
|
71
|
-
id="video-tab-button"
|
|
72
|
-
className={({ selected }) =>
|
|
73
|
-
classNames(
|
|
74
|
-
tabButtonClassName || defaultTabButtonBaseClass,
|
|
75
|
-
selected
|
|
76
|
-
? tabButtonActiveClassName || defaultTabButtonActiveClass
|
|
77
|
-
: tabButtonInactiveClassName || defaultTabButtonInactiveClass
|
|
78
|
-
)
|
|
79
|
-
}
|
|
80
|
-
>
|
|
81
|
-
<span>Videos</span>
|
|
82
|
-
</Tab>
|
|
83
|
-
)}
|
|
84
|
-
{options.includes('file') && (
|
|
85
|
-
<Tab
|
|
86
|
-
as="p"
|
|
87
|
-
id="file-tab-button"
|
|
88
|
-
className={({ selected }) =>
|
|
89
|
-
classNames(
|
|
90
|
-
tabButtonClassName || defaultTabButtonBaseClass,
|
|
91
|
-
selected
|
|
92
|
-
? tabButtonActiveClassName || defaultTabButtonActiveClass
|
|
93
|
-
: tabButtonInactiveClassName || defaultTabButtonInactiveClass
|
|
94
|
-
)
|
|
95
|
-
}
|
|
96
|
-
>
|
|
97
|
-
<span>Files</span>
|
|
98
|
-
</Tab>
|
|
99
|
-
)}
|
|
100
|
-
</Tab.List>
|
|
101
|
-
<Tab.Panels className="h-full" selectedIndex={selectedIndex}>
|
|
102
|
-
{options.includes('image') && (
|
|
103
|
-
<Tab.Panel className={tabPanelClassName || defaultTabPanelClass}>
|
|
104
|
-
<ImagesGallery
|
|
105
|
-
imagePopup={imagePopup}
|
|
106
|
-
update_data={update_data}
|
|
107
|
-
current_data={current_data}
|
|
108
|
-
closePopup={closePopup}
|
|
109
|
-
apiService={apiService}
|
|
110
|
-
onError={onError}
|
|
111
|
-
gridClassName={gridClassName}
|
|
112
|
-
imageItemClassName={imageItemClassName}
|
|
113
|
-
paginationContainerClassName={paginationContainerClassName}
|
|
114
|
-
/>
|
|
115
|
-
</Tab.Panel>
|
|
116
|
-
)}
|
|
117
|
-
{options.includes('video') && (
|
|
118
|
-
<Tab.Panel className={tabPanelClassName || defaultTabPanelClass}>
|
|
119
|
-
<VideosGallery
|
|
120
|
-
imagePopup={imagePopup}
|
|
121
|
-
update_data={update_data}
|
|
122
|
-
current_data={current_data}
|
|
123
|
-
closePopup={closePopup}
|
|
124
|
-
apiService={apiService}
|
|
125
|
-
onError={onError}
|
|
126
|
-
gridClassName={gridClassName}
|
|
127
|
-
videoItemClassName={videoItemClassName}
|
|
128
|
-
paginationContainerClassName={paginationContainerClassName}
|
|
129
|
-
/>
|
|
130
|
-
</Tab.Panel>
|
|
131
|
-
)}
|
|
132
|
-
{options.includes('file') && (
|
|
133
|
-
<Tab.Panel className={tabPanelClassName || defaultTabPanelClass}>
|
|
134
|
-
<ImagesGallery
|
|
135
|
-
imagePopup={imagePopup}
|
|
136
|
-
update_data={update_data}
|
|
137
|
-
current_data={current_data}
|
|
138
|
-
closePopup={closePopup}
|
|
139
|
-
apiService={apiService}
|
|
140
|
-
onError={onError}
|
|
141
|
-
gridClassName={gridClassName}
|
|
142
|
-
imageItemClassName={imageItemClassName}
|
|
143
|
-
paginationContainerClassName={paginationContainerClassName}
|
|
144
|
-
/>
|
|
145
|
-
</Tab.Panel>
|
|
146
|
-
)}
|
|
147
|
-
</Tab.Panels>
|
|
148
|
-
</Tab.Group>
|
|
149
|
-
)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export default MediaTab
|