%PDF- <> %âãÏÓ endobj 2 0 obj <> endobj 3 0 obj <>/ExtGState<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/Annots[ 28 0 R 29 0 R] /MediaBox[ 0 0 595.5 842.25] /Contents 4 0 R/Group<>/Tabs/S>> endobj ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<> endobj 2 0 obj<>endobj 2 0 obj<>es 3 0 R>> endobj 2 0 obj<> ox[ 0.000000 0.000000 609.600000 935.600000]/Fi endobj 3 0 obj<> endobj 7 1 obj<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/Subtype/Form>> stream
/* eslint-disable react-hooks/exhaustive-deps */ import { useEffect, useState, useRef } from "react"; import Service from "../../services/Service"; import AuthService from "../../services/AuthService"; import LeadsFilterForm from "./LeadsFilterForm"; import util from "../../util"; import FileSaver from "file-saver"; import { AntdSelect } from "../../components"; import { Row, Button, message, Modal, Table, Card, Typography } from "antd"; import { ExclamationCircleOutlined, ReloadOutlined } from "@ant-design/icons"; const { Text } = Typography; const $ = window.$; function AddLeadsModal({ refOb, masters, campaignId, callback }) { const [showModal, setShowModal] = useState(false); const [loading, setLoading] = useState(false); const [filterFd, setFilterFd] = useState({}); const [result, setResult] = useState([]); const [paging, setPaging] = useState({ p: 1, ps: 10 }); const cols = [ { title: "Name", render: (row) => ( <div> <div>{row.name}</div> <div className="pt5 pb5 bold600" style={{ color: "purple" }}> {row.application_no} </div> <div className="text-secondary fs11 d-flex" style={{ flexDirection: "column", gap: "3px" }} > <div className="bold600">{row.email}</div> <div> Mob: <span className="bold600">{row.mob}</span> </div> <div> State: <span className="bold600">{row.state}</span> </div> <div> Verified By: <span className="bold600">{row.verified_by}</span> </div> {row.isdead === "Y" && <Text type="danger">DEAD</Text>} </div> </div> ), }, { title: "Course Applied", render: (row) => ( <div> <div>{row.program}</div> <div className="text-secondary mt5">{row.plan}</div> <div className="fs11 bold600" style={{ color: row.followup_count_all > 0 ? "purple" : "#ccc", marginTop: "10px", }} > {row.followup_count_all} Followup </div> <div className="fs11 mt3" style={{ color: "purple" }}> Remarks:{" "} <span className="bold600">{row.followup_remarks || "N/A"}</span> </div> </div> ), }, { title: "State", dataIndex: "state" }, { title: "Utm Source", render: (row) => ( <div> <div>{row.utm_source}</div> <div className="text-secondary mt5">{row.utm_group}</div> </div> ), }, { title: "Step", dataIndex: "step_completed", width: 80, render: (n) => `Step ${n}`, }, { title: "Created", width: 100, render: (row) => ( <div> <div>{util.getDate(row.created, "DD MMM YYYY")}</div> </div> ), }, ]; const getList = () => { setLoading(true); Service.leadsN({ ...filterFd, social: 1 }) .then(({ data }) => { data.result.forEach((v) => { v.key = v.id; }); setResult(data.result); setPaging({ ...paging, p: 1 }); }) .catch((e) => { message.error(e.message); }) .finally(() => { setLoading(false); }); }; const addLeadsToSocialCampaign = () => { if (result.length >= 50000) { message.error("Leads count must be less than 50000"); return; } const fn = () => { message.destroy(); setLoading(true); const fd = { campaign_id: campaignId, leads: [], filters: filterFd }; fd.leads = result.map((v) => ({ app_id: v.id, mob: "+91" + v.mob, email: v.email, name: v.name, state: v.state, program: v.program, plan: v.plan, system_id: v.application_no, lpage_id: v.lpage_id, })); Service.addLeadsToSocialCampaign(fd) .then(({ data }) => { message.success(data.message || "Sent"); callback(); setShowModal(false); }) .catch((e) => { message.error(e.message); }) .finally(() => { setLoading(false); }); }; Modal.confirm({ title: `Are you sure to send these leads?`, icon: <ExclamationCircleOutlined />, content: "", okText: "Yes", okType: "danger", cancelText: "No", onOk() { fn(); }, onCancel() {}, }); }; const handleCancel = () => { setShowModal(false); setResult([]); }; refOb.current = { open: () => { setShowModal(true); }, }; return ( <Modal title="Leads" open={showModal} okText="Send to Campaign" onOk={addLeadsToSocialCampaign} okButtonProps={{ loading, disabled: result.length < 1 }} onCancel={handleCancel} cancelText="Close" destroyOnClose maskClosable={false} width={1100} style={{ top: 20 }} > <Card size="small" className="mb15" title="Filter Creteria"> <LeadsFilterForm masters={masters} onChange={(data) => setFilterFd(data)} /> <div className="bdr-top" style={{ margin: "10px -12px 0 -12px", padding: "12px 12px 0 12px" }} > <Button type="primary" size="small" onClick={getList} loading={loading} > Apply Filter </Button> </div> </Card> <div className="def-pag-custom bdr ant-table-text-top"> <Table size="small" dataSource={result} columns={cols} loading={loading} pagination={{ showTotal: (total, range) => `${range[0]}-${range[1]} of ${total} items`, showSizeChanger: true, pageSize: paging.ps, current: paging.p, onChange: (p, ps) => { setPaging({ p, ps }); }, }} /> </div> </Modal> ); } export default function AddedLeads({ campaignDtl, masters, closeDrawer = () => {}, }) { const addleadRef = useRef({}); const [loading, setLoading] = useState(false); const [result, setResult] = useState([]); const [sent_status, set_sent_status] = useState(null); const [steps, setSteps] = useState([]); const [paging, setPaging] = useState({ p: 1, ps: 10 }); const wh = $(window).height(); const isAdmin = AuthService.isAdmin(); const cols = [ { title: "Name", render: (row) => ( <div> <div className="uc">{row.name}</div> <div className="pt5 pb5 bold600" style={{ color: "purple" }}> {row.application_no} </div> <div className="text-secondary fs11 d-flex" style={{ flexDirection: "column", gap: "3px" }} > <div className="bold600">{row.email}</div> <div> Mob: <span className="bold600">{row.mob}</span> </div> <div> State: <span className="bold600">{row.state}</span> </div> <div> UTM:{" "} <span className="bold600"> {row.utm_source} ({row.utm_group}) </span> </div> <div> Verified By: <span className="bold600">{row.verified_by}</span> </div> {row.isdead === "Y" && <Text type="danger">DEAD</Text>} </div> </div> ), }, { title: "Course Applied", render: (row) => ( <div> <div>{row.program}</div> <div className="text-secondary mt5">{row.plan}</div> <div className="fs11 bold600" style={{ color: row.followup_count_all > 0 ? "purple" : "#ccc", marginTop: "10px", }} > {row.followup_count_all} Followup </div> <div className="fs11 mt3" style={{ color: "purple" }}> Remarks:{" "} <span className="bold600">{row.followup_remarks || "N/A"}</span> </div> <div className="pt10 fs11"> Superbot: <strong>{row.superbot_disposition || "N/A"}</strong> </div> </div> ), }, { title: "Step Completed", dataIndex: "step_completed" }, { title: "Initiated On", dataIndex: "initiated_on" }, { title: "Sent On", dataIndex: "sent_on" }, { title: "Opened On", dataIndex: "opened_on" }, ]; const getList = () => { setLoading(true); Service.socialCampaignLeads(campaignDtl?.id, { sent_status, steps }) .then(({ data }) => { data.result.forEach((v) => { v.key = v.id; }); setResult(data.result); setPaging({ ...paging, p: 1 }); }) .catch((e) => { message.error(e.message); }) .finally(() => { setLoading(false); }); }; const downloadCsv = () => { let header = { application_no: "SYSTEM ID", email: "EMAIL", mob: "MOBILE", state: "STATE", utm_source: "UTM SOURCE", utm_group: "UTM GROUP", program: "PROGRAM", plan: "PLAN", followup_count_all: "FOLLOWUP COUNT", superbot_disposition: "SUPERBOT DISPOSITION", step_completed: "STEP COMPLETED", initiated_on: "INITIATED ON", sent_on: "SENT ON", opened_on: "OPENED ON", }; let blob = util.convertToCSVBlob(result, header); FileSaver.saveAs(blob, "leads_sent_to_campaign.csv"); }; useEffect(() => { if (campaignDtl) { getList(); } }, [campaignDtl, sent_status]); return ( <div> {!!campaignDtl && !!campaignDtl.leads_filter && ( <div className="mb10"> <div className="mb5">Applied Filters</div> <div style={{ background: "#eee", padding: "20px 10px", borderRadius: "8px", position: "relative", }} > <div style={{ position: "absolute", zIndex: 2, left: 0, top: 0, width: "100%", height: "100%", }} ></div> <LeadsFilterForm masters={masters} data={campaignDtl.leads_filter} /> </div> </div> )} <Row justify="space-between" className="mb15"> <div className="d-flex" style={{ gap: "8px" }}> <AntdSelect allowClear placeholder="Status (All)" options={["Pending", "Sent", "Opened"]} value={sent_status} onChange={(v) => set_sent_status(v)} style={{ width: "150px" }} /> <AntdSelect allowClear placeholder="Steps (All)" mode="multiple" options={[0, 1, 2, 3]} value={steps} onChange={(v) => setSteps(v)} style={{ width: 200 }} /> {isAdmin && <Button onClick={downloadCsv}>Download CSV</Button>} <Button onClick={getList}> <ReloadOutlined spin={loading} /> </Button> </div> <Button type="primary" onClick={() => addleadRef.current.open()} disabled={campaignDtl?.status === "Published"} > Add Leads </Button> </Row> <Card size="small" bodyStyle={{ padding: 0 }}> <div className="def-pag-custom ant-table-text-top"> <Table size="small" dataSource={result} columns={cols} loading={loading} scroll={{ y: wh - 250 }} pagination={{ showTotal: (total, range) => `${range[0]}-${range[1]} of ${total} items`, showSizeChanger: true, pageSize: paging.ps, current: paging.p, onChange: (p, ps) => { setPaging({ p, ps }); }, }} /> </div> </Card> <AddLeadsModal refOb={addleadRef} masters={masters} campaignId={campaignDtl?.id} callback={() => { closeDrawer(); campaignDtl.status = "Published"; }} /> </div> ); }