Files
nuzlocke-tracker/frontend/src/components/RulesConfiguration.tsx

115 lines
3.8 KiB
TypeScript
Raw Normal View History

2026-02-04 17:13:58 +01:00
import type { NuzlockeRules } from '../types/rules'
import { RULE_DEFINITIONS, DEFAULT_RULES } from '../types/rules'
import { RuleToggle } from './RuleToggle'
interface RulesConfigurationProps {
rules: NuzlockeRules
onChange: (rules: NuzlockeRules) => void
onReset?: (() => void) | undefined
hiddenRules?: Set<keyof NuzlockeRules> | undefined
2026-02-04 17:13:58 +01:00
}
export function RulesConfiguration({
rules,
onChange,
onReset,
hiddenRules,
2026-02-04 17:13:58 +01:00
}: RulesConfigurationProps) {
const visibleRules = hiddenRules
? RULE_DEFINITIONS.filter((r) => !hiddenRules.has(r.key))
: RULE_DEFINITIONS
const coreRules = visibleRules.filter((r) => r.category === 'core')
const difficultyRules = visibleRules.filter((r) => r.category === 'difficulty')
const completionRules = visibleRules.filter((r) => r.category === 'completion')
2026-02-04 17:13:58 +01:00
const handleRuleChange = (key: keyof NuzlockeRules, value: boolean) => {
onChange({ ...rules, [key]: value })
}
const handleResetToDefault = () => {
onChange(DEFAULT_RULES)
onReset?.()
}
const enabledCount = visibleRules.filter((r) => rules[r.key]).length
const totalCount = visibleRules.length
2026-02-04 17:13:58 +01:00
return (
<div className="space-y-6">
<div className="flex items-center justify-between">
<div>
<h2 className="text-xl font-semibold text-text-primary">Rules Configuration</h2>
<p className="text-sm text-text-tertiary">
2026-02-04 17:13:58 +01:00
{enabledCount} of {totalCount} rules enabled
</p>
</div>
<button
type="button"
onClick={handleResetToDefault}
className="text-sm text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
>
Reset to Default
</button>
</div>
<div className="bg-surface-1 rounded-lg shadow">
<div className="px-4 py-3 border-b border-border-default">
<h3 className="text-lg font-medium text-text-primary">Core Rules</h3>
<p className="text-sm text-text-tertiary">
2026-02-04 17:13:58 +01:00
The fundamental rules of a Nuzlocke challenge
</p>
</div>
<div className="px-4">
{coreRules.map((rule) => (
<RuleToggle
key={rule.key}
name={rule.name}
description={rule.description}
enabled={rules[rule.key]}
onChange={(value) => handleRuleChange(rule.key, value)}
/>
))}
</div>
</div>
<div className="bg-surface-1 rounded-lg shadow">
<div className="px-4 py-3 border-b border-border-default">
<h3 className="text-lg font-medium text-text-primary">Difficulty Modifiers</h3>
<p className="text-sm text-text-tertiary">Optional rules to increase the challenge</p>
2026-02-04 17:13:58 +01:00
</div>
<div className="px-4">
{difficultyRules.map((rule) => (
<RuleToggle
key={rule.key}
name={rule.name}
description={rule.description}
enabled={rules[rule.key]}
onChange={(value) => handleRuleChange(rule.key, value)}
/>
))}
</div>
</div>
{completionRules.length > 0 && (
<div className="bg-surface-1 rounded-lg shadow">
<div className="px-4 py-3 border-b border-border-default">
<h3 className="text-lg font-medium text-text-primary">Completion</h3>
<p className="text-sm text-text-tertiary">When is the run considered complete</p>
</div>
<div className="px-4">
{completionRules.map((rule) => (
<RuleToggle
key={rule.key}
name={rule.name}
description={rule.description}
enabled={rules[rule.key]}
onChange={(value) => handleRuleChange(rule.key, value)}
/>
))}
</div>
</div>
)}
2026-02-04 17:13:58 +01:00
</div>
)
}