import { useCallback, useEffect, useState } from '@wordpress/element'; import { Button, ButtonGroup } from '@wordpress/components'; import ApprovalStatus from './ApprovalStatus/index'; import { ResendAllButton } from './ApprovalStatus/ResendButton'; import ShortcodeElement from '@admin/components/ShortcodeElement'; import { __ } from '@wordpress/i18n'; import { type Submissions, type SubmissionItem, type SubmissionID, type SubmissionStatus, type ChangeAction, type FetchSettings, type Order, type OrderBy, PER_PAGE, } from './consts'; import type { ApprovalState, CheckboxValue, } from '@admin/sections/EditFields/consts'; import { fetchSubmissions, updateSubmissions, deleteSubmissions, getFieldLabels, getHumanValue, } from './utilities'; import { ExportButtonWrapper, SubmissionTabWrapper, EntriesWrapper, } from './styled'; import Table, { usePagination, useTableHeadings, } from '@admin/components/Table'; import type { OnSortArgs } from '@admin/components/Table/consts'; import SubmissionEditModal from './SubmissionEditModal'; import ExportModal from './ExportModal'; import NoticeSystem, { useNoticeSystem } from '@admin/components/NoticeSystem'; const SUBMISSION_LABELS = getFieldLabels(); export default function Submissions() { const { form_id = null, export_url = '' } = window?.petitionerData; const requireApproval = window?.petitionerData ?.require_approval as CheckboxValue; const approvalState = window.petitionerData.approval_state as ApprovalState; const [submissions, setSubmissions] = useState([]); const [total, setTotal] = useState(0); const [tableState, setTableState] = useState({ currentPage: 1, order: null as Order | null | undefined, orderby: null as OrderBy | null | undefined, }); const updateTableState = useCallback( (newState: Partial) => { setTableState((prevState) => ({ ...prevState, ...newState, })); }, [] ); const [showApproval, setShowApproval] = useState(requireApproval); const [defaultApprovalState, setDefaultApprovalState] = useState(() => { return approvalState === 'Email' ? 'Declined' : approvalState; }); const [activeModal, setActiveModal] = useState(); const [showExportModal, setShowExportModal] = useState(false); const { showNotice, noticeStatus, noticeText, hideNotice } = useNoticeSystem(); const hasSubmissions = submissions.length > 0; const fetchData = async () => { return fetchSubmissions({ currentPage: tableState.currentPage, formID: form_id as FetchSettings['formID'], perPage: PER_PAGE, order: tableState.order, orderby: tableState.orderby, onSuccess: (data) => { setTotal(data.total); setSubmissions(data.submissions); }, }); }; useEffect(() => { if (!form_id) return; fetchData(); }, [tableState.currentPage, form_id, tableState.order, tableState.orderby]); useEffect(() => { const handleApprovalChange = () => { setShowApproval(requireApproval); if (approvalState) { setDefaultApprovalState(approvalState); } }; window.addEventListener('onPtrApprovalChange', handleApprovalChange); return () => { window.removeEventListener( 'onPtrApprovalChange', handleApprovalChange ); }; }, []); const handleStatusChange = async ( id: SubmissionID, newStatus: SubmissionStatus, changeAction: ChangeAction ) => { const question = `Are you sure you want to ${String(changeAction).toLowerCase()} this submission?`; if (window.confirm(question)) { updateSubmissions({ data: { id: id, approval_status: newStatus, }, onSuccess: () => { fetchData(); showNotice( 'success', __('Submission status updated!', 'petitioner') ); }, onError: (msg) => { console.error(msg); showNotice( 'error', __('Failed to update submission status!', 'petitioner') ); }, }); } }; const paginationButtons = usePagination( total, PER_PAGE, tableState.currentPage, (page: number) => updateTableState({ currentPage: page }) ); const headingData = useTableHeadings( [ { id: 'email', label: SUBMISSION_LABELS.email, width: '20%' }, { id: 'name', label: SUBMISSION_LABELS.name }, { id: 'consent', label: SUBMISSION_LABELS.accept_tos, width: '80px' }, { id: 'submitted_at', label: SUBMISSION_LABELS.submitted_at }, ], [ { condition: showApproval, heading: { id: 'status', label: SUBMISSION_LABELS.approval_status, }, }, ] ); const ExportComponent = () => { return ( {/* @ts-ignore */} ); }; const tableRows = submissions.map((item) => { const cells: React.ReactNode[] = [ item.email, `${item.fname} ${item.lname}`, getHumanValue(String(item.accept_tos), 'checkbox'), getHumanValue(item.submitted_at, 'date'), ]; if (showApproval) { cells.push( ); } return { id: item.id, cells, isFeatured: item.is_featured === '1', }; }); const handleSortChange = ({ order, orderby }: OnSortArgs) => { updateTableState({ order, orderby: orderby as OrderBy, currentPage: 1, }); }; const selectedSubmission = submissions.find( (item) => item.id === activeModal ); const onModalClose = useCallback(() => setActiveModal(undefined), []); const onModalSave = useCallback( async (newData: SubmissionItem) => { await updateSubmissions({ data: newData, onSuccess: () => { showNotice( 'success', __('Submission updated!', 'petitioner') ); onModalClose(); }, onError: (msg) => { console.error(msg); showNotice( 'error', __('Failed to update submission!', 'petitioner') ); onModalClose(); }, }); fetchData(); }, [activeModal] ); const onModalDelete = useCallback((id: SubmissionID) => { deleteSubmissions({ id, onSuccess: () => { showNotice('success', __('Submission deleted!', 'petitioner')); onModalClose(); fetchData(); }, onError: (msg: string) => { console.error(msg); showNotice( 'error', __('Failed to delete submission!', 'petitioner') ); onModalClose(); }, }); }, []); const handleExportClose = useCallback(() => { setShowExportModal(false); }, []); return (

{__('Submissions', 'petitioner-theme')}

{hasSubmissions && }

{__('Total:', 'petitioner-theme')} {total}

setActiveModal(id)} />
{hasSubmissions && }
{paginationButtons?.length > 1 && ( {paginationButtons} )} {selectedSubmission ? ( ) : null} {showExportModal && } ); }