Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 88 additions & 14 deletions client/src/components/TextContainer/TextContainer.css
Original file line number Diff line number Diff line change
@@ -1,33 +1,107 @@
/* ===========================
TextContainer Styles
Updated for better clarity,
modern look, and accessibility
=========================== */

.textContainer {
display: flex;
flex-direction: column;
margin-left: 100px;
color: white;
height: 60%;
justify-content: space-between;
justify-content: flex-start;
align-items: center;
padding: 1rem;
font-family: 'Arial', sans-serif;
color: #333;
text-align: center;
background-color: #fafafa;
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}

/* Intro Section */
.intro h1 {
font-size: 2rem;
font-weight: 600;
margin-bottom: 0.5rem;
color: #111;
}

.intro h2 {
font-size: 1.1rem;
margin-bottom: 0.5rem;
color: #555;
}

/* Users Section */
.usersSection {
margin-top: 2rem;
width: 100%;
max-width: 320px;
}

/* Active User List Container */
.activeContainer {
display: flex;
align-items: center;
margin-bottom: 50%;
flex-direction: column;
gap: 0.6rem;
max-height: 220px;
overflow-y: auto;
padding: 0.7rem;
border: 1px solid #e2e2e2;
border-radius: 0.6rem;
background-color: #ffffff;
scrollbar-width: thin;
scrollbar-color: #ccc transparent;
}

/* Scrollbar Styling for WebKit browsers */
.activeContainer::-webkit-scrollbar {
width: 6px;
}
.activeContainer::-webkit-scrollbar-thumb {
background-color: #ccc;
border-radius: 3px;
}

/* Individual Active Item */
.activeItem {
display: flex;
align-items: center;
gap: 0.6rem;
padding: 0.4rem 0.6rem;
border-radius: 0.4rem;
transition: background-color 0.2s ease, transform 0.1s ease;
cursor: default;
}

.activeItem:hover {
background-color: #e6f7ff;
transform: scale(1.02);
}

.activeContainer img {
padding-left: 10px;
/* Online Icon */
.onlineIcon {
width: 16px;
height: 16px;
}

.textContainer h1 {
margin-bottom: 0px;
/* Username Text */
.username {
font-weight: 500;
color: #222;
}

@media (min-width: 320px) and (max-width: 1200px) {
.textContainer {
display: none;
/* Responsive Design */
@media (max-width: 480px) {
.intro h1 {
font-size: 1.6rem;
}
}

.usersSection {
max-width: 90%;
}

.activeContainer {
max-height: 180px;
}
}
49 changes: 24 additions & 25 deletions client/src/components/TextContainer/TextContainer.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,35 @@
import React from 'react';

import onlineIcon from '../../icons/onlineIcon.png';

import './TextContainer.css';

const TextContainer = ({ users }) => (
<div className="textContainer">
<div>
<h1>Realtime Chat Application <span role="img" aria-label="emoji">💬</span></h1>
<h2>Created with React, Express, Node and Socket.IO <span role="img" aria-label="emoji">❤️</span></h2>
<h2>Try it out right now! <span role="img" aria-label="emoji">⬅️</span></h2>
<div className="intro">
<h1>
Realtime Chat Application <span role="img" aria-label="chat">💬</span>
</h1>
<h2>
Created with React, Express, Node and Socket.IO <span role="img" aria-label="heart">❤️</span>
</h2>
<h2>
Try it out right now! <span role="img" aria-label="arrow">⬅️</span>
</h2>
</div>
{
users
? (
<div>
<h1>People currently chatting:</h1>
<div className="activeContainer">
<h2>
{users.map(({name}) => (
<div key={name} className="activeItem">
{name}
<img alt="Online Icon" src={onlineIcon}/>
</div>
))}
</h2>

{users && users.length > 0 && (
<div className="usersSection">
<h1>People currently chatting:</h1>
<div className="activeContainer">
{users.map(({ name }) => (
<div key={name} className="activeItem">
<img alt="Online Icon" src={onlineIcon} className="onlineIcon" />
<span className="username">{name}</span>
</div>
</div>
)
: null
}
))}
</div>
</div>
)}
Comment on lines +19 to +31

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify users type or add explicit array check.

The conditional check users && users.length > 0 assumes users is an array, but the relevant code snippet from Chat.js (line 18) shows it's initialized as an empty string: const [users, setUsers] = useState('');. While an empty string is falsy and won't cause immediate issues, if users is set to a non-empty non-array value, users.map() on line 23 will throw a runtime error.

Consider using a more defensive check:

-    {users && users.length > 0 && (
+    {Array.isArray(users) && users.length > 0 && (
       <div className="usersSection">

Alternatively, ensure the parent component (Chat.js) initializes users as an empty array instead of an empty string:

// In Chat.js
const [users, setUsers] = useState([]);

Run this script to verify how users is managed throughout the codebase:


🏁 Script executed:

#!/bin/bash
# Description: Check users state initialization and usage patterns

# Find all useState declarations for users
echo "=== Checking users state initialization ==="
rg -n "useState.*users" --type=js --type=jsx -A 2

# Find all places where users is set
echo -e "\n=== Checking setUsers calls ==="
rg -n "setUsers\(" --type=js --type=jsx -C 2

# Find all users.map or users.length usage
echo -e "\n=== Checking users array operations ==="
rg -n "users\.(map|length|filter|forEach)" --type=js --type=jsx -C 2

Length of output: 201


🏁 Script executed:

#!/bin/bash
# Locate Chat.js
echo "=== Finding Chat.js ==="
CHAT_PATH=$(fd --ignore-case Chat.js | head -n1)
echo "Chat.js path: $CHAT_PATH"
# Show useState and setUsers in Chat.js
echo "=== useState and setUsers in Chat.js ==="
grep -nE "useState|setUsers" "$CHAT_PATH" -C2

# Locate TextContainer.js
echo -e "\n=== Finding TextContainer.js ==="
TC_PATH=$(fd --ignore-case TextContainer.js | head -n1)
echo "TextContainer.js path: $TC_PATH"
# Show users usage in TextContainer.js
echo "=== users usage in TextContainer.js ==="
grep -n "users" "$TC_PATH" -C2

Length of output: 1314


Initialize users as an array and guard against non-arrays
Chat.js (client/src/components/Chat/Chat.js) line 19:

- const [users, setUsers] = useState('');
+ const [users, setUsers] = useState([]);

TextContainer.js (client/src/components/TextContainer/TextContainer.js) line 19:

-    {users && users.length > 0 && (
+    {Array.isArray(users) && users.length > 0 && (
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{users && users.length > 0 && (
<div className="usersSection">
<h1>People currently chatting:</h1>
<div className="activeContainer">
{users.map(({ name }) => (
<div key={name} className="activeItem">
<img alt="Online Icon" src={onlineIcon} className="onlineIcon" />
<span className="username">{name}</span>
</div>
</div>
)
: null
}
))}
</div>
</div>
)}
{Array.isArray(users) && users.length > 0 && (
<div className="usersSection">
<h1>People currently chatting:</h1>
<div className="activeContainer">
{users.map(({ name }) => (
<div key={name} className="activeItem">
<img alt="Online Icon" src={onlineIcon} className="onlineIcon" />
<span className="username">{name}</span>
</div>
))}
</div>
</div>
)}

</div>
);

export default TextContainer;
export default TextContainer;