74 lines
2.6 KiB
TypeScript
74 lines
2.6 KiB
TypeScript
import { t } from '@/lib/i18n'
|
||
import type { SyncProgress } from './types'
|
||
|
||
export function SyncErrorBanner(params: { error: string | null; onDismiss: () => void }): React.ReactElement | null {
|
||
if (!params.error) {
|
||
return null
|
||
}
|
||
return (
|
||
<div className="mb-4 bg-red-900/30 border border-red-500/50 rounded p-3 text-red-300 text-sm">
|
||
{params.error}
|
||
<button type="button" onClick={params.onDismiss} className="ml-2 text-red-400 hover:text-red-200">
|
||
×
|
||
</button>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export function SyncResyncButton(params: { isSyncing: boolean; onClick: () => void }): React.ReactElement | null {
|
||
if (params.isSyncing) {
|
||
return null
|
||
}
|
||
return (
|
||
<button
|
||
type="button"
|
||
onClick={params.onClick}
|
||
className="px-3 py-1 text-xs bg-neon-cyan/20 hover:bg-neon-cyan/30 text-neon-cyan rounded border border-neon-cyan/50 hover:border-neon-cyan transition-colors"
|
||
>
|
||
{t('settings.sync.resync')}
|
||
</button>
|
||
)
|
||
}
|
||
|
||
export function SyncDateRange(params: { totalDays: number; startDate: string; endDate: string }): React.ReactElement | null {
|
||
if (params.totalDays <= 0) {
|
||
return null
|
||
}
|
||
return (
|
||
<div className="mb-2">
|
||
<p className="text-sm text-cyber-accent">
|
||
{t('settings.sync.daysRange', { startDate: params.startDate, endDate: params.endDate, days: params.totalDays })}
|
||
</p>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export function SyncProgressSection(params: { isSyncing: boolean; syncProgress: SyncProgress; progressPercentage: number }): React.ReactElement | null {
|
||
if (!params.isSyncing || !params.syncProgress) {
|
||
return null
|
||
}
|
||
return (
|
||
<div className="space-y-2">
|
||
<div className="flex items-center justify-between text-sm">
|
||
<span className="text-cyber-accent">
|
||
{t('settings.sync.progress', { current: params.syncProgress.currentStep, total: params.syncProgress.totalSteps })}
|
||
</span>
|
||
<span className="text-neon-cyan font-semibold">{Math.round(params.progressPercentage)}%</span>
|
||
</div>
|
||
<div className="w-full bg-cyber-dark rounded-full h-2 overflow-hidden">
|
||
<div className="bg-neon-cyan h-full transition-all duration-300" style={{ width: `${params.progressPercentage}%` }} />
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export function SyncStatusMessage(params: { isSyncing: boolean; totalDays: number; isRecentlySynced: boolean }): React.ReactElement | null {
|
||
if (params.isSyncing || params.totalDays !== 0) {
|
||
return null
|
||
}
|
||
if (params.isRecentlySynced) {
|
||
return <p className="text-sm text-green-400">{t('settings.sync.completed')}</p>
|
||
}
|
||
return <p className="text-sm text-cyber-accent">{t('settings.sync.ready')}</p>
|
||
}
|