import { useState, useEffect, useRef } from 'react'
import { api } from '../api'
function KeyList({ keys, label, color }) {
if (!keys || keys.length === 0) return null
return (
Select a source first.
return (
Import — {source}
{/* Stats */}
{stats && (
{[
{ label: 'Total records', value: stats.total_records },
{ label: 'Transformed', value: stats.transformed_records },
{ label: 'Pending', value: stats.pending_records },
].map(({ label, value }) => (
))}
)}
{/* SimpleFIN sync — only for sources with a bridge account in their config */}
{simplefin?.account_id && (
SimpleFIN
{simplefin.account_id}
)}
{/* Drop zone */}
{ e.preventDefault(); setDragOver(true) }}
onDragLeave={() => setDragOver(false)}
onDrop={e => { e.preventDefault(); setDragOver(false); handleImport(e.dataTransfer.files[0]) }}
onClick={() => fileRef.current?.click()}
>
handleImport(e.target.files[0])}
/>
{loading
?
Importing…
:
Drop a CSV file here, or click to browse
}
{error &&
{error}
}
{result && (
{result.success === false ? (
<>
{result.error}
{result.duplicate_rows && (
Offending rows:
{result.duplicate_rows.map((row, i) => (
{Object.entries(row).map(([f, v]) => `${f}: ${v}`).join(' · ')}
))}
)}
>
) : result.imported !== undefined ? (
<>
{result.errors?.length > 0 && (
{result.errors.map((e, i) =>
Bridge: {e}
)}
)}
{result.fetched !== undefined && (
<>
{result.fetched} fetched
·
>
)}
{result.imported} imported
·
{result.duplicates} duplicates skipped
{result.transform && (
<>
·
{result.transform.transformed} transformed
>
)}
>
) : (
{result.transformed} records transformed
)}
)}
{/* Action buttons */}
{stats && Number(stats.pending_records) > 0 && (
)}
{stats && Number(stats.total_records) > 0 && (
)}
{/* Import log */}
{log.length > 0 && (
Import history
{selected.size > 0 && (
)}
|
ID |
Date |
Imported |
Duplicates |
|
{log.map(entry => (
toggleSelect(entry.id)}
/>
))}
)}
)
}