feat(auth): separate landlord and tenant login experience based on domain
This commit is contained in:
@@ -15,6 +15,12 @@ class LoginController extends Controller
|
||||
*/
|
||||
public function show()
|
||||
{
|
||||
$centralDomains = config('tenancy.central_domains', []);
|
||||
|
||||
if (in_array(request()->getHost(), $centralDomains)) {
|
||||
return Inertia::render('Landlord/Auth/Login');
|
||||
}
|
||||
|
||||
return Inertia::render('Auth/Login');
|
||||
}
|
||||
|
||||
@@ -36,6 +42,11 @@ class LoginController extends Controller
|
||||
if (Auth::attempt($credentials, $request->boolean('remember'))) {
|
||||
$request->session()->regenerate();
|
||||
|
||||
$centralDomains = config('tenancy.central_domains', []);
|
||||
if (in_array($request->getHost(), $centralDomains)) {
|
||||
return redirect()->intended(route('landlord.dashboard'));
|
||||
}
|
||||
|
||||
return redirect()->intended(route('dashboard'));
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,12 @@ class DashboardController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$centralDomains = config('tenancy.central_domains', []);
|
||||
|
||||
if (in_array(request()->getHost(), $centralDomains)) {
|
||||
return redirect()->route('landlord.dashboard');
|
||||
}
|
||||
|
||||
$stats = [
|
||||
'productsCount' => Product::count(),
|
||||
'vendorsCount' => Vendor::count(),
|
||||
|
||||
101
resources/js/Pages/Landlord/Auth/Login.tsx
Normal file
101
resources/js/Pages/Landlord/Auth/Login.tsx
Normal file
@@ -0,0 +1,101 @@
|
||||
import { Head, useForm } from "@inertiajs/react";
|
||||
import { FormEventHandler, useEffect } from "react";
|
||||
import { Button } from "@/Components/ui/button";
|
||||
import { Input } from "@/Components/ui/input";
|
||||
import { Label } from "@/Components/ui/label";
|
||||
import InputError from "@/Components/InputError";
|
||||
|
||||
export default function LandlordLogin() {
|
||||
const { data, setData, post, processing, errors, reset } = useForm({
|
||||
username: "",
|
||||
password: "",
|
||||
remember: false,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
reset("password");
|
||||
};
|
||||
}, []);
|
||||
|
||||
const submit: FormEventHandler = (e) => {
|
||||
e.preventDefault();
|
||||
post(route("login"), {
|
||||
onFinish: () => reset("password"),
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-slate-900 relative overflow-hidden">
|
||||
<Head title="總後台登入" />
|
||||
|
||||
{/* 深色背景裝飾 */}
|
||||
<div className="absolute top-0 -left-4 w-96 h-96 bg-indigo-900/30 rounded-full mix-blend-screen filter blur-3xl opacity-50 animate-blob"></div>
|
||||
<div className="absolute bottom-0 -right-4 w-96 h-96 bg-blue-900/30 rounded-full mix-blend-screen filter blur-3xl opacity-50 animate-blob animation-delay-2000"></div>
|
||||
|
||||
<div className="w-full max-w-md p-8 relative z-10">
|
||||
<div className="flex flex-col items-center mb-8">
|
||||
{/* 使用不同風格的 Logo 或純文字 */}
|
||||
<div className="text-white text-3xl font-bold tracking-wider mb-2">Koori ERP</div>
|
||||
<div className="text-slate-400 text-sm tracking-widest uppercase">Central Administration</div>
|
||||
</div>
|
||||
|
||||
<div className="glass-panel p-8 rounded-xl shadow-2xl bg-slate-800/50 backdrop-blur-md border border-slate-700/50">
|
||||
<form onSubmit={submit} className="space-y-6">
|
||||
<div>
|
||||
<Label htmlFor="username" className="text-slate-200">帳號</Label>
|
||||
<Input
|
||||
id="username"
|
||||
type="text"
|
||||
className="mt-2 block w-full bg-slate-900/50 border-slate-700 text-white placeholder-slate-500 focus:border-indigo-500 focus:ring-indigo-500"
|
||||
value={data.username}
|
||||
onChange={(e) => setData("username", e.target.value)}
|
||||
required
|
||||
autoFocus
|
||||
placeholder="Admin Username"
|
||||
/>
|
||||
<InputError message={errors.username} className="mt-2" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="password" className="text-slate-200">密碼</Label>
|
||||
<Input
|
||||
id="password"
|
||||
type="password"
|
||||
className="mt-2 block w-full bg-slate-900/50 border-slate-700 text-white placeholder-slate-500 focus:border-indigo-500 focus:ring-indigo-500"
|
||||
value={data.password}
|
||||
onChange={(e) => setData("password", e.target.value)}
|
||||
required
|
||||
placeholder="••••••••"
|
||||
/>
|
||||
<InputError message={errors.password} className="mt-2" />
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<label className="flex items-center">
|
||||
<span className="mr-2 text-sm text-slate-400">保持登入</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
className="rounded border-slate-700 bg-slate-900 text-indigo-600 shadow-sm focus:ring-indigo-500 focus:ring-offset-slate-800"
|
||||
checked={data.remember}
|
||||
onChange={(e) => setData("remember", e.target.checked)}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
className="w-full h-11 text-base bg-indigo-600 hover:bg-indigo-500 text-white transition-all shadow-lg hover:shadow-indigo-500/25 border-none"
|
||||
disabled={processing}
|
||||
>
|
||||
{processing ? "驗證中..." : "登入管理後台"}
|
||||
</Button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<p className="text-center text-slate-600 text-xs mt-8 font-mono">
|
||||
SECURE SYSTEM ACCESS RESTRICTED
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user