diff --git a/src/components/Post.tsx b/src/components/Post.tsx index 0bf795fe58325adc81b716f5680e21966c16b9f7..10d19f54477e66b30f8c2ce03660d1c6ef95aeae 100644 --- a/src/components/Post.tsx +++ b/src/components/Post.tsx @@ -11,7 +11,7 @@ import { faLocationDot, faHeart, faCommentDots, faEllipsisVertical } from '@fort import useAppDispatch from '../hooks/useAppDispatch'; import { likepostAsync, unlikePostAsync, followUserFeedAsync, unfollowUserFeedAsync } from '../redux/feed/thunks'; import { followUserPostAction } from '../redux/post/actions'; -import { addLikePostAsync, deleteLikePostAsync, followUserPostAsync, unfollowUserPostAsync } from '../redux/post/thunks'; +import { addLikePostAsync, deleteLikePostAsync, followUserPostAsync, unfollowUserPostAsync, deletePostAsync } from '../redux/post/thunks'; @@ -84,11 +84,23 @@ return <> </div> <div className="relative"> {/* ICON */} - <div className="w-5 md:w-10 flex justify-center items-center cursor-pointer" onClick={() => setDropdownOpen(!dropdownOpen)}> - <FontAwesomeIcon className="text-[22px]" icon={faEllipsisVertical} /> + <div role="button" tabIndex={0} className="w-5 md:w-10 flex justify-center items-center cursor-pointer" onClick={() => setDropdownOpen(!dropdownOpen)} onKeyDown={(event) => event.key === 'Enter' && setDropdownOpen(!dropdownOpen)}> + <FontAwesomeIcon className="text-[22px]" icon={faEllipsisVertical} /> </div> + {/* DROPDOWN */} <div className={`absolute bg-white dark:bg-darkblue rounded border w-32 right-0 mt-4 overflow-hidden ${dropdownOpen ? '' : 'hidden'}`}> + {/* DELETE POST */} + {post.owner.isViewer && ( + <button className="hover:bg-gray-200 p-2 dark:hover:bg-gray-700 font-bold text-blue-500 w-full text-left" + onClick={() => { + dispatch(deletePostAsync(post.id)); + }} + > + Supprimer + </button> + )} + {/* FOLLOW / UNFOLLOW */} {post.owner.isFollowedByViewer ? ( <button className="hover:bg-gray-200 dark:hover:bg-gray-700 p-2 font-bold text-red-500 w-full text-left" onClick={() => { @@ -115,11 +127,13 @@ return <> </button> ) } + {/* SEE PUBLICATION */} {inFeed && - <button className="hover:bg-gray-200 dark:hover:bg-gray-700 p-2 w-full text-left"> - <Link to={`/post/${postid}`}>Voir la publication</Link> - </button> + <button className="hover:bg-gray-200 dark:hover:bg-gray-700 p-2 w-full text-left"> + <Link to={`/post/${postid}`}>Voir la publication</Link> + </button> } + {/* COPY LINK */} <button className="hover:bg-gray-200 dark:hover:bg-gray-700 p-2 w-full text-left" onClick={() => { copyLink(window.location.origin.toString() + '/post/' + postid); }} diff --git a/src/redux/post/actions.ts b/src/redux/post/actions.ts index 984502d6ac28efcb01696a123e63650084e2b4de..1e3d14b520f7f8236032d882ea262cc2490a26b0 100644 --- a/src/redux/post/actions.ts +++ b/src/redux/post/actions.ts @@ -8,7 +8,7 @@ export const REQUEST_POST_SUCCESS = 'POST/REQUEST_FEED_SUCCESS'; export const REQUEST_POST_FAILURE = 'POST/REQUEST_FEED_FAILURE'; export const UNFOLLOW_USER_POST = 'POST/UNFOLLOW_USER_POST'; export const FOLLOW_USER_POST = 'POST/FOLLOW_USER_POST'; - +export const DELETE_POST = 'POST/DELETE_POST'; export type setPostAction = AppAction<typeof SET_POST, Instalike.Post>; @@ -17,9 +17,11 @@ export type LoadPostEndSucessAction = AppAction<typeof REQUEST_POST_SUCCESS>; export type LoadPostEndFailureAction = AppAction<typeof REQUEST_POST_FAILURE>; export type unfollowUserPostAction = AppAction<typeof UNFOLLOW_USER_POST>; export type followUserPostAction = AppAction<typeof FOLLOW_USER_POST>; +export type deletePostAction = AppAction<typeof DELETE_POST>; + -export type PostAction = setPostAction | LoadPostStartAction | LoadPostEndSucessAction | LoadPostEndFailureAction | followUserPostAction | unfollowUserPostAction; +export type PostAction = setPostAction | LoadPostStartAction | LoadPostEndSucessAction | LoadPostEndFailureAction | followUserPostAction | unfollowUserPostAction | deletePostAction; export const setPost = (data: Instalike.Post): setPostAction => ({ @@ -51,3 +53,8 @@ export const followUserPostAction = (): followUserPostAction => ({ type: FOLLOW_USER_POST, payload: undefined, }); + +export const deletePostAction = (): deletePostAction => ({ + type: DELETE_POST, + payload: undefined, +}); diff --git a/src/redux/post/reducer.ts b/src/redux/post/reducer.ts index 2705ac965fb6e278f56c849ae3036a2c5205f9e2..8ea9cf3789c9e39a819d665030ea9bb80554aea3 100644 --- a/src/redux/post/reducer.ts +++ b/src/redux/post/reducer.ts @@ -1,7 +1,7 @@ import { Instalike } from '@jmetterrothan/instalike'; import { Reducer } from 'redux'; -import { PostAction, SET_POST } from './actions'; +import { PostAction, SET_POST, DELETE_POST } from './actions'; import { SetLikeFeedAction, SetUnlikeFeedAction, LIKE_POST_FEED, UNLIKE_POST_FEED, UNFOLLOW_USER_FEED, FOLLOW_USER_FEED } from '../feed/actions' type PostState = { @@ -36,6 +36,8 @@ const postReducer: Reducer<PostState, PostAction | SetLikeFeedAction | SetUnlike return { ...state, data: { ...state.data, owner: { ...state.data.owner, isFollowedByViewer: true } } }; } return state; + case DELETE_POST: + return { ...state, data: { ...state.data, id: -1 } }; default: return state; } diff --git a/src/redux/post/thunks.ts b/src/redux/post/thunks.ts index 7bb8125a3631d6f28460850fbb47d6fc2d7afa7d..94d545a8d22592410d31a5ec408e14d2b635569e 100644 --- a/src/redux/post/thunks.ts +++ b/src/redux/post/thunks.ts @@ -86,3 +86,15 @@ export const unfollowUserPostAsync = (userId: number): AppThunkAction<Promise<vo } }; }; + +// Delete post +export const deletePostAsync = (postId: number): AppThunkAction<Promise<void>> => { + return async (dispatch, getState, api) => { + try { + await api.posts.find(postId).delete(); + dispatch(deletePostAction()); + } catch (e) { + throw e; + } + }; +};