Skip to content

Commit

Permalink
Merge pull request #51 from hack4impact-calpoly/36-message-table
Browse files Browse the repository at this point in the history
Create a messages table component
  • Loading branch information
elhagen13 authored Mar 6, 2025
2 parents 03502c3 + 2c590ee commit 4093ddc
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ yarn-error.log*
# local env files
.env*.local
.env
.env.local


# vercel
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@chakra-ui/icons": "^2.2.4",
"@chakra-ui/react": "^2.10.5",
"@clerk/clerk-react": "^5.24.0",
"@clerk/nextjs": "^5.0.9",
"@clerk/nextjs": "^5.7.5",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@testing-library/user-event": "^14.6.1",
Expand Down
139 changes: 139 additions & 0 deletions src/app/messages/messages.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/* messages.module.css */
.container {
padding: 20px;
border-radius: 10px;
}

.header {
font-size: 24px;
font-weight: bold;
color: #333;
}

.unread {
color: #6c757d;
margin-bottom: 16px;
}

.topBar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}

.tabContainer {
display: flex;
gap: 10px;
}

.tab {
background: none;
border: none;
font-size: 16px;
cursor: pointer;
padding: 10px 20px;
border-radius: 20px;
transition: background-color 0.3s;
}

.activeTab {
background-color: #596334;
color: white;
}

.newMessageButton {
background-color: #e57300;
color: white;
border: none;
padding: 10px 16px;
border-radius: 20px;
cursor: pointer;
font-weight: bold;
display: flex;
align-items: center;
gap: 5px;
}

.newMessageButton:hover {
background-color: #d17b1f;
}

.table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
background: white;
}

.table th {
background-color: #dfed98;
padding: 10px;
text-align: left;
}

.table td {
padding: 10px;
border-bottom: 1px solid #ddd;
}

.avatarContainer {
display: flex;
align-items: center;
gap: 8px;
}

.menuButton {
background: none;
border: none;
cursor: pointer;
}

.sentMessage {
color: #555;
font-size: 16px;
margin-top: 10px;
}

.fadedText {
text-decoration: line-through;
opacity: 0.5;
transition: opacity 0.4s ease-in-out;
}

.fadedRow {
transition: opacity 0.4s ease-in-out;
opacity: 0.5;
}

.pageControls {
display: flex;
justify-content: center;
margin-top: 20px;
gap: 10px;
}

.pageButton {
background-color: #ffffff;
color: #323131;
border: none;
padding: 8px 12px;
border-radius: 30px !important;
cursor: pointer;
}

.pageButton:hover {
background-color: #83924f !important;
}

.activePage {
background-color: #596334 !important;
color: white !important;
}

.sentMessage {
text-align: center;
font-size: 18px;
color: #555;
margin-top: 20px;
}
158 changes: 157 additions & 1 deletion src/app/messages/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,164 @@
"use client";

import React, { useState } from "react";
import styles from "./messages.module.css";
import {
Table,
Thead,
Tbody,
Tr,
Th,
Td,
IconButton,
Menu,
MenuButton,
MenuList,
MenuItem,
Flex,
Avatar,
Checkbox,
Button,
Box,
} from "@chakra-ui/react";
import { BsThreeDotsVertical } from "react-icons/bs";

function Messages() {
return <div>Messages</div>;
const messagesPerPage = 10;
const [currentPage, setCurrentPage] = useState(1);
const [activeTab, setActiveTab] = useState("inbox");

const [messages, setMessages] = useState(
Array.from({ length: 24 }, (_, index) => ({
id: index + 1,
sender: "Jane Doe",
message: "Hi! This is a message sent to you...",
date: "01.01.25",
selected: false,
})),
);

const totalPages = Math.ceil(messages.length / messagesPerPage);
const indexOfLastMessage = currentPage * messagesPerPage;
const indexOfFirstMessage = indexOfLastMessage - messagesPerPage;
const currentMessages = messages.slice(indexOfFirstMessage, indexOfLastMessage);

const handlePageChange = (pageNumber: number) => {
if (pageNumber >= 1 && pageNumber <= totalPages) {
setCurrentPage(pageNumber);
}
};

const toggleSelect = (id: number) => {
setMessages((prevMessages) =>
prevMessages.map((msg) => (msg.id === id ? { ...msg, selected: !msg.selected } : msg)),
);
};

const handleDelete = (id: number) => {
setMessages((prevMessages) => prevMessages.filter((msg) => msg.id !== id));
};

return (
<div className={styles.container}>
<h2 className={styles.header}>Messages</h2>
<p className={styles.unread}>10 unread announcements</p>
<div className={styles.topBar}>
<div className={styles.tabContainer}>
<button
className={`${styles.tab} ${activeTab === "inbox" ? styles.activeTab : ""}`}
onClick={() => {
setActiveTab("inbox");
setCurrentPage(1);
}}
>
Inbox
</button>
<button
className={`${styles.tab} ${activeTab === "sent" ? styles.activeTab : ""}`}
onClick={() => {
setActiveTab("sent");
setCurrentPage(1);
}}
>
Sent
</button>
</div>
<button className={styles.newMessageButton}>New Message +</button>
</div>

{activeTab === "inbox" ? (
<>
<Table className={styles.table}>
<Thead>
<Tr>
<Th>Select</Th>
<Th>Sender</Th>
<Th>Message</Th>
<Th>Date</Th>
<Th>Actions</Th>
</Tr>
</Thead>
<Tbody>
{currentMessages.map((msg) => (
<Tr key={msg.id} className={msg.selected ? styles.fadedRow : ""}>
<Td>
<Checkbox isChecked={msg.selected} onChange={() => toggleSelect(msg.id)} />
</Td>
<Td className={msg.selected ? styles.fadedText : ""}>
<Flex className={styles.avatarContainer}>
<Avatar name={msg.sender} size="sm" bg="#596334" color="white" />
{msg.sender}
</Flex>
</Td>
<Td className={msg.selected ? styles.fadedText : ""}>{msg.message}</Td>
<Td className={msg.selected ? styles.fadedText : ""}>{msg.date}</Td>
<Td>
<Menu>
<MenuButton as={IconButton} icon={<BsThreeDotsVertical />} className={styles.menuButton} />
<MenuList>
<MenuItem onClick={() => handleDelete(msg.id)}>Delete</MenuItem>
</MenuList>
</Menu>
</Td>
</Tr>
))}
</Tbody>
</Table>

{/* Pagination Controls */}
<Box className={styles.pageControls}>
<Button
className={styles.pageButton}
onClick={() => handlePageChange(currentPage - 1)}
disabled={currentPage === 1}
>
Previous
</Button>

{Array.from({ length: totalPages }, (_, index) => (
<Button
key={index + 1}
className={currentPage === index + 1 ? styles.activePage : styles.pageButton}
onClick={() => handlePageChange(index + 1)}
>
{index + 1}
</Button>
))}

<Button
className={styles.pageButton}
onClick={() => handlePageChange(currentPage + 1)}
disabled={currentPage === totalPages}
>
Next
</Button>
</Box>
</>
) : (
<p className={styles.sentMessage}>Sent messages here.</p>
)}
</div>
);
}

export default Messages;

0 comments on commit 4093ddc

Please sign in to comment.