import { useState, useEffect } from 'react' import { useParams, useNavigate, Link } from 'react-router-dom' import { motion } from 'framer-motion' import { format } from 'date-fns' import toast from 'react-hot-toast' import { ArrowLeftIcon, ClipboardIcon, ArrowTopRightOnSquareIcon, PencilIcon, ArchiveBoxIcon, ChartBarIcon, CheckIcon, } from '@heroicons/react/24/outline' import { paywallsApi } from '../../services/api' export default function PaywallDetail() { const { id } = useParams() const navigate = useNavigate() const [paywall, setPaywall] = useState(null) const [stats, setStats] = useState(null) const [embedCode, setEmbedCode] = useState(null) const [isLoading, setIsLoading] = useState(true) const [isSaving, setIsSaving] = useState(false) const [activeTab, setActiveTab] = useState('overview') const [editData, setEditData] = useState({}) useEffect(() => { fetchPaywall() fetchEmbed() }, [id]) const fetchPaywall = async () => { try { const response = await paywallsApi.get(id) setPaywall(response.data.paywall) setStats(response.data.stats) setEditData({ title: response.data.paywall.title || '', description: response.data.paywall.description || '', priceSats: response.data.paywall.priceSats || 100, originalUrl: response.data.paywall.originalUrl || '', accessExpirySeconds: response.data.paywall.accessExpirySeconds || null, maxDevices: response.data.paywall.maxDevices || 3, allowEmbed: response.data.paywall.allowEmbed ?? true, customSuccessMessage: response.data.paywall.customSuccessMessage || '', slug: response.data.paywall.slug || '', }) } catch (error) { console.error('Error fetching paywall:', error) toast.error('Failed to load paywall') } finally { setIsLoading(false) } } const handleEditChange = (e) => { const { name, value, type, checked } = e.target setEditData(prev => ({ ...prev, [name]: type === 'checkbox' ? checked : (type === 'number' ? (value === '' ? null : parseInt(value)) : value) })) } const handleSaveSettings = async (e) => { e.preventDefault() setIsSaving(true) try { const updateData = { ...editData, priceSats: parseInt(editData.priceSats), accessExpirySeconds: editData.accessExpirySeconds ? parseInt(editData.accessExpirySeconds) : null, maxDevices: parseInt(editData.maxDevices), } const response = await paywallsApi.update(id, updateData) setPaywall(response.data.paywall) toast.success('Paywall updated successfully!') } catch (error) { console.error('Error updating paywall:', error) toast.error(error.response?.data?.error || 'Failed to update paywall') } finally { setIsSaving(false) } } const fetchEmbed = async () => { try { const response = await paywallsApi.getEmbed(id) setEmbedCode(response.data) } catch (error) { console.error('Error fetching embed:', error) } } const handleCopy = (text, label) => { navigator.clipboard.writeText(text) toast.success(`${label} copied!`) } const handleArchive = async () => { try { await paywallsApi.archive(id) toast.success('Paywall archived') navigate('/dashboard/paywalls') } catch (error) { toast.error('Failed to archive paywall') } } if (isLoading) { return (
) } if (!paywall) { return (

Paywall not found

Back to paywalls
) } const paywallUrl = embedCode?.link || `${window.location.origin}/p/${paywall.slug || paywall.id}` return (
{/* Header */}

{paywall.title}

{paywall.description}

Preview
{/* Stats */}

Price

⚡ {paywall.priceSats.toLocaleString()}

Total Sales

{stats?.salesCount || 0}

Total Revenue

⚡ {(stats?.totalRevenue || 0).toLocaleString()}

Status

{paywall.status}

{/* Tabs */}
{['overview', 'embed', 'settings'].map((tab) => ( ))}
{/* Tab content */} {activeTab === 'overview' && (
{/* Preview */}
{paywall.coverImageUrl ? ( ) : (
)}

{paywall.title}

{paywall.description}

⚡ {paywall.priceSats.toLocaleString()} sats {paywall.accessExpirySeconds ? `${Math.round(paywall.accessExpirySeconds / 86400)} day access` : 'Lifetime access'}
{/* Quick links */}

Share Link

Details

Created
{format(new Date(paywall.createdAt), 'MMM d, yyyy')}
Max Devices
{paywall.maxDevices}
Content Type
{paywall.originalUrlType}
Allow Embed
{paywall.allowEmbed ? 'Yes' : 'No'}
)} {activeTab === 'embed' && embedCode && (

Iframe Embed

Add this code to your website to embed the paywall directly.

                  {embedCode.iframe}
                

Button Embed

Add a button that opens a checkout modal when clicked.

                  {embedCode.button}
                

Direct Link

Share this link directly or use it in your own custom integration.

)} {activeTab === 'settings' && (

Basic Settings