70 lines
3 KiB
TypeScript
70 lines
3 KiB
TypeScript
import { Link } from 'react-router-dom';
|
|
import { Zap, CheckCircle2, AlertCircle } from 'lucide-react';
|
|
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
|
import { useAuthor } from '@/hooks/useAuthor';
|
|
import { isValidLightningAddress, isValidSilentPayment } from '@/lib/types';
|
|
import { useTranslation } from '@/contexts/language';
|
|
|
|
/**
|
|
* Payment-readiness note for provider / Lab / crew forms.
|
|
*
|
|
* Lightning address (lud16) and Bitcoin Silent Payment live on the user's Nostr
|
|
* profile (kind 0), NOT on each individual Lab event — so a single source of
|
|
* truth never goes stale across a person's many profiles. This note simply
|
|
* tells a provider whether that source is set up, and links them to Edit Profile
|
|
* if it isn't, so they always have a clear path to "get paid".
|
|
*/
|
|
export function PaymentReadinessNote() {
|
|
const { t } = useTranslation();
|
|
const { user } = useCurrentUser();
|
|
const author = useAuthor(user?.pubkey || '');
|
|
const metadata = author.data?.metadata;
|
|
|
|
const lud16 = metadata?.lud16;
|
|
const hasLightning = isValidLightningAddress(lud16) || !!metadata?.lud06;
|
|
// Silent payment lives in a custom kind-0 field the app reads elsewhere.
|
|
const rawSp = (metadata as Record<string, unknown> | undefined)?.bitcoin_silent_payment;
|
|
const hasSilentPayment = typeof rawSp === 'string' && isValidSilentPayment(rawSp);
|
|
|
|
if (!user) return null;
|
|
|
|
const ready = hasLightning;
|
|
|
|
return (
|
|
<div
|
|
className={
|
|
ready
|
|
? 'space-y-1.5 rounded-lg border border-green-500/25 bg-green-500/5 p-4'
|
|
: 'space-y-1.5 rounded-lg border border-yellow-500/30 bg-yellow-500/5 p-4'
|
|
}
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<Zap className={ready ? 'h-4 w-4 text-green-400' : 'h-4 w-4 text-yellow-400'} />
|
|
<span className={ready ? 'text-sm font-bold text-green-300' : 'text-sm font-bold text-yellow-300'}>
|
|
{ready ? t('marketUi.paymentReadiness.ready') : t('marketUi.paymentReadiness.notReady')}
|
|
</span>
|
|
</div>
|
|
|
|
{ready ? (
|
|
<p className="flex items-start gap-1.5 text-xs text-gray-400">
|
|
<CheckCircle2 className="mt-0.5 h-3.5 w-3.5 shrink-0 text-green-400" />
|
|
<span>
|
|
{t('marketUi.paymentReadiness.readyBefore')}{lud16 ? <> (<span className="font-mono">{lud16}</span>)</> : ''}{t('marketUi.paymentReadiness.readyAfter')}
|
|
{hasSilentPayment && t('marketUi.paymentReadiness.silentSet')}
|
|
</span>
|
|
</p>
|
|
) : (
|
|
<p className="flex items-start gap-1.5 text-xs text-gray-400">
|
|
<AlertCircle className="mt-0.5 h-3.5 w-3.5 shrink-0 text-yellow-400" />
|
|
<span>
|
|
{t('marketUi.paymentReadiness.notReadyBefore')}{' '}
|
|
<Link to="/settings?section=profile" className="text-yellow-400 underline hover:text-yellow-300">
|
|
{t('marketUi.paymentReadiness.nostrProfile')}
|
|
</Link>{' '}
|
|
{t('marketUi.paymentReadiness.notReadyAfter')}
|
|
</span>
|
|
</p>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|