Component Details

Auth Component 05

Auth Component 05

AuthErrorContent.tsx

Next.jsTailwind CSS
1// app/auth/error/error-content.tsx - The actual component with useSearchParams
2"use client";
3
4import { useEffect, useState } from "react";
5import { useRouter, useSearchParams } from "next/navigation";
6import Link from "next/link";
7import { Button } from "@/components/ui/button";
8import {
9  Card,
10  CardContent,
11  CardHeader,
12  CardTitle,
13  CardDescription,
14} from "@/components/ui/card";
15import { Alert, AlertDescription } from "@/components/ui/alert";
16import { AlertCircle, Home, RefreshCw } from "lucide-react";
17
18export default function AuthErrorContent() {
19  const [error, setError] = useState<string>("");
20  const [errorDescription, setErrorDescription] = useState<string>("");
21  const searchParams = useSearchParams();
22  const router = useRouter();
23
24  useEffect(() => {
25    // Get error from query parameters
26    const errorParam = searchParams.get("error");
27    const errorDescParam = searchParams.get("error_description");
28
29    if (errorParam) {
30      setError(decodeURIComponent(errorParam));
31    }
32    if (errorDescParam) {
33      setErrorDescription(decodeURIComponent(errorDescParam));
34    }
35  }, [searchParams]);
36
37  // Common error messages and solutions
38  const commonErrors = [
39    {
40      code: "invalid_credentials",
41      message: "Invalid email or password",
42      solution: "Check your credentials and try again",
43    },
44    {
45      code: "email_not_confirmed",
46      message: "Email not confirmed",
47      solution: "Check your inbox for the confirmation email",
48    },
49    {
50      code: "user_already_exists",
51      message: "User already exists",
52      solution: "Try signing in instead of signing up",
53    },
54    {
55      code: "weak_password",
56      message: "Password is too weak",
57      solution: "Use a stronger password with at least 8 characters",
58    },
59    {
60      code: "oauth_error",
61      message: "OAuth authentication failed",
62      solution: "Try another sign-in method",
63    },
64    {
65      code: "magic_link_expired",
66      message: "Magic link has expired",
67      solution: "Request a new magic link",
68    },
69    {
70      code: "rate_limit_exceeded",
71      message: "Too many attempts. Please try again later",
72      solution: "Wait a few minutes before trying again",
73    },
74  ];
75
76  const getErrorSolution = (errorMsg: string) => {
77    const foundError = commonErrors.find(
78      (err) =>
79        errorMsg.toLowerCase().includes(err.code) ||
80        errorMsg.toLowerCase().includes(err.message.toLowerCase())
81    );
82    return foundError?.solution || "Please try again or contact support.";
83  };
84
85  return (
86    <div className="flex flex-col">
87      <main className="flex-1 flex items-center justify-center px-4 py-12">
88        <div className="w-full max-w-md">
89          <div className="text-center mb-8">
90            <h1 className="text-3xl font-bold mb-2">Authentication Error</h1>
91            <p className="text-muted-foreground">
92              Something went wrong during authentication
93            </p>
94          </div>
95
96          <Card className="border shadow-sm">
97            <CardHeader className="space-y-1">
98              <CardTitle className="text-2xl">Error Details</CardTitle>
99              <CardDescription>
100                Here&apos;s what went wrong and how to fix it
101              </CardDescription>
102            </CardHeader>
103
104            <CardContent className="space-y-4">
105              {/* Error Message */}
106              <Alert variant="destructive">
107                <AlertCircle className="h-4 w-4" />
108                <AlertDescription>
109                  {error || "An unknown authentication error occurred"}
110                </AlertDescription>
111              </Alert>
112
113              {/* Error Description */}
114              {errorDescription && (
115                <div className="p-3 bg-muted rounded-lg">
116                  <p className="text-sm text-muted-foreground">
117                    <span className="font-medium">Details:</span>{" "}
118                    {errorDescription}
119                  </p>
120                </div>
121              )}
122
123              {/* Suggested Solution */}
124              <div className="p-4 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg">
125                <h3 className="font-medium text-blue-800 dark:text-blue-300 mb-2">
126                  How to fix this:
127                </h3>
128                <p className="text-sm text-blue-700 dark:text-blue-400">
129                  {getErrorSolution(error || errorDescription)}
130                </p>
131              </div>
132
133              {/* Action Buttons */}
134              <div className="space-y-3">
135                <Button
136                  onClick={() => router.push("/signin")}
137                  className="w-full"
138                >
139                  <RefreshCw className="mr-2 h-4 w-4" />
140                  Try Again
141                </Button>
142
143                <Button variant="outline" className="w-full" asChild>
144                  <Link href="/">
145                    <Home className="mr-2 h-4 w-4" />
146                    Go Home
147                  </Link>
148                </Button>
149              </div>
150
151              {/* Common Error Solutions */}
152              <div className="mt-4">
153                <h3 className="text-sm font-medium mb-2">Common Solutions:</h3>
154                <ul className="text-sm text-muted-foreground space-y-2">
155                  <li className="flex items-start gap-2">
156                    <div className="w-1 h-1 mt-2 rounded-full bg-muted-foreground" />
157                    Clear browser cookies and cache
158                  </li>
159                  <li className="flex items-start gap-2">
160                    <div className="w-1 h-1 mt-2 rounded-full bg-muted-foreground" />
161                    Try a different browser
162                  </li>
163                  <li className="flex items-start gap-2">
164                    <div className="w-1 h-1 mt-2 rounded-full bg-muted-foreground" />
165                    Check your internet connection
166                  </li>
167                  <li className="flex items-start gap-2">
168                    <div className="w-1 h-1 mt-2 rounded-full bg-muted-foreground" />
169                    Disable browser extensions temporarily
170                  </li>
171                </ul>
172              </div>
173            </CardContent>
174          </Card>
175
176          {/* Contact Support */}
177          <div className="mt-6">
178            <div className="relative">
179              <div className="absolute inset-0 flex items-center">
180                <div className="w-full border-t"></div>
181              </div>
182              <div className="relative flex justify-center text-xs">
183                <span className="bg-background px-2 text-muted-foreground">
184                  Still having issues?
185                </span>
186              </div>
187            </div>
188
189            <div className="mt-4">
190              <Button variant="outline" className="w-full" asChild>
191                <Link href="/contact">Contact our support team</Link>
192              </Button>
193            </div>
194          </div>
195        </div>
196      </main>
197    </div>
198  );
199}
200
201// app/auth/error/page.tsx
202import { Suspense } from "react";
203import AuthErrorContent from "./error-content";
204
205export default function AuthErrorPage() {
206  return (
207    <Suspense fallback={<AuthErrorSkeleton />}>
208      <AuthErrorContent />
209    </Suspense>
210  );
211}
212
213// Skeleton loading component
214function AuthErrorSkeleton() {
215  return (
216    <div className="flex flex-col">
217      <main className="flex-1 flex items-center justify-center px-4 py-12">
218        <div className="w-full max-w-md">
219          <div className="text-center mb-8">
220            <h1 className="text-3xl font-bold mb-2">Loading...</h1>
221            <p className="text-muted-foreground">Preparing error details</p>
222          </div>
223          <div className="animate-pulse space-y-4">
224            <div className="h-48 bg-gray-200 dark:bg-gray-800 rounded-lg"></div>
225            <div className="h-24 bg-gray-200 dark:bg-gray-800 rounded-lg"></div>
226            <div className="h-12 bg-gray-200 dark:bg-gray-800 rounded-lg"></div>
227          </div>
228        </div>
229      </main>
230    </div>
231  );
232}