build: da8aa2fb-9871-4e3e-a583-70eda77c4d68
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
IonContent,
|
||||
IonPage,
|
||||
IonInput,
|
||||
IonButton,
|
||||
IonSpinner,
|
||||
IonIcon,
|
||||
} from '@ionic/react';
|
||||
import { chevronBackOutline } from 'ionicons/icons';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { supabase } from '../supabase';
|
||||
|
||||
const NewPasswordPage: React.FC = () => {
|
||||
const [password, setPassword] = useState('');
|
||||
const [confirmPassword, setConfirmPassword] = useState('');
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [message, setMessage] = useState<string | null>(null);
|
||||
|
||||
const history = useHistory();
|
||||
|
||||
const showMessage = (msg: string) => {
|
||||
setMessage(msg);
|
||||
setTimeout(() => setMessage(null), 4000);
|
||||
};
|
||||
|
||||
const handleUpdate = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (!password || !confirmPassword) {
|
||||
showMessage('Please fill in all fields');
|
||||
return;
|
||||
}
|
||||
|
||||
if (password.length < 6) {
|
||||
showMessage('Password must be at least 6 characters');
|
||||
return;
|
||||
}
|
||||
|
||||
if (password !== confirmPassword) {
|
||||
showMessage('Passwords do not match');
|
||||
return;
|
||||
}
|
||||
|
||||
setSubmitting(true);
|
||||
setMessage(null);
|
||||
|
||||
try {
|
||||
const { error } = await supabase.auth.updateUser({ password });
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
history.push('/home');
|
||||
} catch (err: any) {
|
||||
showMessage(err.message || 'An error occurred');
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
<IonContent
|
||||
fullscreen
|
||||
style={{
|
||||
'--background':
|
||||
'linear-gradient(160deg, rgba(199,210,254,0.52) 0%, #f0f4ff 58%, #f8fafc 100%)',
|
||||
}}
|
||||
>
|
||||
<div className="auth-shell">
|
||||
<IonButton
|
||||
fill="clear"
|
||||
color="dark"
|
||||
onClick={() => history.push('/auth')}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 'calc(var(--ion-safe-area-top, 0px) + 8px)',
|
||||
left: '8px',
|
||||
'--padding-start': '8px',
|
||||
'--padding-end': '8px',
|
||||
zIndex: 10,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
background: '#ffffff',
|
||||
width: '44px',
|
||||
height: '44px',
|
||||
borderRadius: '12px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<IonIcon icon={chevronBackOutline} />
|
||||
</div>
|
||||
</IonButton>
|
||||
|
||||
<div style={{ marginTop: '80px' }}>
|
||||
<h1
|
||||
className="bold"
|
||||
style={{ fontSize: '24px', margin: '0 0 8px 0' }}
|
||||
>
|
||||
Create new password
|
||||
</h1>
|
||||
<p
|
||||
className="secondary-text"
|
||||
style={{ margin: '0', fontSize: '14px' }}
|
||||
>
|
||||
Set a strong password to protect your account.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="auth-card">
|
||||
<form
|
||||
onSubmit={handleUpdate}
|
||||
style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}
|
||||
>
|
||||
<div className="input-wrapper">
|
||||
<IonInput
|
||||
label="New Password"
|
||||
labelPlacement="floating"
|
||||
type="password"
|
||||
placeholder="Min. 6 characters"
|
||||
value={password}
|
||||
onIonChange={(e) => setPassword(e.detail.value!)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="input-wrapper">
|
||||
<IonInput
|
||||
label="Confirm Password"
|
||||
labelPlacement="floating"
|
||||
type="password"
|
||||
placeholder="Repeat your password"
|
||||
value={confirmPassword}
|
||||
onIonChange={(e) => setConfirmPassword(e.detail.value!)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{message && (
|
||||
<div
|
||||
style={{
|
||||
background: 'var(--color-danger-soft)',
|
||||
color: 'var(--ion-color-danger-shade)',
|
||||
padding: '12px',
|
||||
borderRadius: '12px',
|
||||
fontSize: '13px',
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
{message}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<IonButton
|
||||
type="submit"
|
||||
expand="block"
|
||||
className="bold"
|
||||
style={{
|
||||
height: '52px',
|
||||
'--border-radius': 'var(--radius-pill)',
|
||||
marginTop: '8px',
|
||||
}}
|
||||
disabled={submitting}
|
||||
>
|
||||
{submitting ? (
|
||||
<IonSpinner name="crescent" />
|
||||
) : (
|
||||
'Update password'
|
||||
)}
|
||||
</IonButton>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewPasswordPage;
|
||||
Reference in New Issue
Block a user