Skip to content

Commit 9878e57

Browse files
authored
Merge branch 'develop' into K-17-Put-the-WebGL-onto-a-React-Component
2 parents c11e8f3 + 53fccac commit 9878e57

File tree

16 files changed

+1735
-65
lines changed

16 files changed

+1735
-65
lines changed

.gitignore

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,3 @@ yarn-error.log*
3333
# typescript
3434
*.tsbuildinfo
3535
next-env.d.ts
36-
37-
38-
# package manager files
39-
package.json
40-
package-lock.json
41-
# clerk configuration (can include secrets)
42-
/.clerk/

package-lock.json

Lines changed: 1451 additions & 43 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,15 @@
1313
"prepare": "husky"
1414
},
1515
"dependencies": {
16-
"@clerk/nextjs": "^6.36.10",
16+
"@chakra-ui/react": "^3.31.0",
17+
"@clerk/nextjs": "^6.37.1",
18+
"@emotion/react": "^11.14.0",
1719
"mongoose": "^8",
1820
"next": "^14.2.35",
21+
"next-themes": "^0.4.6",
1922
"react": "^18",
20-
"react-dom": "^18"
23+
"react-dom": "^18",
24+
"react-icons": "^5.5.0"
2125
},
2226
"devDependencies": {
2327
"@types/node": "^20",
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import connectDB from "@/database/db";
2+
import Session from "@/database/sessionSchema";
3+
import { NextRequest, NextResponse } from "next/server";
4+
import mongoose from "mongoose";
5+
// GET and PATCH routes for sessions
6+
7+
/**
8+
* GET /api/sessions/:sessionId
9+
* Fetch a session by ID
10+
*/
11+
export async function GET(request: NextRequest, { params }: { params: { sessionId: string } }) {
12+
try {
13+
await connectDB();
14+
15+
const { sessionId } = params;
16+
17+
if (!mongoose.Types.ObjectId.isValid(sessionId)) {
18+
return NextResponse.json({ error: "Invalid session ID" }, { status: 400 });
19+
}
20+
21+
const session = await Session.findById(sessionId);
22+
23+
if (!session) {
24+
return NextResponse.json({ error: "Session not found" }, { status: 404 });
25+
}
26+
27+
return NextResponse.json({
28+
_id: session._id,
29+
anonUserId: session.anonUserId,
30+
startedAt: session.startedAt,
31+
endedAt: session.endedAt,
32+
durationMs: session.durationMs,
33+
});
34+
} catch (error) {
35+
console.error("GET /api/sessions/:sessionId error:", error);
36+
return NextResponse.json({ error: "Failed to fetch session" }, { status: 500 });
37+
}
38+
}
39+
40+
/**
41+
* PATCH /api/sessions/:sessionId
42+
* Update a session (e.g., end it by setting endedAt and durationMs)
43+
* Body: { endedAt?: Date, durationMs?: number } or empty to auto-end
44+
*/
45+
export async function PATCH(request: NextRequest, { params }: { params: { sessionId: string } }) {
46+
try {
47+
await connectDB();
48+
49+
const { sessionId } = params;
50+
51+
if (!mongoose.Types.ObjectId.isValid(sessionId)) {
52+
return NextResponse.json({ error: "Invalid session ID" }, { status: 400 });
53+
}
54+
55+
const session = await Session.findById(sessionId);
56+
57+
if (!session) {
58+
return NextResponse.json({ error: "Session not found" }, { status: 404 });
59+
}
60+
61+
const body = await request.json().catch(() => ({}));
62+
63+
// If body is empty or only endedAt/durationMs, allow update
64+
const update: { endedAt?: Date; durationMs?: number } = {};
65+
66+
if (body.endedAt !== undefined) {
67+
update.endedAt = typeof body.endedAt === "string" ? new Date(body.endedAt) : body.endedAt;
68+
} else if (Object.keys(body).length === 0 || body.endSession) {
69+
// Auto-end: set endedAt to now and calculate duration
70+
const endedAt = new Date();
71+
update.endedAt = endedAt;
72+
update.durationMs = endedAt.getTime() - session.startedAt.getTime();
73+
}
74+
75+
if (body.durationMs !== undefined) {
76+
update.durationMs = Number(body.durationMs);
77+
}
78+
79+
const updatedSession = await Session.findByIdAndUpdate(sessionId, { $set: update }, { new: true });
80+
81+
return NextResponse.json({
82+
_id: updatedSession!._id,
83+
anonUserId: updatedSession!.anonUserId,
84+
startedAt: updatedSession!.startedAt,
85+
endedAt: updatedSession!.endedAt,
86+
durationMs: updatedSession!.durationMs,
87+
});
88+
} catch (error) {
89+
console.error("PATCH /api/sessions/:sessionId error:", error);
90+
return NextResponse.json({ error: "Failed to update session" }, { status: 500 });
91+
}
92+
}

src/app/api/sessions/route.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import connectDB from "@/database/db";
2+
import Session from "@/database/sessionSchema";
3+
import { NextRequest, NextResponse } from "next/server";
4+
// POST route for creating a new session
5+
6+
/**
7+
* POST /api/sessions
8+
* Create a new session
9+
* Body: { anonUserId: string }
10+
*/
11+
export async function POST(request: NextRequest) {
12+
try {
13+
await connectDB();
14+
15+
const body = await request.json();
16+
const { anonUserId } = body;
17+
18+
if (!anonUserId || typeof anonUserId !== "string") {
19+
return NextResponse.json({ error: "anonUserId is required and must be a string" }, { status: 400 });
20+
}
21+
22+
const startedAt = new Date();
23+
const session = await Session.create({
24+
anonUserId,
25+
startedAt,
26+
endedAt: null,
27+
durationMs: 0,
28+
});
29+
30+
return NextResponse.json({
31+
_id: session._id,
32+
anonUserId: session.anonUserId,
33+
startedAt: session.startedAt,
34+
endedAt: session.endedAt,
35+
durationMs: session.durationMs,
36+
});
37+
} catch (error) {
38+
console.error("POST /api/sessions error:", error);
39+
return NextResponse.json({ error: "Failed to create session" }, { status: 500 });
40+
}
41+
}

src/app/api/users/[id]/route.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import connectDB from "@/database/db";
2+
import { NextResponse, NextRequest } from "next/server";
3+
import User from "@/database/userSchema";
4+
import mongoose from "mongoose";
5+
6+
// Get a specific user, finding the user by their userID
7+
export async function GET(_req: NextRequest, { params }: { params: { id: string } }) {
8+
try {
9+
const { id } = params;
10+
if (!mongoose.Types.ObjectId.isValid(id)) {
11+
return NextResponse.json({ error: "Invalid user id" }, { status: 400 });
12+
}
13+
await connectDB();
14+
15+
const user = await User.findById(id).lean();
16+
if (!user) {
17+
return NextResponse.json({ error: "User not found" }, { status: 404 });
18+
}
19+
return NextResponse.json(user, { status: 200 });
20+
} catch (err: any) {
21+
console.error("Caught an error", err);
22+
return NextResponse.json({ error: err.message }, { status: 500 });
23+
}
24+
}
25+
26+
// Update a specific user, finding the user by their userID
27+
export async function PUT(req: NextRequest, { params }: { params: { id: string } }) {
28+
try {
29+
const { id } = params;
30+
const changes = await req.json();
31+
if (!mongoose.Types.ObjectId.isValid(id)) {
32+
return NextResponse.json({ error: "Invalid user id" }, { status: 400 });
33+
}
34+
await connectDB();
35+
36+
const updatedUser = await User.findByIdAndUpdate(id, { $set: changes }, { new: true, runValidators: true }).lean();
37+
if (!updatedUser) {
38+
return NextResponse.json({ error: "User not found" }, { status: 404 });
39+
}
40+
41+
return NextResponse.json(updatedUser, { status: 200 });
42+
} catch (err: any) {
43+
console.error("Caught an error", err);
44+
return NextResponse.json({ error: err.message }, { status: 400 });
45+
}
46+
}

src/app/api/users/route.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import connectDB from "@/database/db";
2+
import { NextResponse, NextRequest } from "next/server";
3+
import User from "@/database/userSchema";
4+
5+
// CREATE a user with the parameters that are passed in, catching any server connection or bad requestst that may occur
6+
export async function POST(req: NextRequest) {
7+
try {
8+
await connectDB();
9+
10+
const body = await req.json();
11+
const user = await User.create(body);
12+
return NextResponse.json(user, { status: 201 });
13+
} catch (err: any) {
14+
console.error("Caught an error", err);
15+
return NextResponse.json({ error: err.message }, { status: 400 });
16+
}
17+
}
18+
19+
// RETRIEVE all users from the database, catching any errors that may occur
20+
export async function GET() {
21+
try {
22+
await connectDB();
23+
24+
const retrieved_users = await User.find({}).lean();
25+
return NextResponse.json(retrieved_users, { status: 200 });
26+
} catch (err: any) {
27+
console.error("Caught an error", err);
28+
return NextResponse.json({ error: err.message }, { status: 400 });
29+
}
30+
}

src/app/dashboard/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default function Dashboard() {}

src/app/home/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default function Home() {}

src/app/layout.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Metadata } from "next";
22
import "./globals.css";
3-
import { ClerkProvider } from "@clerk/nextjs";
3+
import Providers from "./providers";
44

55
//! Update metadata to match your project
66
export const metadata: Metadata = {
@@ -10,10 +10,10 @@ export const metadata: Metadata = {
1010

1111
export default function RootLayout({ children }: { children: React.ReactNode }) {
1212
return (
13-
<ClerkProvider>
14-
<html lang="en">
15-
<body>{children}</body>
16-
</html>
17-
</ClerkProvider>
13+
<html lang="en">
14+
<body>
15+
<Providers>{children}</Providers>
16+
</body>
17+
</html>
1818
);
1919
}

0 commit comments

Comments
 (0)