|
|
|
@ -1,10 +1,11 @@
|
|
|
|
import { useState } from 'react'
|
|
|
|
import { useMemo, useState } from 'react'
|
|
|
|
import { formatINR, fromRupees } from '@sims/domain'
|
|
|
|
import { formatINR, fromRupees } from '@sims/domain'
|
|
|
|
import { Badge, Button, DataTable, EmptyState, Field, Notice, PageHeader, Toolbar } from '@sims/ui'
|
|
|
|
import { Badge, Button, DataTable, EmptyState, Field, Notice, PageHeader, Toolbar } from '@sims/ui'
|
|
|
|
import {
|
|
|
|
import {
|
|
|
|
addPrice, createModule, getModules, getPrices, patchModule, role,
|
|
|
|
addPrice, createModule, getModules, getPrices, patchModule, previewSample, role,
|
|
|
|
KIND_LABEL, type Kind, type Module,
|
|
|
|
KIND_LABEL, type Kind, type Module,
|
|
|
|
} from '../api'
|
|
|
|
} from '../api'
|
|
|
|
|
|
|
|
import { LivePreview } from '../components/LivePreview'
|
|
|
|
import { useData } from './Clients'
|
|
|
|
import { useData } from './Clients'
|
|
|
|
|
|
|
|
|
|
|
|
const ALL_KINDS: Kind[] = ['one_time', 'monthly', 'yearly', 'usage']
|
|
|
|
const ALL_KINDS: Kind[] = ['one_time', 'monthly', 'yearly', 'usage']
|
|
|
|
@ -65,6 +66,8 @@ function QuoteContent(props: { module: Module; isOwner: boolean; onSaved: () =>
|
|
|
|
const [text, setText] = useState(props.module.quoteContent.join('\n'))
|
|
|
|
const [text, setText] = useState(props.module.quoteContent.join('\n'))
|
|
|
|
const [saved, setSaved] = useState(false)
|
|
|
|
const [saved, setSaved] = useState(false)
|
|
|
|
const [error, setError] = useState<string | undefined>()
|
|
|
|
const [error, setError] = useState<string | undefined>()
|
|
|
|
|
|
|
|
const [commitNonce, setCommitNonce] = useState(0)
|
|
|
|
|
|
|
|
const previewBody = useMemo(() => JSON.stringify({ contentLines: splitLines(text) }), [text])
|
|
|
|
|
|
|
|
|
|
|
|
const save = () => {
|
|
|
|
const save = () => {
|
|
|
|
setError(undefined)
|
|
|
|
setError(undefined)
|
|
|
|
@ -77,16 +80,25 @@ function QuoteContent(props: { module: Module; isOwner: boolean; onSaved: () =>
|
|
|
|
<>
|
|
|
|
<>
|
|
|
|
<h3 style={{ marginTop: 20 }}>Quote content — {props.module.name}</h3>
|
|
|
|
<h3 style={{ marginTop: 20 }}>Quote content — {props.module.name}</h3>
|
|
|
|
{props.isOwner ? (
|
|
|
|
{props.isOwner ? (
|
|
|
|
<div style={{ maxWidth: 560 }}>
|
|
|
|
<div style={{ display: 'flex', gap: 16, alignItems: 'flex-start', flexWrap: 'wrap' }}>
|
|
|
|
<textarea
|
|
|
|
<div style={{ flex: '0 0 560px', minWidth: 0 }}>
|
|
|
|
className="wf" rows={4} placeholder="One included item per line…"
|
|
|
|
<textarea className="wf" rows={4} placeholder="One included item per line…"
|
|
|
|
value={text} onChange={(e) => { setText(e.target.value); setSaved(false) }}
|
|
|
|
value={text} onChange={(e) => { setText(e.target.value); setSaved(false) }} onBlur={() => setCommitNonce((n) => n + 1)} />
|
|
|
|
/>
|
|
|
|
<Toolbar>
|
|
|
|
<Toolbar>
|
|
|
|
<Button tone="primary" onClick={save}>Save quote content</Button>
|
|
|
|
<Button tone="primary" onClick={save}>Save quote content</Button>
|
|
|
|
{saved && <Badge tone="ok">saved</Badge>}
|
|
|
|
{saved && <Badge tone="ok">saved</Badge>}
|
|
|
|
</Toolbar>
|
|
|
|
</Toolbar>
|
|
|
|
{error !== undefined && <Notice tone="err">{error}</Notice>}
|
|
|
|
{error !== undefined && <Notice tone="err">{error}</Notice>}
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div style={{ flex: 1, minWidth: 320, height: 420, background: 'var(--bg-sunken, #e9e9ee)', borderRadius: 8, padding: 12 }}>
|
|
|
|
|
|
|
|
<div style={{ width: '100%', height: '100%', background: '#fff', borderRadius: 4, boxShadow: '0 1px 6px rgba(0,0,0,.15)', overflow: 'hidden' }}>
|
|
|
|
|
|
|
|
<LivePreview
|
|
|
|
|
|
|
|
body={previewBody}
|
|
|
|
|
|
|
|
commitNonce={commitNonce}
|
|
|
|
|
|
|
|
fetchPreview={(b, signal) => previewSample(JSON.parse(b), signal).then((r) => ({ html: r.html }))}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
) : props.module.quoteContent.length === 0 ? (
|
|
|
|
) : props.module.quoteContent.length === 0 ? (
|
|
|
|
<EmptyState>No quote content.</EmptyState>
|
|
|
|
<EmptyState>No quote content.</EmptyState>
|
|
|
|
|