Localize order modals, add dual logos, and improve admin order tools.
Farsi business order/variation UI, light/dark logo upload on business profile, payment order steps, variation editing, super-admin site links, and checkout/auth fixes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
dc570c1e7f
commit
5e799eddf9
@@ -10,6 +10,7 @@ import {
|
||||
RotateCcw,
|
||||
Search,
|
||||
ShieldPlus,
|
||||
X,
|
||||
} from 'lucide-react'
|
||||
import { ConfirmDeleteModal } from '../components/ConfirmDeleteModal'
|
||||
import { DomainLinksOverflowMenu } from '../components/DomainLinksOverflowMenu'
|
||||
@@ -107,6 +108,7 @@ export function WebsitesPage() {
|
||||
const [removeTarget, setRemoveTarget] = useState<DomainListItem | null>(null)
|
||||
const [togglingActiveId, setTogglingActiveId] = useState<number | null>(null)
|
||||
const [deployingId, setDeployingId] = useState<DomainListItem['id'] | null>(null)
|
||||
const [deployError, setDeployError] = useState('')
|
||||
const [syncingSsl, setSyncingSsl] = useState(false)
|
||||
const [issuingWebsiteSsl, setIssuingWebsiteSsl] = useState(false)
|
||||
const [issuingSslId, setIssuingSslId] = useState<DomainListItem['id'] | null>(null)
|
||||
@@ -356,7 +358,7 @@ export function WebsitesPage() {
|
||||
flushSync(() => {
|
||||
setDeployingId(domain.id)
|
||||
})
|
||||
setError('')
|
||||
setDeployError('')
|
||||
showToast(`Deploying "${domain.host}"…`, 'info')
|
||||
|
||||
try {
|
||||
@@ -376,15 +378,17 @@ export function WebsitesPage() {
|
||||
),
|
||||
}
|
||||
})
|
||||
showToast(
|
||||
result.lastDeployStatus === 'success'
|
||||
? `Deploy succeeded for "${result.host}".`
|
||||
: `Deploy finished for "${result.host}" (${result.lastDeployStatus ?? 'unknown'}).`,
|
||||
result.lastDeployStatus === 'success' ? 'success' : 'info',
|
||||
)
|
||||
if (result.lastDeployStatus === 'success') {
|
||||
showToast(`Deploy succeeded for "${result.host}".`, 'success')
|
||||
return
|
||||
}
|
||||
const detail =
|
||||
result.message?.trim() ||
|
||||
`Deploy finished for "${result.host}" with status ${result.lastDeployStatus ?? 'unknown'}.`
|
||||
setDeployError(`${result.host}: ${detail}`)
|
||||
} catch (err) {
|
||||
const message = err instanceof ApiError ? err.message : 'Deploy failed.'
|
||||
setError(message)
|
||||
setDeployError(`${domain.host}: ${message}`)
|
||||
setData((prev) => {
|
||||
if (!prev) return prev
|
||||
return {
|
||||
@@ -400,7 +404,6 @@ export function WebsitesPage() {
|
||||
),
|
||||
}
|
||||
})
|
||||
showToast(message, 'error')
|
||||
} finally {
|
||||
setDeployingId(null)
|
||||
}
|
||||
@@ -511,6 +514,24 @@ export function WebsitesPage() {
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{deployError ? (
|
||||
<div className={styles.deployErrorTip} role="alert">
|
||||
<AlertTriangle size={18} className={styles.deployErrorIcon} aria-hidden />
|
||||
<div className={styles.deployErrorBody}>
|
||||
<p className={styles.deployErrorTitle}>Deploy failed</p>
|
||||
<pre className={styles.deployErrorDetail}>{deployError}</pre>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className={styles.deployErrorDismiss}
|
||||
onClick={() => setDeployError('')}
|
||||
aria-label="Dismiss deploy error"
|
||||
>
|
||||
<X size={16} aria-hidden />
|
||||
</button>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<div className={tableStyles.tablePanel}>
|
||||
<div className={tableStyles.tableWrap}>
|
||||
<div className={tableStyles.tableHeader}>
|
||||
@@ -527,10 +548,10 @@ export function WebsitesPage() {
|
||||
</div>
|
||||
|
||||
{error && (
|
||||
<div style={{ padding: 16 }}>
|
||||
<div className={tableStyles.meta} style={{ color: '#b91c1c' }}>
|
||||
<div className={styles.listErrorWrap}>
|
||||
<p className={tableStyles.alertError} role="alert">
|
||||
{error}
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user