import React, { useCallback, useState } from "react"; import pick from "lodash/pick"; import { acceptProposal, announceProposal, archive, dislike, edit, hide, like, loadPosts, markSeen, rejectProposal, rejectProposalByChairman, } from "actions/posts"; import { ban, unban } from "actions/users"; import ErrorMessage from "components/ErrorMessage"; import ModalConfirm from "components/modals/ModalConfirm"; import PostEditModal from "components/posts/PostEditModal"; import PostList from "components/posts/PostList"; import { useActionState, useItemActionConfirm } from "hooks"; import { AuthStore, PostStore } from "stores"; const PostsContainer = ({ className }) => { const [postToEdit, setPostToEdit] = useState(null); const [confirmingEdit, setConfirmingEdit] = useState(false); const [editError, setEditError] = useState(null); const [ userToBan, setUserToBan, onBanUserConfirm, onBanUserCancel, ] = useItemActionConfirm(ban); const [ userToUnban, setUserToUnban, onUnbanUserConfirm, onUnbanUserCancel, ] = useItemActionConfirm(unban); const [ postToHide, setPostToHide, onPostHideConfirm, onPostHideCancel, ] = useItemActionConfirm(hide); const [ postToArchive, setPostToArchive, onPostArchiveConfirm, onPostArchiveCancel, ] = useItemActionConfirm(archive); const [ postToAnnounce, setPostToAnnounce, onAnnounceConfirm, onAnnounceCancel, ] = useItemActionConfirm(announceProposal); const [ postToAccept, setPostToAccept, onAcceptConfirm, onAcceptCancel, ] = useItemActionConfirm(acceptProposal); const [ postToReject, setPostToReject, onRejectConfirm, onRejectCancel, ] = useItemActionConfirm(rejectProposal); const [ postToRejectByChairman, setPostToRejectByChairman, onRejectByChairmanConfirm, onRejectByChairmanCancel, ] = useItemActionConfirm(rejectProposalByChairman); const { isAuthenticated, user } = AuthStore.useState(); const { window, items } = PostStore.useState((state) => pick(state, ["window", "items"]) ); const showingArchivedOnly = PostStore.useState( (state) => state.filters.flags === "archived" ); const [banningUser, banningUserError] = useActionState(ban, userToBan); const [unbanningUser, unbanningUserError] = useActionState( unban, userToUnban ); const [hidingPost, hidingPostError] = useActionState(hide, postToHide); const [archivingPost, archivingPostError] = useActionState( archive, postToArchive ); const [announcingProposal, announcingProposalError] = useActionState( announceProposal, postToAnnounce ); const [acceptingProposal, acceptingProposalError] = useActionState( acceptProposal, postToAccept ); const [rejectingProposal, rejectingProposalError] = useActionState( rejectProposal, postToReject ); const [ rejectingProposalByChairman, rejectingProposalByChairmanError, ] = useActionState(rejectProposalByChairman, postToRejectByChairman); const { 2: loadResult } = loadPosts.useWatch(); const confirmEdit = useCallback( async (newContent) => { if (postToEdit && newContent) { setConfirmingEdit(true); const result = await edit.run({ post: postToEdit, newContent }); if (!result.error) { setPostToEdit(null); setEditError(null); } else { setEditError(result.message); } setConfirmingEdit(false); } }, [postToEdit, setPostToEdit] ); const cancelEdit = useCallback(() => { setPostToEdit(null); }, [setPostToEdit]); /** * Ban a post's author. * @param {CF2021.Post} post */ const onBanUser = (post) => { setUserToBan(post.author); }; /** * Ban a post's author. * @param {CF2021.Post} post */ const onUnbanUser = (post) => { setUserToUnban(post.author); }; const sliceStart = (window.page - 1) * window.perPage; const sliceEnd = window.page * window.perPage; const windowItems = window.items.map((postId) => items[postId]); return ( <> {loadResult && loadResult.error && ( <ErrorMessage> Příspěvky se nepodařilo načíst: {loadResult.message} </ErrorMessage> )} <PostList items={windowItems.slice(sliceStart, sliceEnd)} canThumb={isAuthenticated} onLike={like.run} onDislike={dislike.run} onSeen={markSeen} className={className} dimArchived={!showingArchivedOnly} currentUser={user} onHide={setPostToHide} onBanUser={onBanUser} onUnbanUser={onUnbanUser} onEdit={setPostToEdit} onArchive={setPostToArchive} onAnnounceProcedureProposal={setPostToAnnounce} onAcceptProcedureProposal={setPostToAccept} onRejectProcedureProposal={setPostToReject} onRejectProcedureProposalByChairman={setPostToRejectByChairman} /> <ModalConfirm isOpen={!!userToBan} onConfirm={onBanUserConfirm} onCancel={onBanUserCancel} confirming={banningUser} error={banningUserError} title={`Zablokovat uživatele ${userToBan ? userToBan.name : null}?`} yesActionLabel="Zablokovat" > Uživatel <strong>{userToBan ? userToBan.name : null}</strong> bude zablokován a nebude dále moci vkládat nové příspěvky. Opravdu to chcete? </ModalConfirm> <ModalConfirm isOpen={!!userToUnban} onConfirm={onUnbanUserConfirm} onCancel={onUnbanUserCancel} confirming={unbanningUser} error={unbanningUserError} title={`Odblokovat uživatele ${userToUnban ? userToUnban.name : null}?`} yesActionLabel="Odblokovat" > Uživatel <strong>{userToUnban ? userToUnban.name : null}</strong> bude odblokován a bude mu opět umožněno přidávat nové příspěvky. Opravdu to chcete? </ModalConfirm> <ModalConfirm isOpen={!!postToHide} onConfirm={onPostHideConfirm} onCancel={onPostHideCancel} confirming={hidingPost} error={hidingPostError} title="Skrýt příspěvek?" yesActionLabel="Potvrdit" > Příspěvek se skryje a uživatelé ho neuvidí. Opravdu to chcete? </ModalConfirm> <ModalConfirm isOpen={!!postToArchive} onConfirm={onPostArchiveConfirm} onCancel={onPostArchiveCancel} confirming={archivingPost} error={archivingPostError} title="Archivovat příspěvek?" yesActionLabel="Potvrdit" > Příspěvek bude archivován a bude ve výpisu vizuálně odlišen. Opravdu to chcete? </ModalConfirm> <ModalConfirm isOpen={!!postToAnnounce} onConfirm={onAnnounceConfirm} onCancel={onAnnounceCancel} confirming={announcingProposal} error={announcingProposalError} title="Vyhlásit procedurální návrh?" yesActionLabel="Vyhlásit návrh" > Procedurální návrh bude <strong>vyhlášen</strong>. Opravdu to chcete? </ModalConfirm> <ModalConfirm isOpen={!!postToAccept} onConfirm={onAcceptConfirm} onCancel={onAcceptCancel} confirming={acceptingProposal} error={acceptingProposalError} title="Schválit procedurální návrh?" yesActionLabel="Schválit návrh" > Procedurální návrh bude <strong>schválen</strong>. Opravdu to chcete? </ModalConfirm> <ModalConfirm isOpen={!!postToReject} onConfirm={onRejectConfirm} onCancel={onRejectCancel} confirming={rejectingProposal} error={rejectingProposalError} title="Zamítnout procedurální návrh?" yesActionLabel="Zamítnout návrh" > Procedurální návrh bude <strong>zamítnut</strong>. Opravdu to chcete? </ModalConfirm> <ModalConfirm isOpen={!!postToRejectByChairman} onConfirm={onRejectByChairmanConfirm} onCancel={onRejectByChairmanCancel} confirming={rejectingProposalByChairman} error={rejectingProposalByChairmanError} title="Zamítnout procedurální návrh předsedajícícm?" yesActionLabel="Zamítnout návrh předsedajícím" > Procedurální návrh bude <strong>zamítnut předsedajícím</strong>. Opravdu to chcete? </ModalConfirm> {postToEdit && ( <PostEditModal isOpen={true} post={postToEdit} onConfirm={confirmEdit} onCancel={cancelEdit} confirming={confirmingEdit} error={editError} /> )} </> ); }; export default PostsContainer;