|
|
|
@ -1,5 +1,5 @@
|
|
|
|
import { useState } from 'react'
|
|
|
|
import { useState } from 'react'
|
|
|
|
import { Button } from '@sims/ui'
|
|
|
|
import { Button, useToast } from '@sims/ui'
|
|
|
|
import { dismissReminder, getReminderPreview, sendReminder, type Reminder } from '../api'
|
|
|
|
import { dismissReminder, getReminderPreview, sendReminder, type Reminder } from '../api'
|
|
|
|
|
|
|
|
|
|
|
|
/** Fallback kind labels for queue rows whose server `label` is empty. */
|
|
|
|
/** Fallback kind labels for queue rows whose server `label` is empty. */
|
|
|
|
@ -23,13 +23,17 @@ export const reminderTone = (status: string): 'ok' | 'warn' | 'err' | undefined
|
|
|
|
* and the row must flip live.
|
|
|
|
* and the row must flip live.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export function QueueActions(props: { rem: Reminder; onDone: () => void; onError: (m: string) => void }) {
|
|
|
|
export function QueueActions(props: { rem: Reminder; onDone: () => void; onError: (m: string) => void }) {
|
|
|
|
|
|
|
|
const toast = useToast()
|
|
|
|
const [busy, setBusy] = useState(false)
|
|
|
|
const [busy, setBusy] = useState(false)
|
|
|
|
const [mail, setMail] = useState<{ subject: string; body: string } | undefined>()
|
|
|
|
const [mail, setMail] = useState<{ subject: string; body: string } | undefined>()
|
|
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
const run = (start: () => Promise<unknown>) => {
|
|
|
|
// Toast on success only — onDone still fires on failure too (the server has
|
|
|
|
|
|
|
|
// already parked the reminder as 'failed' and the row must flip live).
|
|
|
|
|
|
|
|
const run = (start: () => Promise<unknown>, okMsg: string) => {
|
|
|
|
if (busy) return // Button has no disabled prop — guard re-entry here
|
|
|
|
if (busy) return // Button has no disabled prop — guard re-entry here
|
|
|
|
setBusy(true); props.onError('')
|
|
|
|
setBusy(true); props.onError('')
|
|
|
|
start()
|
|
|
|
start()
|
|
|
|
|
|
|
|
.then(() => toast.ok(okMsg))
|
|
|
|
.catch((e: Error) => props.onError(e.message))
|
|
|
|
.catch((e: Error) => props.onError(e.message))
|
|
|
|
.then(props.onDone)
|
|
|
|
.then(props.onDone)
|
|
|
|
.finally(() => setBusy(false))
|
|
|
|
.finally(() => setBusy(false))
|
|
|
|
@ -49,10 +53,10 @@ export function QueueActions(props: { rem: Reminder; onDone: () => void; onError
|
|
|
|
{SENDABLE.has(props.rem.ruleKind) && (
|
|
|
|
{SENDABLE.has(props.rem.ruleKind) && (
|
|
|
|
<>
|
|
|
|
<>
|
|
|
|
<Button onClick={preview}>{loading ? '…' : mail !== undefined ? 'Hide' : 'Preview'}</Button>
|
|
|
|
<Button onClick={preview}>{loading ? '…' : mail !== undefined ? 'Hide' : 'Preview'}</Button>
|
|
|
|
<Button tone="primary" onClick={() => run(() => sendReminder(props.rem.id))}>{busy ? '…' : 'Send'}</Button>
|
|
|
|
<Button tone="primary" onClick={() => run(() => sendReminder(props.rem.id), 'Reminder sent')}>{busy ? '…' : 'Send'}</Button>
|
|
|
|
</>
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
<Button onClick={() => run(() => dismissReminder(props.rem.id))}>Dismiss</Button>
|
|
|
|
<Button onClick={() => run(() => dismissReminder(props.rem.id), 'Dismissed')}>Dismiss</Button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{mail !== undefined && (
|
|
|
|
{mail !== undefined && (
|
|
|
|
<div style={{ border: '1px solid var(--border)', borderRadius: 6, padding: '6px 8px', background: 'var(--bg-raised)', maxWidth: 420 }}>
|
|
|
|
<div style={{ border: '1px solid var(--border)', borderRadius: 6, padding: '6px 8px', background: 'var(--bg-raised)', maxWidth: 420 }}>
|
|
|
|
|