Add Arvan/Cloudflare DNS choice on domain edit and restyle empty add boxes.

Domain save can upsert tenant records on either provider, overflow menus stay opaque, and empty-state add controls use a dashed outline.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-31 18:46:48 +03:30
co-authored by Cursor
parent 0d62a4ca79
commit c962fe524b
11 changed files with 177 additions and 89 deletions
@@ -27,18 +27,14 @@
.menu {
position: fixed;
z-index: 1200;
isolation: isolate;
min-width: 220px;
padding: 6px;
border-radius: 14px;
border: 1px solid var(--glass-border);
background:
linear-gradient(
180deg,
rgba(255, 255, 255, 0.72) 0%,
var(--glass-bg-strong) 100%
);
backdrop-filter: blur(var(--blur-glass)) saturate(1.85);
-webkit-backdrop-filter: blur(var(--blur-glass)) saturate(1.85);
/* Card glass (0.62) is too thin over row icons; page orbs already use
backdrop-filter, so a second blur on this panel often does nothing. */
background: var(--toast-bg, rgba(255, 255, 255, 0.94));
box-shadow:
0 18px 48px rgba(15, 23, 42, 0.2),
0 0 0 1px rgba(255, 255, 255, 0.45),
@@ -46,6 +42,17 @@
animation: menuIn 0.16s ease;
}
.menu::before {
content: '';
position: absolute;
inset: 0;
z-index: -1;
border-radius: inherit;
pointer-events: none;
backdrop-filter: blur(var(--blur-glass)) saturate(1.85);
-webkit-backdrop-filter: blur(var(--blur-glass)) saturate(1.85);
}
.item {
display: flex;
align-items: center;
@@ -0,0 +1,33 @@
import type { ParkedDnsProvider } from '../types/domain'
import styles from './ParkedDomainsModal.module.css'
interface DnsProviderSwitchProps {
value: ParkedDnsProvider
onChange: (dns: ParkedDnsProvider) => void
disabled?: boolean
}
export function DnsProviderSwitch({ value, onChange, disabled }: DnsProviderSwitchProps) {
return (
<div className={styles.dnsSwitch} role="group" aria-label="DNS provider">
<button
type="button"
className={`${styles.dnsOption} ${value === 'arvan' ? styles.dnsOptionOn : ''}`}
onClick={() => onChange('arvan')}
disabled={disabled}
aria-pressed={value === 'arvan'}
>
Arvan
</button>
<button
type="button"
className={`${styles.dnsOption} ${value === 'cloudflare' ? styles.dnsOptionOn : ''}`}
onClick={() => onChange('cloudflare')}
disabled={disabled}
aria-pressed={value === 'cloudflare'}
>
Cloudflare
</button>
</div>
)
}
@@ -1,6 +1,7 @@
import { useEffect, useState } from 'react'
import { Plus, X } from 'lucide-react'
import { Modal } from './Modal'
import { DnsProviderSwitch } from './DnsProviderSwitch'
import { ApiError } from '../lib/api'
import { updateParkedHosts } from '../services/domainService'
import type { DomainListItem, ParkedAlias, ParkedDnsProvider } from '../types/domain'
@@ -135,26 +136,11 @@ export function ParkedDomainsModal({ domain, onClose, onSaved }: ParkedDomainsMo
dir="ltr"
aria-label={`Parked domain ${index + 1}`}
/>
<div className={styles.dnsSwitch} role="group" aria-label="DNS provider">
<button
type="button"
className={`${styles.dnsOption} ${row.dns === 'arvan' ? styles.dnsOptionOn : ''}`}
onClick={() => updateDns(index, 'arvan')}
disabled={submitting}
aria-pressed={row.dns === 'arvan'}
>
Arvan
</button>
<button
type="button"
className={`${styles.dnsOption} ${row.dns === 'cloudflare' ? styles.dnsOptionOn : ''}`}
onClick={() => updateDns(index, 'cloudflare')}
disabled={submitting}
aria-pressed={row.dns === 'cloudflare'}
>
Cloudflare
</button>
</div>
<DnsProviderSwitch
value={row.dns}
onChange={(dns) => updateDns(index, dns)}
disabled={submitting}
/>
<button
type="button"
className={styles.removeRowBtn}