fix(settings): fix password error persistence and audio quality clearable

- Wrap password state setters to auto-clear passwordError on input change,
  so stale validation errors don't persist after user corrects the fields
- Add clearable prop to Select component (default true for back-compat)
- Pass clearable={false} to audio quality dropdown so users cannot clear
  it to an empty/invalid state

Fixes: Settings bugs #17, #20

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
senke 2026-03-25 23:43:45 +01:00
parent c1f3503a82
commit 178c4b340c
5 changed files with 23 additions and 4 deletions

View file

@ -7,6 +7,7 @@ import type { SelectProps } from './types';
export function Select({
placeholder = 'Select an option...',
name,
clearable = true,
'aria-label': ariaLabel,
'aria-labelledby': ariaLabelledBy,
className,
@ -36,6 +37,7 @@ export function Select({
className={className}
ariaLabel={ariaLabel}
ariaLabelledBy={ariaLabelledBy}
clearable={clearable}
onClear={handleClear}
/>
);

View file

@ -9,6 +9,7 @@ interface SelectTriggerProps {
multiple: boolean;
disabled: boolean;
open: boolean;
clearable?: boolean;
className?: string;
ariaLabel?: string;
ariaLabelledBy?: string;
@ -22,6 +23,7 @@ export function SelectTrigger({
multiple,
disabled,
open,
clearable = true,
className,
ariaLabel,
ariaLabelledBy,
@ -49,7 +51,7 @@ export function SelectTrigger({
>
<span className="truncate">{showPlaceholder ? placeholder : displayValue}</span>
<div className="flex items-center gap-1 ml-2">
{hasValue && (
{hasValue && clearable && (
<span
role="button"
tabIndex={0}

View file

@ -27,6 +27,7 @@ export interface SelectProps {
searchable?: boolean;
placeholder?: string;
disabled?: boolean;
clearable?: boolean;
className?: string;
name?: string;
'aria-label'?: string;

View file

@ -62,6 +62,7 @@ export function PlaybackSettings({
onChange={handleQualityChange}
placeholder="Select audio quality"
name="quality"
clearable={false}
/>
<p className="text-xs text-muted-foreground">
Higher quality uses more bandwidth

View file

@ -13,11 +13,24 @@ export function useAccountSettings() {
const [isDeletingAccount, setIsDeletingAccount] = useState(false);
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
const [currentPassword, setCurrentPassword] = useState('');
const [newPassword, setNewPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [currentPassword, setCurrentPasswordRaw] = useState('');
const [newPassword, setNewPasswordRaw] = useState('');
const [confirmPassword, setConfirmPasswordRaw] = useState('');
const [passwordError, setPasswordError] = useState('');
const setCurrentPassword = useCallback((v: string) => {
setCurrentPasswordRaw(v);
if (passwordError) setPasswordError('');
}, [passwordError]);
const setNewPassword = useCallback((v: string) => {
setNewPasswordRaw(v);
if (passwordError) setPasswordError('');
}, [passwordError]);
const setConfirmPassword = useCallback((v: string) => {
setConfirmPasswordRaw(v);
if (passwordError) setPasswordError('');
}, [passwordError]);
const [deletePassword, setDeletePassword] = useState('');
const [deleteReason, setDeleteReason] = useState('');
const [deleteConfirmText, setDeleteConfirmText] = useState('');