Untitled
user_5257650
plain_text
2 years ago
18 kB
4
Indexable
import Dropdown from '@/components/Dropdown'; import { turboFootballUrl } from '@/lib/api/getAxios'; import { Dialog, Transition } from '@headlessui/react'; import axios from 'axios'; import { MantineReactTable } from 'mantine-react-table'; import moment from 'moment'; import Image from 'next/image'; import Link from 'next/link'; import { Fragment, useEffect, useMemo, useRef, useState } from 'react'; import { toast } from 'react-hot-toast'; import { BiSolidCopy } from 'react-icons/bi'; import { BsTrash } from 'react-icons/bs'; import { FaPaperPlane } from 'react-icons/fa'; import { FiEdit } from 'react-icons/fi'; import { IoIosFootball } from 'react-icons/io'; import { useQuery } from 'react-query'; function LiveMatchList() { const [isLoading, setIsLoading] = useState(true); const [deleteModal, setDeleteModal] = useState(false); const [deleteObj, setDeleteObj] = useState({}); const [realData, setRealData] = useState([]); const statusRefs = useRef(null); const handleStatusChange = (e, id) => { statusRefs.current[id].checked = !statusRefs.current[id].checked; console.log(statusRefs.current[id]); }; const { isLoading: isLoading1, data: live_matches, refetch, } = useQuery('live_matches', async () => { const { data } = await turboFootballUrl.post('/api/admin/v1/matches'); return data?.data; }); useEffect(() => { if (!isLoading1) { setRealData(live_matches); } setIsLoading(false); }, [live_matches, isLoading1]); const columns = useMemo( () => [ { id: 'team_one_image', header: 'Team One', columnDefType: 'display', enableColumnOrdering: false, Cell: ({ row }) => ( <div className="flex items-center"> {row?.original?.team_one_image ? ( <Image className="h-12 w-12 rounded-full" src={row?.original?.team_one_image} width={0} height={0} sizes="100vw" alt="Team Image" /> ) : ( <Image src="/default-placeholder.png" width={0} height={0} sizes="100vw" className="h-12 w-12 rounded-full" alt="Image" /> )} <span className="ml-2">{row?.original?.team_one_name}</span> </div> ), }, { id: 'team_two_image', header: 'Team Two', columnDefType: 'display', enableColumnOrdering: false, Cell: ({ row }) => ( <div className="flex items-center"> {row?.original?.team_one_image ? ( <Image className="h-12 w-12 rounded-full" src={row?.original?.team_two_image} width={0} height={0} sizes="100vw" alt="Team Image" /> ) : ( <Image src="/default-placeholder.png" width={0} height={0} sizes="100vw" className="h-12 w-12 rounded-full" alt="Image" /> )} <span className="ml-2">{row?.original?.team_two_name}</span> </div> ), }, { accessorKey: 'title', header: 'Title & Time', mantineTableHeadCellProps: { align: 'center', }, mantineTableBodyCellProps: { align: 'center', }, Cell: ({ row }) => ( <div> <p className="mb-1 text-center text-sm font-medium">{row.original.title}</p> <p className="text-center">{moment(row.original.time).format('MMMM Do YYYY / h:mm')}</p> </div> ), size: 150, }, { accessorKey: 'status', header: 'Status', mantineTableHeadCellProps: { align: 'center', }, mantineTableBodyCellProps: { align: 'center', }, Cell: ({ row }) => { return row.original.status == '1' ? <span className="badge rounded-full bg-success">Active</span> : <span className="badge rounded-full bg-danger">Inactive</span>; // return ( // <div> // <label className="relative h-6 w-12"> // <input // name="is_featured" // type="checkbox" // className="custom_switch peer absolute z-10 h-full w-full cursor-pointer opacity-0" // id="custom_switch_checkbox1" // ref={(el) => (statusRefs.current[row.original.id] = el)} // checked={row.original.status == '1'} // onChange={(e) => handleStatusChange(e, row.original.id)} // /> // <span className="block h-full cursor-pointer rounded-full bg-danger before:absolute before:bottom-1 before:left-1 before:h-4 before:w-4 before:rounded-full before:bg-white before:transition-all before:duration-300 peer-checked:bg-success peer-checked:before:left-7 dark:bg-dark dark:before:bg-white-dark dark:peer-checked:before:bg-white"></span> // </label> // </div> // ); }, }, { id: 'edit', header: 'Action', columnDefType: 'display', enableColumnOrdering: false, Cell: ({ row }) => ( <div> <Dropdown placement="left-start" btnClassName="btn btn-primary btn-sm dropdown-toggle" button={ <> Action <span> <svg className="inline-block h-4 w-4 ltr:ml-1 rtl:mr-1" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M19 9L12 15L5 9" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" /> </svg> </span> </> } > <ul className="mt-2 !min-w-[170px] rounded-md bg-[#ebebeb]"> <li> <Link href={`/admin/notifications/create?title=${row?.original?.team_one_name} vs ${row?.original?.team_two_name}&body=Enjoy Live Match`} className="flex cursor-pointer items-center px-5 py-2 hover:rounded-md hover:bg-[#f0f8ff]" > <FaPaperPlane className="mr-2 text-sm" /> Send Notification </Link> </li> <li> <Link href={`/admin/live_matches/edit/${row.original.id}`} className="flex cursor-pointer items-center px-5 py-2 hover:rounded-md hover:bg-[#f0f8ff]"> <FiEdit className="mr-2 text-sm" /> Edit </Link> </li> <li> <Link href={`/admin/live_matches/clone/${row.original.id}`} className="flex cursor-pointer items-center px-5 py-2 hover:rounded-md hover:bg-[#f0f8ff]"> <BiSolidCopy className="mr-2 text-sm" /> Clone </Link> </li> <li> <div onClick={() => { setDeleteModal(true); setDeleteObj(row.original); }} className="flex cursor-pointer items-center justify-start px-5 py-2 hover:rounded-md hover:bg-[#f0f8ff]" > <BsTrash className="mr-2 text-sm" /> Delete </div> </li> </ul> </Dropdown> </div> ), mantineTableHeadCellProps: { align: 'center', }, mantineTableBodyCellProps: { align: 'center', }, }, ], [] ); const handleConfirmClick = async () => { setIsLoading(true); setDeleteModal(false); try { // Delete from the main panel const { data } = await turboFootballUrl.delete(`api/admin/v1/match/${deleteObj?.unique_id}`); if (data?.status) { setDeleteObj({}); toast.success('Match deleted successfully from the main panel!'); } // Delete from other panels const panelsToDeleteFrom = deleteObj.panel.filter((panel) => panel.status); const axiosPromises = panelsToDeleteFrom.map(async (panel) => { const panelUrl = panel.value + `/api/admin/v1/match/${deleteObj?.unique_id}`; const axiosConfig = { headers: { 'content-type': 'application/json', Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest', api_key: panel.api_key, }, }; try { await axios.delete(panelUrl, axiosConfig); return `Match deleted successfully from ${panel.label} panel!`; } catch (error) { return `Match already deleted from ${panel.label} panel: ${error.message}`; } }); const responses = await Promise.all(axiosPromises); responses.forEach((response) => { toast.success(response); }); refetch(); } catch (error) { console.error('Error deleting match:', error); } setIsLoading(false); }; return ( <div> <div className="col-md-12 bg-light text-right"> <Link href="/admin/live_matches/create" className="btn btn-outline-primary inline cursor-pointer"> Add New Live Match </Link> <div className="mt-10"> {isLoading || isLoading1 ? ( <div className="flex justify-center border-b border-[#f6f6f657] px-10 pt-10"> <div className="animate-bounce"> <IoIosFootball className="animate-spin text-6xl text-blue-400" /> </div> </div> ) : ( <MantineReactTable columns={columns} data={realData || []} enableRowDragging={true} enableRowOrdering={true} defaultDisplayColumn={true} autoResetPageIndex={false} enableSorting={false} mantineRowDragHandleProps={({ table }) => ({ onDragEnd: async () => { const { draggingRow, hoveredRow } = table.getState(); let array = [...realData]; const elementToMove = array.splice(draggingRow.index, 1)[0]; array.splice(hoveredRow.index, 0, elementToMove); const updatedArray = array.map((obj, index) => ({ ...obj, position: index + 1, })); setRealData(updatedArray); await turboFootballUrl.post('/api/admin/v1/sort_matches', updatedArray).then((res) => { if (res?.data?.status) { toast.success('Matches sorted successfully!'); } }); }, })} /> )} </div> <div className="mb-5"> <Transition appear show={deleteModal} as={Fragment}> <Dialog as="div" open={deleteModal} onClose={() => setDeleteModal(false)}> <Transition.Child as={Fragment} enter="ease-out duration-300" enterFrom="opacity-0" enterTo="opacity-100" leave="ease-in duration-200" leaveFrom="opacity-100" leaveTo="opacity-0" > <div className="fixed inset-0" /> </Transition.Child> <div className="fixed inset-0 z-[999] overflow-y-auto bg-[black]/60"> <div className="flex min-h-screen items-center justify-center px-4"> <Transition.Child as={Fragment} enter="ease-out duration-300" enterFrom="opacity-0 scale-95" enterTo="opacity-100 scale-100" leave="ease-in duration-200" leaveFrom="opacity-100 scale-100" leaveTo="opacity-0 scale-95" > <Dialog.Panel as="div" className="panel my-8 w-full max-w-lg overflow-hidden rounded-lg border-0 p-0 text-black dark:text-white-dark"> <div className="flex items-center justify-between bg-[#fbfbfb] px-5 py-3 dark:bg-[#121c2c]"> <h5 className="text-lg font-bold">Delete Confirmation</h5> <button type="button" className="text-white-dark hover:text-dark" onClick={() => setDeleteModal(false)}> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" > <line x1="18" y1="6" x2="6" y2="18"></line> <line x1="6" y1="6" x2="18" y2="18"></line> </svg> </button> </div> <div className="p-5"> <p> You are deleting <span className="font-semibold text-danger">{deleteObj?.title}</span> Live Match and its associated streaming sources! </p> <div className="mt-8 flex items-center justify-end"> <button type="button" className="btn btn-primary" onClick={() => setDeleteModal(false)}> Not Now </button> <button type="button" className="btn btn-outline-danger ltr:ml-4 rtl:mr-4" onClick={handleConfirmClick}> Confirm </button> </div> </div> </Dialog.Panel> </Transition.Child> </div> </div> </Dialog> </Transition> </div> </div> </div> ); } export default LiveMatchList;
Editor is loading...
Leave a Comment