122 lines
4.9 KiB
TypeScript
122 lines
4.9 KiB
TypeScript
import { message, Modal } from 'antd';
|
|
import React, { type FormEvent, type ReactNode } from 'react'
|
|
import { UserApi, type UserSignInDTO } from '../../../apis/core/user.api';
|
|
import { Apis } from '../../../apis';
|
|
import { UserRole, type User } from '../../../types/user.type';
|
|
import { useSelector } from 'react-redux';
|
|
import type { StoreType } from '../../../stores';
|
|
|
|
export default function ProtectedAdmin(
|
|
{ children }: {
|
|
children: ReactNode;
|
|
}) {
|
|
const userStore = useSelector((store: StoreType) => {
|
|
return store.user
|
|
})
|
|
|
|
|
|
if (userStore.data?.role == UserRole.MASTER || userStore.data?.role == UserRole.ADMIN) {
|
|
return (
|
|
<>
|
|
{children}
|
|
</>
|
|
)
|
|
}
|
|
|
|
if (!userStore.data?.role) {
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 p-4">
|
|
<div className="w-full max-w-md bg-white rounded-2xl shadow-2xl overflow-hidden">
|
|
{/* Header */}
|
|
<div className="p-6 text-center border-b border-gray-200">
|
|
<h1 className="text-2xl font-bold text-slate-800">Rikkei Phone Store</h1>
|
|
<p className="text-gray-500 text-sm mt-1">Chào mừng bạn quay trở lại 👋</p>
|
|
</div>
|
|
|
|
{/* Form */}
|
|
<div className="p-6">
|
|
<form onSubmit={(e) => {
|
|
signInHandle(e)
|
|
}} className="space-y-5">
|
|
{/* Email */}
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700">
|
|
Email của bạn
|
|
</label>
|
|
<input
|
|
name='emailOrUserName'
|
|
type="text"
|
|
className="mt-1 w-full rounded-xl border border-gray-300 px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
placeholder="admin@example.com"
|
|
/>
|
|
</div>
|
|
|
|
{/* Password */}
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700">
|
|
Mật khẩu của bạn
|
|
</label>
|
|
<input
|
|
name="password"
|
|
type="password"
|
|
className="mt-1 w-full rounded-xl border border-gray-300 px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
placeholder="••••••••"
|
|
/>
|
|
</div>
|
|
|
|
{/* Remember me + Forgot */}
|
|
<div className="flex items-center justify-between text-sm">
|
|
<a href="#" className="text-blue-600 hover:underline">
|
|
Quên mật khẩu?
|
|
</a>
|
|
</div>
|
|
|
|
{/* Submit */}
|
|
<button
|
|
type="submit"
|
|
className="cursor-pointer w-full py-2 rounded-xl bg-blue-600 text-white font-semibold shadow-md hover:bg-blue-700 transition"
|
|
>
|
|
Đăng nhập
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
{/* Footer */}
|
|
<div className="p-4 bg-gray-50 text-center text-sm text-gray-500">
|
|
© 2025 Rikkei Admin
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
if (userStore.data?.role) {
|
|
window.location.href="/"
|
|
return <></>
|
|
}
|
|
|
|
async function signInHandle(e: FormEvent) {
|
|
e.preventDefault()
|
|
let data: UserSignInDTO = {
|
|
emailOrUserName: (e.target as any).emailOrUserName.value,
|
|
password: (e.target as any).password.value,
|
|
}
|
|
try {
|
|
let result = await Apis.user.signIn(data)
|
|
localStorage.setItem("userLogin", JSON.stringify(result.data))
|
|
Modal.confirm({
|
|
title: "Đăng nhập thành công",
|
|
content: result.message,
|
|
onOk: () => {
|
|
window.location.reload()
|
|
},
|
|
onCancel: () => {
|
|
window.location.reload()
|
|
}
|
|
})
|
|
} catch (err) {
|
|
message.error(err.message)
|
|
}
|
|
}
|
|
}
|