Skip to content

Commit 928363b

Browse files
Merge pull request #18 from MurakawaTakuya/add-add-all-papers-in-category
カテゴリの論文を一括保存する機能を追加
2 parents 9ccc175 + c00e929 commit 928363b

File tree

5 files changed

+336
-85
lines changed

5 files changed

+336
-85
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { getUserIdFromRequest } from "@/lib/auth-server";
2+
import { db, schema } from "@/lib/db";
3+
import { and, eq } from "drizzle-orm";
4+
import { NextRequest, NextResponse } from "next/server";
5+
6+
// POST /api/favorites/batch - 複数論文を一括でお気に入りに追加
7+
export async function POST(request: NextRequest) {
8+
const userId = await getUserIdFromRequest(request);
9+
if (!userId) {
10+
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
11+
}
12+
13+
if (!db) {
14+
return NextResponse.json(
15+
{ error: "Database not configured" },
16+
{ status: 500 }
17+
);
18+
}
19+
20+
try {
21+
const body = await request.json();
22+
const { paperIds, folderId } = body;
23+
24+
if (!Array.isArray(paperIds) || paperIds.length === 0) {
25+
return NextResponse.json(
26+
{ error: "paperIds must be a non-empty array" },
27+
{ status: 400 }
28+
);
29+
}
30+
31+
// folderId が指定されている場合、自分のフォルダか検証
32+
if (folderId) {
33+
const folderCheck = await db
34+
.select()
35+
.from(schema.folders)
36+
.where(
37+
and(
38+
eq(schema.folders.id, folderId),
39+
eq(schema.folders.userId, userId)
40+
)
41+
);
42+
if (folderCheck.length === 0) {
43+
return NextResponse.json(
44+
{ error: "Folder not found or not authorized" },
45+
{ status: 403 }
46+
);
47+
}
48+
}
49+
50+
// 一括挿入(重複は無視)
51+
const values = paperIds.map((paperId: number) => ({
52+
userId,
53+
paperId,
54+
folderId: folderId || null,
55+
}));
56+
57+
const inserted = await db
58+
.insert(schema.favorites)
59+
.values(values)
60+
.onConflictDoNothing()
61+
.returning();
62+
63+
return NextResponse.json(
64+
{ added: inserted.length, total: paperIds.length },
65+
{ status: 201 }
66+
);
67+
} catch (error) {
68+
console.error("Error batch adding favorites:", error);
69+
return NextResponse.json(
70+
{ error: "Internal server error" },
71+
{ status: 500 }
72+
);
73+
}
74+
}

src/app/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ export default function Home() {
286286
<CategorizationResults
287287
groupedPapers={groupedPapers}
288288
categories={categorizationInfo.categories}
289+
searchKeyword={keyword}
289290
/>
290291
</motion.main>
291292
)}

src/components/app-sidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ export function AppSidebar() {
200200
<SidebarMenuSub>
201201
{item.items?.map((subItem) => (
202202
<SidebarMenuSubItem
203-
key={subItem.title}
203+
key={subItem.folderId || subItem.title}
204204
className="group/sub-item relative"
205205
>
206206
<SidebarMenuSubButton asChild>

0 commit comments

Comments
 (0)