Skip to content

Commit 6448a5c

Browse files
enhance download toolbar with clear selection functionality and improved layout
Signed-off-by: Shahm Najeeb <Shahm_Najeeb@outlook.com>
1 parent 60c5514 commit 6448a5c

2 files changed

Lines changed: 69 additions & 41 deletions

File tree

components/gallery/download-toolbar.tsx

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,71 @@
11
"use client";
22

33
import React from "react";
4-
import {Download} from "lucide-react";
4+
import {Download, X} from "lucide-react";
55

66
type Props = {
77
selectedCount: number;
88
totalCount: number;
99
id?: string;
10+
onClearSelectionAction?: () => void;
1011
};
1112

12-
export default function DownloadToolbar({selectedCount, totalCount, id}: Props) {
13+
export default function DownloadToolbar({selectedCount, totalCount, id, onClearSelectionAction}: Props) {
1314
return (
1415
<div
1516
id={id}
16-
className="flex items-center justify-between gap-4 mb-6 p-4 rounded-lg border border-gray-800"
17+
className="sticky top-0 z-50 flex items-center justify-between gap-2 sm:gap-4 mb-6 p-2 sm:p-4 rounded-lg border border-gray-800"
1718
data-role="download-toolbar"
1819
style={{
1920
background: 'linear-gradient(to right, #000000, #1a1a1a)',
20-
boxShadow: '0 2px 10px rgba(0, 0, 0, 0.3)'
21+
boxShadow: '0 2px 10px rgba(0, 0, 0, 0.3)',
22+
backdropFilter: 'blur(10px)'
2123
}}
2224
>
23-
<div className="text-sm font-medium" style={{color: '#f8fafc'}}>
25+
<div className="text-xs sm:text-sm font-medium" style={{color: '#f8fafc'}}>
2426
{selectedCount > 0 ? (
2527
<span>
26-
<span style={{color: '#D4AF37', fontWeight: 600}}>{selectedCount}</span> selected
28+
<span style={{color: '#D4AF37', fontWeight: 600}}>{selectedCount}</span>
29+
<span className="hidden sm:inline"> selected</span>
2730
</span>
2831
) : (
2932
<span>
30-
<span style={{color: '#7a7a7a'}}>{totalCount}</span> photos
33+
<span style={{color: '#7a7a7a'}}>{totalCount}</span>
34+
<span className="hidden sm:inline"> photos</span>
3135
</span>
3236
)}
3337
</div>
3438

35-
<div className="flex gap-3">
39+
<div className="flex gap-2 sm:gap-3">
40+
{selectedCount > 0 && onClearSelectionAction && (
41+
<button
42+
onClick={onClearSelectionAction}
43+
className="px-2 sm:px-4 py-2 rounded-lg text-sm font-semibold transition-all duration-300 flex items-center gap-2"
44+
style={{
45+
background: 'transparent',
46+
color: '#ef4444',
47+
border: '1px solid rgba(239, 68, 68, 0.3)',
48+
cursor: 'pointer'
49+
}}
50+
onMouseEnter={(e) => {
51+
e.currentTarget.style.borderColor = '#ef4444';
52+
e.currentTarget.style.boxShadow = '0 4px 15px rgba(239, 68, 68, 0.2)';
53+
e.currentTarget.style.transform = 'translateY(-1px)';
54+
}}
55+
onMouseLeave={(e) => {
56+
e.currentTarget.style.borderColor = 'rgba(239, 68, 68, 0.3)';
57+
e.currentTarget.style.boxShadow = 'none';
58+
e.currentTarget.style.transform = 'translateY(0)';
59+
}}
60+
title="Clear Selection"
61+
>
62+
<X className="w-4 h-4"/>
63+
<span className="hidden sm:inline">Clear</span>
64+
</button>
65+
)}
3666
<button
3767
data-action="download-selected"
38-
className="px-4 py-2 rounded-lg text-sm font-semibold transition-all duration-300 flex items-center gap-2"
68+
className="px-2 sm:px-4 py-2 rounded-lg text-sm font-semibold transition-all duration-300 flex items-center gap-2"
3969
disabled={selectedCount === 0}
4070
style={{
4171
background: 'transparent',
@@ -58,13 +88,14 @@ export default function DownloadToolbar({selectedCount, totalCount, id}: Props)
5888
e.currentTarget.style.transform = 'translateY(0)';
5989
}
6090
}}
91+
title="Download Selected"
6192
>
6293
<Download className="w-4 h-4"/>
63-
Download Selected
94+
<span className="hidden sm:inline">Download</span>Selected
6495
</button>
6596
<button
6697
data-action="download-all"
67-
className="px-4 py-2 rounded-lg text-sm font-semibold transition-all duration-300 flex items-center gap-2"
98+
className="px-2 sm:px-4 py-2 rounded-lg text-sm font-semibold transition-all duration-300 flex items-center gap-2"
6899
style={{
69100
background: '#D4AF37',
70101
color: '#000',
@@ -81,9 +112,10 @@ export default function DownloadToolbar({selectedCount, totalCount, id}: Props)
81112
e.currentTarget.style.boxShadow = '0 4px 20px rgba(212, 175, 55, 0.25)';
82113
e.currentTarget.style.transform = 'translateY(0)';
83114
}}
115+
title="Download All"
84116
>
85117
<Download className="w-4 h-4"/>
86-
Download All
118+
<span className="hidden sm:inline">Download</span>All
87119
</button>
88120
</div>
89121
</div>

components/gallery/gallery-client.tsx

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,29 @@ export default function GalleryClient({folders}: { folders: Folder[] }) {
100100
}, [selected])
101101

102102
const onDownloadAll = useCallback(async () => {
103+
// Generate filename based on active filters
104+
let filename: string
105+
if (activeFilters.has(ALL_KEY)) {
106+
filename = 'Entire_Gallery.zip'
107+
} else {
108+
const filterNames = Array.from(activeFilters)
109+
.map(f => f.replace(/\//g, '_'))
110+
.join('_')
111+
filename = `${filterNames}_Gallery.zip`
112+
}
113+
114+
// If ALL is selected, use mode 'all', otherwise send the filtered image paths
115+
const body = activeFilters.has(ALL_KEY)
116+
? {mode: 'all', filename}
117+
: {items: visibleImages.map(img => img.path), filename}
118+
103119
const res = await fetch('/api/download', {
104120
method: 'POST',
105121
headers: {'Content-Type': 'application/json'},
106-
body: JSON.stringify({mode: 'all'}),
122+
body: JSON.stringify(body),
107123
})
108-
await downloadBlob(res, 'gallery.zip')
109-
}, [])
124+
await downloadBlob(res, filename)
125+
}, [activeFilters, ALL_KEY, visibleImages])
110126

111127
// toolbar id (serializable)
112128
const toolbarId = useMemo(() => 'download-toolbar-' + Math.random().toString(36).slice(2, 8), [])
@@ -139,34 +155,14 @@ export default function GalleryClient({folders}: { folders: Folder[] }) {
139155
onToggleFilterAction={toggleFilter}
140156
/>
141157

142-
<DownloadToolbar id={toolbarId} selectedCount={selected.size} totalCount={visibleImages.length}/>
158+
<DownloadToolbar
159+
id={toolbarId}
160+
selectedCount={selected.size}
161+
totalCount={visibleImages.length}
162+
onClearSelectionAction={clearSelection}
163+
/>
143164

144165
<GalleryGrid images={visibleImages} selected={selectedArray} onToggle={toggleSelect}/>
145-
146-
{selected.size > 0 && (
147-
<div className="mt-8 text-center">
148-
<button
149-
className="px-6 py-2 rounded-lg text-sm font-medium transition-all duration-300"
150-
onClick={clearSelection}
151-
style={{
152-
background: 'transparent',
153-
color: '#D4AF37',
154-
border: '1px solid rgba(212, 175, 55, 0.3)',
155-
cursor: 'pointer'
156-
}}
157-
onMouseEnter={(e) => {
158-
e.currentTarget.style.borderColor = '#D4AF37'
159-
e.currentTarget.style.boxShadow = '0 2px 10px rgba(212, 175, 55, 0.15)'
160-
}}
161-
onMouseLeave={(e) => {
162-
e.currentTarget.style.borderColor = 'rgba(212, 175, 55, 0.3)'
163-
e.currentTarget.style.boxShadow = 'none'
164-
}}
165-
>
166-
Clear Selection
167-
</button>
168-
</div>
169-
)}
170166
</div>
171167
)
172168
}

0 commit comments

Comments
 (0)