74 lines
3.0 KiB
TypeScript
74 lines
3.0 KiB
TypeScript
'use client';
|
|
|
|
import shared from '../../styles/shared.module.css';
|
|
import styles from '../../styles/Customizations.module.css';
|
|
import { CustomizationItem, CATEGORY_LABELS, CATEGORY_ORDER, getCosmeticIconUrl } from './types';
|
|
|
|
type Props = {
|
|
charName: string;
|
|
charCosmetics: Record<number, CustomizationItem[]>;
|
|
unlockedSet: Set<string>;
|
|
characterMap: Map<number, string>;
|
|
onBack: () => void;
|
|
onUnlockAll: () => void;
|
|
onLockAll: () => void;
|
|
onToggle: (id: string) => void;
|
|
};
|
|
|
|
export default function CharacterCosmetics({
|
|
charName,
|
|
charCosmetics,
|
|
unlockedSet,
|
|
characterMap,
|
|
onBack,
|
|
onUnlockAll,
|
|
onLockAll,
|
|
onToggle,
|
|
}: Props) {
|
|
const allItems = Object.values(charCosmetics).flat();
|
|
const unlockedCount = allItems.filter(i => unlockedSet.has(i.id)).length;
|
|
|
|
return (
|
|
<div className={styles.cosmeticsView}>
|
|
<div className={styles.cosmeticsHeader}>
|
|
<button className={styles.backBtn} onClick={onBack}>← Back</button>
|
|
<span className={styles.cosmeticsCharName}>{charName}</span>
|
|
<span className={shared.resultCount}>{unlockedCount} / {allItems.length} unlocked</span>
|
|
<span className={shared.spacer} />
|
|
<button className={shared.unlockAllBtn} onClick={onUnlockAll}>Unlock all</button>
|
|
<button className={shared.lockAllBtn} onClick={onLockAll}>Lock all</button>
|
|
</div>
|
|
|
|
<div className={styles.cosmeticsBody}>
|
|
{CATEGORY_ORDER.filter(cat => charCosmetics[cat]?.length > 0).map(cat => (
|
|
<div key={cat} className={styles.categoryGroup}>
|
|
<div className={styles.categoryTitle}>
|
|
{CATEGORY_LABELS[cat] ?? `Category ${cat}`}
|
|
</div>
|
|
<div className={styles.gridInline}>
|
|
{charCosmetics[cat].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>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|