Skip to content

Commit 0930ca7

Browse files
authored
Upgrade staging (#199)
* fix log * responsive moderation * feed page revamp * auth flow * nitpicks
1 parent 0099664 commit 0930ca7

File tree

31 files changed

+954
-790
lines changed

31 files changed

+954
-790
lines changed

apps/api/src/routes/api/submission.ts

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import {
55
RichSubmission,
66
} from "@curatedotfun/shared-db";
77
import {
8-
Submission as DomainSubmission,
98
FeedContextSubmission,
10-
SubmissionStatus as DomainSubmissionStatus,
11-
SubmissionStatusEnum as DomainSubmissionStatusEnum,
12-
SubmissionFeed as DomainSubmissionFeed,
9+
Submission,
10+
SubmissionFeed,
11+
SubmissionStatus,
12+
SubmissionStatusSchema,
1313
} from "@curatedotfun/types";
1414
import { zValidator } from "@hono/zod-validator";
1515
import { Hono } from "hono";
@@ -47,9 +47,8 @@ submissionRoutes.get(
4747
limit,
4848
);
4949

50-
const domainItems: DomainSubmission[] = repoResult.items.map((rs) => {
51-
let overallStatus: DomainSubmissionStatus =
52-
DomainSubmissionStatusEnum.PENDING;
50+
const domainItems: Submission[] = repoResult.items.map((rs) => {
51+
let overallStatus: SubmissionStatus = SubmissionStatusSchema.enum.pending;
5352
if (rs.moderationHistory && rs.moderationHistory.length > 0) {
5453
// Prefer direct moderation history for overall status if available
5554
const approvedAction = rs.moderationHistory.find(
@@ -59,16 +58,17 @@ submissionRoutes.get(
5958
(mh) => mh.action === "reject",
6059
);
6160

62-
if (approvedAction) overallStatus = DomainSubmissionStatusEnum.APPROVED;
61+
if (approvedAction)
62+
overallStatus = SubmissionStatusSchema.enum.approved;
6363
else if (rejectedAction)
64-
overallStatus = DomainSubmissionStatusEnum.REJECTED;
64+
overallStatus = SubmissionStatusSchema.enum.rejected;
6565
// If only pending or other actions, it remains PENDING by default
6666
} else if (rs.feeds && rs.feeds.length > 0) {
6767
// Fallback to feed statuses if no direct moderation history
6868
if (rs.feeds.some((f) => f.status === "approved")) {
69-
overallStatus = DomainSubmissionStatusEnum.APPROVED;
69+
overallStatus = SubmissionStatusSchema.enum.approved;
7070
} else if (rs.feeds.every((f) => f.status === "rejected")) {
71-
overallStatus = DomainSubmissionStatusEnum.REJECTED;
71+
overallStatus = SubmissionStatusSchema.enum.rejected;
7272
}
7373
// If feeds are all pending, it remains PENDING
7474
}
@@ -82,9 +82,9 @@ submissionRoutes.get(
8282
content: rs.content,
8383
curatorNotes: rs.curatorNotes,
8484
curatorTweetId: rs.curatorTweetId!,
85-
createdAt: rs.createdAt,
86-
submittedAt: rs.submittedAt,
87-
updatedAt: rs.updatedAt,
85+
createdAt: rs.createdAt.toISOString(),
86+
submittedAt: rs.submittedAt ? rs.submittedAt.toISOString() : null,
87+
updatedAt: rs.updatedAt ? rs.updatedAt.toISOString() : null,
8888
moderationHistory: (rs.moderationHistory ?? []).map((mh) => ({
8989
id: mh.id,
9090
moderatorAccountId: mh.moderatorAccountId,
@@ -104,16 +104,16 @@ submissionRoutes.get(
104104
({
105105
submissionId: sf.submissionId,
106106
feedId: sf.feedId,
107-
status: sf.status as DomainSubmissionStatus,
108-
createdAt: sf.createdAt,
109-
updatedAt: sf.updatedAt,
110-
}) as DomainSubmissionFeed,
107+
status: sf.status as SubmissionStatus,
108+
createdAt: sf.createdAt.toISOString(),
109+
updatedAt: sf.updatedAt ? sf.updatedAt.toISOString() : null,
110+
}) as SubmissionFeed,
111111
),
112112
status: overallStatus,
113113
};
114114
});
115115

116-
const response: PaginatedResponse<DomainSubmission> = {
116+
const response: PaginatedResponse<Submission> = {
117117
items: domainItems,
118118
pagination: repoResult.pagination,
119119
};
@@ -135,8 +135,8 @@ submissionRoutes.get("/single/:submissionId", async (c) => {
135135
return c.notFound();
136136
}
137137

138-
let overallStatusSingle: DomainSubmissionStatus =
139-
DomainSubmissionStatusEnum.PENDING;
138+
let overallStatusSingle: SubmissionStatus =
139+
SubmissionStatusSchema.enum.pending;
140140
if (
141141
richSubmission.moderationHistory &&
142142
richSubmission.moderationHistory.length > 0
@@ -149,18 +149,18 @@ submissionRoutes.get("/single/:submissionId", async (c) => {
149149
);
150150

151151
if (approvedAction)
152-
overallStatusSingle = DomainSubmissionStatusEnum.APPROVED;
152+
overallStatusSingle = SubmissionStatusSchema.enum.approved;
153153
else if (rejectedAction)
154-
overallStatusSingle = DomainSubmissionStatusEnum.REJECTED;
154+
overallStatusSingle = SubmissionStatusSchema.enum.rejected;
155155
} else if (richSubmission.feeds && richSubmission.feeds.length > 0) {
156156
if (richSubmission.feeds.some((f) => f.status === "approved")) {
157-
overallStatusSingle = DomainSubmissionStatusEnum.APPROVED;
157+
overallStatusSingle = SubmissionStatusSchema.enum.approved;
158158
} else if (richSubmission.feeds.every((f) => f.status === "rejected")) {
159-
overallStatusSingle = DomainSubmissionStatusEnum.REJECTED;
159+
overallStatusSingle = SubmissionStatusSchema.enum.rejected;
160160
}
161161
}
162162

163-
const domainSubmission: DomainSubmission = {
163+
const domainSubmission: Submission = {
164164
tweetId: richSubmission.tweetId,
165165
userId: richSubmission.userId,
166166
username: richSubmission.username,
@@ -169,9 +169,13 @@ submissionRoutes.get("/single/:submissionId", async (c) => {
169169
content: richSubmission.content,
170170
curatorNotes: richSubmission.curatorNotes,
171171
curatorTweetId: richSubmission.curatorTweetId!,
172-
createdAt: richSubmission.createdAt,
173-
submittedAt: richSubmission.submittedAt,
174-
updatedAt: richSubmission.updatedAt,
172+
createdAt: richSubmission.createdAt.toISOString(),
173+
submittedAt: richSubmission.submittedAt
174+
? richSubmission.submittedAt.toISOString()
175+
: null,
176+
updatedAt: richSubmission.updatedAt
177+
? richSubmission.updatedAt.toISOString()
178+
: null,
175179
moderationHistory: (richSubmission.moderationHistory ?? []).map((mh) => ({
176180
id: mh.id,
177181
moderatorAccountId: mh.moderatorAccountId,
@@ -191,10 +195,10 @@ submissionRoutes.get("/single/:submissionId", async (c) => {
191195
({
192196
submissionId: sf.submissionId,
193197
feedId: sf.feedId,
194-
status: sf.status as DomainSubmissionStatus,
195-
createdAt: sf.createdAt,
196-
updatedAt: sf.updatedAt,
197-
}) as DomainSubmissionFeed,
198+
status: sf.status as SubmissionStatus,
199+
createdAt: sf.createdAt.toISOString(),
200+
updatedAt: sf.updatedAt ? sf.updatedAt.toISOString() : null,
201+
}) as SubmissionFeed,
198202
),
199203
status: overallStatusSingle,
200204
};
@@ -236,9 +240,9 @@ submissionRoutes.get(
236240
const domainItems: FeedContextSubmission[] = repoResult.items.map((rs) => {
237241
const specificFeedLink = rs.feeds.find((f) => f.feedId === feedIdParam);
238242

239-
const statusInFeed: DomainSubmissionStatus = specificFeedLink
240-
? (specificFeedLink.status as DomainSubmissionStatus)
241-
: DomainSubmissionStatusEnum.PENDING;
243+
const statusInFeed: SubmissionStatus = specificFeedLink
244+
? (specificFeedLink.status as SubmissionStatus)
245+
: SubmissionStatusSchema.enum.pending;
242246

243247
return {
244248
tweetId: rs.tweetId,
@@ -249,9 +253,9 @@ submissionRoutes.get(
249253
content: rs.content,
250254
curatorNotes: rs.curatorNotes,
251255
curatorTweetId: rs.curatorTweetId!,
252-
createdAt: rs.createdAt,
253-
submittedAt: rs.submittedAt,
254-
updatedAt: rs.updatedAt,
256+
createdAt: rs.createdAt.toISOString(),
257+
submittedAt: rs.submittedAt ? rs.submittedAt.toISOString() : null,
258+
updatedAt: rs.updatedAt ? rs.updatedAt.toISOString() : null,
255259
status: statusInFeed,
256260
moderationHistory: (rs.moderationHistory ?? []).map((mh) => ({
257261
id: mh.id,

apps/app/src/components/FeedItem.tsx

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { FeedContextSubmission } from "@curatedotfun/types";
22
import { useAuth } from "../contexts/auth-context";
3+
import { useSubmission } from "../lib/api";
4+
import { useMemo } from "react";
35
import {
46
useApproveSubmission,
57
useRejectSubmission,
@@ -137,15 +139,42 @@ const truncateText = (text: string, maxLength: number): string => {
137139
};
138140

139141
export const FeedItem = ({
140-
submission,
142+
submission: initialSubmission,
141143
feedId,
142144
allowModerationControls,
143145
}: FeedItemProps) => {
144146
const auth = useAuth();
147+
const { data: submissionData, isLoading } = useSubmission(
148+
initialSubmission.tweetId,
149+
);
150+
151+
const submission: FeedContextSubmission = useMemo(
152+
() => ({
153+
...initialSubmission,
154+
...(submissionData || {}),
155+
status: submissionData?.status ?? initialSubmission.status,
156+
moderationHistory:
157+
submissionData?.moderationHistory ??
158+
initialSubmission.moderationHistory ??
159+
[],
160+
}),
161+
[initialSubmission, submissionData],
162+
);
163+
145164
const canModerateQuery = useCanModerateFeed(feedId);
146165
const lastModeration =
147166
submission.moderationHistory?.[submission.moderationHistory.length - 1];
148167

168+
if (isLoading && !submissionData) {
169+
return (
170+
<div className="flex gap-3 flex-col p-4 w-full items-center justify-between border rounded-lg border-neutral-300 animate-pulse">
171+
<div className="h-8 bg-gray-200 rounded w-3/4"></div>
172+
<div className="h-4 bg-gray-200 rounded w-full mt-2"></div>
173+
<div className="h-4 bg-gray-200 rounded w-5/6 mt-1"></div>
174+
</div>
175+
);
176+
}
177+
149178
return (
150179
<div
151180
className="flex gap-3 flex-col p-4 w-full items-center justify-between border rounded-lg border-neutral-300"

apps/app/src/components/FeedLayout.tsx

Lines changed: 0 additions & 75 deletions
This file was deleted.

apps/app/src/components/TopCurators.tsx renamed to apps/app/src/components/feed/top-curators.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { useLeaderboard } from "../lib/api";
2-
import { UserLink } from "./FeedItem";
3-
import { Badge } from "./ui/badge";
1+
import { useLeaderboard } from "../../lib/api";
2+
import { UserLink } from "../FeedItem";
3+
import { Badge } from "../ui/badge";
44

55
interface TopCuratorsProps {
66
feedId?: string;

0 commit comments

Comments
 (0)