|
| 1 | +import React, { useEffect, useState } from "react"; |
| 2 | +import { useRouter } from "next/router"; |
| 3 | +import Link from "next/link"; |
| 4 | +import type { NextPage } from "next"; |
| 5 | +import Layout from "@layout/layout-01"; |
| 6 | + |
| 7 | +type ErrorType = { |
| 8 | + [key: string]: { |
| 9 | + title: string; |
| 10 | + message: string; |
| 11 | + action: string; |
| 12 | + }; |
| 13 | +}; |
| 14 | + |
| 15 | +const errorMessages: ErrorType = { |
| 16 | + default: { |
| 17 | + title: "Authentication Error", |
| 18 | + message: |
| 19 | + "An unexpected error occurred during the authentication process.", |
| 20 | + action: "Please try signing in again.", |
| 21 | + }, |
| 22 | + configuration: { |
| 23 | + title: "Server Configuration Error", |
| 24 | + message: "There is a problem with the server configuration.", |
| 25 | + action: "Please contact support for assistance.", |
| 26 | + }, |
| 27 | + accessdenied: { |
| 28 | + title: "Access Denied", |
| 29 | + message: |
| 30 | + "You must be a member of the required GitHub organization to access this application.", |
| 31 | + action: "Please request access from your organization administrator.", |
| 32 | + }, |
| 33 | + verification: { |
| 34 | + title: "Account Verification Required", |
| 35 | + message: "Your account requires verification before continuing.", |
| 36 | + action: "Please check your email for verification instructions.", |
| 37 | + }, |
| 38 | + signin: { |
| 39 | + title: "Sign In Error", |
| 40 | + message: "The sign in attempt was unsuccessful.", |
| 41 | + action: "Please try again or use a different method to sign in.", |
| 42 | + }, |
| 43 | + callback: { |
| 44 | + title: "Callback Error", |
| 45 | + message: "There was a problem with the authentication callback.", |
| 46 | + action: "Please try signing in again. If the problem persists, clear your browser cookies.", |
| 47 | + }, |
| 48 | + oauthsignin: { |
| 49 | + title: "GitHub Sign In Error", |
| 50 | + message: "Unable to initiate GitHub sign in process.", |
| 51 | + action: "Please try again or check if GitHub is accessible.", |
| 52 | + }, |
| 53 | + oauthcallback: { |
| 54 | + title: "GitHub Callback Error", |
| 55 | + message: "There was a problem processing the GitHub authentication.", |
| 56 | + action: "Please try signing in again or ensure you've granted the required permissions.", |
| 57 | + }, |
| 58 | +}; |
| 59 | + |
| 60 | +type PageWithLayout = NextPage & { |
| 61 | + Layout?: typeof Layout; |
| 62 | +}; |
| 63 | + |
| 64 | +const AuthError: PageWithLayout = () => { |
| 65 | + const router = useRouter(); |
| 66 | + const [error, setError] = useState(errorMessages.default); |
| 67 | + const [countdown, setCountdown] = useState(10); |
| 68 | + |
| 69 | + useEffect(() => { |
| 70 | + const errorType = router.query.error as string; |
| 71 | + if (errorType && errorMessages[errorType]) { |
| 72 | + setError(errorMessages[errorType]); |
| 73 | + } |
| 74 | + }, [router.query]); |
| 75 | + |
| 76 | + useEffect(() => { |
| 77 | + const timer = setInterval(() => { |
| 78 | + setCountdown((prev) => { |
| 79 | + if (prev <= 1) { |
| 80 | + clearInterval(timer); |
| 81 | + router.push("/").catch(console.error); |
| 82 | + return 0; |
| 83 | + } |
| 84 | + return prev - 1; |
| 85 | + }); |
| 86 | + }, 1000); |
| 87 | + |
| 88 | + return () => clearInterval(timer); |
| 89 | + }, [router]); |
| 90 | + |
| 91 | + return ( |
| 92 | + <div className="tw-min-h-screen tw-bg-gray-50 tw-flex tw-flex-col tw-justify-center tw-py-12 tw-sm:px-6 tw-lg:px-8"> |
| 93 | + <div className="tw-sm:mx-auto tw-sm:w-full tw-sm:max-w-md"> |
| 94 | + <div className="tw-bg-white tw-py-8 tw-px-4 tw-shadow tw-sm:rounded-lg tw-sm:px-10"> |
| 95 | + <div className="tw-text-center"> |
| 96 | + <h2 className="tw-text-2xl tw-font-bold tw-text-gray-900 tw-mb-4"> |
| 97 | + {error.title} |
| 98 | + </h2> |
| 99 | + <div className="tw-rounded-md tw-bg-red-50 tw-p-4 tw-mb-6"> |
| 100 | + <div className="tw-flex"> |
| 101 | + <div className="tw-flex-shrink-0"> |
| 102 | + <svg |
| 103 | + className="tw-h-5 tw-w-5 tw-text-red-400" |
| 104 | + xmlns="http://www.w3.org/2000/svg" |
| 105 | + viewBox="0 0 20 20" |
| 106 | + fill="currentColor" |
| 107 | + aria-hidden="true" |
| 108 | + > |
| 109 | + <path |
| 110 | + fillRule="evenodd" |
| 111 | + d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" |
| 112 | + clipRule="evenodd" |
| 113 | + /> |
| 114 | + </svg> |
| 115 | + </div> |
| 116 | + <div className="tw-ml-3"> |
| 117 | + <p className="tw-text-sm tw-text-red-700"> |
| 118 | + {error.message} |
| 119 | + </p> |
| 120 | + <p className="tw-mt-2 tw-text-sm tw-text-red-700"> |
| 121 | + {error.action} |
| 122 | + </p> |
| 123 | + </div> |
| 124 | + </div> |
| 125 | + </div> |
| 126 | + |
| 127 | + <div className="tw-space-y-4"> |
| 128 | + <Link |
| 129 | + href="/" |
| 130 | + className="tw-inline-flex tw-items-center tw-px-4 tw-py-2 tw-border tw-border-transparent tw-text-sm tw-font-medium tw-rounded-md tw-shadow-sm tw-text-white tw-bg-primary tw-hover:tw-bg-opacity-90 tw-focus:tw-outline-none tw-focus:tw-ring-2 tw-focus:tw-ring-offset-2 tw-focus:tw-ring-primary" |
| 131 | + > |
| 132 | + Return to Home Page |
| 133 | + </Link> |
| 134 | + |
| 135 | + <p className="tw-text-sm tw-text-gray-500"> |
| 136 | + Redirecting in {countdown} seconds... |
| 137 | + </p> |
| 138 | + |
| 139 | + <div className="tw-mt-4 tw-text-sm tw-text-gray-500"> |
| 140 | + Need help?{" "} |
| 141 | + <a |
| 142 | + |
| 143 | + className="tw-font-medium tw-text-primary tw-hover:tw-text-opacity-90" |
| 144 | + > |
| 145 | + Contact Support |
| 146 | + </a> |
| 147 | + </div> |
| 148 | + </div> |
| 149 | + </div> |
| 150 | + </div> |
| 151 | + </div> |
| 152 | + </div> |
| 153 | + ); |
| 154 | +}; |
| 155 | + |
| 156 | +AuthError.Layout = Layout; |
| 157 | + |
| 158 | +export default AuthError; |
0 commit comments