]> PHS Git Server - phs-admin.git/commitdiff
Setting tables to properly use useMaterialReactTable and setting proper widths to...
authorcharleswrayjr <charleswrayjr@gmail.com>
Sat, 13 Sep 2025 22:48:02 +0000 (17:48 -0500)
committercharleswrayjr <charleswrayjr@gmail.com>
Sat, 13 Sep 2025 22:48:02 +0000 (17:48 -0500)
.idea/phs-admin.iml
src/app/components/MediaTable.js
src/app/components/MessageGroupMembersTable.js
src/app/components/MessageGroupsTable.js
src/app/components/MessagesTable.js
src/app/components/PostsTable.js

index 4e9dda5d626f4ef21c09c90e82723127f37481c8..2bfa9454551d80120bd663b5baea1a8eced05d79 100644 (file)
@@ -9,6 +9,5 @@
     </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="@types/lodash" level="application" />
   </component>
 </module>
\ No newline at end of file
index 12c2c3dfc1c78dafa635c061a66b86254ba2f7ea..613a6db42cdb9c52f722b448cf88a13d03f00bbc 100644 (file)
@@ -3,8 +3,8 @@
  */
 
 import React, { useMemo, useState } from 'react';
-import { MaterialReactTable } from 'material-react-table';
-import { Button } from '@mui/material';
+import { MaterialReactTable, useMaterialReactTable } from 'material-react-table';
+import { Button, Container } from '@mui/material';
 import { useSnackbar } from 'notistack';
 import { useNavigate } from 'react-router-dom';
 import { MediaService } from '../services';
@@ -13,85 +13,64 @@ import { getFormattedDate } from '../utils';
 const MediaTable = () => {
   const { enqueueSnackbar } = useSnackbar();
   const navigate = useNavigate();
-  const [mediaItems, setMediaItems] = useState([]);
+  const [mediaItems, setMediaItems] = useState( [] );
+
+  const fetchMedia = useMemo( () => async () => {
+    try {
+      const response = await MediaService.getMedia();
+      setMediaItems( response.data );
+    } catch (error) {
+      enqueueSnackbar( `Error fetching media: ${ error.message }`, { variant:'error' } );
+    }
+  }, [enqueueSnackbar] );
 
   // Fetch media on mount
-  React.useEffect(() => {
-    const fetchMedia = async () => {
-      try {
-        const response = await MediaService.getMedia();
-        setMediaItems(response.data);
-      } catch (error) {
-        enqueueSnackbar(`Error fetching media: ${error.message}`, { variant: 'error' });
-      }
-    };
-    fetchMedia();
-  }, [enqueueSnackbar]);
+  React.useEffect( () => {
+    fetchMedia().catch();
+  }, [enqueueSnackbar, fetchMedia] );
 
-  const columns = useMemo(() => [
-    {
-      accessorKey: 'id',
-      header: 'ID',
-      size: 80,
-    },
-    {
-      accessorKey: 'user_id',
-      header: 'User ID',
-      size: 100,
-    },
-    {
-      accessorKey: 'file_path',
-      header: 'File Path',
-      size: 200,
-    },
-    {
-      accessorKey: 'file_type',
-      header: 'Type',
-      size: 100,
-    },
-    {
-      accessorKey: 'visibility',
-      header: 'Visibility',
-      size: 100,
+  const columns = useMemo( () => [{
+    accessorKey:'id', header:'ID', size:80,
+  }, {
+    accessorKey:'user_id', header:'User ID', size:100,
+  }, {
+    accessorKey:'file_path', header:'File Path', size:200,
+  }, {
+    accessorKey:'file_type', header:'Type', size:100,
+  }, {
+    accessorKey:'visibility', header:'Visibility', size:100,
+  }, {
+    accessorKey:'created_at', header:'Created At', size:150, Cell:( { cell } ) => getFormattedDate( cell.getValue() ),
+  },], [] );
+
+  const table = useMaterialReactTable( {
+    columns,
+    data:mediaItems,
+    enableColumnActions:false,
+    enableColumnFilters:true,
+    enablePagination:true,
+    enableSorting:true,
+    muiTablePaperProps:{
+      className:'shadow-md rounded-lg',
     },
-    {
-      accessorKey: 'created_at',
-      header: 'Created At',
-      size: 150,
-      Cell: ({ cell }) => getFormattedDate(cell.getValue()),
+    muiTableHeadCellProps:{
+      className:'table-header',
     },
-  ], []);
+    muiTableBodyCellProps:{
+      className:'table-row',
+    }
+  } );
 
-  return (
-    <div className="container">
+  return (<Container maxWidth="xxl">
       <h2 className="text-2xl font-bold mb-4">Media</h2>
-      <Button
-        variant="contained"
-        color="primary"
-        onClick={() => navigate('/media/new')}
-        className="mb-4"
-      >
+      <Button variant="contained"
+              color="primary"
+              onClick={ () => navigate( '/media/new' ) }
+              className="mb-4">
         Upload Media
       </Button>
-      <MaterialReactTable
-        columns={columns}
-        data={mediaItems}
-        enableColumnActions={false}
-        enableColumnFilters={true}
-        enablePagination={true}
-        enableSorting={true}
-        muiTablePaperProps={{
-          className: 'shadow-md rounded-lg',
-        }}
-        muiTableHeadCellProps={{
-          className: 'table-header',
-        }}
-        muiTableBodyCellProps={{
-          className: 'table-row',
-        }}
-      />
-    </div>
-  );
+      <MaterialReactTable table={ table }/>
+    </Container>);
 };
 
 export default MediaTable;
\ No newline at end of file
index dc53f5ca9f78b8167a61d6ec2b0a0283792db269..d02f945bd2dd3e8a3bbf234ef79cdf7c0490e0e6 100644 (file)
+/* eslint-disable react-hooks/exhaustive-deps */
 /**
  * @file Component for displaying message group members in a table
  */
 
 import React, { useMemo, useState } from 'react';
-import { MaterialReactTable } from 'material-react-table';
-import { Button } from '@mui/material';
+import { MaterialReactTable, useMaterialReactTable } from 'material-react-table';
+import { Button, Container } from '@mui/material';
 import { useSnackbar } from 'notistack';
-import { useParams, useNavigate } from 'react-router-dom';
+import { useNavigate, useParams } from 'react-router-dom';
 import { MessageGroupMembersService } from '../services';
 
 const MessageGroupMembersTable = () => {
   const { group_id } = useParams();
   const { enqueueSnackbar } = useSnackbar();
   const navigate = useNavigate();
-  const [members, setMembers] = useState([]);
+  const [members, setMembers] = useState( [] );
+
+  const fetchMembers = useMemo( () => async () => {
+    try {
+      const response = await MessageGroupMembersService.getMembersByGroupId( group_id );
+      setMembers( response.data );
+    } catch (error) {
+      enqueueSnackbar( `Error fetching group members: ${ error.message }`, { variant:'error' } );
+    }
+  }, [enqueueSnackbar, group_id] );
 
   // Fetch members on mount
-  React.useEffect(() => {
-    const fetchMembers = async () => {
-      try {
-        const response = await MessageGroupMembersService.getMembersByGroupId(group_id);
-        setMembers(response.data);
-      } catch (error) {
-        enqueueSnackbar(`Error fetching group members: ${error.message}`, { variant: 'error' });
-      }
-    };
-    fetchMembers();
-  }, [group_id, enqueueSnackbar]);
+  React.useEffect( () => {
+    fetchMembers().catch();
+  }, [fetchMembers, enqueueSnackbar, group_id] );
 
   // Remove member
-  const handleRemoveMember = async (user_id) => {
+  const handleRemoveMember = async ( user_id ) => {
     try {
-      await MessageGroupMembersService.removeMember({ user_id, group_id });
-      setMembers(members.filter(member => member.user_id !== user_id));
-      enqueueSnackbar('Member removed successfully', { variant: 'success' });
+      await MessageGroupMembersService.removeMember( { user_id, group_id } );
+      setMembers( members.filter( member => member.user_id !== user_id ) );
+      enqueueSnackbar( 'Member removed successfully', { variant:'success' } );
     } catch (error) {
-      enqueueSnackbar(`Error removing member: ${error.message}`, { variant: 'error' });
+      enqueueSnackbar( `Error removing member: ${ error.message }`, { variant:'error' } );
     }
   };
 
-  const columns = useMemo(() => [
-    {
-      accessorKey: 'user_id',
-      header: 'User ID',
-      size: 100,
-    },
-    {
-      accessorKey: 'group_id',
-      header: 'Group ID',
-      size: 100,
+  const columns = useMemo( () => [{
+    accessorKey:'user_id', header:'User ID', size:100,
+  }, {
+    accessorKey:'group_id', header:'Group ID', size:100,
+  }, {
+    accessorKey:'user_id',
+    header:'Actions',
+    size:100,
+    Cell:( { cell } ) => (<Button variant="outlined"
+                                  color="error"
+                                  onClick={ () => handleRemoveMember( cell.getValue() ) }>
+        Remove
+      </Button>),
+  },], [members] );
+
+  const table = useMaterialReactTable( {
+    columns,
+    data:members,
+    enableColumnActions:false,
+    enableColumnFilters:true,
+    enablePagination:true,
+    enableSorting:true,
+    muiTablePaperProps:{
+      className:'shadow-md rounded-lg',
     },
-    {
-      accessorKey: 'user_id',
-      header: 'Actions',
-      size: 100,
-      Cell: ({ cell }) => (
-        <Button
-          variant="outlined"
-          color="error"
-          onClick={() => handleRemoveMember(cell.getValue())}
-        >
-          Remove
-        </Button>
-      ),
+    muiTableHeadCellProps:{
+      className:'table-header',
     },
-  ], [members]);
+    muiTableBodyCellProps:{
+      className:'table-row',
+    }
+  } );
 
-  return (
-    <div className="container">
+  return (<Container maxWidth="xxl">
       <h2 className="text-2xl font-bold mb-4">Message Group Members</h2>
-      <Button
-        variant="contained"
-        color="primary"
-        onClick={() => navigate(`/message-groups/${group_id}/members/new`)}
-        className="mb-4"
-      >
+      <Button variant="contained"
+              color="primary"
+              onClick={ () => navigate( `/message-groups/${ group_id }/members/new` ) }
+              className="mb-4">
         Add Member
       </Button>
-      <MaterialReactTable
-        columns={columns}
-        data={members}
-        enableColumnActions={false}
-        enableColumnFilters={true}
-        enablePagination={true}
-        enableSorting={true}
-        muiTablePaperProps={{
-          className: 'shadow-md rounded-lg',
-        }}
-        muiTableHeadCellProps={{
-          className: 'table-header',
-        }}
-        muiTableBodyCellProps={{
-          className: 'table-row',
-        }}
-      />
-    </div>
-  );
+      <MaterialReactTable table={ table }/>
+    </Container>);
 };
 
 export default MessageGroupMembersTable;
\ No newline at end of file
index 568b1bb7c043dfae87197ade91158d63e58cfdce..af5f61152d99c93e9c5b8ba09e35ccb74eca12bf 100644 (file)
@@ -1,10 +1,11 @@
+/* eslint-disable react-hooks/exhaustive-deps */
 /**
  * @file Component for displaying message groups in a table
  */
 
 import React, { useMemo, useState } from 'react';
-import { MaterialReactTable } from 'material-react-table';
-import { Button } from '@mui/material';
+import { MaterialReactTable, useMaterialReactTable } from 'material-react-table';
+import { Button, Container } from '@mui/material';
 import { useSnackbar } from 'notistack';
 import { useNavigate } from 'react-router-dom';
 import { MessageGroupService } from '../services';
@@ -13,97 +14,94 @@ import { getFormattedDate } from '../utils';
 const MessageGroupsTable = () => {
   const { enqueueSnackbar } = useSnackbar();
   const navigate = useNavigate();
-  const [messageGroups, setMessageGroups] = useState([]);
+  const [messageGroups, setMessageGroups] = useState( [] );
+
+  const fetchMessageGroups = useMemo( () => async () => {
+    try {
+      const response = await MessageGroupService.getMessageGroups();
+      setMessageGroups( response.data );
+    } catch (error) {
+      enqueueSnackbar( `Error fetching message groups: ${ error.message }`, { variant:'error' } );
+    }
+  }, [enqueueSnackbar] );
 
   // Fetch message groups on mount
-  React.useEffect(() => {
-    const fetchMessageGroups = async () => {
-      try {
-        const response = await MessageGroupService.getMessageGroups();
-        setMessageGroups(response.data);
-      } catch (error) {
-        enqueueSnackbar(`Error fetching message groups: ${error.message}`, { variant: 'error' });
-      }
-    };
-    fetchMessageGroups();
-  }, [enqueueSnackbar]);
+  React.useEffect( () => {
+    fetchMessageGroups().catch();
+  }, [enqueueSnackbar, fetchMessageGroups] );
 
-  const columns = useMemo(() => [
+  const columns = useMemo( () => [
     {
-      accessorKey: 'id',
-      header: 'ID',
-      size: 80,
+      accessorKey:'id',
+      header:'ID',
+      size:80,
     },
     {
-      accessorKey: 'name',
-      header: 'Name',
-      size: 200,
+      accessorKey:'name',
+      header:'Name',
+      size:200,
     },
     {
-      accessorKey: 'created_by_id',
-      header: 'Created By',
-      size: 100,
+      accessorKey:'created_by_id',
+      header:'Created By',
+      size:100,
     },
     {
-      accessorKey: 'created_at',
-      header: 'Created At',
-      size: 150,
-      Cell: ({ cell }) => getFormattedDate(cell.getValue()),
+      accessorKey:'created_at',
+      header:'Created At',
+      size:150,
+      Cell:( { cell } ) => getFormattedDate( cell.getValue() ),
     },
     {
-      accessorKey: 'id',
-      header: 'Actions',
-      size: 150,
-      Cell: ({ cell }) => (
+      accessorKey:'id',
+      header:'Actions',
+      size:150,
+      Cell:( { cell } ) => (
         <div className="space-x-2">
-          <Button
-            variant="outlined"
-            color="primary"
-            onClick={() => navigate(`/message-groups/${cell.getValue()}/members`)}
-          >
+          <Button variant="outlined"
+                  color="primary"
+                  onClick={ () => navigate( `/message-groups/${ cell.getValue() }/members` ) }>
             View Members
           </Button>
-          <Button
-            variant="outlined"
-            color="primary"
-            onClick={() => navigate(`/messages?group_id=${cell.getValue()}`)}
-          >
+          <Button variant="outlined"
+                  color="primary"
+                  onClick={ () => navigate( `/messages?group_id=${ cell.getValue() }` ) }>
             View Messages
           </Button>
         </div>
       ),
     },
-  ], []);
+  ], [] );
+
+  const table = useMaterialReactTable( {
+    columns,
+    data:messageGroups,
+    enableColumnActions:false,
+    enableColumnFilters:true,
+    enablePagination:true,
+    enableSorting:true,
+    muiTablePaperProps:{
+      className:'shadow-md rounded-lg',
+    },
+    muiTableHeadCellProps:{
+      className:'table-header',
+    },
+    muiTableBodyCellProps:{
+      className:'table-row',
+    }
+  } );
 
   return (
-    <div className="container">
+    <Container maxWidth="xxl">
       <h2 className="text-2xl font-bold mb-4">Message Groups</h2>
-      <Button
-        variant="contained"
-        color="primary"
-        onClick={() => navigate('/message-groups/new')}
-        className="mb-4"
-      >
+      <Button variant="contained"
+              color="primary"
+              onClick={ () => navigate( '/message-groups/new' ) }
+              className="mb-4">
         New Group
       </Button>
-      <MaterialReactTable
-        columns={columns}
-        data={messageGroups}
-        enableColumnActions={false}
-        enableColumnFilters={true}
-        enablePagination={true}
-        enableSorting={true}
-        muiTablePaperProps={{
-          className: 'shadow-md rounded-lg',
-        }}
-        muiTableHeadCellProps={{
-          className: 'table-header',
-        }}
-        muiTableBodyCellProps={{
-          className: 'table-row',
-        }}
-      />
-    </div>
+      <MaterialReactTable table={ table }/>
+    </Container>
   );
 };
 
index 9542c15c88c451626b2bb5d4acf3b552dc309ae9..a38a37953078cba0580bf3f00bbd017ed73fbe37 100644 (file)
@@ -1,10 +1,11 @@
+/* eslint-disable react-hooks/exhaustive-deps */
 /**
  * @file Component for displaying messages in a table
  */
 
 import React, { useMemo, useState } from 'react';
-import { MaterialReactTable } from 'material-react-table';
-import { Button, IconButton } from '@mui/material';
+import { MaterialReactTable, useMaterialReactTable } from 'material-react-table';
+import { Button, IconButton, Container } from '@mui/material';
 import { MarkEmailRead } from '@mui/icons-material';
 import { useSnackbar } from 'notistack';
 import { useNavigate } from 'react-router-dom';
@@ -16,27 +17,28 @@ const MessagesTable = ({ groupId, recipientId }) => {
   const navigate = useNavigate();
   const [messages, setMessages] = useState([]);
 
+  const fetchMessages = useMemo( () => async () => {
+    try {
+      let response;
+      if (groupId) {
+        response = await MessageService.getMessagesByGroupId(groupId);
+      } else if (recipientId) {
+        response = await MessageService.getMessagesByRecipientId(recipientId);
+      } else {
+        response = await MessageService.getMessages();
+      }
+      setMessages(response.data);
+    } catch (error) {
+      enqueueSnackbar(`Error fetching messages: ${error.message}`, { variant: 'error' });
+    }
+  }, [] );
+
   // Fetch messages on mount
   React.useEffect(() => {
-    const fetchMessages = async () => {
-      try {
-        let response;
-        if (groupId) {
-          response = await MessageService.getMessagesByGroupId(groupId);
-        } else if (recipientId) {
-          response = await MessageService.getMessagesByRecipientId(recipientId);
-        } else {
-          response = await MessageService.getMessages();
-        }
-        setMessages(response.data);
-      } catch (error) {
-        enqueueSnackbar(`Error fetching messages: ${error.message}`, { variant: 'error' });
-      }
-    };
-    fetchMessages();
+    fetchMessages().catch();
   }, [enqueueSnackbar, groupId, recipientId]);
 
-  // Mark message as read
+  // Mark message as read
   const handleMarkAsRead = async (messageId) => {
     try {
       const response = await MessageService.markMessageAsRead(messageId);
@@ -92,10 +94,28 @@ const MessagesTable = ({ groupId, recipientId }) => {
         )
       ),
     },
-  ], [messages]);
+  ], [messages] );
+
+  const table = useMaterialReactTable({
+    columns,
+    data: messages,
+    enableColumnActions: false,
+    enableColumnFilters: true,
+    enablePagination: true,
+    enableSorting: true,
+    muiTablePaperProps: {
+      className: 'shadow-md rounded-lg',
+    },
+    muiTableHeadCellProps: {
+      className: 'table-header',
+    },
+    muiTableBodyCellProps: {
+      className: 'table-row',
+    }
+  });
 
   return (
-    <div className="container">
+    <Container maxWidth='xxl'>
       <h2 className="text-2xl font-bold mb-4">Messages</h2>
       <Button
         variant="contained"
@@ -105,24 +125,8 @@ const MessagesTable = ({ groupId, recipientId }) => {
       >
         New Message
       </Button>
-      <MaterialReactTable
-        columns={columns}
-        data={messages}
-        enableColumnActions={false}
-        enableColumnFilters={true}
-        enablePagination={true}
-        enableSorting={true}
-        muiTablePaperProps={{
-          className: 'shadow-md rounded-lg',
-        }}
-        muiTableHeadCellProps={{
-          className: 'table-header',
-        }}
-        muiTableBodyCellProps={{
-          className: 'table-row',
-        }}
-      />
-    </div>
+      <MaterialReactTable table={table} />
+    </Container>
   );
 };
 
index dd2f259671515d77412d68503a5e6d8162f28e70..1217385ed3707f1600e66f6d555a2ca731b3482e 100644 (file)
@@ -3,8 +3,8 @@
  */
 
 import React, { useMemo, useState } from 'react';
-import { MaterialReactTable } from 'material-react-table';
-import { Button } from '@mui/material';
+import { MaterialReactTable, useMaterialReactTable } from 'material-react-table';
+import { Button, Container } from '@mui/material';
 import { useSnackbar } from 'notistack';
 import { useNavigate } from 'react-router-dom';
 import { PostService } from '../services';
@@ -15,7 +15,7 @@ const PostsTable = () => {
   const navigate = useNavigate();
   const [posts, setPosts] = useState([]);
 
-  const fetchPosts = async () => {
+  const fetchPosts = useMemo( () => async () => {
     try {
       console.log('Fetching posts...');
       const response = await PostService.getPosts();
@@ -23,14 +23,12 @@ const PostsTable = () => {
     } catch (error) {
       enqueueSnackbar(`Error fetching posts: ${error.message}`, { variant: 'error' });
     }
-  };
+  }, [enqueueSnackbar] );
 
   // Fetch posts on mount
   React.useEffect(() => {
-    console.log('loaded...');
-
-    fetchPosts();
-  }, []);
+    fetchPosts().catch();
+  }, [fetchPosts, enqueueSnackbar]);
 
   const columns = useMemo(() => [
     {
@@ -71,8 +69,25 @@ const PostsTable = () => {
     },
   ], []);
 
+  const table = useMaterialReactTable({
+    columns,
+    data: posts,
+    enableColumnActions: false,
+    enableColumnFilters: true,
+    enablePagination: true,
+    enableSorting: true,
+    muiTablePaperProps: {
+      className: 'shadow-md rounded-lg',
+    },
+    muiTableHeadCellProps: {
+      className: 'table-header',
+    },
+    muiTableBodyCellProps: {
+      className: 'table-row',
+  }});
+
   return (
-    <div className="container">
+    <Container maxWidth='xxl'>
       <h2 className="text-2xl font-bold mb-4">Posts</h2>
       <Button
         variant="contained"
@@ -82,24 +97,8 @@ const PostsTable = () => {
       >
         Create Post
       </Button>
-      <MaterialReactTable
-        columns={columns}
-        data={posts}
-        enableColumnActions={false}
-        enableColumnFilters={true}
-        enablePagination={true}
-        enableSorting={true}
-        muiTablePaperProps={{
-          className: 'shadow-md rounded-lg',
-        }}
-        muiTableHeadCellProps={{
-          className: 'table-header',
-        }}
-        muiTableBodyCellProps={{
-          className: 'table-row',
-        }}
-      />
-    </div>
+      <MaterialReactTable table={table} />
+    </Container>
   );
 };