Autosave: 20260408-230340
This commit is contained in:
parent
67930e0c1a
commit
ec7d0e496c
@ -6,15 +6,17 @@ import { useState } from "react"
|
||||
import { useRouter } from "next/navigation"
|
||||
import Link from "next/link"
|
||||
import { createClient } from "@/lib/supabase/client"
|
||||
import { Film, Eye, Loader2 } from "lucide-react"
|
||||
import { Film, Eye, Loader2, Mail } from "lucide-react"
|
||||
import { useLanguage } from "@/contexts/LanguageContext"
|
||||
import { LanguageToggle } from "@/components/language-toggle"
|
||||
import { toast } from "sonner"
|
||||
|
||||
export default function LoginPage() {
|
||||
const [email, setEmail] = useState("")
|
||||
const [password, setPassword] = useState("")
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [resetLoading, setResetLoading] = useState(false)
|
||||
const router = useRouter()
|
||||
const { t } = useLanguage()
|
||||
|
||||
@ -22,6 +24,8 @@ export default function LoginPage() {
|
||||
e.preventDefault()
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
console.log("Attempting login for:", email);
|
||||
|
||||
const supabase = createClient()
|
||||
const { error } = await supabase.auth.signInWithPassword({
|
||||
@ -30,7 +34,8 @@ export default function LoginPage() {
|
||||
})
|
||||
|
||||
if (error) {
|
||||
setError(t("auth.invalidCredentials"))
|
||||
console.error("Login error:", error);
|
||||
setError(error.message)
|
||||
setLoading(false)
|
||||
return
|
||||
}
|
||||
@ -39,6 +44,29 @@ export default function LoginPage() {
|
||||
router.refresh()
|
||||
}
|
||||
|
||||
async function handleResetPassword() {
|
||||
if (!email) {
|
||||
setError("Bitte gib deine E-Mail-Adresse oben ein.")
|
||||
return
|
||||
}
|
||||
|
||||
setResetLoading(true)
|
||||
setError(null)
|
||||
|
||||
const supabase = createClient()
|
||||
const { error } = await supabase.auth.resetPasswordForEmail(email, {
|
||||
redirectTo: `${window.location.origin}/auth/callback?next=/auth/update-password`,
|
||||
})
|
||||
|
||||
if (error) {
|
||||
setError(error.message)
|
||||
setResetLoading(false)
|
||||
} else {
|
||||
toast.success("E-Mail zum Zurücksetzen des Passworts wurde gesendet.")
|
||||
setResetLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="flex min-h-dvh flex-col items-center justify-center px-6">
|
||||
<div className="w-full max-w-sm">
|
||||
@ -108,6 +136,19 @@ export default function LoginPage() {
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<button
|
||||
onClick={handleResetPassword}
|
||||
disabled={resetLoading}
|
||||
className="mt-4 flex w-full items-center justify-center gap-2 text-sm text-muted-foreground hover:text-primary transition-colors disabled:opacity-50"
|
||||
>
|
||||
{resetLoading ? (
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
) : (
|
||||
<Mail className="h-4 w-4" />
|
||||
)}
|
||||
Passwort vergessen?
|
||||
</button>
|
||||
|
||||
<p className="mt-6 text-center text-sm text-muted-foreground">
|
||||
{t("auth.dontHaveAccount")}{" "}
|
||||
<Link href="/auth/sign-up" className="font-medium text-primary hover:underline">
|
||||
|
||||
@ -1,8 +1,15 @@
|
||||
import { createBrowserClient } from '@supabase/ssr'
|
||||
|
||||
export function createClient() {
|
||||
const url = process.env.NEXT_PUBLIC_SUPABASE_URL || "https://ekbpexbhuochrplzorce.supabase.co";
|
||||
const key = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || "sb_publishable__UII_iKx3pgvLQvc1xrN1w_qnwP6JOv" || process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY;
|
||||
|
||||
if (!url || !key) {
|
||||
console.error("Supabase config missing!", { url: !!url, key: !!key });
|
||||
}
|
||||
|
||||
return createBrowserClient(
|
||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
||||
url!,
|
||||
key!,
|
||||
)
|
||||
}
|
||||
|
||||
@ -7,8 +7,8 @@ export async function updateSession(request: NextRequest) {
|
||||
})
|
||||
|
||||
const supabase = createServerClient(
|
||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
||||
process.env.NEXT_PUBLIC_SUPABASE_URL || "https://ekbpexbhuochrplzorce.supabase.co"!,
|
||||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || "sb_publishable__UII_iKx3pgvLQvc1xrN1w_qnwP6JOv" || process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY!,
|
||||
{
|
||||
cookies: {
|
||||
getAll() {
|
||||
|
||||
@ -5,8 +5,8 @@ export async function createClient() {
|
||||
const cookieStore = await cookies()
|
||||
|
||||
return createServerClient(
|
||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
||||
process.env.NEXT_PUBLIC_SUPABASE_URL || "https://ekbpexbhuochrplzorce.supabase.co"!,
|
||||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || "sb_publishable__UII_iKx3pgvLQvc1xrN1w_qnwP6JOv" || process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY!,
|
||||
{
|
||||
cookies: {
|
||||
getAll() {
|
||||
|
||||
2
next-env.d.ts
vendored
2
next-env.d.ts
vendored
@ -1,6 +1,6 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
import "./.next/dev/types/routes.d.ts";
|
||||
import "./.next/types/routes.d.ts";
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
|
||||
14
public/sw.js
14
public/sw.js
@ -39,8 +39,10 @@ self.addEventListener("fetch", (event) => {
|
||||
(cached) =>
|
||||
cached ||
|
||||
fetch(event.request).then((response) => {
|
||||
const clone = response.clone()
|
||||
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, clone))
|
||||
if (response.status === 200 && event.request.method === 'GET') {
|
||||
const clone = response.clone()
|
||||
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, clone))
|
||||
}
|
||||
return response
|
||||
})
|
||||
)
|
||||
@ -52,10 +54,12 @@ self.addEventListener("fetch", (event) => {
|
||||
event.respondWith(
|
||||
fetch(event.request)
|
||||
.then((response) => {
|
||||
const clone = response.clone()
|
||||
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, clone))
|
||||
if (response.status === 200 && event.request.method === 'GET') {
|
||||
const clone = response.clone()
|
||||
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, clone))
|
||||
}
|
||||
return response
|
||||
})
|
||||
.catch(() => caches.match(event.request))
|
||||
)
|
||||
})
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user