142 lines
5.1 KiB
JavaScript
142 lines
5.1 KiB
JavaScript
"use client"
|
|
|
|
import { useState, Suspense } from "react"
|
|
import { signIn, getSession } from "next-auth/react"
|
|
import { useRouter } from "next/navigation"
|
|
import { useSearchParams } from "next/navigation"
|
|
|
|
function SignInContent() {
|
|
const [username, setUsername] = useState("")
|
|
const [password, setPassword] = useState("")
|
|
const [error, setError] = useState("")
|
|
const [isLoading, setIsLoading] = useState(false)
|
|
const router = useRouter()
|
|
const searchParams = useSearchParams()
|
|
const callbackUrl = searchParams.get("callbackUrl") || "/"
|
|
|
|
const handleSubmit = async (e) => {
|
|
e.preventDefault()
|
|
setIsLoading(true)
|
|
setError("")
|
|
|
|
try {
|
|
const result = await signIn("credentials", {
|
|
username,
|
|
password,
|
|
redirect: false,
|
|
})
|
|
|
|
if (result?.error) {
|
|
setError("Invalid username or password")
|
|
} else {
|
|
// Successful login
|
|
router.push(callbackUrl)
|
|
router.refresh()
|
|
}
|
|
} catch (error) {
|
|
setError("An error occurred. Please try again.")
|
|
} finally {
|
|
setIsLoading(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
|
<div className="max-w-md w-full space-y-8">
|
|
<div>
|
|
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
|
|
Zaloguj się do swojego konta
|
|
</h2>
|
|
<p className="mt-2 text-center text-sm text-gray-600">
|
|
Dostęp do panelu
|
|
</p>
|
|
</div>
|
|
<form className="mt-8 space-y-6" onSubmit={handleSubmit}>
|
|
{error && (
|
|
<div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded relative">
|
|
{error}
|
|
</div>
|
|
)}
|
|
|
|
<div className="rounded-md shadow-sm -space-y-px">
|
|
<div>
|
|
<label htmlFor="username" className="sr-only">
|
|
Nazwa użytkownika
|
|
</label>
|
|
<input
|
|
id="username"
|
|
name="username"
|
|
type="text"
|
|
autoComplete="username"
|
|
required
|
|
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
|
|
placeholder="Nazwa użytkownika"
|
|
value={username}
|
|
onChange={(e) => setUsername(e.target.value)}
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label htmlFor="password" className="sr-only">
|
|
Hasło
|
|
</label>
|
|
<input
|
|
id="password"
|
|
name="password"
|
|
type="password"
|
|
autoComplete="current-password"
|
|
required
|
|
className="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
|
|
placeholder="Password"
|
|
value={password}
|
|
onChange={(e) => setPassword(e.target.value)}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<button
|
|
type="submit"
|
|
disabled={isLoading}
|
|
className="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
>
|
|
{isLoading ? (
|
|
<span className="flex items-center">
|
|
<svg className="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
|
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
</svg>
|
|
Zaloguj...
|
|
</span>
|
|
) : (
|
|
"Sign in"
|
|
)}
|
|
</button>
|
|
</div>
|
|
|
|
{/* <div className="text-center">
|
|
<div className="text-sm text-gray-600 bg-blue-50 p-3 rounded">
|
|
<p className="font-medium">Default Admin Account:</p>
|
|
<p>Email: admin@localhost</p>
|
|
<p>Password: admin123456</p>
|
|
</div>
|
|
</div> */}
|
|
</form>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default function SignIn() {
|
|
return (
|
|
<Suspense fallback={
|
|
<div className="min-h-screen flex items-center justify-center bg-gray-50">
|
|
<div className="text-center">
|
|
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500 mx-auto mb-4"></div>
|
|
<p className="text-gray-600">Loading...</p>
|
|
</div>
|
|
</div>
|
|
}>
|
|
<SignInContent />
|
|
</Suspense>
|
|
)
|
|
} |