fix: replace toast.promise with await to ensure state refresh after API calls

sonner's toast.promise() returns a toast ID (not a Promise), so
await resolves immediately and subsequent data refresh fetches stale
data. Users had to manually reload to see changes.

Fixed across AITradersPage, SettingsPage, and TraderConfigModal.
This commit is contained in:
shinchan-zhai
2026-03-21 00:54:36 +08:00
parent 58236ba8b5
commit 53ac52562f
3 changed files with 32 additions and 80 deletions

View File

@@ -211,11 +211,8 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
return return
} }
await toast.promise(api.createTrader(data), { await api.createTrader(data)
loading: t('aiTradersToast.creating', language), toast.success(t('aiTradersToast.created', language))
success: t('aiTradersToast.created', language),
error: t('aiTradersToast.createFailed', language),
})
setShowCreateModal(false) setShowCreateModal(false)
await mutateTraders() await mutateTraders()
} catch (error) { } catch (error) {
@@ -268,11 +265,8 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
console.log('🔥 handleSaveEditTrader - data.strategy_id:', data.strategy_id) console.log('🔥 handleSaveEditTrader - data.strategy_id:', data.strategy_id)
console.log('🔥 handleSaveEditTrader - request:', request) console.log('🔥 handleSaveEditTrader - request:', request)
await toast.promise(api.updateTrader(editingTrader.trader_id, request), { await api.updateTrader(editingTrader.trader_id, request)
loading: t('aiTradersToast.saving', language), toast.success(t('aiTradersToast.saved', language))
success: t('aiTradersToast.saved', language),
error: t('aiTradersToast.saveFailed', language),
})
setShowEditModal(false) setShowEditModal(false)
setEditingTrader(null) setEditingTrader(null)
await mutateTraders() await mutateTraders()
@@ -289,11 +283,8 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
} }
try { try {
await toast.promise(api.deleteTrader(traderId), { await api.deleteTrader(traderId)
loading: t('aiTradersToast.deleting', language), toast.success(t('aiTradersToast.deleted', language))
success: t('aiTradersToast.deleted', language),
error: t('aiTradersToast.deleteFailed', language),
})
await mutateTraders() await mutateTraders()
} catch (error) { } catch (error) {
@@ -305,17 +296,11 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
const handleToggleTrader = async (traderId: string, running: boolean) => { const handleToggleTrader = async (traderId: string, running: boolean) => {
try { try {
if (running) { if (running) {
await toast.promise(api.stopTrader(traderId), { await api.stopTrader(traderId)
loading: t('aiTradersToast.stopping', language), toast.success(t('aiTradersToast.stopped', language))
success: t('aiTradersToast.stopped', language),
error: t('aiTradersToast.stopFailed', language),
})
} else { } else {
await toast.promise(api.startTrader(traderId), { await api.startTrader(traderId)
loading: t('aiTradersToast.starting', language), toast.success(t('aiTradersToast.started', language))
success: t('aiTradersToast.started', language),
error: t('aiTradersToast.startFailed', language),
})
} }
await mutateTraders() await mutateTraders()
@@ -328,11 +313,8 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
const handleToggleCompetition = async (traderId: string, currentShowInCompetition: boolean) => { const handleToggleCompetition = async (traderId: string, currentShowInCompetition: boolean) => {
try { try {
const newValue = !currentShowInCompetition const newValue = !currentShowInCompetition
await toast.promise(api.toggleCompetition(traderId, newValue), { await api.toggleCompetition(traderId, newValue)
loading: t('aiTradersToast.updating', language), toast.success(newValue ? t('aiTradersToast.showInCompetition', language) : t('aiTradersToast.hideInCompetition', language))
success: newValue ? t('aiTradersToast.showInCompetition', language) : t('aiTradersToast.hideInCompetition', language),
error: t('aiTradersToast.updateFailed', language),
})
await mutateTraders() await mutateTraders()
} catch (error) { } catch (error) {
@@ -392,11 +374,8 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
) || [] ) || []
const request = config.buildRequest(updatedItems) const request = config.buildRequest(updatedItems)
await toast.promise(config.updateApi(request), { await config.updateApi(request)
loading: t('aiTradersToast.updatingConfig', language), toast.success(t('aiTradersToast.configUpdated', language))
success: t('aiTradersToast.configUpdated', language),
error: t('aiTradersToast.configUpdateFailed', language),
})
const refreshedItems = await config.refreshApi() const refreshedItems = await config.refreshApi()
config.setItems(refreshedItems) config.setItems(refreshedItems)
@@ -505,11 +484,8 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
), ),
} }
await toast.promise(api.updateModelConfigs(request), { await api.updateModelConfigs(request)
loading: t('aiTradersToast.updatingModelConfig', language), toast.success(t('aiTradersToast.modelConfigUpdated', language))
success: t('aiTradersToast.modelConfigUpdated', language),
error: t('aiTradersToast.modelConfigUpdateFailed', language),
})
const refreshedModels = await api.getModelConfigs() const refreshedModels = await api.getModelConfigs()
setAllModels(refreshedModels) setAllModels(refreshedModels)
@@ -535,11 +511,8 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
if (!ok) return if (!ok) return
try { try {
await toast.promise(api.deleteExchange(exchangeId), { await api.deleteExchange(exchangeId)
loading: t('aiTradersToast.deletingExchange', language), toast.success(t('aiTradersToast.exchangeDeleted', language))
success: t('aiTradersToast.exchangeDeleted', language),
error: t('aiTradersToast.exchangeDeleteFailed', language),
})
const refreshedExchanges = await api.getExchangeConfigs() const refreshedExchanges = await api.getExchangeConfigs()
setAllExchanges(refreshedExchanges) setAllExchanges(refreshedExchanges)
@@ -597,11 +570,8 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
}, },
} }
await toast.promise(api.updateExchangeConfigsEncrypted(request), { await api.updateExchangeConfigsEncrypted(request)
loading: t('aiTradersToast.updatingExchangeConfig', language), toast.success(t('aiTradersToast.exchangeConfigUpdated', language))
success: t('aiTradersToast.exchangeConfigUpdated', language),
error: t('aiTradersToast.exchangeConfigUpdateFailed', language),
})
} else { } else {
const createRequest = { const createRequest = {
exchange_type: exchangeType, exchange_type: exchangeType,
@@ -621,11 +591,8 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
lighter_api_key_index: lighterApiKeyIndex || 0, lighter_api_key_index: lighterApiKeyIndex || 0,
} }
await toast.promise(api.createExchangeEncrypted(createRequest), { await api.createExchangeEncrypted(createRequest)
loading: t('aiTradersToast.creatingExchange', language), toast.success(t('aiTradersToast.exchangeCreated', language))
success: t('aiTradersToast.exchangeCreated', language),
error: t('aiTradersToast.exchangeCreateFailed', language),
})
} }
const refreshedExchanges = await api.getExchangeConfigs() const refreshedExchanges = await api.getExchangeConfigs()

View File

@@ -174,11 +174,8 @@ export function TraderConfigModal({
saveData.initial_balance = formData.initial_balance saveData.initial_balance = formData.initial_balance
} }
await toast.promise(onSave(saveData), { await onSave(saveData)
loading: t('saving', language), toast.success(t('saveSuccess', language))
success: t('saveSuccess', language),
error: t('saveFailed', language),
})
onClose() onClose()
} catch (error) { } catch (error) {
console.error(t('saveFailed', language) + ':', error) console.error(t('saveFailed', language) + ':', error)

View File

@@ -120,11 +120,8 @@ export function SettingsPage() {
}]) }])
), ),
} }
await toast.promise(api.updateModelConfigs(request), { await api.updateModelConfigs(request)
loading: 'Saving model config...', toast.success('Model config saved')
success: 'Model config saved',
error: 'Failed to save model config',
})
const refreshed = await api.getModelConfigs() const refreshed = await api.getModelConfigs()
setConfiguredModels(refreshed) setConfiguredModels(refreshed)
setShowModelModal(false) setShowModelModal(false)
@@ -198,11 +195,8 @@ export function SettingsPage() {
}, },
}, },
} }
await toast.promise(api.updateExchangeConfigsEncrypted(request), { await api.updateExchangeConfigsEncrypted(request)
loading: 'Updating exchange config...', toast.success('Exchange config updated')
success: 'Exchange config updated',
error: 'Failed to update exchange config',
})
} else { } else {
const createRequest = { const createRequest = {
exchange_type: exchangeType, exchange_type: exchangeType,
@@ -221,11 +215,8 @@ export function SettingsPage() {
lighter_api_key_private_key: lighterApiKeyPrivateKey || '', lighter_api_key_private_key: lighterApiKeyPrivateKey || '',
lighter_api_key_index: lighterApiKeyIndex || 0, lighter_api_key_index: lighterApiKeyIndex || 0,
} }
await toast.promise(api.createExchangeEncrypted(createRequest), { await api.createExchangeEncrypted(createRequest)
loading: 'Creating exchange account...', toast.success('Exchange account created')
success: 'Exchange account created',
error: 'Failed to create exchange account',
})
} }
const refreshed = await api.getExchangeConfigs() const refreshed = await api.getExchangeConfigs()
setExchanges(refreshed) setExchanges(refreshed)
@@ -238,11 +229,8 @@ export function SettingsPage() {
const handleDeleteExchange = async (exchangeId: string) => { const handleDeleteExchange = async (exchangeId: string) => {
try { try {
await toast.promise(api.deleteExchange(exchangeId), { await api.deleteExchange(exchangeId)
loading: 'Deleting exchange account...', toast.success('Exchange account deleted')
success: 'Exchange account deleted',
error: 'Failed to delete exchange account',
})
const refreshed = await api.getExchangeConfigs() const refreshed = await api.getExchangeConfigs()
setExchanges(refreshed) setExchanges(refreshed)
setShowExchangeModal(false) setShowExchangeModal(false)