Files
HexUnlockedWeb/app/customizations/FlatCategory.tsx
T
2026-06-18 21:54:12 -03:00

136 lines
5.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import shared from '../../styles/shared.module.css';
import styles from '../../styles/Customizations.module.css';
import { CustomizationItem, Tab, getCosmeticIconUrl } from './types';
type Props = {
tab: Tab;
allFilteredItems: CustomizationItem[];
pagedItems: CustomizationItem[];
page: number;
totalPages: number;
search: string;
unlockedSet: Set<string>;
characterMap: Map<number, string>;
onSearchChange: (s: string) => void;
onUnlockAll: () => void;
onLockAll: () => void;
onUnlockPage: () => void;
onLockPage: () => void;
onToggle: (id: string) => void;
onPageChange: (p: number) => void;
};
export default function FlatCategory({
tab,
allFilteredItems,
pagedItems,
page,
totalPages,
search,
unlockedSet,
characterMap,
onSearchChange,
onUnlockAll,
onLockAll,
onUnlockPage,
onLockPage,
onToggle,
onPageChange,
}: Props) {
const buildPageNumbers = () => {
const pages: number[] = [];
const start = Math.max(1, Math.min(page - 2, totalPages - 4));
const end = Math.min(totalPages, start + 4);
for (let i = start; i <= end; i++) pages.push(i);
return pages;
};
return (
<>
<div className={shared.toolbar}>
<input
className={shared.searchInput}
type="text"
placeholder={`Search ${tab}...`}
value={search}
onChange={e => onSearchChange(e.target.value)}
/>
<span className={shared.spacer} />
<span className={shared.resultCount}>{allFilteredItems.length} items</span>
<button className={shared.unlockAllBtn} onClick={onUnlockAll}>
Unlock all ({allFilteredItems.length})
</button>
<button className={shared.lockAllBtn} onClick={onLockAll}>
Lock all
</button>
<button className={styles.pageActionBtn} onClick={onUnlockPage}>
Unlock visible
</button>
<button className={styles.pageActionBtn} onClick={onLockPage}>
Lock visible
</button>
</div>
{allFilteredItems.length === 0 ? (
<div className={shared.empty}>No items found</div>
) : (
<>
<div className={styles.grid}>
{pagedItems.map(item => {
const unlocked = unlockedSet.has(item.id);
return (
<div
key={item.id}
className={`${shared.card} ${unlocked ? shared.cardUnlocked : ''}`}
onClick={() => onToggle(item.id)}
>
<img
className={shared.cardIcon}
src={getCosmeticIconUrl(item, characterMap)}
alt={item.name}
loading="lazy"
/>
<span className={shared.cardName}>{item.name}</span>
</div>
);
})}
</div>
{totalPages > 1 && (
<div className={shared.pagination}>
<button
className={`${shared.pageBtn} ${page === 1 ? shared.pageBtnDisabled : ''}`}
onClick={() => onPageChange(1)}
>«</button>
<button
className={`${shared.pageBtn} ${page === 1 ? shared.pageBtnDisabled : ''}`}
onClick={() => onPageChange(page - 1)}
></button>
{buildPageNumbers().map(n => (
<button
key={n}
className={`${shared.pageBtn} ${n === page ? shared.pageBtnActive : ''}`}
onClick={() => onPageChange(n)}
>{n}</button>
))}
<button
className={`${shared.pageBtn} ${page === totalPages ? shared.pageBtnDisabled : ''}`}
onClick={() => onPageChange(page + 1)}
></button>
<button
className={`${shared.pageBtn} ${page === totalPages ? shared.pageBtnDisabled : ''}`}
onClick={() => onPageChange(totalPages)}
>»</button>
<span className={shared.pageInfo}>{page} / {totalPages}</span>
</div>
)}
</>
)}
</>
);
}