/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import React, { useRef, useEffect, useCallback, useState } from "react"; import { useSelector, useDispatch } from "react-redux"; import { actionTypes as at, actionCreators as ac } from "common/Actions.mjs"; export const ReportContent = spocs => { const dispatch = useDispatch(); const modal = useRef(null); const radioGroupRef = useRef(null); const submitButtonRef = useRef(null); const report = useSelector(state => state.DiscoveryStream.report); const [valueSelected, setValueSelected] = useState(false); const [selectedReason, setSelectedReason] = useState(null); const spocData = spocs.spocs.data; // Sends a dispatch to update the redux store when modal is cancelled const handleCancel = () => { dispatch( ac.AlsoToMain({ type: at.REPORT_CLOSE, }) ); }; const handleSubmit = useCallback(() => { const { card_type, corpus_item_id, position, reporting_url, scheduled_corpus_item_id, section_position, section, title, topic, url, } = report; if (card_type === "organic") { dispatch( ac.AlsoToMain({ type: at.REPORT_CONTENT_SUBMIT, data: { card_type, corpus_item_id, report_reason: selectedReason, scheduled_corpus_item_id, section_position, section, title, topic, url, }, }) ); } else if (card_type === "spoc") { // Retrieve placement_id by comparing spocData with the ad that was reported const getPlacementId = () => { if (!spocData || !report.url) { return null; } for (const [placementId, spocList] of Object.entries(spocData)) { for (const spoc of Object.values(spocList)) { if (spoc?.url === report.url) { return placementId; } } } return null; }; const placement_id = getPlacementId(); dispatch( ac.AlsoToMain({ type: at.REPORT_AD_SUBMIT, data: { report_reason: selectedReason, placement_id, position, reporting_url, url, }, }) ); } dispatch( ac.AlsoToMain({ type: at.BLOCK_URL, data: [{ ...report }], }) ); dispatch( ac.OnlyToOneContent( { type: at.SHOW_TOAST_MESSAGE, data: { toastId: "reportSuccessToast", showNotifications: true, }, }, "ActivityStream:Content" ) ); }, [dispatch, selectedReason, report, spocData]); // Opens and closes the modal based on user interaction useEffect(() => { if (report.visible && modal?.current) { modal.current.showModal(); // Clear any previously selected radio button const radioGroup = radioGroupRef.current; if (radioGroup) { const selectedRadioButton = radioGroup.querySelector("moz-radio[checked]"); if (selectedRadioButton) { selectedRadioButton.removeAttribute("checked"); } } // Clear out the states setValueSelected(false); setSelectedReason(null); } else if (!report.visible && modal?.current?.open) { modal.current.close(); } }, [report.visible]); // Updates the submit button's state based on if a value is selected useEffect(() => { const radioGroup = radioGroupRef.current; const submitButton = submitButtonRef.current; const handleRadioChange = e => { const reasonValue = e?.target?.value; if (reasonValue) { setValueSelected(true); setSelectedReason(reasonValue); } }; if (radioGroup) { radioGroup.addEventListener("change", handleRadioChange); } // Handle submit button state on valueSelected change const updateSubmitState = () => { if (valueSelected) { submitButton.removeAttribute("disabled"); } else { submitButton.setAttribute("disabled", ""); } }; updateSubmitState(); return () => { if (radioGroup) { radioGroup.removeEventListener("change", handleRadioChange); } }; }, [valueSelected, selectedReason]); return ( dispatch({ type: at.REPORT_CLOSE })} >
{/* spocs and stories are going to have different reporting options, so placed a conditional to render the different reasons */} {report.card_type === "spoc" ? ( <> ) : ( <> )}
); };