Skip to content

Reset password #132

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions app/auth/forgot-password/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'use client'

import { useState } from 'react'
import { Button } from '@/components/ui/button'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { supabase } from '@/lib/supabaseClient'

export default function ForgotPasswordPage() {
const [email, setEmail] = useState('')
const [status, setStatus] = useState<'idle' | 'sending' | 'sent' | 'error'>('idle')

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setStatus('sending')

const { error } = await supabase.auth.resetPasswordForEmail(email, {
redirectTo: `${window.location.origin}/auth/reset-password`
})

if (error) {
setStatus('error')
console.error('Error sending reset email:', error.message)
} else {
setStatus('sent')
}
}

return (
<main className="flex min-h-screen items-center justify-center px-4">
<Card className="w-full max-w-md rounded-2xl">
<CardHeader>
<CardTitle className="text-center text-2xl">Forgot Password</CardTitle>
</CardHeader>
<CardContent className='space-y-4 align-center'>
<form onSubmit={handleSubmit} className="space-y-4">
<input
type="email"
placeholder="you@example.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
className="w-full p-2 border rounded"
/>
<div className="flex justify-center">
<Button type="submit" disabled={status === 'sending'}>
{status === 'sending' ? 'Sending...' : 'Send Reset Link'}
</Button>
</div>
</form>
{status === 'sent' && (
<Alert variant="default" className="mt-4">
<AlertDescription>Check your email for the reset link.</AlertDescription>
</Alert>
)}
{status === 'error' && (
<Alert variant="destructive" className="mt-4">
<AlertDescription>Failed to send reset link. Please try again.</AlertDescription>
</Alert>
)}
</CardContent>
</Card>
</main>
)
}
90 changes: 90 additions & 0 deletions app/auth/reset-password/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
'use client'

import { useState } from 'react'
import { useRouter } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { supabase } from '@/lib/supabaseClient'

export default function ResetPasswordPage() {
const router = useRouter()
const [newPassword, setNewPassword] = useState('')
const [confirmPassword, setConfirmPassword] = useState('')
const [status, setStatus] = useState<'idle' | 'updating' | 'updated' | 'error'>('idle')
const [errorMessage, setErrorMessage] = useState('')

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setErrorMessage('')

if (newPassword !== confirmPassword) {
setErrorMessage('Passwords do not match.')
return
}

setStatus('updating')

// Use the access token to update the user's password
const { data, error } = await supabase.auth.updateUser({ password: newPassword })

if (error) {
setStatus('error')
console.error('Error updating password:', error.message)
} else {
setStatus('updated')
// Redirect to login or another page after successful password update
setTimeout(() => {
router.push('/auth/signin')
}, 2000)
}
}

return (
<main className="flex min-h-screen items-center justify-center px-4">
<Card className="w-full max-w-md rounded-2xl">
<CardHeader>
<CardTitle className="text-center text-2xl">Set New Password</CardTitle>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
<input
type="password"
placeholder="New Password"
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
required
className="w-full p-2 border rounded"
/>
<input
type="password"
placeholder="Confirm Password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
required
className="w-full p-2 border rounded"
/>
{errorMessage && (
<Alert variant="destructive" className="mt-2">
<AlertDescription>{errorMessage}</AlertDescription>
</Alert>
)}
<Button type="submit" disabled={status === 'updating'}>
{status === 'updating' ? 'Updating...' : 'Set New Password'}
</Button>
</form>
{status === 'updated' && (
<Alert variant="default" className="mt-4">
<AlertDescription>Password updated successfully! Redirecting to sign in...</AlertDescription>
</Alert>
)}
{status === 'error' && (
<Alert variant="destructive" className="mt-4">
<AlertDescription>Failed to update password. Please try again.</AlertDescription>
</Alert>
)}
</CardContent>
</Card>
</main>
)
}
5 changes: 5 additions & 0 deletions components/AuthComponent/SigninForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ export default function SigninForm() {
title="Sign in"
type="submit"
/>
<div className="flex justify-center mt-4">
<a href="/auth/forgot-password" className="text-blue-600 hover:underline">
Forgot Password?
</a>
</div>
</form>
</Form>
</CardContent>
Expand Down