import React, { useEffect, useState, useRef } from 'react'; import axios from 'axios'; import { useToast } from '@/hooks/useToast'; import { Tag } from 'primereact/tag'; import Image from 'next/image'; import { useRouter } from 'next/router'; import ResourcePaymentButton from '@/components/bitcoinConnect/ResourcePaymentButton'; import ZapDisplay from '@/components/zaps/ZapDisplay'; import GenericButton from '@/components/buttons/GenericButton'; import { useImageProxy } from '@/hooks/useImageProxy'; import { useZapsSubscription } from '@/hooks/nostrQueries/zaps/useZapsSubscription'; import { getTotalFromZaps } from '@/utils/lightning'; import { useSession } from 'next-auth/react'; import useWindowWidth from '@/hooks/useWindowWidth'; import dynamic from 'next/dynamic'; import { Toast } from 'primereact/toast'; import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu'; const MDDisplay = dynamic(() => import('@uiw/react-markdown-preview'), { ssr: false }); const CombinedDetails = ({ processedEvent, topics, title, summary, image, price, author, paidResource, decryptedContent, nAddress, handlePaymentSuccess, handlePaymentError, authorView, isLesson, }) => { const [zapAmount, setZapAmount] = useState(0); const [course, setCourse] = useState(null); const router = useRouter(); const { returnImageProxy } = useImageProxy(); const { zaps, zapsLoading } = useZapsSubscription({ event: processedEvent }); const { data: session } = useSession(); const { showToast } = useToast(); const windowWidth = useWindowWidth(); const isMobileView = windowWidth <= 768; const menuRef = useRef(null); const toastRef = useRef(null); const handleDelete = async () => { try { const response = await axios.delete(`/api/resources/${processedEvent.d}`); if (response.status === 204) { showToast('success', 'Success', 'Resource deleted successfully.'); router.push('/'); } } catch (error) { if (error.response?.data?.error?.includes('Invalid `prisma.resource.delete()`')) { showToast( 'error', 'Error', 'Resource cannot be deleted because it is part of a course, delete the course first.' ); } else { showToast('error', 'Error', 'Failed to delete resource. Please try again.'); } } }; const authorMenuItems = [ { label: 'Edit', icon: 'pi pi-pencil', command: () => router.push(`/details/${processedEvent.id}/edit`), }, { label: 'Delete', icon: 'pi pi-trash', command: handleDelete, }, { label: 'View Nostr note', icon: 'pi pi-globe', command: () => { window.open(`https://habla.news/a/${nAddress}`, '_blank'); }, }, ]; const userMenuItems = [ { label: 'View Nostr note', icon: 'pi pi-globe', command: () => { window.open(`https://habla.news/a/${nAddress}`, '_blank'); }, }, ]; if (course) { userMenuItems.unshift({ label: isMobileView ? 'Course' : 'Open Course', icon: 'pi pi-external-link', command: () => window.open(`/course/${course}`, '_blank'), }); } useEffect(() => { if (isLesson) { axios .get(`/api/resources/${processedEvent.d}`) .then(res => { if (res.data && res.data.lessons[0]?.courseId) { setCourse(res.data.lessons[0]?.courseId); } }) .catch(err => { console.error('err', err); }); } }, [processedEvent.d, isLesson]); useEffect(() => { if (zaps.length > 0) { const total = getTotalFromZaps(zaps, processedEvent); setZapAmount(total); } }, [zaps, processedEvent]); const renderPaymentMessage = () => { if (session?.user?.role?.subscribed && decryptedContent) { return ( ); } if ( isLesson && course && session?.user?.purchased?.some(purchase => purchase.courseId === course) ) { const coursePurchase = session?.user?.purchased?.find( purchase => purchase.courseId === course ); return ( ); } if ( paidResource && decryptedContent && author && processedEvent?.pubkey !== session?.user?.pubkey && !session?.user?.role?.subscribed ) { return ( ); } if (paidResource && author && processedEvent?.pubkey === session?.user?.pubkey) { return ( ); } return null; }; const renderContent = () => { if (decryptedContent) { return ; } if (paidResource && !decryptedContent) { return (

This content is paid and needs to be purchased before viewing.

); } if (processedEvent?.content) { return ; } return null; }; return (
background image

{title}

{topics?.map((topic, index) => ( ))} {isLesson && }
{summary?.split('\n').map((line, index) => (

{line}

))}
{renderPaymentMessage()}
{renderContent()}
); }; export default CombinedDetails;