Skip to content

Commit 85c21e2

Browse files
committed
戻す必要がある
1 parent 6a7d184 commit 85c21e2

File tree

6 files changed

+132
-11
lines changed

6 files changed

+132
-11
lines changed

package-lock.json

Lines changed: 11 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
"@biomejs/biome": "^1.9.1",
1414
"@types/bun": "^1.1.10",
1515
"cspell": "^8.14.4",
16-
"typescript": "^5.6.2",
17-
"lefthook": "^1.8.2"
16+
"lefthook": "^1.8.2",
17+
"typescript": "^5.6.2"
1818
},
1919
"dependencies": {
20+
"cookie": "^1.0.2",
2021
"zod": "^3.23.8"
2122
},
2223
"trustedDependencies": ["@biomejs/biome", "lefthook"]

web/api/admin/login/route.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { serialize } from "cookie";
2+
import { NextResponse } from "next/server";
3+
4+
export async function POST(request) {
5+
const body = await request.json();
6+
const { name, password } = body;
7+
console.log("あああ", body);
8+
if (name === "admin" && password === "password123") {
9+
// 認証成功時にCookieを設定
10+
const cookie = serialize("authToken", "admin-token", {
11+
httpOnly: true,
12+
secure: process.env.NODE_ENV === "production",
13+
sameSite: "strict",
14+
path: "/",
15+
maxAge: 60 * 60 * 24, // 1日
16+
});
17+
18+
const response = NextResponse.json({ message: "Login successful" });
19+
response.headers.set("Set-Cookie", cookie);
20+
return response;
21+
}
22+
23+
return NextResponse.json({ message: "Invalid credentials" }, { status: 401 });
24+
}

web/api/admin/validate/route.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { parse } from "cookie";
2+
import { NextResponse } from "next/server";
3+
4+
export async function GET(request) {
5+
const cookies = parse(request.headers.get("cookie") || "");
6+
console.log("こんにちは", cookies);
7+
8+
if (cookies.authToken === "admin-token") {
9+
return NextResponse.json({ isAuthenticated: true });
10+
}
11+
12+
return NextResponse.json({ isAuthenticated: false }, { status: 401 });
13+
}

web/app/admin/login/page.tsx

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,67 @@
1-
import AdminLoginForm from "~/components/admin/adminLoginForm";
1+
"use client";
2+
3+
import { useRouter } from "next/navigation";
4+
import { useState } from "react";
25

36
export default function LoginPage() {
7+
const [name, setName] = useState("");
8+
const [password, setPassword] = useState("");
9+
const router = useRouter();
10+
11+
const handleSubmit = async (e: { preventDefault: () => void }) => {
12+
e.preventDefault();
13+
14+
const res = await fetch("/admin/login", {
15+
method: "POST",
16+
headers: { "Content-Type": "application/json" },
17+
body: JSON.stringify({ name, password }),
18+
});
19+
20+
if (res.ok) {
21+
router.replace("/admin");
22+
} else {
23+
alert("Invalid credentials");
24+
}
25+
};
26+
427
return (
5-
<main className="flex items-center justify-center md:h-screen">
6-
<div className="md:-mt-32 relative mx-auto flex w-full max-w-[400px] flex-col space-y-2.5 p-4">
7-
<h2>管理者ログインページ</h2>
8-
<AdminLoginForm />
28+
<div className="flex min-h-screen items-center justify-center bg-gray-100">
29+
<div className="w-full max-w-md space-y-6 rounded-lg bg-white p-8 shadow-md">
30+
<h2 className="text-center font-bold text-2xl text-gray-700">
31+
管理者画面
32+
</h2>
33+
<form onSubmit={handleSubmit} className="space-y-4">
34+
<div className="form-control">
35+
{/* biome-ignore lint/a11y/noLabelWithoutControl: <explanation> */}
36+
<label className="label">
37+
<span className="label-text">Name</span>
38+
</label>
39+
<input
40+
type="text"
41+
value={name}
42+
onChange={(e) => setName(e.target.value)}
43+
className="input input-bordered w-full"
44+
placeholder="Enter your name"
45+
/>
46+
</div>
47+
<div className="form-control">
48+
{/* biome-ignore lint/a11y/noLabelWithoutControl: <explanation> */}
49+
<label className="label">
50+
<span className="label-text">Password</span>
51+
</label>
52+
<input
53+
type="password"
54+
value={password}
55+
onChange={(e) => setPassword(e.target.value)}
56+
className="input input-bordered w-full"
57+
placeholder="Enter your password"
58+
/>
59+
</div>
60+
<button type="submit" className="btn btn-primary w-full">
61+
Login
62+
</button>
63+
</form>
964
</div>
10-
</main>
65+
</div>
1166
);
1267
}

web/app/admin/page.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1-
export default function Admin() {
2-
return <div>管理者画面</div>;
1+
"use client";
2+
3+
import { useRouter } from "next/navigation";
4+
import { useEffect } from "react";
5+
6+
export default function AdminPage() {
7+
const router = useRouter();
8+
9+
useEffect(() => {
10+
const checkAuth = async () => {
11+
const res = await fetch("/admin/validate");
12+
if (!res.ok) {
13+
router.replace("/admin/login");
14+
}
15+
};
16+
17+
checkAuth();
18+
}, [router]);
19+
20+
return <div>Welcome to the Admin Dashboard</div>;
321
}

0 commit comments

Comments
 (0)