import React, { useEffect, useState } from 'react'; import axios from 'axios'; import { useRouter } from 'next/router'; import { parseEvent, findKind0Fields } from '@/utils/nostr'; import { Button } from 'primereact/button'; import { nip19, nip04 } from 'nostr-tools'; import { useSession } from 'next-auth/react'; import dynamic from 'next/dynamic'; import ZapThreadsWrapper from '@/components/ZapThreadsWrapper'; import { useToast } from '@/hooks/useToast'; import { useNDKContext } from '@/context/NDKContext'; import ResourceDetails from '@/components/content/resources/ResourceDetails'; import 'primeicons/primeicons.css'; const MDDisplay = dynamic( () => import("@uiw/react-markdown-preview"), { ssr: false, } ); const privkey = process.env.NEXT_PUBLIC_APP_PRIV_KEY; const pubkey = process.env.NEXT_PUBLIC_APP_PUBLIC_KEY; export default function Details() { const [event, setEvent] = useState(null); const [processedEvent, setProcessedEvent] = useState({}); const [author, setAuthor] = useState(null); const [nAddress, setNAddress] = useState(null); const [paidResource, setPaidResource] = useState(false); const [decryptedContent, setDecryptedContent] = useState(null); const [authorView, setAuthorView] = useState(false); const {ndk, addSigner} = useNDKContext(); const { data: session, update } = useSession(); const [user, setUser] = useState(null); const { showToast } = useToast(); const router = useRouter(); useEffect(() => { if (session) { setUser(session.user); } }, [session]); useEffect(() => { if (processedEvent.price) { setPaidResource(true); } }, [processedEvent]); useEffect(() => { const decryptContent = async () => { if (user && paidResource) { if (user?.purchased?.length > 0) { const purchasedResource = user?.purchased.find(purchase => purchase.resourceId === processedEvent.d); if (purchasedResource) { console.log("purchasedResource", purchasedResource) const decryptedContent = await nip04.decrypt(privkey, pubkey, processedEvent.content); setDecryptedContent(decryptedContent); } } else if (user?.role && user?.role.subscribed) { // decrypt the content const decryptedContent = await nip04.decrypt(privkey, pubkey, processedEvent.content); setDecryptedContent(decryptedContent); } } } decryptContent(); }, [user, paidResource, processedEvent]); useEffect(() => { if (router.isReady) { const { slug } = router.query; const fetchEvent = async (slug) => { try { await ndk.connect(); const filter = { ids: [slug] } const event = await ndk.fetchEvent(filter); if (event) { setEvent(event); if (user && user.pubkey === event.pubkey) { setAuthorView(true); } } } catch (error) { console.error('Error fetching event:', error); } }; if (ndk) { fetchEvent(slug); } } }, [router.isReady, router.query, ndk, user]); useEffect(() => { const fetchAuthor = async (pubkey) => { try { await ndk.connect(); const filter = { kinds: [0], authors: [pubkey] } const author = await ndk.fetchEvent(filter); if (author) { const fields = await findKind0Fields(JSON.parse(author.content)); console.log("fields", fields); setAuthor(fields); } } catch (error) { console.error('Error fetching author:', error); } } if (event && ndk) { fetchAuthor(event.pubkey); } }, [ndk, event]); useEffect(() => { if (event) { const parsedEvent = parseEvent(event); setProcessedEvent(parsedEvent); } }, [event]); useEffect(() => { if (processedEvent?.d) { const naddr = nip19.naddrEncode({ pubkey: processedEvent.pubkey, kind: processedEvent.kind, identifier: processedEvent.d, }); setNAddress(naddr); } }, [processedEvent]); 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 && error.response.data && 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 if (error.response && error.response.data && error.response.data.error) { showToast('error', 'Error', error.response.data.error); } else { showToast('error', 'Error', 'Failed to delete resource. Please try again.'); } } } const handlePaymentSuccess = async (response, newResource) => { if (response && response?.preimage) { console.log("newResource", newResource); const updated = await update(); console.log("session after update", updated); } else { showToast('error', 'Error', 'Failed to purchase resource. Please try again.'); } } const handlePaymentError = (error) => { showToast('error', 'Payment Error', `Failed to purchase resource. Please try again. Error: ${error}`); } 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 (
{authorView && (
)} {typeof window !== 'undefined' && nAddress !== null && (
)}
{renderContent()}
); }