@@ -20,6 +20,7 @@ export default function ClientPage() {
2020 const [ error , setError ] = useState < string | undefined > ( ) ;
2121 const [ effectivePassword , setEffectivePassword ] = useState < string | undefined > ( undefined ) ;
2222 const [ askPassword , setAskPassword ] = useState ( false ) ;
23+ const [ passwordError , setPasswordError ] = useState ( false ) ;
2324 type DownUrl = { url : string ; expiresAt ?: string } ;
2425 const [ downUrls , setDownUrls ] = useState < Record < string , DownUrl > > ( { } ) ;
2526 const [ updating , setUpdating ] = useState ( false ) ;
@@ -61,6 +62,8 @@ export default function ClientPage() {
6162 if ( e instanceof HttpError && ( e . status === 401 || e . status === 403 ) ) {
6263 // Need or wrong password → open modal
6364 setAskPassword ( true ) ;
65+ // If we already tried with a password, mark error to display feedback
66+ setPasswordError ( ! ! effectivePassword ) ;
6467 } else {
6568 const msg = e instanceof Error ? e . message : '加载失败' ;
6669 setError ( msg ) ;
@@ -129,8 +132,10 @@ export default function ClientPage() {
129132 const updated = await Api . patchClaim ( id , { status : newStatus , password : effectivePassword || undefined } ) ;
130133 setClaim ( updated ) ;
131134 } catch ( e : unknown ) {
132- if ( e instanceof HttpError && e . status === 403 ) setAskPassword ( true ) ;
133- else setError ( e instanceof Error ? e . message : '更新失败' ) ;
135+ if ( e instanceof HttpError && e . status === 403 ) {
136+ setAskPassword ( true ) ;
137+ setPasswordError ( ! ! effectivePassword ) ;
138+ } else setError ( e instanceof Error ? e . message : '更新失败' ) ;
134139 } finally {
135140 setUpdating ( false ) ;
136141 }
@@ -155,8 +160,10 @@ export default function ClientPage() {
155160 setClaimPassword ( id , pwd ) ;
156161 setEffectivePassword ( pwd ) ;
157162 setAskPassword ( false ) ;
163+ setPasswordError ( false ) ;
158164 } }
159- onCancel = { ( ) => setAskPassword ( false ) }
165+ onCancel = { ( ) => { setAskPassword ( false ) ; setPasswordError ( false ) ; } }
166+ error = { passwordError }
160167 />
161168 </ div >
162169 </ div >
@@ -300,7 +307,7 @@ export default function ClientPage() {
300307 ) ;
301308}
302309
303- function PasswordPrompt ( { onSubmit, onCancel } : { onSubmit : ( pwd : string ) => void ; onCancel : ( ) => void } ) {
310+ function PasswordPrompt ( { onSubmit, onCancel, error } : { onSubmit : ( pwd : string ) => void ; onCancel : ( ) => void ; error ?: boolean } ) {
304311 const [ v , setV ] = useState ( '' ) ;
305312 const { t } = useI18n ( ) ;
306313 return (
@@ -312,6 +319,7 @@ function PasswordPrompt({ onSubmit, onCancel }: { onSubmit: (pwd: string) => voi
312319 } }
313320 className = "space-y-3"
314321 >
322+ { error && < div className = "text-sm text-red-600" > { t ( 'passwordWrong' ) } </ div > }
315323 < input autoFocus type = "password" value = { v } onChange = { ( e ) => setV ( e . target . value ) } className = "w-full rounded border px-3 py-2 bg-transparent" placeholder = { t ( 'enterPassword' ) } />
316324 < div className = "flex justify-end gap-2" >
317325 < button type = "button" className = "px-3 py-1.5 rounded border" onClick = { onCancel } > { t ( 'cancel' ) } </ button >
0 commit comments