Repository: brianangulo/feb-2025-DSD-cohort
Pull request #90: Feature/complaintcard (#64)
Author: login: johnmdrake1
Created: 2025-03-13T07:57:19Z | Merged: 2025-03-18T00:08:41Z

The complaint card component has been created in ComplaintCard.jsx, and the Complaints.jsx file has been modified accordingly to render the cards in a scrolling grid. 

The card has the complaint date, type, corresponding type icon, description truncated to 250 characters, the complaint status, and a "View details" button that's not hooked up. I gave appropriate corresponding colors to each icon and status type. 

The page with the list of cards rendered in a grid does have scrolling functionality if it is necessary, but I kept the mock data short to save whoever is reviewing this. The real data will be fetched in Complaints.jsx, and then each complaint the endpoint returns will be passed to its own complaint card component as a prop, as an object with all of the appropriate values. For now I just had it match the schema in complaint.js on the backend and the enum there for complaint type. I also added a "AI summary" button at the top which isn't hooked up to anything yet but will be when the AI functionality is added.

This is what it looks like, but I took some of this mock data out for the sake of merging this branch.

![Screenshot 2025-03-13 at 2 49 45 AM](https://github.com/user-attachments/assets/7a0bf99f-2848-4f3a-b5cc-165aedbc7145)



Diff:
diff --git a/front-end/src/components/ComplaintCard.jsx b/front-end/src/components/ComplaintCard.jsx
new file mode 100644
index 0000000..8dd9512
--- /dev/null
+++ b/front-end/src/components/ComplaintCard.jsx
@@ -0,0 +1,84 @@
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; 
+import WarningIcon from '@mui/icons-material/Warning'; 
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; 
+import BuildIcon from '@mui/icons-material/Build'; 
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline'; 
+
+import { Link } from "react-router";
+
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        id,
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    const dateString = new Date(timestamp).toLocaleDateString("en-US", {
+        month: "long",
+        day: "numeric",
+        year: "numeric",
+    })
+
+    //Cut down description to 250 chars
+    const shortDescription = description && description.length > 250 ? description.slice(0,250) + "..." : description;
+
+    return (
+        <Card sx={{ display: "flex", flexDirection: "column", height: "100%", border: "1px solid #ccc", borderRadius: 1, boxShadow: 1, }}>
+            <CardContent sx={{ flexGrow: 1 }}>
+                <Typography variant='caption' color='text.secondary'>
+                    {dateString}
+                </Typography>
+
+                <Box sx={{ display: 'flex', alignItems: 'center', mt: 1, mb:2 }}>
+                    {iconElement}
+                    <Typography variant="subtitle1" sx={{ ml: 1, fontWeight: "bold" }}>
+                        {complaint_type}
+                    </Typography>
+                </Box>
+
+                <Typography variant='body2' sx={{ mb: 2 }}>
+                    {shortDescription}
+                </Typography>
+
+                <Typography variant='body2' sx={{ fontWeight: "bold", color: statusColors[status] || "text.primary", }}>
+                    {status}
+                </Typography>
+            </CardContent>
+
+            <CardActions sx={{ justifyContent: "flex-end" }}>
+                <Button variant='contained' size="small" component={Link} to={`/complaint-details/${id}`}>
+                    View Details
+                </Button>
+            </CardActions>
+        </Card>
+    )
+}
+
+export default ComplaintCard;
\ No newline at end of file
diff --git a/front-end/src/components/tables/PendingLeasesTable.jsx b/front-end/src/components/tables/PendingLeasesTable.jsx
index bf085f4..0d70dc3 100644
--- a/front-end/src/components/tables/PendingLeasesTable.jsx
+++ b/front-end/src/components/tables/PendingLeasesTable.jsx
@@ -85,16 +85,3 @@ export default function PendingLeasesTable() {
   );
 }
 
-// const PendingLeasesTable = () => {
-//     return (
-//         <div style={{ height: 300, width: "100%" }}>
-//             <DataGrid
-//               rows={rows}
-//               columns={columns}
-//               disableRowSelectionOnClick
-//               pageSize={5}
-//               rowsPerPageOptions={[5]}
-//             />
-//         </div>
-//     )
-// }
diff --git a/front-end/src/pages/Complaints.jsx b/front-end/src/pages/Complaints.jsx
index b812906..53716ea 100644
--- a/front-end/src/pages/Complaints.jsx
+++ b/front-end/src/pages/Complaints.jsx
@@ -1,15 +1,50 @@
 import { Box, Typography } from "@mui/material";
+import Grid from '@mui/material/Grid2';
+import ComplaintCard from '../components/ComplaintCard';
+import { useQuery } from "@tanstack/react-query";
+import api from "../api";
+
 
 const Complaints = () => {
+  const { isPending, error, data } = useQuery({
+    queryKey: ['repoData'],
+    queryFn: async () => {
+      const result = await api.get('/api/complaints')
+      return result.data;
+    }
+  })
+  if (isPending) return <Typography>Loading...</Typography>
+
+  if (error) return <Typography>An error has occurred:  {error.message} </Typography>
   return (
     <Box>
       <Typography
         component="h1"
         align="left"
-        sx={{ fontWeight: "bold", fontSize: "2rem" }}
+        sx={{ fontWeight: "bold", fontSize: "2rem", mb: 2 }}
       >
         Tenant Complaints
       </Typography>
+
+      {/* Scrollable grid of complaint cards */}
+      <Grid
+        container
+        spacing={2}
+        sx={{
+          maxHeight: "100vh",
+          overflowY: "auto",
+        }}
+      >
+        {data?.length > 0 ? (
+          data.map((complaint) => (
+            <Grid size={{ xs: 12, sm: 6, md: 4, lg: 3 }} key={complaint.id}>
+              <ComplaintCard complaint={complaint} />
+            </Grid>
+          ))
+        ) : (
+          <Typography>No complaints found</Typography>
+        )}
+      </Grid>
     </Box>
   );
 };


Reviews:
user: login: bethanyann
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-13T13:17:33Z
user: login: bethanyann
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-13T13:18:20Z
user: login: bethanyann
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-13T13:20:00Z
user: login: bethanyann
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-13T13:20:23Z
user: login: bethanyann
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-13T13:29:14Z
user: login: bethanyann
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-13T14:05:49Z
user: login: brianangulo
body: No mocked data please
state: CHANGES_REQUESTED
author_association: OWNER
submitted_at: 2025-03-13T17:31:05Z
user: login: brianangulo
state: COMMENTED
author_association: OWNER
submitted_at: 2025-03-13T21:42:26Z
user: login: johnmdrake1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T04:45:13Z
user: login: johnmdrake1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T04:46:35Z
user: login: johnmdrake1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T04:47:46Z
user: login: johnmdrake1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T04:52:44Z
user: login: johnmdrake1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T04:55:50Z
user: login: johnmdrake1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T04:57:08Z
user: login: johnmdrake1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T05:01:53Z
user: login: bethanyann
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T13:38:48Z
user: login: bethanyann
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T13:40:29Z
user: login: bethanyann
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T13:40:52Z
user: login: bethanyann
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-14T13:43:06Z
user: login: johnmdrake1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-15T04:49:13Z
user: login: johnmdrake1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-15T05:12:36Z
user: login: johnmdrake1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-15T05:14:05Z
user: login: johnmdrake1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-15T05:15:12Z
user: login: johnmdrake1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-15T05:31:39Z
user: login: brianangulo
state: APPROVED
author_association: OWNER
submitted_at: 2025-03-15T05:43:13Z
user: login: bethanyann
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-15T16:31:31Z
user: login: bethanyann
body: Left a comment about the api route
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-03-15T17:23:49Z
user: login: bethanyann
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-03-15T17:25:20Z
user: login: johnmdrake1
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T23:32:24Z
user: login: bethanyann
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-18T00:08:31Z

Review comments:
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
path: front-end/src/components/ComplaintCard.jsx
user: login: bethanyann
body: There are a lot of unnecessary comments in this PR.  A comment is not always needed, especially when the code is self-explanatory. 
Please go through this PR and remove most of the comments
created_at: 2025-03-13T13:17:33Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
+    const dateString = new Date(timestamp).toLocaleDateString("en-US", {
+        month: "long",
+        day: "numeric",
+        year: "numeric",
+    })
+
+    //We only want to show the first 50 characters of the description on these cards, unless it's already shorted than 50 characters
path: front-end/src/components/ComplaintCard.jsx
user: login: bethanyann
body: This comment says you're only showing the first 50 characters but the code is slicing at 250. 
created_at: 2025-03-13T13:18:20Z
author_association: COLLABORATOR
diff_hunk: @@ -1,15 +1,101 @@
-import { Box, Typography } from "@mui/material";
+import React from "react";
+import { Box, Typography, Button } from "@mui/material";
+import Grid from '@mui/material/Grid2';
+import ComplaintCard from '../components/ComplaintCard';
 
 const Complaints = () => {
+  //some generated dummy complaints objects that match the current state of the backend schema, for testing my new card component. This part will be replaced with a fetch from the backend.
+  const dummyComplaints = [
path: front-end/src/pages/Complaints.jsx
user: login: bethanyann
body: We discussed last night that we were not going to use dummy data in the frontend any longer. If the backend api isn't ready yet, work with the person assigned to the task so that both of your work connects.  

I don't want to see dummy data in PRs any longer. 

Do not merge this PR until this data is being pulled from the database
created_at: 2025-03-13T13:20:00Z
author_association: COLLABORATOR
diff_hunk: @@ -1,15 +1,101 @@
-import { Box, Typography } from "@mui/material";
+import React from "react";
+import { Box, Typography, Button } from "@mui/material";
+import Grid from '@mui/material/Grid2';
+import ComplaintCard from '../components/ComplaintCard';
 
 const Complaints = () => {
+  //some generated dummy complaints objects that match the current state of the backend schema, for testing my new card component. This part will be replaced with a fetch from the backend.
+  const dummyComplaints = [
+    {
+      id: 1,
+      apt_num: 101,
+      complaint_type: "Noise",
+      description:
+        "Description of submitted complaint, this can display quite a few characters here to give a basic idea for what the complaint is about.",
+      location: "Living Room",
+      timestamp: "2024-06-13T12:00:00Z",
+      status: "New",
+      admin_response: null,
+      priority: "Medium",
+    },
+    {
+      id: 2,
+      apt_num: 202,
+      complaint_type: "Disturbance",
+      description:
+        "Resident is causing disturbance in the hallway. It happens frequently and is affecting the neighbors.",
+      location: "Hallway",
+      timestamp: "2024-06-13T15:30:00Z",
+      status: "In Progress",
+      admin_response: null,
+      priority: "High",
+    },
+    {
+      id: 3,
+      apt_num: 303,
+      complaint_type: "Emergency",
+      description:
+        "Water pipe burst in the kitchen causing flooding, immediate attention required!",
+      location: "Kitchen",
+      timestamp: "2024-06-14T09:45:00Z",
+      status: "New",
+      admin_response: null,
+      priority: "Urgent",
+    },
+    {
+      id: 4,
+      apt_num: 404,
+      complaint_type: "Maintenance",
+      description:
+        "AC unit not working, the apartment is extremely hot and we need a repair soon. It's been broken for a few days.",
+      location: "Apartment 404",
+      timestamp: "2024-06-15T08:10:00Z",
+      status: "Resolved",
+      admin_response: "Technician dispatched and problem resolved.",
+      priority: "Low",
+    },
+    {
+      id: 5,
+      apt_num: 505,
+      complaint_type: "Other",
+      description:
+        "Some other type of complaint that doesn't quite fit in the other categories. Possibly an administrative issue.",
+      location: "Leasing Office",
+      timestamp: "2024-06-16T11:00:00Z",
+      status: "New",
+      admin_response: null,
+      priority: "Medium",
+    },
+  ];
   return (
     <Box>
       <Typography
         component="h1"
         align="left"
-        sx={{ fontWeight: "bold", fontSize: "2rem" }}
+        sx={{ fontWeight: "bold", fontSize: "2rem", mb: 2 }}
       >
         Tenant Complaints
       </Typography>
+      {/* AI summary button placeholder that's not hooked up to anything yet */}
+      <Button variant="contained" color="success" sx={{ mb:2 }}>
path: front-end/src/pages/Complaints.jsx
user: login: bethanyann
body: Take this out, we won't be doing anything with an AI summary 
created_at: 2025-03-13T13:20:23Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
+    const dateString = new Date(timestamp).toLocaleDateString("en-US", {
+        month: "long",
+        day: "numeric",
+        year: "numeric",
+    })
+
+    //We only want to show the first 50 characters of the description on these cards, unless it's already shorted than 50 characters
path: front-end/src/components/ComplaintCard.jsx
user: login: bethanyann
body: I want to point out that your PR description says 'description truncated to 250 characters', but the Acceptance Criteria says 'Show 50 characters of the description'

created_at: 2025-03-13T13:29:14Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
path: front-end/src/components/ComplaintCard.jsx
user: login: bethanyann
body: Is this React import being used? 
created_at: 2025-03-13T14:05:49Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
+    const dateString = new Date(timestamp).toLocaleDateString("en-US", {
+        month: "long",
+        day: "numeric",
+        year: "numeric",
+    })
+
+    //We only want to show the first 50 characters of the description on these cards, unless it's already shorted than 50 characters
+    const shortDescription = description && description.length > 250 ? description.slice(0,250) + "..." : description;
+
+
+    return (
+        <Card sx={{ display: "flex", flexDirection: "column", height: "100%", border: "1px solid #ccc", borderRadius: 1, boxShadow: 1, }}>
+            <CardContent sx={{ flexGrow: 1 }}>
+                {/* date complaint was submitted  */}
+                <Typography variant='caption' color='text.secondary'>
+                    {dateString}
+                </Typography>
+
+                {/* Complaint type and corresponding icon  */}
+                <Box sx={{ display: 'flex', alignItems: 'center', mt: 1, mb:2 }}>
+                    {iconElement}
+                    <Typography variant="subtitle1" sx={{ ml: 1, fontWeight: "bold" }}>
+                        {complaint_type}
+                    </Typography>
+                </Box>
+
+                {/* The first 50 characters of the potentially longer description.  */}
+                <Typography variant='body2' sx={{ mb: 2 }}>
+                    {shortDescription}
+                </Typography>
+
+                {/* Complaint status  */}
+                <Typography variant='body2' sx={{ fontWeight: "bold", color: statusColors[status] || "text.primary", }}>
+                    {status}
+                </Typography>
+            </CardContent>
+
+            <CardActions sx={{ justifyContent: "flex-end" }}>
+                <Button variant='contained' size="small">
+                    View Details
+                </Button>
+            </CardActions>
+        </Card>
+    )
+
+
+
+
+
+
+
path: front-end/src/components/ComplaintCard.jsx
user: login: brianangulo
body: So much empty space. Please format and remove extra space.
created_at: 2025-03-13T21:29:07Z
author_association: OWNER
diff_hunk: @@ -1,15 +1,101 @@
-import { Box, Typography } from "@mui/material";
+import React from "react";
+import { Box, Typography, Button } from "@mui/material";
+import Grid from '@mui/material/Grid2';
+import ComplaintCard from '../components/ComplaintCard';
 
 const Complaints = () => {
+  //some generated dummy complaints objects that match the current state of the backend schema, for testing my new card component. This part will be replaced with a fetch from the backend.
+  const dummyComplaints = [
+    {
+      id: 1,
+      apt_num: 101,
+      complaint_type: "Noise",
+      description:
+        "Description of submitted complaint, this can display quite a few characters here to give a basic idea for what the complaint is about.",
+      location: "Living Room",
+      timestamp: "2024-06-13T12:00:00Z",
+      status: "New",
+      admin_response: null,
+      priority: "Medium",
+    },
+    {
+      id: 2,
+      apt_num: 202,
+      complaint_type: "Disturbance",
+      description:
+        "Resident is causing disturbance in the hallway. It happens frequently and is affecting the neighbors.",
+      location: "Hallway",
+      timestamp: "2024-06-13T15:30:00Z",
+      status: "In Progress",
+      admin_response: null,
+      priority: "High",
+    },
+    {
+      id: 3,
+      apt_num: 303,
+      complaint_type: "Emergency",
+      description:
+        "Water pipe burst in the kitchen causing flooding, immediate attention required!",
+      location: "Kitchen",
+      timestamp: "2024-06-14T09:45:00Z",
+      status: "New",
+      admin_response: null,
+      priority: "Urgent",
+    },
+    {
+      id: 4,
+      apt_num: 404,
+      complaint_type: "Maintenance",
+      description:
+        "AC unit not working, the apartment is extremely hot and we need a repair soon. It's been broken for a few days.",
+      location: "Apartment 404",
+      timestamp: "2024-06-15T08:10:00Z",
+      status: "Resolved",
+      admin_response: "Technician dispatched and problem resolved.",
+      priority: "Low",
+    },
+    {
+      id: 5,
+      apt_num: 505,
+      complaint_type: "Other",
+      description:
+        "Some other type of complaint that doesn't quite fit in the other categories. Possibly an administrative issue.",
+      location: "Leasing Office",
+      timestamp: "2024-06-16T11:00:00Z",
+      status: "New",
+      admin_response: null,
+      priority: "Medium",
+    },
+  ];
   return (
     <Box>
       <Typography
         component="h1"
         align="left"
-        sx={{ fontWeight: "bold", fontSize: "2rem" }}
+        sx={{ fontWeight: "bold", fontSize: "2rem", mb: 2 }}
       >
         Tenant Complaints
       </Typography>
+      {/* AI summary button placeholder that's not hooked up to anything yet */}
+      <Button variant="contained" color="success" sx={{ mb:2 }}>
+        AI Summary
+      </Button>
+
+      {/* Scrollable grid of complaint cards */}
+      <Grid
+        container
+        spacing={2}
+        sx={{
+          maxHeight: "100vh", //may need to adjust
+          overflowY: "auto", //to enable vertical scroll
+        }}
+      >
+        {dummyComplaints.map((complaint) => (
path: front-end/src/pages/Complaints.jsx
user: login: brianangulo
body: There should be fallback UI here for when no complaints are returned by the backend. Some simple text such as "No complaints available" should suffice since we didn't design anything in specific but anything is better than a white screen.
created_at: 2025-03-13T21:32:55Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
+    const dateString = new Date(timestamp).toLocaleDateString("en-US", {
+        month: "long",
+        day: "numeric",
+        year: "numeric",
+    })
+
+    //We only want to show the first 50 characters of the description on these cards, unless it's already shorted than 50 characters
+    const shortDescription = description && description.length > 250 ? description.slice(0,250) + "..." : description;
+
+
+    return (
+        <Card sx={{ display: "flex", flexDirection: "column", height: "100%", border: "1px solid #ccc", borderRadius: 1, boxShadow: 1, }}>
+            <CardContent sx={{ flexGrow: 1 }}>
+                {/* date complaint was submitted  */}
+                <Typography variant='caption' color='text.secondary'>
+                    {dateString}
+                </Typography>
+
+                {/* Complaint type and corresponding icon  */}
+                <Box sx={{ display: 'flex', alignItems: 'center', mt: 1, mb:2 }}>
+                    {iconElement}
+                    <Typography variant="subtitle1" sx={{ ml: 1, fontWeight: "bold" }}>
+                        {complaint_type}
+                    </Typography>
+                </Box>
+
+                {/* The first 50 characters of the potentially longer description.  */}
+                <Typography variant='body2' sx={{ mb: 2 }}>
+                    {shortDescription}
+                </Typography>
+
+                {/* Complaint status  */}
+                <Typography variant='body2' sx={{ fontWeight: "bold", color: statusColors[status] || "text.primary", }}>
+                    {status}
+                </Typography>
+            </CardContent>
+
+            <CardActions sx={{ justifyContent: "flex-end" }}>
+                <Button variant='contained' size="small">
path: front-end/src/components/ComplaintCard.jsx
user: login: brianangulo
body: Is this button supposed to have an action?
created_at: 2025-03-13T21:41:48Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
path: front-end/src/components/ComplaintCard.jsx
user: login: johnmdrake1
body: All but 1-3 comments have been removed, the remaining ones have been shortened.
created_at: 2025-03-14T04:45:13Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
+    const dateString = new Date(timestamp).toLocaleDateString("en-US", {
+        month: "long",
+        day: "numeric",
+        year: "numeric",
+    })
+
+    //We only want to show the first 50 characters of the description on these cards, unless it's already shorted than 50 characters
path: front-end/src/components/ComplaintCard.jsx
user: login: johnmdrake1
body: I changed it to 250 as it was more reflective of the description lengths on the mockup, and 50 characters made the description previews relatively useless because they were so short. I can change it back if necessary.
created_at: 2025-03-14T04:46:35Z
author_association: COLLABORATOR
diff_hunk: @@ -1,15 +1,101 @@
-import { Box, Typography } from "@mui/material";
+import React from "react";
+import { Box, Typography, Button } from "@mui/material";
+import Grid from '@mui/material/Grid2';
+import ComplaintCard from '../components/ComplaintCard';
 
 const Complaints = () => {
+  //some generated dummy complaints objects that match the current state of the backend schema, for testing my new card component. This part will be replaced with a fetch from the backend.
+  const dummyComplaints = [
path: front-end/src/pages/Complaints.jsx
user: login: johnmdrake1
body: Dummy data has been removed, will work on getting it hooked up
created_at: 2025-03-14T04:47:46Z
author_association: COLLABORATOR
diff_hunk: @@ -1,15 +1,101 @@
-import { Box, Typography } from "@mui/material";
+import React from "react";
+import { Box, Typography, Button } from "@mui/material";
+import Grid from '@mui/material/Grid2';
+import ComplaintCard from '../components/ComplaintCard';
 
 const Complaints = () => {
+  //some generated dummy complaints objects that match the current state of the backend schema, for testing my new card component. This part will be replaced with a fetch from the backend.
+  const dummyComplaints = [
+    {
+      id: 1,
+      apt_num: 101,
+      complaint_type: "Noise",
+      description:
+        "Description of submitted complaint, this can display quite a few characters here to give a basic idea for what the complaint is about.",
+      location: "Living Room",
+      timestamp: "2024-06-13T12:00:00Z",
+      status: "New",
+      admin_response: null,
+      priority: "Medium",
+    },
+    {
+      id: 2,
+      apt_num: 202,
+      complaint_type: "Disturbance",
+      description:
+        "Resident is causing disturbance in the hallway. It happens frequently and is affecting the neighbors.",
+      location: "Hallway",
+      timestamp: "2024-06-13T15:30:00Z",
+      status: "In Progress",
+      admin_response: null,
+      priority: "High",
+    },
+    {
+      id: 3,
+      apt_num: 303,
+      complaint_type: "Emergency",
+      description:
+        "Water pipe burst in the kitchen causing flooding, immediate attention required!",
+      location: "Kitchen",
+      timestamp: "2024-06-14T09:45:00Z",
+      status: "New",
+      admin_response: null,
+      priority: "Urgent",
+    },
+    {
+      id: 4,
+      apt_num: 404,
+      complaint_type: "Maintenance",
+      description:
+        "AC unit not working, the apartment is extremely hot and we need a repair soon. It's been broken for a few days.",
+      location: "Apartment 404",
+      timestamp: "2024-06-15T08:10:00Z",
+      status: "Resolved",
+      admin_response: "Technician dispatched and problem resolved.",
+      priority: "Low",
+    },
+    {
+      id: 5,
+      apt_num: 505,
+      complaint_type: "Other",
+      description:
+        "Some other type of complaint that doesn't quite fit in the other categories. Possibly an administrative issue.",
+      location: "Leasing Office",
+      timestamp: "2024-06-16T11:00:00Z",
+      status: "New",
+      admin_response: null,
+      priority: "Medium",
+    },
+  ];
   return (
     <Box>
       <Typography
         component="h1"
         align="left"
-        sx={{ fontWeight: "bold", fontSize: "2rem" }}
+        sx={{ fontWeight: "bold", fontSize: "2rem", mb: 2 }}
       >
         Tenant Complaints
       </Typography>
+      {/* AI summary button placeholder that's not hooked up to anything yet */}
+      <Button variant="contained" color="success" sx={{ mb:2 }}>
path: front-end/src/pages/Complaints.jsx
user: login: johnmdrake1
body: Taken out for now
created_at: 2025-03-14T04:52:44Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
path: front-end/src/components/ComplaintCard.jsx
user: login: johnmdrake1
body: I guess not. I also thought it was necessary for all components like Tierney. Removed from Complaints.jsx and ComplaintCard.jsx
created_at: 2025-03-14T04:55:50Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
+    const dateString = new Date(timestamp).toLocaleDateString("en-US", {
+        month: "long",
+        day: "numeric",
+        year: "numeric",
+    })
+
+    //We only want to show the first 50 characters of the description on these cards, unless it's already shorted than 50 characters
+    const shortDescription = description && description.length > 250 ? description.slice(0,250) + "..." : description;
+
+
+    return (
+        <Card sx={{ display: "flex", flexDirection: "column", height: "100%", border: "1px solid #ccc", borderRadius: 1, boxShadow: 1, }}>
+            <CardContent sx={{ flexGrow: 1 }}>
+                {/* date complaint was submitted  */}
+                <Typography variant='caption' color='text.secondary'>
+                    {dateString}
+                </Typography>
+
+                {/* Complaint type and corresponding icon  */}
+                <Box sx={{ display: 'flex', alignItems: 'center', mt: 1, mb:2 }}>
+                    {iconElement}
+                    <Typography variant="subtitle1" sx={{ ml: 1, fontWeight: "bold" }}>
+                        {complaint_type}
+                    </Typography>
+                </Box>
+
+                {/* The first 50 characters of the potentially longer description.  */}
+                <Typography variant='body2' sx={{ mb: 2 }}>
+                    {shortDescription}
+                </Typography>
+
+                {/* Complaint status  */}
+                <Typography variant='body2' sx={{ fontWeight: "bold", color: statusColors[status] || "text.primary", }}>
+                    {status}
+                </Typography>
+            </CardContent>
+
+            <CardActions sx={{ justifyContent: "flex-end" }}>
+                <Button variant='contained' size="small">
+                    View Details
+                </Button>
+            </CardActions>
+        </Card>
+    )
+
+
+
+
+
+
+
path: front-end/src/components/ComplaintCard.jsx
user: login: johnmdrake1
body: Removed nearly all whitespace, thanks for pointing that out
created_at: 2025-03-14T04:57:08Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
+    const dateString = new Date(timestamp).toLocaleDateString("en-US", {
+        month: "long",
+        day: "numeric",
+        year: "numeric",
+    })
+
+    //We only want to show the first 50 characters of the description on these cards, unless it's already shorted than 50 characters
+    const shortDescription = description && description.length > 250 ? description.slice(0,250) + "..." : description;
+
+
+    return (
+        <Card sx={{ display: "flex", flexDirection: "column", height: "100%", border: "1px solid #ccc", borderRadius: 1, boxShadow: 1, }}>
+            <CardContent sx={{ flexGrow: 1 }}>
+                {/* date complaint was submitted  */}
+                <Typography variant='caption' color='text.secondary'>
+                    {dateString}
+                </Typography>
+
+                {/* Complaint type and corresponding icon  */}
+                <Box sx={{ display: 'flex', alignItems: 'center', mt: 1, mb:2 }}>
+                    {iconElement}
+                    <Typography variant="subtitle1" sx={{ ml: 1, fontWeight: "bold" }}>
+                        {complaint_type}
+                    </Typography>
+                </Box>
+
+                {/* The first 50 characters of the potentially longer description.  */}
+                <Typography variant='body2' sx={{ mb: 2 }}>
+                    {shortDescription}
+                </Typography>
+
+                {/* Complaint status  */}
+                <Typography variant='body2' sx={{ fontWeight: "bold", color: statusColors[status] || "text.primary", }}>
+                    {status}
+                </Typography>
+            </CardContent>
+
+            <CardActions sx={{ justifyContent: "flex-end" }}>
+                <Button variant='contained' size="small">
path: front-end/src/components/ComplaintCard.jsx
user: login: johnmdrake1
body: Yes, it will take you to the "Complaint detail" page with the full text of the complaint, which as of right now we're still planning to add unless we run out of time. It was part of the acceptance criteria.
created_at: 2025-03-14T05:01:53Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
+    const dateString = new Date(timestamp).toLocaleDateString("en-US", {
+        month: "long",
+        day: "numeric",
+        year: "numeric",
+    })
+
+    //We only want to show the first 50 characters of the description on these cards, unless it's already shorted than 50 characters
path: front-end/src/components/ComplaintCard.jsx
user: login: bethanyann
body: I think you're missing the point here.  I didn't care that you changed it from 50 to 250, I cared that there was so much inconsistency in your code between the comment and the slice not matching.
created_at: 2025-03-14T13:38:48Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
path: front-end/src/components/ComplaintCard.jsx
user: login: bethanyann
body: Let me ask you this, do you think leaving comments above almost every line of code explaining what the code is doing is more useful than learning to read the code? Most of your comments are not useful to other users, your team members, and only provide visual clutter. 
created_at: 2025-03-14T13:40:29Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
+    const dateString = new Date(timestamp).toLocaleDateString("en-US", {
+        month: "long",
+        day: "numeric",
+        year: "numeric",
+    })
+
+    //We only want to show the first 50 characters of the description on these cards, unless it's already shorted than 50 characters
+    const shortDescription = description && description.length > 250 ? description.slice(0,250) + "..." : description;
+
+
+    return (
+        <Card sx={{ display: "flex", flexDirection: "column", height: "100%", border: "1px solid #ccc", borderRadius: 1, boxShadow: 1, }}>
+            <CardContent sx={{ flexGrow: 1 }}>
+                {/* date complaint was submitted  */}
+                <Typography variant='caption' color='text.secondary'>
+                    {dateString}
+                </Typography>
+
+                {/* Complaint type and corresponding icon  */}
+                <Box sx={{ display: 'flex', alignItems: 'center', mt: 1, mb:2 }}>
+                    {iconElement}
+                    <Typography variant="subtitle1" sx={{ ml: 1, fontWeight: "bold" }}>
+                        {complaint_type}
+                    </Typography>
+                </Box>
+
+                {/* The first 50 characters of the potentially longer description.  */}
+                <Typography variant='body2' sx={{ mb: 2 }}>
+                    {shortDescription}
+                </Typography>
+
+                {/* Complaint status  */}
+                <Typography variant='body2' sx={{ fontWeight: "bold", color: statusColors[status] || "text.primary", }}>
+                    {status}
+                </Typography>
+            </CardContent>
+
+            <CardActions sx={{ justifyContent: "flex-end" }}>
+                <Button variant='contained' size="small">
path: front-end/src/components/ComplaintCard.jsx
user: login: bethanyann
body: I think he was implying to add a button click event here so that it can route to the complaint details page
created_at: 2025-03-14T13:40:52Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
path: front-end/src/components/ComplaintCard.jsx
user: login: bethanyann
body: Danny had a really good post about what defines a useful comment and what doesnt. I'll see if I can find that for you, but overall removing the AI generated comments is usually a good thing so your codebase doesn't look like this: 

![image](https://github.com/user-attachments/assets/979cef1e-98ff-4829-a9f6-68fa69eacff3)

created_at: 2025-03-14T13:43:06Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
+    const dateString = new Date(timestamp).toLocaleDateString("en-US", {
+        month: "long",
+        day: "numeric",
+        year: "numeric",
+    })
+
+    //We only want to show the first 50 characters of the description on these cards, unless it's already shorted than 50 characters
+    const shortDescription = description && description.length > 250 ? description.slice(0,250) + "..." : description;
+
+
+    return (
+        <Card sx={{ display: "flex", flexDirection: "column", height: "100%", border: "1px solid #ccc", borderRadius: 1, boxShadow: 1, }}>
+            <CardContent sx={{ flexGrow: 1 }}>
+                {/* date complaint was submitted  */}
+                <Typography variant='caption' color='text.secondary'>
+                    {dateString}
+                </Typography>
+
+                {/* Complaint type and corresponding icon  */}
+                <Box sx={{ display: 'flex', alignItems: 'center', mt: 1, mb:2 }}>
+                    {iconElement}
+                    <Typography variant="subtitle1" sx={{ ml: 1, fontWeight: "bold" }}>
+                        {complaint_type}
+                    </Typography>
+                </Box>
+
+                {/* The first 50 characters of the potentially longer description.  */}
+                <Typography variant='body2' sx={{ mb: 2 }}>
+                    {shortDescription}
+                </Typography>
+
+                {/* Complaint status  */}
+                <Typography variant='body2' sx={{ fontWeight: "bold", color: statusColors[status] || "text.primary", }}>
+                    {status}
+                </Typography>
+            </CardContent>
+
+            <CardActions sx={{ justifyContent: "flex-end" }}>
+                <Button variant='contained' size="small">
path: front-end/src/components/ComplaintCard.jsx
user: login: johnmdrake1
body: Yeah me and Falilou talked about this last night, I'll hook it up to navigate to that details page even though it doesn't exist yet
created_at: 2025-03-15T04:49:13Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
path: front-end/src/components/ComplaintCard.jsx
user: login: johnmdrake1
body: I think I get the picture on what's useful and what's not now and that picture describes it perfectly. The code in Danny's post was a dead giveaway of AI because of the way the comments are formatted, that's why I always say type it out yourself and make sure you understand what you're doing even if you're using AI to help with pieces of code because it allows you to be more discerning. I've just had a habit of commenting what everything does because I felt it couldn't hurt, but when it comes to readability for myself and others and conciseness it can. 

I think the main thing is that I need to have some more confidence to remind myself that I'm knowledgable enough to be able to to know how everything works and what it does, and I'm not going to magically forget it by the next time I read the code!
created_at: 2025-03-15T05:12:36Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
+    const dateString = new Date(timestamp).toLocaleDateString("en-US", {
+        month: "long",
+        day: "numeric",
+        year: "numeric",
+    })
+
+    //We only want to show the first 50 characters of the description on these cards, unless it's already shorted than 50 characters
path: front-end/src/components/ComplaintCard.jsx
user: login: johnmdrake1
body: Yeah, I totally forgot to change the comment after changing the slice boundary.
created_at: 2025-03-15T05:14:05Z
author_association: COLLABORATOR
diff_hunk: @@ -1,15 +1,101 @@
-import { Box, Typography } from "@mui/material";
+import React from "react";
+import { Box, Typography, Button } from "@mui/material";
+import Grid from '@mui/material/Grid2';
+import ComplaintCard from '../components/ComplaintCard';
 
 const Complaints = () => {
+  //some generated dummy complaints objects that match the current state of the backend schema, for testing my new card component. This part will be replaced with a fetch from the backend.
+  const dummyComplaints = [
+    {
+      id: 1,
+      apt_num: 101,
+      complaint_type: "Noise",
+      description:
+        "Description of submitted complaint, this can display quite a few characters here to give a basic idea for what the complaint is about.",
+      location: "Living Room",
+      timestamp: "2024-06-13T12:00:00Z",
+      status: "New",
+      admin_response: null,
+      priority: "Medium",
+    },
+    {
+      id: 2,
+      apt_num: 202,
+      complaint_type: "Disturbance",
+      description:
+        "Resident is causing disturbance in the hallway. It happens frequently and is affecting the neighbors.",
+      location: "Hallway",
+      timestamp: "2024-06-13T15:30:00Z",
+      status: "In Progress",
+      admin_response: null,
+      priority: "High",
+    },
+    {
+      id: 3,
+      apt_num: 303,
+      complaint_type: "Emergency",
+      description:
+        "Water pipe burst in the kitchen causing flooding, immediate attention required!",
+      location: "Kitchen",
+      timestamp: "2024-06-14T09:45:00Z",
+      status: "New",
+      admin_response: null,
+      priority: "Urgent",
+    },
+    {
+      id: 4,
+      apt_num: 404,
+      complaint_type: "Maintenance",
+      description:
+        "AC unit not working, the apartment is extremely hot and we need a repair soon. It's been broken for a few days.",
+      location: "Apartment 404",
+      timestamp: "2024-06-15T08:10:00Z",
+      status: "Resolved",
+      admin_response: "Technician dispatched and problem resolved.",
+      priority: "Low",
+    },
+    {
+      id: 5,
+      apt_num: 505,
+      complaint_type: "Other",
+      description:
+        "Some other type of complaint that doesn't quite fit in the other categories. Possibly an administrative issue.",
+      location: "Leasing Office",
+      timestamp: "2024-06-16T11:00:00Z",
+      status: "New",
+      admin_response: null,
+      priority: "Medium",
+    },
+  ];
   return (
     <Box>
       <Typography
         component="h1"
         align="left"
-        sx={{ fontWeight: "bold", fontSize: "2rem" }}
+        sx={{ fontWeight: "bold", fontSize: "2rem", mb: 2 }}
       >
         Tenant Complaints
       </Typography>
+      {/* AI summary button placeholder that's not hooked up to anything yet */}
+      <Button variant="contained" color="success" sx={{ mb:2 }}>
+        AI Summary
+      </Button>
+
+      {/* Scrollable grid of complaint cards */}
+      <Grid
+        container
+        spacing={2}
+        sx={{
+          maxHeight: "100vh", //may need to adjust
+          overflowY: "auto", //to enable vertical scroll
+        }}
+      >
+        {dummyComplaints.map((complaint) => (
path: front-end/src/pages/Complaints.jsx
user: login: johnmdrake1
body: A typography with "No complaints found" is now displayed when the returned data is of 0 length, good catch
created_at: 2025-03-15T05:15:12Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,100 @@
+import React from 'react';
+import {
+    Card,
+    CardContent,
+    CardActions,
+    Typography,
+    Button,
+    Box
+} from '@mui/material';
+
+//Complaint type icons
+import VolumeUpIcon from '@mui/icons-material/VolumeUp'; //Noise
+import WarningIcon from '@mui/icons-material/Warning'; //Disturbance
+import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; //Emergency
+import BuildIcon from '@mui/icons-material/Build'; //Maintenance
+import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
+
+//Map complaint type enum to their corresponding icons and colors
+const complaintTypeIcons = {
+    Noise: <VolumeUpIcon fontSize='small' sx={{ color: "purple" }} />,
+    Disturbance: <WarningIcon fontSize='small' sx={{ color: "red" }} />,
+    Emergency: <PriorityHighIcon fontSize='small' sx={{ color: "orange" }} />,
+    Maintenance: <BuildIcon fontSize='small' sx={{ color: "blue" }} />,
+    Other: <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />,
+}
+
+//Colors for each status
+const statusColors = {
+    New: "blue",
+    "In Progress": "orange",
+    Resolved: "green",
+}
+
+
+const ComplaintCard = ({ complaint }) => {
+    const {
+        complaint_type,
+        timestamp,
+        description,
+        status,
+    } = complaint;
+
+    //choose an icon based on the complaint type or default to "other"
+    const iconElement = complaintTypeIcons[complaint_type] || <HelpOutlineIcon fontSize='small' sx={{ color: "gray" }} />;
+
+    //Format the timestamp in Month, Day, Year format
+    const dateString = new Date(timestamp).toLocaleDateString("en-US", {
+        month: "long",
+        day: "numeric",
+        year: "numeric",
+    })
+
+    //We only want to show the first 50 characters of the description on these cards, unless it's already shorted than 50 characters
+    const shortDescription = description && description.length > 250 ? description.slice(0,250) + "..." : description;
+
+
+    return (
+        <Card sx={{ display: "flex", flexDirection: "column", height: "100%", border: "1px solid #ccc", borderRadius: 1, boxShadow: 1, }}>
+            <CardContent sx={{ flexGrow: 1 }}>
+                {/* date complaint was submitted  */}
+                <Typography variant='caption' color='text.secondary'>
+                    {dateString}
+                </Typography>
+
+                {/* Complaint type and corresponding icon  */}
+                <Box sx={{ display: 'flex', alignItems: 'center', mt: 1, mb:2 }}>
+                    {iconElement}
+                    <Typography variant="subtitle1" sx={{ ml: 1, fontWeight: "bold" }}>
+                        {complaint_type}
+                    </Typography>
+                </Box>
+
+                {/* The first 50 characters of the potentially longer description.  */}
+                <Typography variant='body2' sx={{ mb: 2 }}>
+                    {shortDescription}
+                </Typography>
+
+                {/* Complaint status  */}
+                <Typography variant='body2' sx={{ fontWeight: "bold", color: statusColors[status] || "text.primary", }}>
+                    {status}
+                </Typography>
+            </CardContent>
+
+            <CardActions sx={{ justifyContent: "flex-end" }}>
+                <Button variant='contained' size="small">
path: front-end/src/components/ComplaintCard.jsx
user: login: johnmdrake1
body: now navigates to complaint-detail, but the route doesn't exist yet
created_at: 2025-03-15T05:31:39Z
author_association: COLLABORATOR
diff_hunk: @@ -1,15 +1,50 @@
 import { Box, Typography } from "@mui/material";
+import Grid from '@mui/material/Grid2';
+import ComplaintCard from '../components/ComplaintCard';
+import { useQuery } from "@tanstack/react-query";
+import api from "../api";
+
 
 const Complaints = () => {
+  const { isPending, error, data } = useQuery({
+    queryKey: ['repoData'],
+    queryFn: async () => {
+      const result = await api.get('http://localhost:4000/api/complaints')
path: front-end/src/pages/Complaints.jsx
user: login: bethanyann
body: The api route already includes the base route of localhost:4000 so writing out this way isn't necessary and I'm not even sure if this will work to connect to the backend

Look at how the other api endpoints are working and follow that pattern. 
created_at: 2025-03-15T17:25:10Z
author_association: COLLABORATOR
diff_hunk: @@ -1,15 +1,50 @@
 import { Box, Typography } from "@mui/material";
+import Grid from '@mui/material/Grid2';
+import ComplaintCard from '../components/ComplaintCard';
+import { useQuery } from "@tanstack/react-query";
+import api from "../api";
+
 
 const Complaints = () => {
+  const { isPending, error, data } = useQuery({
+    queryKey: ['repoData'],
+    queryFn: async () => {
+      const result = await api.get('http://localhost:4000/api/complaints')
path: front-end/src/pages/Complaints.jsx
user: login: johnmdrake1
body: Change has been made! It was still working because if the URL starts with a relative path /api/complaints, it's appended to the baseURL, but if it's an absolute url like it is in this example http://localhost:4000/api/complaints, Axios ignores the base URL and uses the full URL as it is.
created_at: 2025-03-17T23:32:24Z
author_association: COLLABORATOR

PR comments:
user: login: vercel[bot]
created_at: 2025-03-13T07:57:24Z
body: [vc]: #gP6t/WcNkXcDwoSfZk354Kz/mQawyF+F9612DZgLb4M=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJmZWItMjAyNS1kc2QtY29ob3J0IiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6ImZlYi0yMDI1LWRzZC1jb2hvcnQtZ2l0LWZlYXR1cmUtY28tNWFiNTU2LWJyaWFuYW5ndWxvcy1wcm9qZWN0cy52ZXJjZWwuYXBwIn0sImluc3BlY3RvclVybCI6Imh0dHBzOi8vdmVyY2VsLmNvbS9icmlhbmFuZ3Vsb3MtcHJvamVjdHMvZmViLTIwMjUtZHNkLWNvaG9ydC81cVpIZWpkZzlCclgzenZDTlVjblRyU1RXVFA4IiwicHJldmlld1VybCI6ImZlYi0yMDI1LWRzZC1jb2hvcnQtZ2l0LWZlYXR1cmUtY28tNWFiNTU2LWJyaWFuYW5ndWxvcy1wcm9qZWN0cy52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IkRFUExPWUVEIiwicm9vdERpcmVjdG9yeSI6ImZyb250LWVuZCJ9XX0=
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **feb-2025-dsd-cohort** | ✅ Ready ([Inspect](https://vercel.com/brianangulos-projects/feb-2025-dsd-cohort/5qZHejdg9BrX3zvCNUcnTrSTWTP8)) | [Visit Preview](https://feb-2025-dsd-cohort-git-feature-co-5ab556-brianangulos-projects.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/feb-2025-dsd-cohort-git-feature-co-5ab556-brianangulos-projects.vercel.app?via=pr-comment-feedback-link) | Mar 17, 2025 11:28pm |


author_association: NONE