From 5c8c198fc5630467ce97efa23a447363d7423e5e Mon Sep 17 00:00:00 2001 From: DanielS Date: Wed, 24 Jun 2026 10:54:00 +0200 Subject: [PATCH] fix: production login error masking, resolve navbar hydration mismatch, and gracefully handle database render errors --- shop/app/my-customers/page.tsx | 21 ++++++++- shop/components/NavbarClient.tsx | 9 +++- shop/components/login-form.tsx | 27 ++++++----- shop/lib/actions/auth.ts | 80 ++++++++++++++++++++++---------- 4 files changed, 96 insertions(+), 41 deletions(-) diff --git a/shop/app/my-customers/page.tsx b/shop/app/my-customers/page.tsx index a507b3d..94a3481 100644 --- a/shop/app/my-customers/page.tsx +++ b/shop/app/my-customers/page.tsx @@ -2,6 +2,7 @@ export const dynamic = 'force-dynamic'; import { redirect } from 'next/navigation' import Link from 'next/link' import { getEndCustomers } from '@/lib/actions/end-customers' +import type { EndCustomer } from '@/lib/types' import { ArrowLeft, Building2, Plus, Edit2, AlertTriangle } from 'lucide-react' import { Button } from '@/components/ui/button' import { Card, CardContent } from '@/components/ui/card' @@ -13,10 +14,20 @@ export default async function MyCustomersPage() { const { data: { user } } = await supabase.auth.getUser() if (!user) redirect('/auth/login') - const customers = await getEndCustomers() + let customers: EndCustomer[] = [] + let fetchError: string | null = null + try { + customers = await getEndCustomers() + } catch (err: any) { + console.error("Error loading end customers:", err) + fetchError = err.message || "Es gab ein Problem beim Laden Ihrer Endkunden." + } // Anzahl Bestellungen pro Endkunde - const { data: orderCounts } = await supabase.from('orders').select('end_customer_id').not('end_customer_id', 'is', null); + const { data: orderCounts, error: orderError } = await supabase.from('orders').select('end_customer_id').not('end_customer_id', 'is', null); + if (orderError) { + console.error("Error loading order counts:", orderError) + } const countMap: Record = {} ;(orderCounts ?? []).forEach(o => { @@ -53,6 +64,12 @@ export default async function MyCustomersPage() { + {fetchError && ( +
+ {fetchError} +
+ )} + {/* Keine Kunden */} {customers.length === 0 && ( diff --git a/shop/components/NavbarClient.tsx b/shop/components/NavbarClient.tsx index e008cf7..ea8319a 100644 --- a/shop/components/NavbarClient.tsx +++ b/shop/components/NavbarClient.tsx @@ -21,6 +21,11 @@ export function NavbarClient({ user, role = "partner" }: NavbarClientProps) { const [userRole, setUserRole] = useState(role); const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); const [open, setOpen] = useState(false); + const [pathname, setPathname] = useState("/"); + + useEffect(() => { + setPathname(window.location.pathname); + }, []); // Supabase URL & Anon Key auslesen (für Browser-Client) const supabaseUrl = process.env.SUPABASE_URL || process.env.NEXT_PUBLIC_SUPABASE_URL; @@ -186,7 +191,7 @@ export function NavbarClient({ user, role = "partner" }: NavbarClientProps) { ) : ( )} @@ -269,7 +274,7 @@ export function NavbarClient({ user, role = "partner" }: NavbarClientProps) { ) : ( )} diff --git a/shop/components/login-form.tsx b/shop/components/login-form.tsx index 468b189..9b96535 100644 --- a/shop/components/login-form.tsx +++ b/shop/components/login-form.tsx @@ -14,7 +14,7 @@ import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import Link from "next/link"; import { useRouter } from "next/navigation"; -import { useState } from "react"; +import { useState, useEffect } from "react"; export function LoginForm({ className, @@ -24,8 +24,13 @@ export function LoginForm({ const [password, setPassword] = useState(""); const [error, setError] = useState(null); const [isLoading, setIsLoading] = useState(false); + const [messageParam, setMessageParam] = useState(null); const router = useRouter(); + useEffect(() => { + setMessageParam(new URLSearchParams(window.location.search).get('message')); + }, []); + const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); setIsLoading(true); @@ -35,6 +40,10 @@ export function LoginForm({ try { const res = await signIn(email, password); + if (!res.success) { + setError(res.error || "An error occurred"); + return; + } if (nextParam) { router.push(nextParam); } else if (res.role === "admin") { @@ -90,17 +99,11 @@ export function LoginForm({ onChange={(e) => setPassword(e.target.value)} /> - {(() => { - const messageParam = typeof window !== 'undefined' ? new URLSearchParams(window.location.search).get('message') : null; - if (messageParam === "concurrent") { - return ( -

- Sie wurden abgemeldet, da Sie sich an einem anderen Gerät angemeldet haben. -

- ); - } - return null; - })()} + {messageParam === "concurrent" && ( +

+ Sie wurden abgemeldet, da Sie sich an einem anderen Gerät angemeldet haben. +

+ )} {error &&

{error}

}