refactor: apply Astro, Preact, and general best practices to src
- Refactored all components in src/components to: - Use arrow function components and prop destructuring - Add JSDoc for all exported components - Improve accessibility (aria-labels, roles, etc.) - Use correct key usage in lists - Add comments for non-obvious logic - Use modern event handler patterns and memoization where appropriate - Refactored src/pages/index.astro: - Removed <html>, <head>, and <body> (should be in layout) - Used semantic <main> for main content - Kept only necessary imports and markup - Refactored src/styles/index.css: - Removed duplicate rules - Ensured only global resets/utilities are present - Added comments for clarity - Ensured no component-specific styles are present - Used consistent formatting Brings the codebase in line with modern Astro and Preact best practices, improves maintainability, accessibility, and code clarity.
This commit is contained in:
@@ -1,7 +1,18 @@
|
||||
import { h } from 'preact';
|
||||
import styles from './GameList.module.css';
|
||||
|
||||
export default function GameList({ games, filter = 'all', setFilter, onShowGameDetail, onDeleteGame }) {
|
||||
/**
|
||||
* List of games with filter and delete options.
|
||||
* @param {object} props
|
||||
* @param {object[]} props.games
|
||||
* @param {string} props.filter
|
||||
* @param {Function} props.setFilter
|
||||
* @param {Function} props.onShowGameDetail
|
||||
* @param {Function} props.onDeleteGame
|
||||
* @returns {import('preact').VNode}
|
||||
*/
|
||||
const GameList = ({ games, filter = 'all', setFilter, onShowGameDetail, onDeleteGame }) => {
|
||||
// Filter and sort games
|
||||
const filteredGames = games
|
||||
.filter(game => {
|
||||
if (filter === 'active') return game.status === 'active';
|
||||
@@ -13,9 +24,9 @@ export default function GameList({ games, filter = 'all', setFilter, onShowGameD
|
||||
return (
|
||||
<div className={styles['game-list'] + ' ' + styles['games-container']}>
|
||||
<div className={styles['filter-buttons']}>
|
||||
<button className={styles['filter-button'] + (filter === 'all' ? ' ' + styles['active'] : '')} onClick={() => setFilter('all')}>Alle</button>
|
||||
<button className={styles['filter-button'] + (filter === 'active' ? ' ' + styles['active'] : '')} onClick={() => setFilter('active')}>Aktiv</button>
|
||||
<button className={styles['filter-button'] + (filter === 'completed' ? ' ' + styles['active'] : '')} onClick={() => setFilter('completed')}>Abgeschlossen</button>
|
||||
<button className={styles['filter-button'] + (filter === 'all' ? ' ' + styles['active'] : '')} onClick={() => setFilter('all')} aria-label="Alle Spiele anzeigen">Alle</button>
|
||||
<button className={styles['filter-button'] + (filter === 'active' ? ' ' + styles['active'] : '')} onClick={() => setFilter('active')} aria-label="Nur aktive Spiele anzeigen">Aktiv</button>
|
||||
<button className={styles['filter-button'] + (filter === 'completed' ? ' ' + styles['active'] : '')} onClick={() => setFilter('completed')} aria-label="Nur abgeschlossene Spiele anzeigen">Abgeschlossen</button>
|
||||
</div>
|
||||
{filteredGames.length === 0 ? (
|
||||
<div className={styles['empty-state']}>Keine Spiele vorhanden</div>
|
||||
@@ -28,19 +39,24 @@ export default function GameList({ games, filter = 'all', setFilter, onShowGameD
|
||||
? `${game.score1} - ${game.score2} - ${game.score3}`
|
||||
: `${game.score1} - ${game.score2}`;
|
||||
return (
|
||||
<div className={
|
||||
styles['game-item'] + ' ' + (game.status === 'completed' ? styles['completed'] : styles['active'])
|
||||
} key={game.id}>
|
||||
<div className={styles['game-info']} onClick={() => onShowGameDetail(game.id)}>
|
||||
<div
|
||||
className={
|
||||
styles['game-item'] + ' ' + (game.status === 'completed' ? styles['completed'] : styles['active'])
|
||||
}
|
||||
key={game.id}
|
||||
>
|
||||
<div className={styles['game-info']} onClick={() => onShowGameDetail(game.id)} role="button" tabIndex={0} aria-label={`Details für Spiel ${playerNames}`}>
|
||||
<div className={styles['game-type']}>{game.gameType}{game.raceTo ? ` | ${game.raceTo}` : ''}</div>
|
||||
<div className={styles['player-names']}>{playerNames}</div>
|
||||
<div className={styles['game-scores']}>{scores}</div>
|
||||
</div>
|
||||
<button className={styles['delete-button']} onClick={() => onDeleteGame(game.id)}></button>
|
||||
<button className={styles['delete-button']} onClick={() => onDeleteGame(game.id)} aria-label={`Spiel löschen: ${playerNames}`}></button>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default GameList;
|
||||
Reference in New Issue
Block a user