atom-deploy/src/components/StatusDisplay.tsx
2025-05-05 16:47:39 -04:00

148 lines
5.0 KiB
TypeScript

'use client';
interface StatusDisplayProps {
status: 'idle' | 'verifying' | 'creating' | 'success' | 'error';
txHash?: string;
recordId?: string;
appRecordId?: string;
lrn?: string;
dns?: string;
appName?: string;
repoUrl?: string;
commitHash?: string;
shortCommitHash?: string;
error?: string;
}
export default function StatusDisplay({
status,
txHash,
recordId,
appRecordId,
lrn,
dns,
appName,
repoUrl,
commitHash,
shortCommitHash,
error,
}: StatusDisplayProps) {
// Get domain suffix from environment variable
const domainSuffix = process.env.NEXT_PUBLIC_DOMAIN_SUFFIX || '';
if (status === 'idle') return null;
const StatusBadge = ({ type }: { type: 'verifying' | 'creating' | 'success' | 'error' }) => {
const getBadgeStyles = () => {
switch (type) {
case 'verifying':
case 'creating':
return {
bg: 'var(--warning-light)',
color: 'var(--warning)',
text: type === 'verifying' ? 'Verifying' : 'Creating Record'
};
case 'success':
return {
bg: 'var(--success-light)',
color: 'var(--success)',
text: 'Success'
};
case 'error':
return {
bg: 'var(--error-light)',
color: 'var(--error)',
text: 'Error'
};
}
};
const styles = getBadgeStyles();
return (
<span className="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold"
style={{ backgroundColor: styles.bg, color: styles.color }}>
{styles.text}
</span>
);
};
const InfoItem = ({ label, value }: { label: string, value: string }) => (
<div className="mb-3 border rounded-md overflow-hidden" style={{ borderColor: 'var(--card-border)' }}>
<div className="px-3 py-2 text-xs font-semibold" style={{ background: 'var(--muted-light)' }}>
{label}
</div>
<div className="px-3 py-2 text-sm font-mono break-all bg-opacity-50" style={{ background: 'var(--card-bg)' }}>
{value}
</div>
</div>
);
return (
<div>
<div className="flex items-center justify-between mb-4">
{(status === 'verifying' || status === 'creating') && (
<div className="flex items-center">
<StatusBadge type={status} />
<div className="ml-3 flex items-center">
<svg className="animate-spin mr-2 h-4 w-4" style={{ color: 'var(--warning)' }} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
<span style={{ color: 'var(--warning)' }}>
{status === 'verifying' ? 'Verifying transaction...' : 'Creating Laconic Registry record...'}
</span>
</div>
</div>
)}
{status === 'success' && (
<div className="flex items-center">
<StatusBadge type="success" />
<span className="ml-3" style={{ color: 'var(--success)' }}>Successfully deployed!</span>
</div>
)}
{status === 'error' && (
<div className="flex items-center">
<StatusBadge type="error" />
<span className="ml-3" style={{ color: 'var(--error)' }}>Deployment Failed</span>
</div>
)}
</div>
{status === 'success' && (
<div className="mt-4">
{appName && (
<div className="mb-6 p-4 rounded-md" style={{ backgroundColor: 'var(--success-light)', color: 'var(--success)' }}>
<h3 className="font-semibold mb-2 text-lg">
Successfully deployed
{appName && <span> {appName}</span>}
</h3>
{repoUrl && (
<p className="mb-1 text-sm">
<span className="font-medium">Repository:</span> {repoUrl}
</p>
)}
</div>
)}
{txHash && <InfoItem label="ATOM Payment Transaction Hash" value={txHash} />}
{appRecordId && <InfoItem label="Laconic Application Record ID" value={appRecordId} />}
{recordId && <InfoItem label="Laconic Deployment Request Record ID" value={recordId} />}
{lrn && <InfoItem label="Laconic Resource Name (LRN)" value={lrn} />}
{dns && <InfoItem label="Deployment DNS" value={domainSuffix ? `${dns}${domainSuffix}` : dns} />}
</div>
)}
{status === 'error' && (
<div className="mt-4">
<div className="p-3 rounded-md mb-4" style={{ backgroundColor: 'var(--error-light)', color: 'var(--error)' }}>
{error || 'An unknown error occurred'}
</div>
{txHash && <InfoItem label="Transaction Hash" value={txHash} />}
</div>
)}
</div>
);
}