Skip to content

add admin dashboard, fix s3 uploading workflow#37

Merged
kiet08hogit merged 3 commits into
mainfrom
kiet
Jul 5, 2026
Merged

add admin dashboard, fix s3 uploading workflow#37
kiet08hogit merged 3 commits into
mainfrom
kiet

Conversation

@kiet08hogit

Copy link
Copy Markdown
Owner

No description provided.

Copilot AI review requested due to automatic review settings July 2, 2026 04:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an Admin Console (overview/users/reports + warn/ban actions), extends notifications with admin “WARNING” events and follow-state UI, and reworks chat image uploads to an async BullMQ/S3 workflow (plus reply + shared media UI). It also introduces an AI-assisted listing auto-fill endpoint and UI, and makes minor frontend performance tweaks (Next Image sizes) and repo hygiene updates (.clerk in gitignore).

Changes:

  • Add admin dashboard (frontend routes + backend admin module/guard/service) with user management, report triage, and warning notifications.
  • Add chat reply/shared-media UI and move chat image uploads to a BullMQ background upload processor, emitting a new message_images_uploaded socket event.
  • Add AI listing suggestion endpoint (/listings/ai-suggest) and Add Product UI auto-fill action.

Reviewed changes

Copilot reviewed 31 out of 32 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
README.md Updates clone instructions to Orbit repo URL.
frontend/components/NotificationsMenu.tsx Adds WARNING notification rendering, follow button + expanded content behavior.
frontend/components/MiniChatWidget.tsx Adds reply/media/actions + image sending in mini chat; updates toast UX.
frontend/components/CustomUserButton.tsx Adds Admin Dashboard link gated by role check.
frontend/components/ChatBadge.tsx Updates socket listeners to resync unread count on more events.
frontend/components/admin/WarningModal.tsx Adds modal UI for sending admin warnings.
frontend/app/page.tsx Adds sizes props to Next <Image /> usage; adds a footer link.
frontend/app/chat/page.tsx Adds reply/media/actions + image upload flow with optimistic UI + socket reconciliation.
frontend/app/admin/users/page.tsx Admin UI for listing users, banning/unbanning, and warning.
frontend/app/admin/reports/page.tsx Admin UI for reviewing reports and warning reported users.
frontend/app/admin/page.tsx Admin overview stats page.
frontend/app/admin/layout.tsx Admin layout shell + client-side role gate.
frontend/app/add-product/page.tsx Adds AI auto-fill action based on first uploaded image.
frontend/.gitignore Ignores /.clerk/ config directory.
backend/src/modules/storage/upload.processor.ts Adds BullMQ worker to upload images to S3 and emit message_images_uploaded.
backend/src/modules/storage/storage.service.ts Adjusts S3 upload parameters (adds ACL).
backend/src/modules/storage/storage.module.ts Registers upload queue + processor; wires Prisma/Chat dependencies.
backend/src/modules/notifications/notifications.service.ts Adds actor.id + isFollowedByMe computed field.
backend/src/modules/listings/listings.service.ts Adds AI suggestion service method; refactors listing image creation.
backend/src/modules/listings/listings.controller.ts Adds /listings/ai-suggest endpoint.
backend/src/modules/chat/chat.service.ts Adds image-message creation via BullMQ and replyTo support.
backend/src/modules/chat/chat.module.ts Registers upload-queue for chat module.
backend/src/modules/chat/chat.gateway.ts Extends send_message payload to include replyToId.
backend/src/modules/chat/chat.controller.ts Adds REST endpoint for sending image messages.
backend/src/modules/ai/ai.service.ts Adds Gemini-based image-to-listing suggestion method.
backend/src/modules/admin/admin.service.ts Implements admin stats/reports/users, warn + auto-ban workflow.
backend/src/modules/admin/admin.module.ts Registers admin module.
backend/src/modules/admin/admin.controller.ts Exposes admin endpoints guarded by AdminGuard.
backend/src/common/guards/admin.guard.ts Adds admin role guard on top of Clerk auth.
backend/src/app.module.ts Wires AdminModule into the application.
backend/prisma/schema.prisma Adds Role/isBanned fields, message imageUrls/replies, and WARNING notification type.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 34 to 40
const command = new PutObjectCommand({
Bucket: bucketName,
Key: uniqueFilename,
Body: file.buffer,
ContentType: file.mimetype,
ACL: 'public-read',
});
Comment on lines +35 to +40
// Update the message in DB
const updatedMessage = await this.prisma.message.update({
where: { id: messageId },
data: { imageUrls },
include: { sender: true },
});
Comment on lines 58 to 64
socket.on("receive_message", onReceiveMessage);
socket.on("messages_read", onReceiveMessage); // when we read messages on another device or tab

return () => {
socket.off("receive_message", onReceiveMessage);
socket.off("messages_read", onReceiveMessage);
};
Comment on lines +397 to +408
const onMessageImagesUploaded = (updatedMessage: Message) => {
setMessages((prev) => {
const idx = prev.findIndex(m => m.id.startsWith('temp-'));
if (idx !== -1) {
const newMsgs = [...prev];
newMsgs[idx] = updatedMessage;
return newMsgs;
}
return [...prev, updatedMessage];
});
setRefreshInbox((r) => r + 1);
};
Comment on lines +843 to +864
// Optimistically add to UI with local blobs
const optimisticMessage: Message = {
id: 'temp-' + Date.now(),
content: newMessage,
conversationId: activeConversationId,
senderId: clerkUser?.id || '',
createdAt: new Date().toISOString(),
imageUrls: selectedImages.map(f => URL.createObjectURL(f)),
replyToId: replyingToMessage?.id || null,
replyTo: replyingToMessage ? {
sender: { name: replyingToMessage.sender?.name || null, username: replyingToMessage.sender?.username || null },
content: replyingToMessage.content
} : null,
sender: {
id: clerkUser?.id || '',
name: clerkUser?.fullName || null,
username: clerkUser?.username || null,
avatarUrl: clerkUser?.imageUrl || null,
clerkUserId: clerkUser?.id || '',
}
};
setMessages(prev => [...prev, optimisticMessage]);
Comment on lines +866 to +876
const token = await getToken();
await axios.post(
`http://localhost:3000/chat/message/${activeConversationId}/images`,
formData,
{
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "multipart/form-data",
},
}
);
Comment on lines +167 to +171
setNotifications(prev => prev.map(notif =>
notif.actor?.id === targetId
? { ...notif, actor: { ...notif.actor, isFollowedByMe: true } }
: notif
));
Comment on lines +184 to +188
setNotifications(prev => prev.map(notif =>
notif.actor?.id === targetId
? { ...notif, actor: { ...notif.actor, isFollowedByMe: false } }
: notif
));
Comment on lines +310 to +314
<Button
variant={notif.actor.isFollowedByMe ? "outline" : "secondary"}
size="sm"
className={`h-7 text-[11px] px-3 font-bold rounded-full ${!notif.actor.isFollowedByMe ? "hover:bg-primary hover:text-primary-foreground" : ""}`}
onClick={(e) => {
Comment on lines +123 to 127
), {
duration: 4000,
});
}
});
@kiet08hogit
kiet08hogit merged commit 47c505b into main Jul 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants