Add pre-commit hooks for linting and formatting
All checks were successful
CI / backend-lint (push) Successful in 9s
CI / frontend-lint (push) Successful in 33s

Set up pre-commit framework with ruff (backend) and ESLint/Prettier/tsc
(frontend) hooks to catch issues locally before CI. Auto-format all
frontend files with Prettier to comply with the new check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-14 16:41:24 +01:00
parent b05a75f7f2
commit 2963f16aa4
67 changed files with 1905 additions and 792 deletions

View File

@@ -10,14 +10,24 @@ interface BossDefeatModalProps {
starterName?: string | null
}
function matchVariant(labels: string[], starterName?: string | null): string | null {
function matchVariant(
labels: string[],
starterName?: string | null
): string | null {
if (!starterName || labels.length === 0) return null
const lower = starterName.toLowerCase()
const matches = labels.filter((l) => l.toLowerCase().includes(lower))
return matches.length === 1 ? matches[0] : null
}
export function BossDefeatModal({ boss, onSubmit, onClose, isPending, hardcoreMode, starterName }: BossDefeatModalProps) {
export function BossDefeatModal({
boss,
onSubmit,
onClose,
isPending,
hardcoreMode,
starterName,
}: BossDefeatModalProps) {
const [result, setResult] = useState<'won' | 'lost'>('won')
const [attempts, setAttempts] = useState('1')
@@ -30,16 +40,20 @@ export function BossDefeatModal({ boss, onSubmit, onClose, isPending, hardcoreMo
}, [boss.pokemon])
const hasVariants = variantLabels.length > 0
const autoMatch = useMemo(() => matchVariant(variantLabels, starterName), [variantLabels, starterName])
const autoMatch = useMemo(
() => matchVariant(variantLabels, starterName),
[variantLabels, starterName]
)
const showPills = hasVariants && autoMatch === null
const [selectedVariant, setSelectedVariant] = useState<string | null>(
autoMatch ?? (hasVariants ? variantLabels[0] : null),
autoMatch ?? (hasVariants ? variantLabels[0] : null)
)
const displayedPokemon = useMemo(() => {
if (!hasVariants) return boss.pokemon
return boss.pokemon.filter(
(bp) => bp.conditionLabel === selectedVariant || bp.conditionLabel === null,
(bp) =>
bp.conditionLabel === selectedVariant || bp.conditionLabel === null
)
}, [boss.pokemon, hasVariants, selectedVariant])
@@ -58,7 +72,9 @@ export function BossDefeatModal({ boss, onSubmit, onClose, isPending, hardcoreMo
<div className="relative bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-md w-full mx-4">
<div className="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-lg font-semibold">Battle: {boss.name}</h2>
<p className="text-sm text-gray-500 dark:text-gray-400">{boss.location}</p>
<p className="text-sm text-gray-500 dark:text-gray-400">
{boss.location}
</p>
</div>
{/* Boss team preview */}
@@ -88,7 +104,11 @@ export function BossDefeatModal({ boss, onSubmit, onClose, isPending, hardcoreMo
.map((bp) => (
<div key={bp.id} className="flex flex-col items-center">
{bp.pokemon.spriteUrl ? (
<img src={bp.pokemon.spriteUrl} alt={bp.pokemon.name} className="w-10 h-10" />
<img
src={bp.pokemon.spriteUrl}
alt={bp.pokemon.name}
className="w-10 h-10"
/>
) : (
<div className="w-10 h-10 bg-gray-200 dark:bg-gray-700 rounded-full" />
)}
@@ -138,7 +158,9 @@ export function BossDefeatModal({ boss, onSubmit, onClose, isPending, hardcoreMo
{!hardcoreMode && (
<div>
<label className="block text-sm font-medium mb-1">Attempts</label>
<label className="block text-sm font-medium mb-1">
Attempts
</label>
<input
type="number"
min={1}