diff --git a/.gitignore b/.gitignore index ec94a961..d970c548 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ npm-debug.log* .idea/ + +.cursorrules diff --git a/src/components/BitcoinAmountInput.tsx b/src/components/BitcoinAmountInput.tsx index 2fbc1edc..d4f565b0 100644 --- a/src/components/BitcoinAmountInput.tsx +++ b/src/components/BitcoinAmountInput.tsx @@ -152,9 +152,7 @@ const BitcoinAmountInput = forwardRef( inputMode={inputType.inputMode} className={classNames('slashed-zeroes', className)} value={ - inputType.type === 'text' - ? (field.value?.displayValue ?? '') - : String(field.value?.userRawInputValue ?? '') + inputType.type === 'text' ? field.value?.displayValue ?? '' : String(field.value?.userRawInputValue ?? '') } placeholder={placeholder} min={displayInputUnit === 'BTC' ? '0.00000001' : '1'} diff --git a/src/components/Jam.tsx b/src/components/Jam.tsx index 0b567fb9..583d3e3a 100644 --- a/src/components/Jam.tsx +++ b/src/components/Jam.tsx @@ -14,10 +14,13 @@ import ToggleSwitch from './ToggleSwitch' import Sprite from './Sprite' import Balance from './Balance' import ScheduleProgress from './ScheduleProgress' +import ScheduleDetails, { TransformedScheduleEntry } from './ScheduleDetails' import { ConfirmModal, ConfirmModalProps } from './Modal' import FeeConfigModal from './settings/FeeConfigModal' -import { useFeeConfigValues } from '../hooks/Fees' +import Accordion from './Accordion' import styles from './Jam.module.css' +import { Table, Body, Row, Cell } from '@table-library/react-table-library/table' +import { useFeeConfigValues } from '../hooks/Fees' const DEST_ADDRESS_COUNT_PROD = 3 const DEST_ADDRESS_COUNT_TEST = 1 @@ -351,6 +354,15 @@ export default function Jam({ wallet }: JamProps) { }) } + // Add a function to transform the schedule data to include Jar information + const transformScheduleData = useCallback((schedule: Schedule) => { + return schedule.map((item) => ({ + id: item[3], + type: item[4], + jar: item[0], // Assuming item[0] contains the Jar number + })) + }, []) + return ( <> @@ -382,6 +394,9 @@ export default function Jam({ wallet }: JamProps) { >
{t('scheduler.button_stop')}
+ + + )} diff --git a/src/components/ScheduleDetails.module.css b/src/components/ScheduleDetails.module.css new file mode 100644 index 00000000..4e47bfef --- /dev/null +++ b/src/components/ScheduleDetails.module.css @@ -0,0 +1,45 @@ +.scheduleDetails { + background-color: var(--background-color); + border-radius: 8px; + padding: 16px; + margin-bottom: 16px; + color: var(--text-color); +} + +.scheduleDetailsTitle { + font-size: 18px; + font-weight: bold; + color: var(--text-color); + margin-bottom: 16px; +} + +.scheduleDetailsHeader { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 12px; +} + +.scheduleItem { + display: flex; + justify-content: space-between; + padding: 8px 0; + border-bottom: 1px solid var(--border-color); +} + +.scheduleItem:last-child { + border-bottom: none; +} + +.scheduleItemLabel { + font-weight: 500; + color: var(--secondary-text-color); +} + +.scheduleItemValue { + color: var(--text-color); +} + +.statusIcon { + fill: currentColor; +} diff --git a/src/components/ScheduleDetails.tsx b/src/components/ScheduleDetails.tsx new file mode 100644 index 00000000..76b3644d --- /dev/null +++ b/src/components/ScheduleDetails.tsx @@ -0,0 +1,95 @@ +import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table' +import { useTheme } from '@table-library/react-table-library/theme' +import { Schedule } from '../context/ServiceInfoContext' +import { useSettings } from '../context/SettingsContext' +import Sprite from './Sprite' + +import styles from './ScheduleDetails.module.css' + +export interface TransformedScheduleEntry { + id: string + type: number + jar: number +} + +interface ScheduleDetailsProps { + schedule: TransformedScheduleEntry[] +} + +export default function ScheduleDetails({ schedule }: ScheduleDetailsProps) { + const settings = useSettings() + + const theme = { + backgroundColor: settings.theme === 'dark' ? '#333' : '#fff', + alternateBackgroundColor: settings.theme === 'dark' ? '#444' : '#f5f5f5', + textColor: settings.theme === 'dark' ? '#fff' : '#000', + } + + const tableTheme = useTheme({ + Table: ` + --data-table-library_grid-template-columns: repeat(3, 1fr); + `, + HeaderRow: ` + background-color: ${theme.backgroundColor}; + `, + Row: ` + &:nth-of-type(odd) { + background-color: ${theme.alternateBackgroundColor}; + } + `, + Cell: ` + padding: 8px; + color: ${theme.textColor}; + `, + }) + + const data = { + nodes: schedule.map((item, index) => ({ id: index, idValue: item.id, type: item.type, jar: item.jar })), + } + + const getJarLabel = (jarNumber: number) => { + return String.fromCharCode(65 + jarNumber) // 65 is ASCII for 'A' + } + + const getStatusIcon = (type: number) => { + if (type === 2) { + // Assuming type 2 means completed + return + } + return null + } + + if (!schedule || schedule.length === 0) { + return
No schedule available
+ } + + return ( +
+

Schedule Details

+ + {(tableList: any) => ( + <> +
+ + Id + Type + Jar + Status + +
+ + {tableList.map((item: any) => ( + + {item.idValue} + {item.type} + Jar {getJarLabel(item.jar)} + {getStatusIcon(item.type)} + + ))} + + + )} +
+
+ ) +} diff --git a/src/components/Send/SendForm.tsx b/src/components/Send/SendForm.tsx index 5d866a05..5d051b7e 100644 --- a/src/components/Send/SendForm.tsx +++ b/src/components/Send/SendForm.tsx @@ -67,7 +67,7 @@ function CollaborativeTransactionOptions({ amount: selectedAmount?.isSweep && sourceJarBalance ? sourceJarBalance.calculatedAvailableBalanceInSats - : (selectedAmount?.value ?? null), + : selectedAmount?.value ?? null, numCollaborators: selectedNumCollaborators ?? null, isCoinjoin: true, }) @@ -134,8 +134,8 @@ function CollaborativeTransactionOptions({ numCollaborators={selectedNumCollaborators ?? null} amount={ selectedAmount?.isSweep - ? (sourceJarBalance?.calculatedAvailableBalanceInSats ?? null) - : (selectedAmount?.value ?? null) + ? sourceJarBalance?.calculatedAvailableBalanceInSats ?? null + : selectedAmount?.value ?? null } onClick={() => { setActiveFeeConfigModalSection('cj_fee') diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index fbb7a2d7..5b338259 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -644,6 +644,7 @@ "progress_description": "This estimate is the minimum waiting time. Additional delays due to network communication or transaction confirmation are not considered.", "progress_current_state": "Waiting for transaction <1>{{ current }} of <3>{{ total }} to process...", "progress_done": "All transactions completed successfully. The scheduler will stop soon.", + "details": "Schedule Details", "precondition": { "hint_missing_utxos": "To run the scheduler you need UTXOs with {{ minConfirmations }} or more confirmations. $t(scheduler.precondition.nested_hint_fund_wallet, {\"count\": {{ minConfirmations }} })", "hint_missing_confirmations": "The scheduler requires your UTXOs to have {{ minConfirmations }} or more confirmations. $t(scheduler.precondition.nested_hint_wait_for_block, {\"count\": {{ amountOfMissingConfirmations }} })",