Add pre-commit hooks for linting and formatting
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:
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user