105 lines
3.5 KiB
TypeScript
105 lines
3.5 KiB
TypeScript
import { useRouter } from 'next/router'
|
|
import Head from 'next/head'
|
|
import { useEffect, useState } from 'react'
|
|
import { getReviewTipById } from '@/lib/reviewTipQueries'
|
|
import type { ReviewTip } from '@/types/nostr'
|
|
import { PageHeader } from '@/components/PageHeader'
|
|
import { Footer } from '@/components/Footer'
|
|
import { t } from '@/lib/i18n'
|
|
|
|
export default function ReviewTipPage(): React.ReactElement | null {
|
|
const router = useRouter()
|
|
const { id } = router.query
|
|
const reviewTipId = typeof id === 'string' ? id : ''
|
|
const [reviewTip, setReviewTip] = useState<ReviewTip | null>(null)
|
|
const [loading, setLoading] = useState(true)
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
useEffect(() => {
|
|
if (!reviewTipId) {
|
|
return
|
|
}
|
|
void loadReviewTip({ reviewTipId, setReviewTip, setLoading, setError })
|
|
}, [reviewTipId])
|
|
|
|
if (!reviewTipId) {
|
|
return null
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Head>
|
|
<title>Remerciement d'avis - zapwall.fr</title>
|
|
</Head>
|
|
<main className="min-h-screen bg-cyber-darker">
|
|
<PageHeader />
|
|
<div className="w-full px-4 py-8">
|
|
{loading && <p className="text-sm text-cyber-accent">{t('common.loading')}</p>}
|
|
{error && <p className="text-sm text-red-400">{error}</p>}
|
|
{reviewTip && (
|
|
<div className="bg-cyber-darker border border-neon-cyan/30 rounded-lg p-6 space-y-4">
|
|
<h1 className="text-3xl font-bold text-neon-cyan">Remerciement d'avis</h1>
|
|
<ReviewTipDetails reviewTip={reviewTip} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
<Footer />
|
|
</main>
|
|
</>
|
|
)
|
|
}
|
|
|
|
async function loadReviewTip(params: {
|
|
reviewTipId: string
|
|
setReviewTip: (value: ReviewTip | null) => void
|
|
setLoading: (value: boolean) => void
|
|
setError: (value: string | null) => void
|
|
}): Promise<void> {
|
|
params.setLoading(true)
|
|
params.setError(null)
|
|
try {
|
|
const rt = await getReviewTipById(params.reviewTipId)
|
|
if (!rt) {
|
|
params.setError('Remerciement introuvable')
|
|
return
|
|
}
|
|
params.setReviewTip(rt)
|
|
} catch (e) {
|
|
params.setError(e instanceof Error ? e.message : 'Erreur lors du chargement du remerciement')
|
|
} finally {
|
|
params.setLoading(false)
|
|
}
|
|
}
|
|
|
|
function ReviewTipDetails(params: { reviewTip: ReviewTip }): React.ReactElement {
|
|
const {reviewTip} = params
|
|
return (
|
|
<div className="space-y-2">
|
|
<p className="text-cyber-accent">
|
|
<span className="font-semibold">Montant :</span> {reviewTip.amount} sats
|
|
</p>
|
|
<p className="text-cyber-accent">
|
|
<span className="font-semibold">Article ID :</span> {reviewTip.articleId}
|
|
</p>
|
|
<p className="text-cyber-accent">
|
|
<span className="font-semibold">Avis ID :</span> {reviewTip.reviewId}
|
|
</p>
|
|
<p className="text-cyber-accent">
|
|
<span className="font-semibold">Auteur :</span> {reviewTip.authorPubkey.substring(0, 16)}...
|
|
</p>
|
|
<p className="text-cyber-accent">
|
|
<span className="font-semibold">Critique :</span> {reviewTip.reviewerPubkey.substring(0, 16)}...
|
|
</p>
|
|
<p className="text-cyber-accent">
|
|
<span className="font-semibold">Payeur :</span> {reviewTip.payerPubkey.substring(0, 16)}...
|
|
</p>
|
|
<p className="text-cyber-accent">
|
|
<span className="font-semibold">Hash de paiement :</span> {reviewTip.paymentHash}
|
|
</p>
|
|
<p className="text-cyber-accent">
|
|
<span className="font-semibold">Date :</span> {new Date(reviewTip.createdAt * 1000).toLocaleString()}
|
|
</p>
|
|
</div>
|
|
)
|
|
}
|