|
|
|
@ -2,7 +2,7 @@ import { useState, type ReactNode } from 'react'
|
|
|
|
import { useNavigate } from 'react-router-dom'
|
|
|
|
import { useNavigate } from 'react-router-dom'
|
|
|
|
import { formatINR } from '@sims/domain'
|
|
|
|
import { formatINR } from '@sims/domain'
|
|
|
|
import { Badge, Button, DataTable, EmptyState, Notice, PageHeader, StatCard, Stats } from '@sims/ui'
|
|
|
|
import { Badge, Button, DataTable, EmptyState, Notice, PageHeader, StatCard, Stats } from '@sims/ui'
|
|
|
|
import { getDashboard, sendReminder, dismissReminder, type Reminder } from '../api'
|
|
|
|
import { getDashboard, sendReminder, dismissReminder, getReminderPreview, type Reminder } from '../api'
|
|
|
|
import { useData } from './Clients'
|
|
|
|
import { useData } from './Clients'
|
|
|
|
|
|
|
|
|
|
|
|
const inr = (p: number) => formatINR(p)
|
|
|
|
const inr = (p: number) => formatINR(p)
|
|
|
|
@ -105,20 +105,43 @@ function Section<T>(props: {
|
|
|
|
|
|
|
|
|
|
|
|
function QueueActions(props: { rem: Reminder & { docNo: string | null }; onDone: () => void; onError: (m: string) => void }) {
|
|
|
|
function QueueActions(props: { rem: Reminder & { docNo: string | null }; onDone: () => void; onError: (m: string) => void }) {
|
|
|
|
const [busy, setBusy] = useState(false)
|
|
|
|
const [busy, setBusy] = useState(false)
|
|
|
|
|
|
|
|
const [mail, setMail] = useState<{ subject: string; body: string } | undefined>()
|
|
|
|
|
|
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
const run = (p: Promise<unknown>) => {
|
|
|
|
const run = (p: Promise<unknown>) => {
|
|
|
|
setBusy(true); props.onError('')
|
|
|
|
setBusy(true); props.onError('')
|
|
|
|
p.catch((e: Error) => props.onError(e.message))
|
|
|
|
p.catch((e: Error) => props.onError(e.message))
|
|
|
|
// Reload even on failure: the server has already parked the reminder as
|
|
|
|
// Reload even on failure: the server has already parked the reminder as
|
|
|
|
// 'failed' with its error, and the row must flip live (Task 12 walk §3.2).
|
|
|
|
// 'failed' with its error, and the row must flip live.
|
|
|
|
.then(props.onDone)
|
|
|
|
.then(props.onDone)
|
|
|
|
.finally(() => setBusy(false))
|
|
|
|
.finally(() => setBusy(false))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const preview = () => {
|
|
|
|
|
|
|
|
if (mail !== undefined) { setMail(undefined); return } // toggle closed
|
|
|
|
|
|
|
|
setLoading(true); props.onError('')
|
|
|
|
|
|
|
|
getReminderPreview(props.rem.id)
|
|
|
|
|
|
|
|
.then(setMail)
|
|
|
|
|
|
|
|
.catch((e: Error) => props.onError(e.message))
|
|
|
|
|
|
|
|
.finally(() => setLoading(false))
|
|
|
|
|
|
|
|
}
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div style={{ display: 'flex', gap: 6 }}>
|
|
|
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
|
|
|
{SENDABLE.has(props.rem.ruleKind) && (
|
|
|
|
<div style={{ display: 'flex', gap: 6 }}>
|
|
|
|
<Button tone="primary" onClick={() => run(sendReminder(props.rem.id))}>{busy ? '…' : 'Send'}</Button>
|
|
|
|
{SENDABLE.has(props.rem.ruleKind) && (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<Button onClick={preview}>{loading ? '…' : mail !== undefined ? 'Hide' : 'Preview'}</Button>
|
|
|
|
|
|
|
|
<Button tone="primary" onClick={() => run(sendReminder(props.rem.id))}>{busy ? '…' : 'Send'}</Button>
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
<Button onClick={() => run(dismissReminder(props.rem.id))}>Dismiss</Button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{mail !== undefined && (
|
|
|
|
|
|
|
|
<div style={{ border: '1px solid var(--border)', borderRadius: 6, padding: '6px 8px', background: 'var(--bg-raised)', maxWidth: 420 }}>
|
|
|
|
|
|
|
|
<div style={{ fontSize: 11, textTransform: 'uppercase', color: 'var(--text-muted, #666)' }}>Subject</div>
|
|
|
|
|
|
|
|
<div style={{ fontWeight: 600, marginBottom: 4 }}>{mail.subject}</div>
|
|
|
|
|
|
|
|
<div style={{ fontSize: 11, textTransform: 'uppercase', color: 'var(--text-muted, #666)' }}>Body</div>
|
|
|
|
|
|
|
|
<pre style={{ whiteSpace: 'pre-wrap', margin: 0, fontFamily: 'inherit', fontSize: 13 }}>{mail.body}</pre>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
<Button onClick={() => run(dismissReminder(props.rem.id))}>Dismiss</Button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|