Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | 3x 3x 3x 43x 6x 1x 10x 10x 10x 10x 10x 3x | import React from 'react';
import {AchievementDetails, AchievementIconRecord} from '../types';
import { Styles } from '../defaultStyles';
import { defaultAchievementIcons } from '../assets/defaultIcons';
interface BadgesModalProps {
isOpen: boolean;
achievements: AchievementDetails[];
onClose: () => void;
styles: Styles['badgesModal'];
icons?: Record<string, string>;
}
const BadgesModal: React.FC<BadgesModalProps> = ({ isOpen, achievements, onClose, styles, icons = {} }) => {
if (!isOpen) return null;
return (
<div
style={styles.overlay as React.CSSProperties}
onClick={onClose}
data-testid="modal-overlay"
>
<div
style={styles.content}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
onClick={e => e.stopPropagation()}
>
<h2 id="modal-title" style={styles.title}>Your Achievements</h2>
<div style={styles.badgeContainer}>
{achievements.length > 0 ? (
achievements.map((achievement) => {
const mergedIcons: AchievementIconRecord = { ...defaultAchievementIcons, ...icons };
let iconToDisplay: string | undefined = mergedIcons.default;
if (achievement.achievementIconKey && mergedIcons[achievement.achievementIconKey]) {
iconToDisplay = mergedIcons[achievement.achievementIconKey];
}
return (
<div key={achievement.achievementId} style={styles.badge}>
{iconToDisplay.startsWith('http') || iconToDisplay.startsWith('data:image') ? (
<img src={iconToDisplay} alt={achievement.achievementTitle} style={styles.badgeIcon} />
) : (
<p style={{ fontSize: '2em' }}>{iconToDisplay}</p>
)}
<span style={styles.badgeTitle}>{achievement.achievementTitle}</span>
<span style={styles.badgeDescription}>{achievement.achievementDescription}</span>
</div>
);
})
) : (
<p style={styles.emptyState}>No achievements yet. Keep exploring!</p>
)}
</div>
<button onClick={onClose} style={styles.button}>Close</button>
</div>
</div>
);
};
export default React.memo(BadgesModal); |