alpha
Login
or
Join now
dunkirk.sh
/
smokie
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
This repository has no description
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
Pipelines
feat: add takes per user api route
author
Kieran Klukas
date
1 year ago
(Apr 3, 2025, 9:42 AM -0400)
commit
cf60e5d0
cf60e5d0f9d60f0dffcff43a679cc95b76f25ddc
parent
438a0bde
438a0bde9bdaa811b184da5223a02404c1f7f149
+70
-5
2 changed files
Expand all
Collapse all
Unified
Split
src
features
api
index.ts
routes
recentTakes.ts
+3
-3
src/features/api/index.ts
Reviewed
···
1
1
-
import recentTakes from "./routes/recentTakes";
1
1
+
import { recentTakes, takesPerUser } from "./routes/recentTakes";
2
2
import video from "./routes/video";
3
3
4
4
export { default as video } from "./routes/video";
···
6
6
export async function apiRouter(url: URL) {
7
7
const path = url.pathname.split("/")[2];
8
8
9
9
-
console.log(`API path: ${path}`);
10
10
-
11
9
switch (path) {
12
10
case "video":
13
11
return video(url);
14
12
case "recentTakes":
15
13
return recentTakes();
14
14
+
case "takesPerUser":
15
15
+
return takesPerUser(url.pathname.split("/")[3] as string);
16
16
default:
17
17
return new Response("404 Not Found", { status: 404 });
18
18
}
+67
-2
src/features/api/routes/recentTakes.ts
Reviewed
···
1
1
-
import { eq, desc } from "drizzle-orm";
1
1
+
import { eq, desc, and } from "drizzle-orm";
2
2
import { db } from "../../../libs/db";
3
3
import { takes as takesTable } from "../../../libs/schema";
4
4
5
5
-
export default async function recentTakes(): Promise<Response> {
5
5
+
export async function recentTakes(): Promise<Response> {
6
6
const recentTakes = await db
7
7
.select()
8
8
.from(takesTable)
···
44
44
},
45
45
);
46
46
}
47
47
+
48
48
+
export async function takesPerUser(userId: string): Promise<Response> {
49
49
+
const rawTakes = await db
50
50
+
.select()
51
51
+
.from(takesTable)
52
52
+
.where(and(eq(takesTable.userId, userId)))
53
53
+
.orderBy(desc(takesTable.completedAt));
54
54
+
55
55
+
const takes = rawTakes.map((take) => ({
56
56
+
id: take.id,
57
57
+
description: take.description,
58
58
+
completedAt: take.completedAt,
59
59
+
status: take.status,
60
60
+
mp4Url: take.takeUrl,
61
61
+
elapsedTime: take.elapsedTimeMs,
62
62
+
}));
63
63
+
64
64
+
const approvedTakes = rawTakes.reduce((acc, take) => {
65
65
+
if (take.status !== "approved") return acc;
66
66
+
const multiplier = Number.parseFloat(take.multiplier || "1.0");
67
67
+
return Number(
68
68
+
(
69
69
+
acc +
70
70
+
(take.elapsedTimeMs * multiplier) / (1000 * 60 * 60)
71
71
+
).toFixed(1),
72
72
+
);
73
73
+
}, 0);
74
74
+
75
75
+
const waitingTakes = rawTakes.reduce((acc, take) => {
76
76
+
if (take.status !== "waitingUpload" && take.status !== "uploaded")
77
77
+
return acc;
78
78
+
const multiplier = Number.parseFloat(take.multiplier || "1.0");
79
79
+
return Number(
80
80
+
(
81
81
+
acc +
82
82
+
(take.elapsedTimeMs * multiplier) / (1000 * 60 * 60)
83
83
+
).toFixed(1),
84
84
+
);
85
85
+
}, 0);
86
86
+
87
87
+
const rejectedTakes = rawTakes.reduce((acc, take) => {
88
88
+
if (take.status !== "rejected") return acc;
89
89
+
const multiplier = Number.parseFloat(take.multiplier || "1.0");
90
90
+
return Number(
91
91
+
(
92
92
+
acc +
93
93
+
(take.elapsedTimeMs * multiplier) / (1000 * 60 * 60)
94
94
+
).toFixed(1),
95
95
+
);
96
96
+
}, 0);
97
97
+
98
98
+
return new Response(
99
99
+
JSON.stringify({
100
100
+
approvedTakes,
101
101
+
waitingTakes,
102
102
+
rejectedTakes,
103
103
+
takes,
104
104
+
}),
105
105
+
{
106
106
+
headers: {
107
107
+
"Content-Type": "application/json",
108
108
+
},
109
109
+
},
110
110
+
);
111
111
+
}