@udhuong/admin-core 0.1.7 → 0.2.0
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/client/components/media/FolderTree.d.ts +13 -0
- package/dist/client/components/media/FolderTree.d.ts.map +1 -0
- package/dist/client/components/media/FolderTree.js +50 -0
- package/dist/client/components/media/FolderTree.js.map +1 -0
- package/dist/client/components/media/MediaBrowser.d.ts +8 -0
- package/dist/client/components/media/MediaBrowser.d.ts.map +1 -0
- package/dist/client/components/media/MediaBrowser.js +210 -0
- package/dist/client/components/media/MediaBrowser.js.map +1 -0
- package/dist/client/components/media/MediaGrid.d.ts +11 -0
- package/dist/client/components/media/MediaGrid.d.ts.map +1 -0
- package/dist/client/components/media/MediaGrid.js +67 -0
- package/dist/client/components/media/MediaGrid.js.map +1 -0
- package/dist/client/components/media/MediaPicker.d.ts +12 -0
- package/dist/client/components/media/MediaPicker.d.ts.map +1 -0
- package/dist/client/components/media/MediaPicker.js +154 -0
- package/dist/client/components/media/MediaPicker.js.map +1 -0
- package/dist/client/components/media/MediaUpload.d.ts +9 -0
- package/dist/client/components/media/MediaUpload.d.ts.map +1 -0
- package/dist/client/components/media/MediaUpload.js +98 -0
- package/dist/client/components/media/MediaUpload.js.map +1 -0
- package/dist/client/components/media/index.d.ts +6 -0
- package/dist/client/components/media/index.d.ts.map +1 -0
- package/dist/client/components/media/index.js +6 -0
- package/dist/client/components/media/index.js.map +1 -0
- package/dist/client/constants/api-routes.d.ts +9 -0
- package/dist/client/constants/api-routes.d.ts.map +1 -1
- package/dist/client/constants/api-routes.js +10 -0
- package/dist/client/constants/api-routes.js.map +1 -1
- package/dist/client/index.d.ts +5 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +6 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/lib/ckeditor-upload-adapter.d.ts +8 -0
- package/dist/client/lib/ckeditor-upload-adapter.d.ts.map +1 -0
- package/dist/client/lib/ckeditor-upload-adapter.js +75 -0
- package/dist/client/lib/ckeditor-upload-adapter.js.map +1 -0
- package/dist/client/pages/MediaPage.d.ts +2 -0
- package/dist/client/pages/MediaPage.d.ts.map +1 -0
- package/dist/client/pages/MediaPage.js +303 -0
- package/dist/client/pages/MediaPage.js.map +1 -0
- package/dist/client/pages/PermissionsPage.d.ts.map +1 -1
- package/dist/client/pages/PermissionsPage.js +59 -25
- package/dist/client/pages/PermissionsPage.js.map +1 -1
- package/dist/client/pages/RolesPage.d.ts.map +1 -1
- package/dist/client/pages/RolesPage.js +128 -35
- package/dist/client/pages/RolesPage.js.map +1 -1
- package/dist/client/pages/index.d.ts +1 -0
- package/dist/client/pages/index.d.ts.map +1 -1
- package/dist/client/pages/index.js +1 -0
- package/dist/client/pages/index.js.map +1 -1
- package/dist/client/types/media.d.ts +57 -0
- package/dist/client/types/media.d.ts.map +1 -0
- package/dist/client/types/media.js +10 -0
- package/dist/client/types/media.js.map +1 -0
- package/dist/server/admin-core-options.interface.d.ts +13 -0
- package/dist/server/admin-core-options.interface.d.ts.map +1 -1
- package/dist/server/admin-core-options.interface.js.map +1 -1
- package/dist/server/admin-core.module.d.ts.map +1 -1
- package/dist/server/admin-core.module.js +9 -1
- package/dist/server/admin-core.module.js.map +1 -1
- package/dist/server/index.d.ts +7 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +19 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/media/application/services/media.service.d.ts +134 -0
- package/dist/server/media/application/services/media.service.d.ts.map +1 -0
- package/dist/server/media/application/services/media.service.js +357 -0
- package/dist/server/media/application/services/media.service.js.map +1 -0
- package/dist/server/media/application/services/minio.service.d.ts +24 -0
- package/dist/server/media/application/services/minio.service.d.ts.map +1 -0
- package/dist/server/media/application/services/minio.service.js +175 -0
- package/dist/server/media/application/services/minio.service.js.map +1 -0
- package/dist/server/media/domain/enums/media-type.enum.d.ts +15 -0
- package/dist/server/media/domain/enums/media-type.enum.d.ts.map +1 -0
- package/dist/server/media/domain/enums/media-type.enum.js +19 -0
- package/dist/server/media/domain/enums/media-type.enum.js.map +1 -0
- package/dist/server/media/infrastructure/persistence/entities/media.entity.d.ts +30 -0
- package/dist/server/media/infrastructure/persistence/entities/media.entity.d.ts.map +1 -0
- package/dist/server/media/infrastructure/persistence/entities/media.entity.js +149 -0
- package/dist/server/media/infrastructure/persistence/entities/media.entity.js.map +1 -0
- package/dist/server/media/media.module.d.ts +3 -0
- package/dist/server/media/media.module.d.ts.map +1 -0
- package/dist/server/media/media.module.js +27 -0
- package/dist/server/media/media.module.js.map +1 -0
- package/dist/server/media/presentation/controllers/media.controller.d.ts +62 -0
- package/dist/server/media/presentation/controllers/media.controller.d.ts.map +1 -0
- package/dist/server/media/presentation/controllers/media.controller.js +185 -0
- package/dist/server/media/presentation/controllers/media.controller.js.map +1 -0
- package/dist/server/media/presentation/dto/media.dto.d.ts +38 -0
- package/dist/server/media/presentation/dto/media.dto.d.ts.map +1 -0
- package/dist/server/media/presentation/dto/media.dto.js +184 -0
- package/dist/server/media/presentation/dto/media.dto.js.map +1 -0
- package/dist/server/shared/permissions.d.ts +24 -0
- package/dist/server/shared/permissions.d.ts.map +1 -1
- package/dist/server/shared/permissions.js +24 -0
- package/dist/server/shared/permissions.js.map +1 -1
- package/package.json +11 -1
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import Button from '../ui/Button';
|
|
4
|
+
import Input from '../ui/Input';
|
|
5
|
+
import LoadingSpinner from '../ui/LoadingSpinner';
|
|
6
|
+
import Modal from '../ui/Modal';
|
|
7
|
+
import Pagination from '../ui/Pagination';
|
|
8
|
+
import { getApiClient } from '../auth/api-client';
|
|
9
|
+
import { CORE_API_ROUTES } from '../constants/api-routes';
|
|
10
|
+
import { formatDate } from '../lib/utils';
|
|
11
|
+
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
12
|
+
import { Check, Download, FileText, Film, Folder, FolderPlus, Image as ImageIcon, Plus, Search, Trash2, X, ZoomIn, } from 'lucide-react';
|
|
13
|
+
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
|
|
14
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
15
|
+
import { useDropzone } from 'react-dropzone';
|
|
16
|
+
export default function MediaPage() {
|
|
17
|
+
const apiClient = getApiClient();
|
|
18
|
+
const router = useRouter();
|
|
19
|
+
const pathname = usePathname();
|
|
20
|
+
const searchParams = useSearchParams();
|
|
21
|
+
// Initialize state from URL params
|
|
22
|
+
const [searchTerm, setSearchTerm] = useState(searchParams.get('search') || '');
|
|
23
|
+
const [debouncedSearch, setDebouncedSearch] = useState(searchParams.get('search') || '');
|
|
24
|
+
const [currentPage, setCurrentPage] = useState(Number(searchParams.get('page')) || 1);
|
|
25
|
+
const [filter, setFilter] = useState(searchParams.get('type') || 'all');
|
|
26
|
+
const [selectedMedia, setSelectedMedia] = useState(null);
|
|
27
|
+
const [uploadModalOpen, setUploadModalOpen] = useState(false);
|
|
28
|
+
const [folderModalOpen, setFolderModalOpen] = useState(false);
|
|
29
|
+
const [newFolderName, setNewFolderName] = useState('');
|
|
30
|
+
const [uploading, setUploading] = useState(false);
|
|
31
|
+
const [sortBy, setSortBy] = useState(searchParams.get('sort') || 'recent');
|
|
32
|
+
const [selectedItems, setSelectedItems] = useState([]);
|
|
33
|
+
const [uploadTab, setUploadTab] = useState('computer');
|
|
34
|
+
const [uploadFiles, setUploadFiles] = useState([]);
|
|
35
|
+
const initialFolderId = searchParams.get('folder');
|
|
36
|
+
const initialFolderNumber = initialFolderId && !Number.isNaN(Number(initialFolderId))
|
|
37
|
+
? Number(initialFolderId)
|
|
38
|
+
: null;
|
|
39
|
+
const [currentFolderId, setCurrentFolderId] = useState(initialFolderNumber);
|
|
40
|
+
const [breadcrumbs, setBreadcrumbs] = useState([
|
|
41
|
+
{ id: null, name: 'Media Library' },
|
|
42
|
+
]);
|
|
43
|
+
const queryClient = useQueryClient();
|
|
44
|
+
// Sync state from URL when URL changes (e.g., clicking menu)
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
const urlSearch = searchParams.get('search') || '';
|
|
47
|
+
const urlPage = Number(searchParams.get('page')) || 1;
|
|
48
|
+
const urlType = searchParams.get('type') || 'all';
|
|
49
|
+
const urlSort = searchParams.get('sort') || 'recent';
|
|
50
|
+
const urlFolderRaw = searchParams.get('folder');
|
|
51
|
+
const urlFolder = urlFolderRaw ? Number(urlFolderRaw) : null;
|
|
52
|
+
const parsedFolderId = Number.isNaN(urlFolder) ? null : urlFolder;
|
|
53
|
+
setSearchTerm(urlSearch);
|
|
54
|
+
setDebouncedSearch(urlSearch);
|
|
55
|
+
setCurrentPage(urlPage);
|
|
56
|
+
setFilter(urlType);
|
|
57
|
+
setSortBy(urlSort);
|
|
58
|
+
setCurrentFolderId(parsedFolderId);
|
|
59
|
+
// Reset breadcrumbs if no folder in URL
|
|
60
|
+
if (parsedFolderId === null) {
|
|
61
|
+
setBreadcrumbs([{ id: null, name: 'Media Library' }]);
|
|
62
|
+
}
|
|
63
|
+
}, [searchParams]);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
const params = new URLSearchParams();
|
|
66
|
+
if (debouncedSearch)
|
|
67
|
+
params.set('search', debouncedSearch);
|
|
68
|
+
if (currentPage > 1)
|
|
69
|
+
params.set('page', currentPage.toString());
|
|
70
|
+
if (filter !== 'all')
|
|
71
|
+
params.set('type', filter);
|
|
72
|
+
if (sortBy !== 'recent')
|
|
73
|
+
params.set('sort', sortBy);
|
|
74
|
+
if (currentFolderId !== null)
|
|
75
|
+
params.set('folder', currentFolderId.toString());
|
|
76
|
+
const queryString = params.toString();
|
|
77
|
+
const newUrl = queryString ? `${pathname}?${queryString}` : pathname;
|
|
78
|
+
router.replace(newUrl, { scroll: false });
|
|
79
|
+
}, [debouncedSearch, currentPage, filter, sortBy, currentFolderId, router, pathname]);
|
|
80
|
+
// Debounce search term
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
const timer = setTimeout(() => {
|
|
83
|
+
setDebouncedSearch(searchTerm);
|
|
84
|
+
setCurrentPage(1); // Reset to first page when searching
|
|
85
|
+
}, 500);
|
|
86
|
+
return () => clearTimeout(timer);
|
|
87
|
+
}, [searchTerm]);
|
|
88
|
+
// Fetch media items
|
|
89
|
+
const { data, isLoading } = useQuery({
|
|
90
|
+
queryKey: ['media', currentPage, debouncedSearch, filter, currentFolderId, sortBy],
|
|
91
|
+
queryFn: async () => {
|
|
92
|
+
const response = await apiClient.get(CORE_API_ROUTES.MEDIA.BASE, {
|
|
93
|
+
params: {
|
|
94
|
+
page: currentPage,
|
|
95
|
+
search: debouncedSearch,
|
|
96
|
+
type: filter === 'all' ? undefined : filter,
|
|
97
|
+
// Always pass folderId: null for root, or specific ID for folder
|
|
98
|
+
folderId: currentFolderId !== null ? currentFolderId : 'null',
|
|
99
|
+
limit: 20,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
let items = response.data.items || [];
|
|
103
|
+
// Client-side sorting
|
|
104
|
+
if (sortBy === 'recent') {
|
|
105
|
+
items = [...items].sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
106
|
+
}
|
|
107
|
+
else if (sortBy === 'oldest') {
|
|
108
|
+
items = [...items].sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
109
|
+
}
|
|
110
|
+
else if (sortBy === 'name-asc') {
|
|
111
|
+
items = [...items].sort((a, b) => a.name.localeCompare(b.name));
|
|
112
|
+
}
|
|
113
|
+
else if (sortBy === 'name-desc') {
|
|
114
|
+
items = [...items].sort((a, b) => b.name.localeCompare(a.name));
|
|
115
|
+
}
|
|
116
|
+
return { ...response.data, items };
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
// Fetch folders
|
|
120
|
+
const { data: foldersData } = useQuery({
|
|
121
|
+
queryKey: ['folders', currentFolderId],
|
|
122
|
+
queryFn: async () => {
|
|
123
|
+
const response = await apiClient.get(CORE_API_ROUTES.MEDIA.FOLDERS);
|
|
124
|
+
return response.data;
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
const deleteMutation = useMutation({
|
|
128
|
+
mutationFn: async (id) => {
|
|
129
|
+
return apiClient.delete(CORE_API_ROUTES.MEDIA.BY_ID(id));
|
|
130
|
+
},
|
|
131
|
+
onSuccess: () => {
|
|
132
|
+
queryClient.invalidateQueries({ queryKey: ['media'] });
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
const onDrop = useCallback((acceptedFiles) => {
|
|
136
|
+
setUploadFiles(prev => [...prev, ...acceptedFiles]);
|
|
137
|
+
}, []);
|
|
138
|
+
const { getRootProps, getInputProps, isDragActive } = useDropzone({
|
|
139
|
+
onDrop,
|
|
140
|
+
accept: {
|
|
141
|
+
'image/*': ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg'],
|
|
142
|
+
'video/*': ['.mp4', '.webm', '.mov'],
|
|
143
|
+
'audio/*': ['.mp3', '.wav', '.ogg'],
|
|
144
|
+
'application/pdf': ['.pdf'],
|
|
145
|
+
'application/msword': ['.doc'],
|
|
146
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'],
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
const removeUploadFile = (index) => {
|
|
150
|
+
setUploadFiles(prev => prev.filter((_, i) => i !== index));
|
|
151
|
+
};
|
|
152
|
+
const getFilePreview = (file) => {
|
|
153
|
+
if (file.type.startsWith('image/')) {
|
|
154
|
+
return URL.createObjectURL(file);
|
|
155
|
+
}
|
|
156
|
+
return null;
|
|
157
|
+
};
|
|
158
|
+
const handleUpload = async (e) => {
|
|
159
|
+
if (e)
|
|
160
|
+
e.preventDefault();
|
|
161
|
+
if (uploadFiles.length === 0)
|
|
162
|
+
return;
|
|
163
|
+
setUploading(true);
|
|
164
|
+
try {
|
|
165
|
+
const formData = new FormData();
|
|
166
|
+
uploadFiles.forEach(file => {
|
|
167
|
+
formData.append('files', file);
|
|
168
|
+
});
|
|
169
|
+
// Add folderId if in a folder
|
|
170
|
+
if (currentFolderId !== null) {
|
|
171
|
+
formData.append('folderId', currentFolderId.toString());
|
|
172
|
+
}
|
|
173
|
+
await apiClient.post(CORE_API_ROUTES.MEDIA.UPLOAD, formData, {
|
|
174
|
+
headers: { 'Content-Type': 'multipart/form-data' },
|
|
175
|
+
});
|
|
176
|
+
queryClient.invalidateQueries({ queryKey: ['media'] });
|
|
177
|
+
setUploadModalOpen(false);
|
|
178
|
+
setUploadFiles([]);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
console.error('Upload failed:', error);
|
|
182
|
+
}
|
|
183
|
+
finally {
|
|
184
|
+
setUploading(false);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const handleDelete = async (id) => {
|
|
188
|
+
if (confirm('Are you sure you want to delete this file?')) {
|
|
189
|
+
await deleteMutation.mutateAsync(id);
|
|
190
|
+
if (selectedMedia?.id === id) {
|
|
191
|
+
setSelectedMedia(null);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
const handleCreateFolder = async (e) => {
|
|
196
|
+
e.preventDefault();
|
|
197
|
+
if (!newFolderName.trim())
|
|
198
|
+
return;
|
|
199
|
+
try {
|
|
200
|
+
await apiClient.post(CORE_API_ROUTES.MEDIA.CREATE_FOLDER, {
|
|
201
|
+
name: newFolderName,
|
|
202
|
+
parentId: currentFolderId,
|
|
203
|
+
});
|
|
204
|
+
setFolderModalOpen(false);
|
|
205
|
+
setNewFolderName('');
|
|
206
|
+
queryClient.invalidateQueries({ queryKey: ['media'] });
|
|
207
|
+
queryClient.invalidateQueries({ queryKey: ['folders'] });
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
console.error('Failed to create folder:', error);
|
|
211
|
+
alert('Failed to create folder');
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
const handleFolderClick = (folder) => {
|
|
215
|
+
setCurrentFolderId(folder.id);
|
|
216
|
+
setBreadcrumbs(prev => [...prev, { id: folder.id, name: folder.name }]);
|
|
217
|
+
setCurrentPage(1);
|
|
218
|
+
};
|
|
219
|
+
const handleSelectItem = (id) => {
|
|
220
|
+
setSelectedItems(prev => prev.includes(id)
|
|
221
|
+
? prev.filter(item => item !== id)
|
|
222
|
+
: [...prev, id]);
|
|
223
|
+
};
|
|
224
|
+
const handleSelectAll = () => {
|
|
225
|
+
if (selectedItems.length === data?.items?.length) {
|
|
226
|
+
setSelectedItems([]);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
setSelectedItems(data?.items?.map((item) => item.id) || []);
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
const getFileIcon = (mimeType) => {
|
|
233
|
+
if (mimeType.startsWith('image/'))
|
|
234
|
+
return _jsx(ImageIcon, { className: "h-6 w-6" });
|
|
235
|
+
if (mimeType.startsWith('video/'))
|
|
236
|
+
return _jsx(Film, { className: "h-6 w-6" });
|
|
237
|
+
return _jsx(FileText, { className: "h-6 w-6" });
|
|
238
|
+
};
|
|
239
|
+
const formatFileSize = (bytes) => {
|
|
240
|
+
if (bytes === 0)
|
|
241
|
+
return '0 Bytes';
|
|
242
|
+
const k = 1024;
|
|
243
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
244
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
245
|
+
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
|
|
246
|
+
};
|
|
247
|
+
const getMediaTypeBadge = (mimeType) => {
|
|
248
|
+
if (mimeType.startsWith('image/'))
|
|
249
|
+
return 'IMAGE';
|
|
250
|
+
if (mimeType.startsWith('video/'))
|
|
251
|
+
return 'VIDEO';
|
|
252
|
+
if (mimeType.startsWith('audio/'))
|
|
253
|
+
return 'AUDIO';
|
|
254
|
+
return 'FILE';
|
|
255
|
+
};
|
|
256
|
+
return (_jsxs("div", { className: "container mx-auto bg-base-200 min-h-screen p-6", children: [_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "flex gap-2 justify-between items-center", children: [_jsx("h1", { className: "text-2xl font-semibold text-base-content", children: "Media Library" }), _jsxs(Button, { variant: "primary", btnStyle: "ghost", onClick: () => setFolderModalOpen(true), children: [_jsx(FolderPlus, { className: "h-4 w-4 mr-2" }), "New Folder"] }), _jsxs(Button, { variant: "primary", onClick: () => setUploadModalOpen(true), children: [_jsx(Plus, { className: "h-4 w-4 mr-2" }), "Upload Media"] })] }), _jsx("div", { className: "bg-base-100 rounded-lg mb-6", children: _jsxs("div", { className: "p-6 flex flex-col sm:flex-row items-start sm:items-center gap-4 flex-1", children: [_jsx("div", { className: "w-full sm:w-auto sm:min-w-[300px]", children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-5 w-5 text-base-content/50" }), _jsx(Input, { type: "text", placeholder: "Search media files...", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), className: "pl-10" })] }) }), _jsxs("select", { value: filter, onChange: (e) => setFilter(e.target.value), className: "select select-bordered", children: [_jsx("option", { value: "all", children: "All Types" }), _jsx("option", { value: "image", children: "Images" }), _jsx("option", { value: "video", children: "Videos" }), _jsx("option", { value: "audio", children: "Audio" }), _jsx("option", { value: "document", children: "Documents" })] }), _jsxs("select", { value: sortBy, onChange: (e) => setSortBy(e.target.value), className: "select select-bordered", children: [_jsx("option", { value: "recent", children: "Recently Added" }), _jsx("option", { value: "oldest", children: "Oldest First" }), _jsx("option", { value: "name-asc", children: "Name A-Z" }), _jsx("option", { value: "name-desc", children: "Name Z-A" })] }), (searchTerm || filter !== 'all' || sortBy !== 'recent') && (_jsxs(Button, { variant: "secondary", onClick: () => {
|
|
257
|
+
setSearchTerm('');
|
|
258
|
+
setFilter('all');
|
|
259
|
+
setSortBy('recent');
|
|
260
|
+
setCurrentPage(1);
|
|
261
|
+
}, children: [_jsx(X, { className: "h-4 w-4" }), "Clear"] }))] }) }), _jsx("div", { className: "bg-base-100 rounded-lg py-6 space-y-6", children: isLoading ? (_jsx("div", { className: "py-12", children: _jsx(LoadingSpinner, { size: "lg" }) })) : (_jsxs(_Fragment, { children: [foldersData && foldersData.length > 0 && (_jsxs("div", { className: "px-6 space-y-4", children: [_jsxs("div", { className: "text-sm font-semibold text-base-content/70", children: ["Folders (", foldersData.filter((f) => f.parentId === currentFolderId).length, ")"] }), _jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-4", children: foldersData
|
|
262
|
+
.filter((folder) => folder.parentId === currentFolderId)
|
|
263
|
+
.map((folder) => (_jsx("div", { onClick: () => handleFolderClick(folder), className: "group bg-base-100 rounded-lg border border-base-300 hover:border-primary cursor-pointer transition-all p-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("input", { type: "checkbox", className: "checkbox checkbox-sm", onClick: (e) => e.stopPropagation() }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx(Folder, { className: "h-10 w-10 text-primary mb-2" }), _jsx("p", { className: "font-medium text-base-content truncate mb-1", children: folder.name }), _jsxs("p", { className: "text-xs text-base-content/60", children: [folder.subfolderCount || 0, " folder, ", folder.mediaCount || 0, " asset"] })] })] }) }, folder.id))) })] })), data?.items?.length === 0 && (!foldersData || foldersData.filter((f) => f.parentId === currentFolderId).length === 0) ? (_jsxs("div", { className: "text-center py-12 text-base-content/60", children: [_jsx(ImageIcon, { className: "h-16 w-16 mx-auto mb-4 text-base-content/40" }), _jsx("p", { className: "text-lg mb-2", children: "No media files yet" }), _jsx("p", { className: "text-sm", children: "Upload your first asset to get started" })] })) : data?.items && data.items.length > 0 && (_jsxs("div", { className: "px-6 space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("button", { onClick: handleSelectAll, className: `w-5 h-5 rounded border-2 border-base-300 flex items-center justify-center hover:border-primary transition-colors ${selectedItems.length > 0 ? 'bg-primary border-primary' : ''}`, children: selectedItems.length > 0 && (_jsx(Check, { className: "w-3 h-3 text-primary-content" })) }), _jsxs("span", { className: "text-sm text-base-content/60", children: ["Assets (", data?.total || 0, ")", selectedItems.length > 0 && ` - ${selectedItems.length} selected`] })] }), selectedItems.length > 0 && (_jsx("div", { className: "flex gap-2", children: _jsxs(Button, { variant: "error", size: "sm", onClick: () => {
|
|
264
|
+
if (confirm(`Delete ${selectedItems.length} selected items?`)) {
|
|
265
|
+
selectedItems.forEach(id => handleDelete(id));
|
|
266
|
+
setSelectedItems([]);
|
|
267
|
+
}
|
|
268
|
+
}, children: [_jsx(Trash2, { className: "h-4 w-4 mr-2" }), "Delete selected"] }) }))] }), _jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-4", children: data?.items?.map((item) => (_jsxs("div", { className: `group relative bg-base-100 rounded-lg border-2 overflow-hidden transition-all hover:shadow-lg ${selectedItems.includes(item.id)
|
|
269
|
+
? 'border-primary ring-2 ring-primary/20'
|
|
270
|
+
: 'border-base-300 hover:border-base-400'}`, children: [_jsx("div", { className: "absolute top-2 left-2 z-10", children: _jsx("button", { onClick: () => handleSelectItem(item.id), className: `w-5 h-5 rounded border-2 flex items-center justify-center transition-all ${selectedItems.includes(item.id)
|
|
271
|
+
? 'bg-primary border-primary'
|
|
272
|
+
: 'bg-base-100 border-base-300 opacity-0 group-hover:opacity-100'}`, children: selectedItems.includes(item.id) && (_jsx(Check, { className: "w-3 h-3 text-primary-content" })) }) }), _jsx("div", { className: "absolute top-2 right-2 z-10 opacity-0 group-hover:opacity-100 transition-opacity", children: _jsx("span", { className: "badge badge-neutral text-xs font-medium", children: getMediaTypeBadge(item.mimeType) }) }), _jsxs("div", { className: "aspect-square relative bg-base-200 cursor-pointer", onClick: () => setSelectedMedia(item), children: [item.mimeType.startsWith('image/') ? (_jsx("img", { src: item.url, alt: item.alt || item.name, className: "w-full h-full object-cover" })) : (_jsx("div", { className: "w-full h-full flex items-center justify-center", children: _jsx("div", { className: "text-center", children: getFileIcon(item.mimeType) }) })), _jsx("div", { className: "absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center", children: _jsxs("div", { className: "opacity-0 group-hover:opacity-100 transition-opacity flex gap-2", children: [_jsx("button", { onClick: (e) => {
|
|
273
|
+
e.stopPropagation();
|
|
274
|
+
setSelectedMedia(item);
|
|
275
|
+
}, className: "btn btn-sm btn-circle bg-base-100 hover:bg-base-200 text-base-content", children: _jsx(ZoomIn, { className: "h-4 w-4" }) }), _jsx("button", { onClick: (e) => {
|
|
276
|
+
e.stopPropagation();
|
|
277
|
+
handleDelete(item.id);
|
|
278
|
+
}, className: "btn btn-sm btn-circle bg-base-100 hover:bg-error hover:text-error-content text-error", children: _jsx(Trash2, { className: "h-4 w-4" }) })] }) })] }), _jsxs("div", { className: "p-3 border-t border-base-300", children: [_jsx("p", { className: "text-xs font-medium text-base-content truncate mb-1", children: item.name }), _jsxs("div", { className: "flex items-center justify-between text-xs text-base-content/60", children: [_jsx("span", { children: formatFileSize(item.size) }), item.width && item.height && (_jsxs("span", { className: "text-xs", children: [item.width, "x", item.height] }))] })] })] }, item.id))) }), data?.totalPages > 1 && (_jsx("div", { className: "mt-8 flex justify-center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: data.totalPages, onPageChange: setCurrentPage }) }))] }))] })) })] }), _jsx(Modal, { isOpen: uploadModalOpen, onClose: () => {
|
|
279
|
+
setUploadModalOpen(false);
|
|
280
|
+
setUploadFiles([]);
|
|
281
|
+
setUploadTab('computer');
|
|
282
|
+
}, title: "Add new assets", size: "xl", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex border-b border-base-300", children: [_jsx("button", { onClick: () => setUploadTab('computer'), className: `px-4 py-2 text-sm font-medium border-b-2 transition-colors ${uploadTab === 'computer'
|
|
283
|
+
? 'border-primary text-primary'
|
|
284
|
+
: 'border-transparent text-base-content/60 hover:text-base-content'}`, children: "FROM COMPUTER" }), _jsx("button", { onClick: () => setUploadTab('url'), className: `px-4 py-2 text-sm font-medium border-b-2 transition-colors ${uploadTab === 'url'
|
|
285
|
+
? 'border-primary text-primary'
|
|
286
|
+
: 'border-transparent text-base-content/60 hover:text-base-content'}`, children: "FROM URL" })] }), uploadTab === 'computer' ? (_jsxs("div", { children: [_jsxs("div", { ...getRootProps(), className: `border-2 border-dashed rounded-lg p-12 text-center cursor-pointer transition-colors ${isDragActive
|
|
287
|
+
? 'border-primary bg-primary/10'
|
|
288
|
+
: 'border-base-300 hover:border-base-400 bg-base-200'}`, children: [_jsx("input", { ...getInputProps() }), _jsxs("div", { className: "flex flex-col items-center", children: [_jsx("div", { className: "w-12 h-12 rounded-full bg-primary flex items-center justify-center mb-4", children: _jsx(Plus, { className: "w-6 h-6 text-primary-content" }) }), _jsx("p", { className: "text-base-content/60 mb-2", children: isDragActive ? 'Drop files here...' : 'Drag & Drop here or' }), _jsx("button", { type: "button", className: "btn btn-primary", children: "Browse files" })] })] }), uploadFiles.length > 0 && (_jsxs("div", { className: "mt-4 space-y-2", children: [_jsxs("p", { className: "text-sm font-medium text-base-content/70", children: ["Files to upload (", uploadFiles.length, ")"] }), _jsx("div", { className: "max-h-48 overflow-y-auto space-y-2", children: uploadFiles.map((file, index) => {
|
|
289
|
+
const previewUrl = getFilePreview(file);
|
|
290
|
+
return (_jsxs("div", { className: "flex items-center justify-between p-3 bg-base-200 rounded-lg", children: [_jsxs("div", { className: "flex items-center gap-3 flex-1 min-w-0", children: [previewUrl ? (_jsx("img", { src: previewUrl, alt: file.name, className: "w-12 h-12 rounded object-cover flex-shrink-0" })) : (_jsx("div", { className: "w-12 h-12 rounded bg-base-300 flex items-center justify-center flex-shrink-0", children: _jsx(FileText, { className: "w-6 h-6 text-base-content/50" }) })), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("p", { className: "text-sm font-medium text-base-content truncate", children: file.name }), _jsx("p", { className: "text-xs text-base-content/60", children: formatFileSize(file.size) })] })] }), _jsx("button", { onClick: () => removeUploadFile(index), className: "btn btn-sm btn-circle btn-ghost text-error hover:bg-error hover:text-error-content", children: _jsx(Trash2, { className: "w-4 h-4" }) })] }, index));
|
|
291
|
+
}) })] }))] })) : (_jsxs("div", { children: [_jsx(Input, { label: "URL", placeholder: "https://example.com/image.jpg", className: "mb-4" }), _jsx("p", { className: "text-xs text-base-content/60", children: "Paste a URL to upload an asset from an external source" })] })), _jsxs("div", { className: "flex items-center justify-between pt-4 border-t border-base-300", children: [_jsx(Button, { type: "button", variant: "primary", btnStyle: "ghost", onClick: () => {
|
|
292
|
+
setUploadModalOpen(false);
|
|
293
|
+
setUploadFiles([]);
|
|
294
|
+
setUploadTab('computer');
|
|
295
|
+
}, children: "Cancel" }), _jsxs(Button, { type: "button", variant: "primary", onClick: () => handleUpload(), disabled: uploadFiles.length === 0 || uploading, isLoading: uploading, children: ["Upload ", uploadFiles.length > 0 && `${uploadFiles.length} asset${uploadFiles.length > 1 ? 's' : ''}`] })] })] }) }), _jsx(Modal, { isOpen: folderModalOpen, onClose: () => {
|
|
296
|
+
setFolderModalOpen(false);
|
|
297
|
+
setNewFolderName('');
|
|
298
|
+
}, title: "Create Folder", children: _jsxs("form", { onSubmit: handleCreateFolder, className: "space-y-4", children: [_jsx(Input, { label: "Folder name", value: newFolderName, onChange: (e) => setNewFolderName(e.target.value), required: true }), _jsxs("div", { className: "flex gap-3 justify-end", children: [_jsx(Button, { type: "button", variant: "secondary", onClick: () => {
|
|
299
|
+
setFolderModalOpen(false);
|
|
300
|
+
setNewFolderName('');
|
|
301
|
+
}, children: "Cancel" }), _jsx(Button, { type: "submit", variant: "primary", children: "Create" })] })] }) }), selectedMedia && (_jsx(Modal, { isOpen: !!selectedMedia, onClose: () => setSelectedMedia(null), title: "Asset Details", size: "xl", children: _jsxs("div", { className: "space-y-4", children: [_jsx("div", { className: "rounded-lg overflow-hidden bg-base-200", children: selectedMedia.mimeType.startsWith('image/') ? (_jsx("img", { src: selectedMedia.url, alt: selectedMedia.alt || selectedMedia.name, className: "w-full h-auto max-h-96 object-contain" })) : selectedMedia.mimeType.startsWith('video/') ? (_jsx("video", { src: selectedMedia.url, controls: true, className: "w-full h-auto max-h-96" })) : (_jsx("div", { className: "flex items-center justify-center h-48", children: getFileIcon(selectedMedia.mimeType) })) }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm text-base-content/60", children: "File name" }), _jsx("p", { className: "font-medium text-base-content", children: selectedMedia.name })] }), _jsxs("div", { children: [_jsx("p", { className: "text-sm text-base-content/60", children: "Type" }), _jsx("p", { className: "font-medium text-base-content", children: selectedMedia.mimeType })] }), _jsxs("div", { children: [_jsx("p", { className: "text-sm text-base-content/60", children: "Size" }), _jsx("p", { className: "font-medium text-base-content", children: formatFileSize(selectedMedia.size) })] }), _jsxs("div", { children: [_jsx("p", { className: "text-sm text-base-content/60", children: "Created" }), _jsx("p", { className: "font-medium text-base-content", children: formatDate(selectedMedia.createdAt) })] })] }), _jsxs("div", { children: [_jsx("p", { className: "text-sm text-base-content/60 mb-1", children: "URL" }), _jsxs("div", { className: "flex gap-2", children: [_jsx("input", { type: "text", value: selectedMedia.url, readOnly: true, className: "flex-1 input input-bordered bg-base-200 text-sm" }), _jsx(Button, { variant: "secondary", onClick: () => navigator.clipboard.writeText(selectedMedia.url), children: "Copy" })] })] }), _jsxs("div", { className: "flex gap-3 justify-end pt-4 border-t border-base-300", children: [_jsxs(Button, { variant: "error", onClick: () => handleDelete(selectedMedia.id), children: [_jsx(Trash2, { className: "h-4 w-4" }), "Delete"] }), _jsx("a", { href: selectedMedia.url, download: true, target: "_blank", rel: "noopener noreferrer", children: _jsxs(Button, { variant: "secondary", className: "flex items-center gap-2", children: [_jsx(Download, { className: "h-4 w-4" }), "Download"] }) })] })] }) }))] }));
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=MediaPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MediaPage.js","sourceRoot":"","sources":["../../../src/client/pages/MediaPage.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PermissionsPage.d.ts","sourceRoot":"","sources":["../../../src/client/pages/PermissionsPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PermissionsPage.d.ts","sourceRoot":"","sources":["../../../src/client/pages/PermissionsPage.tsx"],"names":[],"mappings":"AA2BA,MAAM,CAAC,OAAO,UAAU,eAAe,4CAgOtC"}
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useMemo, useState } from 'react';
|
|
3
4
|
import { useQuery } from '@tanstack/react-query';
|
|
4
|
-
import {
|
|
5
|
-
import { useState } from 'react';
|
|
5
|
+
import { Layers, Search, Shield } from 'lucide-react';
|
|
6
6
|
import { getApiClient } from '../auth/api-client';
|
|
7
7
|
import { CORE_ADMIN_API_ROUTES } from '../constants/api-routes';
|
|
8
|
-
import PageHeader from '../components/PageHeader';
|
|
9
8
|
import ProtectedPage from '../auth/ProtectedPage';
|
|
10
9
|
import { PERMISSIONS } from '../constants/permissions';
|
|
10
|
+
import Badge from '../ui/Badge';
|
|
11
|
+
import Input from '../ui/Input';
|
|
12
|
+
import DataTable from '../ui/DataTable';
|
|
13
|
+
// Khóa đại diện cho lựa chọn "Tất cả resource"
|
|
14
|
+
const ALL_RESOURCES = '__all__';
|
|
11
15
|
export default function PermissionsPage() {
|
|
12
16
|
const apiClient = getApiClient();
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
// Resource đang được chọn ở cột trái (mặc định xem tất cả)
|
|
18
|
+
const [selectedResource, setSelectedResource] = useState(ALL_RESOURCES);
|
|
19
|
+
// Từ khóa tìm kiếm danh sách quyền ở cột phải
|
|
20
|
+
const [searchTerm, setSearchTerm] = useState('');
|
|
21
|
+
// Lấy toàn bộ quyền (đã nhóm theo resource phía server)
|
|
15
22
|
const { data, isLoading } = useQuery({
|
|
16
23
|
queryKey: ['permissions'],
|
|
17
24
|
queryFn: async () => {
|
|
@@ -19,24 +26,51 @@ export default function PermissionsPage() {
|
|
|
19
26
|
return response.data;
|
|
20
27
|
},
|
|
21
28
|
});
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
29
|
+
const grouped = data?.grouped || {};
|
|
30
|
+
const resources = Object.keys(grouped);
|
|
31
|
+
// Danh sách quyền hiển thị ở cột phải theo resource đang chọn + lọc tìm kiếm
|
|
32
|
+
const visiblePermissions = useMemo(() => {
|
|
33
|
+
const base = selectedResource === ALL_RESOURCES
|
|
34
|
+
? Object.values(grouped).flat()
|
|
35
|
+
: grouped[selectedResource] || [];
|
|
36
|
+
if (!searchTerm.trim())
|
|
37
|
+
return base;
|
|
38
|
+
const keyword = searchTerm.toLowerCase();
|
|
39
|
+
return base.filter((p) => p.name.toLowerCase().includes(keyword) ||
|
|
40
|
+
p.action?.toLowerCase().includes(keyword) ||
|
|
41
|
+
p.description?.toLowerCase().includes(keyword) ||
|
|
42
|
+
p.resource?.toLowerCase().includes(keyword));
|
|
43
|
+
}, [grouped, selectedResource, searchTerm]);
|
|
44
|
+
// Cấu hình cột bảng quyền
|
|
45
|
+
const columns = [
|
|
46
|
+
{
|
|
47
|
+
key: 'name',
|
|
48
|
+
label: 'Tên quyền',
|
|
49
|
+
render: (value) => (_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "p-2 bg-primary/10 rounded-lg shrink-0", children: _jsx(Shield, { className: "w-4 h-4 text-primary" }) }), _jsx("span", { className: "font-mono text-sm font-medium text-primary", children: value })] })),
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
key: 'resource',
|
|
53
|
+
label: 'Resource',
|
|
54
|
+
width: '160px',
|
|
55
|
+
render: (value) => (_jsx(Badge, { variant: "neutral", style: "soft", children: value || '-' })),
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
key: 'action',
|
|
59
|
+
label: 'Hành động',
|
|
60
|
+
width: '140px',
|
|
61
|
+
render: (value) => (_jsx(Badge, { variant: "neutral", style: "ghost", children: value || '-' })),
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
key: 'description',
|
|
65
|
+
label: 'Mô tả',
|
|
66
|
+
render: (value) => (_jsx("p", { className: "text-base-content/80 line-clamp-2 max-w-md", children: value || '-' })),
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
return (_jsx(ProtectedPage, { permission: PERMISSIONS.ROLE_READ, children: _jsx("div", { className: "container mx-auto bg-base-200 min-h-screen p-6", children: _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-semibold text-base-content", children: "Danh s\u00E1ch quy\u1EC1n h\u1EA1n" }), _jsx("p", { className: "text-sm text-base-content/60 mt-1", children: "T\u1EA5t c\u1EA3 c\u00E1c quy\u1EC1n trong h\u1EC7 th\u1ED1ng \u0111\u01B0\u1EE3c nh\u00F3m theo resource" })] }), _jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: [_jsxs("div", { className: "bg-base-100 rounded-lg p-5 flex items-center gap-4 border border-base-200", children: [_jsx("div", { className: "p-3 bg-primary/10 rounded-lg", children: _jsx(Shield, { className: "w-6 h-6 text-primary" }) }), _jsxs("div", { children: [_jsx("p", { className: "text-sm text-base-content/60", children: "T\u1ED5ng s\u1ED1 quy\u1EC1n" }), _jsx("p", { className: "text-2xl font-semibold text-base-content", children: data?.total ?? 0 })] })] }), _jsxs("div", { className: "bg-base-100 rounded-lg p-5 flex items-center gap-4 border border-base-200", children: [_jsx("div", { className: "p-3 bg-secondary/10 rounded-lg", children: _jsx(Layers, { className: "w-6 h-6 text-secondary" }) }), _jsxs("div", { children: [_jsx("p", { className: "text-sm text-base-content/60", children: "S\u1ED1 nh\u00F3m resource" }), _jsx("p", { className: "text-2xl font-semibold text-base-content", children: resources.length })] })] })] }), _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-[280px_1fr] gap-6", children: [_jsxs("aside", { className: "bg-base-100 rounded-lg p-4 h-fit border border-base-200 lg:sticky lg:top-6", children: [_jsx("h2", { className: "text-sm font-semibold text-base-content/70 uppercase px-2 mb-3", children: "Resource" }), isLoading ? (_jsx("div", { className: "flex justify-center py-8", children: _jsx("span", { className: "loading loading-spinner loading-md" }) })) : (_jsxs("ul", { className: "space-y-1", children: [_jsx("li", { children: _jsxs("button", { onClick: () => setSelectedResource(ALL_RESOURCES), className: `w-full flex items-center justify-between gap-2 px-3 py-2.5 rounded-lg text-left transition-colors ${selectedResource === ALL_RESOURCES
|
|
70
|
+
? 'bg-primary text-primary-content'
|
|
71
|
+
: 'hover:bg-base-200 text-base-content'}`, children: [_jsx("span", { className: "font-medium text-sm", children: "T\u1EA5t c\u1EA3" }), _jsx("span", { className: `badge badge-sm ${selectedResource === ALL_RESOURCES ? 'badge-ghost' : 'badge-primary badge-soft'}`, children: data?.total ?? 0 })] }) }), resources.map((resource) => {
|
|
72
|
+
const isActive = selectedResource === resource;
|
|
73
|
+
return (_jsx("li", { children: _jsxs("button", { onClick: () => setSelectedResource(resource), className: `w-full flex items-center justify-between gap-2 px-3 py-2.5 rounded-lg text-left transition-colors ${isActive ? 'bg-primary text-primary-content' : 'hover:bg-base-200 text-base-content'}`, children: [_jsx("span", { className: "font-medium text-sm uppercase truncate", children: resource }), _jsx("span", { className: `badge badge-sm shrink-0 ${isActive ? 'badge-ghost' : 'badge-primary badge-soft'}`, children: grouped[resource].length })] }) }, resource));
|
|
74
|
+
}), resources.length === 0 && (_jsx("li", { className: "text-center text-base-content/60 text-sm py-6", children: "Ch\u01B0a c\u00F3 resource n\u00E0o" }))] }))] }), _jsxs("section", { className: "space-y-4", children: [_jsxs("div", { className: "bg-base-100 rounded-lg p-4 flex flex-col sm:flex-row sm:items-center justify-between gap-4 border border-base-200", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("h2", { className: "text-lg font-semibold text-base-content uppercase", children: selectedResource === ALL_RESOURCES ? 'Tất cả quyền' : selectedResource }), _jsxs(Badge, { variant: "primary", style: "soft", children: [visiblePermissions.length, " quy\u1EC1n"] })] }), _jsx("div", { className: "w-full sm:w-auto sm:min-w-[260px]", children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-5 w-5 text-base-content/50" }), _jsx(Input, { type: "text", placeholder: "T\u00ECm ki\u1EBFm quy\u1EC1n...", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), className: "pl-10 w-full" })] }) })] }), _jsx("div", { className: "bg-base-100 rounded-lg overflow-hidden border border-base-200", children: _jsx(DataTable, { data: visiblePermissions, columns: columns, loading: isLoading, emptyMessage: "Kh\u00F4ng t\u00ECm th\u1EA5y quy\u1EC1n n\u00E0o" }) })] })] })] }) }) }));
|
|
41
75
|
}
|
|
42
76
|
//# sourceMappingURL=PermissionsPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PermissionsPage.js","sourceRoot":"","sources":["../../../src/client/pages/PermissionsPage.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"PermissionsPage.js","sourceRoot":"","sources":["../../../src/client/pages/PermissionsPage.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RolesPage.d.ts","sourceRoot":"","sources":["../../../src/client/pages/RolesPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RolesPage.d.ts","sourceRoot":"","sources":["../../../src/client/pages/RolesPage.tsx"],"names":[],"mappings":"AAoBA,MAAM,CAAC,OAAO,UAAU,SAAS,4CA6RhC"}
|