From c0666cf35c7afa22c6a650d04426f79a5419ee5c Mon Sep 17 00:00:00 2001 From: charleswrayjr Date: Fri, 26 Sep 2025 01:01:51 -0500 Subject: [PATCH] #PA-1 Modifying posts to work better with attachments. --- src/app/components/PostForm.js | 242 +++++++++++++++------------- src/app/components/PostsTable.js | 79 +++++---- src/app/views/Posts/PostFormView.js | 16 -- src/app/views/Posts/PostsView.js | 7 +- 4 files changed, 178 insertions(+), 166 deletions(-) delete mode 100644 src/app/views/Posts/PostFormView.js diff --git a/src/app/components/PostForm.js b/src/app/components/PostForm.js index 2976126..36be282 100644 --- a/src/app/components/PostForm.js +++ b/src/app/components/PostForm.js @@ -4,136 +4,146 @@ * @file Component for creating a new post */ -import React from 'react'; -import { useForm, Controller } from 'react-hook-form'; +import React, { useEffect } from 'react'; +import { Controller, useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; import * as yup from 'yup'; -import { TextField, MenuItem, Button } from '@mui/material'; +import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Grid, MenuItem, TextField } from '@mui/material'; import { useSnackbar } from 'notistack'; -import { useNavigate } from 'react-router-dom'; import { PostService } from '../services'; -const schema = yup.object({ - user_id: yup.number().required('User ID is required'), - title: yup.string().required('Title is required'), - content: yup.string().required('Content is required'), - post_type: yup.string().oneOf(['blog', 'vlog']).required('Post type is required'), - visibility: yup.string().oneOf(['private', 'family', 'public']).required('Visibility is required'), -}).required(); +const schema = yup.object( { + user_id: yup.number().required( 'User ID is required' ), + title: yup.string().required( 'Title is required' ), + content: yup.string().required( 'Content is required' ), + post_type: yup.string().oneOf( [ 'blog', 'vlog' ] ).required( 'Post type is required' ), + visibility: yup.string().oneOf( [ 'private', 'family', 'public' ] ).required( 'Visibility is required' ), +} ).required(); -const PostForm = () => { +const PostForm = ( { isOpen, setOpen, refresh, user } ) => { const { enqueueSnackbar } = useSnackbar(); - const navigate = useNavigate(); - const { control, handleSubmit, formState: { errors } } = useForm({ - resolver: yupResolver(schema), - }); + const { control, handleSubmit, setValue, reset, formState: { errors } } = useForm( { + resolver: yupResolver( schema ), + } ); - const onSubmit = async (data) => { + useEffect( () => { + setValue( 'user_id', user?.id ); + }, [ user, setValue ] ); + + const onSubmit = async ( data ) => { try { - await PostService.createPost(data); - enqueueSnackbar('Post created successfully', { variant: 'success' }); - navigate('/posts'); - } catch (error) { - enqueueSnackbar(`Error creating post: ${error.message}`, { variant: 'error' }); + await PostService.createPost( data ); + await reset(); + await refresh(); + enqueueSnackbar( 'Post created successfully', { variant: 'success' } ); + setOpen( false ); + } catch ( error ) { + enqueueSnackbar( `Error creating post: ${ error.message }`, { variant: 'error' } ); } }; + const onCancel = () => { + reset(); + setOpen( false ); + }; + return ( -
-

Create Post

-
- ( - - )} - /> - ( - - )} - /> - ( - - )} - /> - ( - - Blog - Vlog - - )} - /> - ( - - Private - Family - Public - - )} - /> - + + Create Post From { ''.concat( user?.first_name, ' ', user.last_name ) } + + + + + ( + + ) } + /> + + + ( + + ) } + /> + + + ( + + Blog + Vlog + + ) } + /> + + + ( + + Private + Family + Public + + ) } + /> + + + + + + + -
+ ); }; diff --git a/src/app/components/PostsTable.js b/src/app/components/PostsTable.js index 1217385..2567cc1 100644 --- a/src/app/components/PostsTable.js +++ b/src/app/components/PostsTable.js @@ -2,43 +2,46 @@ * @file Component for displaying posts in a table */ -import React, { useMemo, useState } from 'react'; +import React, { useContext, useMemo, useState } from 'react'; import { MaterialReactTable, useMaterialReactTable } from 'material-react-table'; -import { Button, Container } from '@mui/material'; +import { Button, Container, Grid } from '@mui/material'; +import { AuthContext } from '../components/AuthContext'; import { useSnackbar } from 'notistack'; -import { useNavigate } from 'react-router-dom'; import { PostService } from '../services'; import { getFormattedDate } from '../utils'; +import PostForm from './PostForm'; const PostsTable = () => { const { enqueueSnackbar } = useSnackbar(); - const navigate = useNavigate(); - const [posts, setPosts] = useState([]); + const [ posts, setPosts ] = useState( [] ); + const [ showForm, setShowForm ] = useState( false ); + const { user } = useContext( AuthContext ); const fetchPosts = useMemo( () => async () => { try { - console.log('Fetching posts...'); - const response = await PostService.getPosts(); - setPosts(response.data); - } catch (error) { - enqueueSnackbar(`Error fetching posts: ${error.message}`, { variant: 'error' }); + console.log( 'Fetching posts...' ); + const response = await PostService.getPosts( { is_deleted: false } ); + setPosts( response.data ); + } catch ( error ) { + enqueueSnackbar( `Error fetching posts: ${ error.message }`, { variant: 'error' } ); } - }, [enqueueSnackbar] ); + }, [ enqueueSnackbar ] ); // Fetch posts on mount - React.useEffect(() => { + React.useEffect( () => { fetchPosts().catch(); - }, [fetchPosts, enqueueSnackbar]); + }, [ fetchPosts, enqueueSnackbar ] ); - const columns = useMemo(() => [ + const columns = useMemo( () => [ { accessorKey: 'id', header: 'ID', size: 80, + visibleInShowHideMenu: false, }, { - accessorKey: 'user_id', - header: 'User ID', + accessorKey: 'user_name', + header: 'Creator', size: 100, }, { @@ -65,11 +68,11 @@ const PostsTable = () => { accessorKey: 'created_at', header: 'Created At', size: 150, - Cell: ({ cell }) => getFormattedDate(cell.getValue()), + Cell: ( { cell } ) => getFormattedDate( cell.getValue() ), }, - ], []); + ], [] ); - const table = useMaterialReactTable({ + const table = useMaterialReactTable( { columns, data: posts, enableColumnActions: false, @@ -84,20 +87,34 @@ const PostsTable = () => { }, muiTableBodyCellProps: { className: 'table-row', - }}); + }, + initialState: { + columnVisibility: { + id: false + } + }, + renderTopToolbarCustomActions: () => ( + + +

Posts

+
+ + + +
+ ) + } ); return ( - -

Posts

- - + + { showForm && } + ); }; diff --git a/src/app/views/Posts/PostFormView.js b/src/app/views/Posts/PostFormView.js deleted file mode 100644 index e6fbdab..0000000 --- a/src/app/views/Posts/PostFormView.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @file View for creating a new post - */ - -import React from 'react'; -import PostForm from '../../components/PostForm'; - -const PostFormView = () => { - return ( -
- -
- ); -}; - -export default PostFormView; \ No newline at end of file diff --git a/src/app/views/Posts/PostsView.js b/src/app/views/Posts/PostsView.js index 14a4d99..da02a68 100644 --- a/src/app/views/Posts/PostsView.js +++ b/src/app/views/Posts/PostsView.js @@ -4,12 +4,13 @@ import React from 'react'; import PostsTable from '../../components/PostsTable'; +import { Container } from '@mui/material'; const PostsView = () => { return ( -
- -
+ + + ); }; -- 2.43.0