Skip to content

London | 26-SDC-MAR | Jamal Laqdiem | Sprint 2 | Chat App #92

Open
jamallaqdiem wants to merge 15 commits into
CodeYourFuture:mainfrom
jamallaqdiem:feat-complete-chat-app
Open

London | 26-SDC-MAR | Jamal Laqdiem | Sprint 2 | Chat App #92
jamallaqdiem wants to merge 15 commits into
CodeYourFuture:mainfrom
jamallaqdiem:feat-complete-chat-app

Conversation

@jamallaqdiem
Copy link
Copy Markdown

@jamallaqdiem jamallaqdiem commented Jun 5, 2026

Self checklist

  • I have titled my PR with Region | Cohort | FirstName LastName | Sprint | Assignment Title
  • My changes meet the requirements of the task
  • I have tested my changes
  • My changes follow the style guide

Changelist

Implementing the chat app using react typescript.

The app support additional features like:

  1. added likes button
  2. Added dislike button
  3. Storing the likes and dislikes count
  4. Persistent username

Urls to Coolify:
Client Url
Server Url

@jamallaqdiem
Copy link
Copy Markdown
Author

Client Url
Server Url

@jamallaqdiem jamallaqdiem added Module-Decomposition The name of the module. 📅 Sprint 2 Assigned during Sprint 2 of this module Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. labels Jun 5, 2026
@cjyuan
Copy link
Copy Markdown

cjyuan commented Jun 6, 2026

The spec has this requirement:

It must also support at least one additional feature.

The Changelist section in the PR description would be the best place to include this info.


The PR description is also a better place to include the frontend and backend links because it would make finding all info in one place easier.


Can you also fix the Markdown syntax of the checkboxes in the PR description?

@jamallaqdiem
Copy link
Copy Markdown
Author

@cjyuan Thanks for reviewing, I addressed the issues in the PR, could you have a look please?

Copy link
Copy Markdown

@cjyuan cjyuan left a comment

Choose a reason for hiding this comment

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

Code could use some documentation (comments).

A useful rule of thumb is to ask yourself whether you could still explain or figure out how the code works few months from now. If the answer is uncertain, consider adding a comment to help future readers understand the intent and reasoning behind it.


I will review this PR in several rounds. Can you addressed the current feedback first?

Comment on lines +62 to +67
const { username, text } = req.body;
if (!username || !text) {
return res.status(400).json({
message: "Expected body to be a JSON object",
});
}
Copy link
Copy Markdown

@cjyuan cjyuan Jun 6, 2026

Choose a reason for hiding this comment

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

It's good practice to validate all request inputs.

Note: A more robust implementation

  • Should also handle the case where req.body is null, which would cause const { text, sender } = req.body; to throw.
  • Should not assume text and sender are strings (if they existed)

In this exercise, let's assume the request is always coming from your client-side code. So no change needed.

const messageId = Date.now();
const timestamp = new Date().toISOString();
const createMessages = {
id: messageId,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Relying on Date.now() for IDs can lead to collisions if multiple messages are processed within the same millisecond. A UUID-based approach is safer and ensures uniqueness.

isNameSaved: boolean;
}

const FormInput = ({
Copy link
Copy Markdown

@cjyuan cjyuan Jun 6, 2026

Choose a reason for hiding this comment

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

Why not name the file FormInput.tsx or name this ChatInput? Using the same name makes locating the component by its file name easier.

const handleFormChat = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (!formChat.username.trim() || !formChat.text.trim()) {
showNotification("Username and message cannot be empty!", "text-red-500");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

When I entered an empty string in any of the two input fields and clicked "SUBMIT", I expected to see this notification message, but I didn't see any message show up on the UI. Why?

Comment on lines +152 to +169
<main className="min-h-screen bg-slate-900 text-slate-100 flex flex-col items-center justify-center p-4 antialiased">
<div className="w-full max-w-4xl bg-slate-800 rounded-2xl shadow-2xl border border-slate-700/50 overflow-hidden flex flex-col h-[800px]">
{/* Header Section */}
<div className="bg-slate-800/80 backdrop-blur-md px-6 py-4 border-b border-slate-700 flex items-center justify-between">
<div className="flex items-center space-x-3">
<div className="w-3 h-3 bg-emerald-400 rounded-full animate-pulse" />
<h1 className="text-xl font-bold tracking-wide bg-gradient-to-r content-box from-emerald-400 to-cyan-400 bg-clip-text text-transparent">
Jamal's Community Chat
</h1>
</div>
<span className="text-xs font-semibold px-2.5 py-1 bg-slate-700 text-slate-300 rounded-full border border-slate-600">
{chat.length} messages
</span>
</div>

{/* Chat Container */}
<div className="flex-1 overflow-y-auto p-6 space-y-4 custom-scrollbar">
{chat.map((message) => (
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

  • Could consider separate presentation logic from the application logic.

  • Cloud also consider implement the Chat container as a separate component.

<div className="p-4 bg-slate-800/50 border-t border-slate-700/60 flex justify-end">
<button
onClick={arrayMessages}
className="px-5 py-2.5 text-sm font-medium text-slate-900 bg-gradient-to-r from-emerald-400 to-cyan-400 hover:from-emerald-500 hover:to-cyan-500 rounded-xl shadow-lg shadow-emerald-500/10 hover:shadow-emerald-500/20 active:scale-[0.98] transition-all duration-150"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

These long lists of class names, similar to inline CSS, make the code harder to read and maintain. Could you find a way to separate the styling from the JSX/HTML markup?

Note: This comment applies to all elements with lengthy class list.

@cjyuan cjyuan added Reviewed Volunteer to add when completing a review with trainee action still to take. and removed Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. labels Jun 6, 2026
@jamallaqdiem
Copy link
Copy Markdown
Author

Code could use some documentation (comments).

A useful rule of thumb is to ask yourself whether you could still explain or figure out how the code works few months from now. If the answer is uncertain, consider adding a comment to help future readers understand the intent and reasoning behind it.

I will review this PR in several rounds. Can you addressed the current feedback first?

Thanks for reviewing, I will add the comments and address the feedbacks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Module-Decomposition The name of the module. Reviewed Volunteer to add when completing a review with trainee action still to take. 📅 Sprint 2 Assigned during Sprint 2 of this module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants