feat: change gallery filter to toggleable tabs

This commit is contained in:
Jannik committed 2026-09-24 04:18:58 +02:00
1 parent d304beeba1
commit 696f2ef50a
2 files changed
+50 -27

No files matched your search

+6 -1
View File
@@ -28,7 +28,12 @@ export async function GET(request: NextRequest) {
where.published = true;
}
if (directoryParam) {
where.directory = directoryParam;
const dirs = directoryParam.split(',');
if (dirs.length === 1) {
where.directory = dirs[0];
} else {
where.directory = { in: dirs };
}
}
let itemsRaw: any[] = [];
+44 -26
View File
@@ -41,23 +41,37 @@ export default function MediaWall({
const [loading, setLoading] = useState(false);
const [hasMore, setHasMore] = useState(!!initialCursor);
const [votingOpen, setVotingOpen] = useState(initialVotingOpen);
const [selectedDir, setSelectedDir] = useState<string>('');
const [selectedDirs, setSelectedDirs] = useState<string[]>(directories);
const handleDirChange = async (e: React.ChangeEvent<HTMLSelectElement>) => {
const dir = e.target.value;
setSelectedDir(dir);
const handleDirToggle = async (dir: string) => {
let newSelected = [...selectedDirs];
if (newSelected.includes(dir)) {
newSelected = newSelected.filter(d => d !== dir);
} else {
newSelected.push(dir);
}
if (dir === '') {
setSelectedDirs(newSelected);
if (newSelected.length === directories.length) {
setItems(initialItems);
setCursor(initialCursor);
setHasMore(!!initialCursor);
return;
}
if (newSelected.length === 0) {
setItems([]);
setCursor(null);
setHasMore(false);
return;
}
setLoading(true);
setItems([]);
try {
const res = await fetch(`/api/media?limit=50&directory=${encodeURIComponent(dir)}`);
const dirParam = newSelected.join(',');
const res = await fetch(`/api/media?limit=50&directory=${encodeURIComponent(dirParam)}`);
if (res.ok) {
const data = await res.json();
setItems(data.items);
@@ -79,10 +93,13 @@ export default function MediaWall({
const wallRef = useRef<HTMLDivElement>(null);
const loadMore = useCallback(async () => {
if (loading || !hasMore || !cursor) return;
if (loading || !hasMore || !cursor || selectedDirs.length === 0) return;
setLoading(true);
try {
const dirParam = selectedDir ? `&directory=${encodeURIComponent(selectedDir)}` : '';
let dirParam = '';
if (selectedDirs.length > 0 && selectedDirs.length < directories.length) {
dirParam = `&directory=${encodeURIComponent(selectedDirs.join(','))}`;
}
const res = await fetch(`/api/media?limit=50&cursor=${cursor}${dirParam}`);
if (res.ok) {
const data = await res.json();
@@ -104,7 +121,7 @@ export default function MediaWall({
} finally {
setLoading(false);
}
}, [loading, hasMore, cursor, selectedDir]);
}, [loading, hasMore, cursor, selectedDirs, directories.length]);
// Infinite scroll observer
useEffect(() => {
@@ -142,29 +159,30 @@ export default function MediaWall({
return (
<>
{directories.length > 0 && (
<div style={{ padding: '80px 20px 0', maxWidth: '1920px', margin: '0 auto', display: 'flex', justifyContent: 'center' }}>
<select
value={selectedDir}
onChange={handleDirChange}
<div style={{ padding: '80px 20px 0', maxWidth: '1920px', margin: '0 auto', display: 'flex', justifyContent: 'center', gap: '10px', flexWrap: 'wrap' }}>
{directories.map(dir => {
const isActive = selectedDirs.includes(dir);
return (
<button
key={dir}
onClick={() => handleDirToggle(dir)}
style={{
padding: '10px 20px',
padding: '8px 16px',
borderRadius: '20px',
border: '1px solid var(--color-border)',
background: 'var(--color-surface)',
border: `1px solid ${isActive ? 'var(--color-primary)' : 'var(--color-border)'}`,
background: isActive ? 'var(--color-primary)' : 'var(--color-surface)',
color: isActive ? 'white' : 'var(--color-text)',
fontFamily: 'var(--font-body)',
fontSize: '1rem',
outline: 'none',
fontSize: '0.9rem',
cursor: 'pointer',
boxShadow: 'var(--shadow)',
color: 'var(--color-text)',
minWidth: '200px'
transition: 'all 0.2s ease',
boxShadow: isActive ? 'var(--shadow)' : 'none',
}}
>
<option value="">Alle Fotos</option>
{directories.map(dir => (
<option key={dir} value={dir}>{dir}</option>
))}
</select>
{dir}
</button>
);
})}
</div>
)}
<div className="media-wall" ref={wallRef} style={directories.length > 0 ? { paddingTop: '20px' } : {}}>