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:
co-authored by
Cursor
parent
0d62a4ca79
commit
c962fe524b
@@ -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')}
|
||||
<DnsProviderSwitch
|
||||
value={row.dns}
|
||||
onChange={(dns) => updateDns(index, dns)}
|
||||
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>
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className={styles.removeRowBtn}
|
||||
|
||||
@@ -144,6 +144,14 @@
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.dnsUpdateRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.alertError {
|
||||
margin: 0 0 12px;
|
||||
padding: 12px 14px;
|
||||
|
||||
@@ -31,6 +31,7 @@ import type {
|
||||
PurgeBusinessDataResponse,
|
||||
PurgeEntityResult,
|
||||
} from '../types/business'
|
||||
import type { ParkedDnsProvider } from '../types/domain'
|
||||
import type { BusinessCategory } from '../types/category'
|
||||
import type { ListBusinessesParams } from '../services/businessService'
|
||||
import { ApiError, isAbortError } from '../lib/api'
|
||||
@@ -58,6 +59,7 @@ import {
|
||||
} from '../services/aiPromptService'
|
||||
import type { AiPromptTemplate, DomainAiPrompt } from '../types/aiPrompt'
|
||||
import { Modal } from '../components/Modal'
|
||||
import { DnsProviderSwitch } from '../components/DnsProviderSwitch'
|
||||
import { PrimaryColorSwatchControl } from '../components/PrimaryColorSwatchControl'
|
||||
import { useToast } from '../context/ToastContext'
|
||||
import {
|
||||
@@ -346,6 +348,7 @@ export function BusinessesPage() {
|
||||
const [domainHost, setDomainHost] = useState('')
|
||||
const [domainGitRepoUrl, setDomainGitRepoUrl] = useState('')
|
||||
const [domainUpdateDns, setDomainUpdateDns] = useState(false)
|
||||
const [domainDnsProvider, setDomainDnsProvider] = useState<ParkedDnsProvider>('arvan')
|
||||
const [domainSubmitting, setDomainSubmitting] = useState(false)
|
||||
const [domainError, setDomainError] = useState('')
|
||||
|
||||
@@ -933,6 +936,7 @@ export function BusinessesPage() {
|
||||
setDomainHost(b.domain ?? '')
|
||||
setDomainGitRepoUrl(b.gitRepoUrl ?? '')
|
||||
setDomainUpdateDns(!b.domainId)
|
||||
setDomainDnsProvider('arvan')
|
||||
setDomainError('')
|
||||
setDomainOpen(true)
|
||||
}
|
||||
@@ -1126,6 +1130,7 @@ export function BusinessesPage() {
|
||||
setDomainHost('')
|
||||
setDomainGitRepoUrl('')
|
||||
setDomainUpdateDns(false)
|
||||
setDomainDnsProvider('arvan')
|
||||
setDomainError('')
|
||||
}
|
||||
|
||||
@@ -1144,6 +1149,7 @@ export function BusinessesPage() {
|
||||
const updated = (await updateBusinessDomain(businessId, domainId, {
|
||||
host,
|
||||
updateDns: domainUpdateDns,
|
||||
...(domainUpdateDns ? { dnsProvider: domainDnsProvider } : {}),
|
||||
...(gitRepoUrl ? { gitRepoUrl } : {}),
|
||||
})) as {
|
||||
id: number
|
||||
@@ -1193,6 +1199,7 @@ export function BusinessesPage() {
|
||||
host,
|
||||
isPrimary: true,
|
||||
updateDns: domainUpdateDns,
|
||||
...(domainUpdateDns ? { dnsProvider: domainDnsProvider } : {}),
|
||||
...(gitRepoUrl ? { gitRepoUrl } : {}),
|
||||
})) as {
|
||||
id: number
|
||||
@@ -1248,6 +1255,7 @@ export function BusinessesPage() {
|
||||
setDomainHost('')
|
||||
setDomainGitRepoUrl('')
|
||||
setDomainUpdateDns(false)
|
||||
setDomainDnsProvider('arvan')
|
||||
setDomainError('')
|
||||
} catch (err) {
|
||||
if (submitId !== domainSubmitGenRef.current) return
|
||||
@@ -1998,7 +2006,7 @@ export function BusinessesPage() {
|
||||
<p className={styles.helperText} role="status">
|
||||
{domainGitRepoUrl.trim()
|
||||
? 'Saving domain and setting up storefront on the websites server…'
|
||||
: 'Saving domain and updating Arvan DNS…'}
|
||||
: `Saving domain and updating ${domainDnsProvider === 'cloudflare' ? 'Cloudflare' : 'Arvan'} DNS…`}
|
||||
</p>
|
||||
) : null}
|
||||
<div className={styles.field}>
|
||||
@@ -2029,6 +2037,7 @@ export function BusinessesPage() {
|
||||
</p>
|
||||
</div>
|
||||
<div style={{ height: 12 }} />
|
||||
<div className={styles.dnsUpdateRow}>
|
||||
<label className={styles.entityCheck} htmlFor="domain-update-dns">
|
||||
<input
|
||||
id="domain-update-dns"
|
||||
@@ -2039,9 +2048,16 @@ export function BusinessesPage() {
|
||||
/>
|
||||
<span>Update DNS records</span>
|
||||
</label>
|
||||
<DnsProviderSwitch
|
||||
value={domainDnsProvider}
|
||||
onChange={setDomainDnsProvider}
|
||||
disabled={domainSubmitting || !domainUpdateDns}
|
||||
/>
|
||||
</div>
|
||||
<p className={styles.subText} style={{ marginTop: 6 }}>
|
||||
When checked, upserts Arvan records: @ ANAME → ns.meshkee.com, plus www,
|
||||
business, customer, and api CNAMEs.
|
||||
{domainDnsProvider === 'cloudflare'
|
||||
? 'When checked, upserts Cloudflare records (DNS-only): @ CNAME → ns.meshkee.com, plus www, business, customer, and api CNAMEs.'
|
||||
: 'When checked, upserts Arvan records: @ ANAME → ns.meshkee.com, plus www, business, customer, and api CNAMEs.'}
|
||||
</p>
|
||||
<div style={{ height: 12 }} />
|
||||
<div className={styles.actionsRow}>
|
||||
|
||||
@@ -16,10 +16,11 @@ import {
|
||||
import { ConfirmDeleteModal } from '../components/ConfirmDeleteModal'
|
||||
import { DomainAiPromptsModal } from '../components/DomainAiPromptsModal'
|
||||
import { DomainLinksOverflowMenu } from '../components/DomainLinksOverflowMenu'
|
||||
import { DnsProviderSwitch } from '../components/DnsProviderSwitch'
|
||||
import { ParkedDomainsModal } from '../components/ParkedDomainsModal'
|
||||
import { Modal } from '../components/Modal'
|
||||
import { ToggleSwitch } from '../components/ToggleSwitch'
|
||||
import type { DomainListItem, DomainsListResponse } from '../types/domain'
|
||||
import type { DomainListItem, DomainsListResponse, ParkedDnsProvider } from '../types/domain'
|
||||
import type { ListDomainsParams } from '../services/domainService'
|
||||
import { ApiError, isAbortError } from '../lib/api'
|
||||
import {
|
||||
@@ -106,6 +107,7 @@ export function WebsitesPage() {
|
||||
const [editExpiresAt, setEditExpiresAt] = useState('')
|
||||
const [editGitRepoUrl, setEditGitRepoUrl] = useState('')
|
||||
const [editUpdateDns, setEditUpdateDns] = useState(false)
|
||||
const [editDnsProvider, setEditDnsProvider] = useState<ParkedDnsProvider>('arvan')
|
||||
const [editSubmitting, setEditSubmitting] = useState(false)
|
||||
const [editError, setEditError] = useState('')
|
||||
|
||||
@@ -179,6 +181,7 @@ export function WebsitesPage() {
|
||||
setEditExpiresAt(domain.expiresAt ? domain.expiresAt.slice(0, 10) : '')
|
||||
setEditGitRepoUrl(domain.gitRepoUrl ?? '')
|
||||
setEditUpdateDns(false)
|
||||
setEditDnsProvider('arvan')
|
||||
setEditError('')
|
||||
setEditOpen(true)
|
||||
}
|
||||
@@ -192,6 +195,7 @@ export function WebsitesPage() {
|
||||
const updated = (await updateDomain(editDomain.id, {
|
||||
host: editHost.trim(),
|
||||
updateDns: editUpdateDns,
|
||||
...(editUpdateDns ? { dnsProvider: editDnsProvider } : {}),
|
||||
...(editExpiresAt ? { expiresAt: new Date(editExpiresAt).toISOString() } : {}),
|
||||
...(gitRepoUrl ? { gitRepoUrl } : {}),
|
||||
})) as {
|
||||
@@ -204,6 +208,7 @@ export function WebsitesPage() {
|
||||
setEditDomain(null)
|
||||
setEditGitRepoUrl('')
|
||||
setEditUpdateDns(false)
|
||||
setEditDnsProvider('arvan')
|
||||
if (updated.provisionError) {
|
||||
showToast(`"${editHost.trim()}" was updated, but storefront setup failed.`, 'error')
|
||||
showToast(updated.provisionError, 'error')
|
||||
@@ -806,6 +811,7 @@ export function WebsitesPage() {
|
||||
setEditDomain(null)
|
||||
setEditGitRepoUrl('')
|
||||
setEditUpdateDns(false)
|
||||
setEditDnsProvider('arvan')
|
||||
setEditError('')
|
||||
}}
|
||||
>
|
||||
@@ -818,7 +824,7 @@ export function WebsitesPage() {
|
||||
<p className={tableStyles.helperText} role="status">
|
||||
{editGitRepoUrl.trim()
|
||||
? 'Saving domain and setting up storefront on the websites server…'
|
||||
: 'Saving domain and updating Arvan DNS…'}
|
||||
: `Saving domain and updating ${editDnsProvider === 'cloudflare' ? 'Cloudflare' : 'Arvan'} DNS…`}
|
||||
</p>
|
||||
) : null}
|
||||
<div className={tableStyles.field}>
|
||||
@@ -859,6 +865,7 @@ export function WebsitesPage() {
|
||||
</p>
|
||||
</div>
|
||||
<div style={{ height: 12 }} />
|
||||
<div className={tableStyles.dnsUpdateRow}>
|
||||
<label className={tableStyles.entityCheck} htmlFor="edit-domain-update-dns">
|
||||
<input
|
||||
id="edit-domain-update-dns"
|
||||
@@ -869,9 +876,16 @@ export function WebsitesPage() {
|
||||
/>
|
||||
<span>Update DNS records</span>
|
||||
</label>
|
||||
<DnsProviderSwitch
|
||||
value={editDnsProvider}
|
||||
onChange={setEditDnsProvider}
|
||||
disabled={editSubmitting || !editUpdateDns}
|
||||
/>
|
||||
</div>
|
||||
<p className={tableStyles.subText} style={{ marginTop: 6 }}>
|
||||
When checked, upserts Arvan records: @ ANAME → ns.meshkee.com, plus www,
|
||||
business, customer, and api CNAMEs.
|
||||
{editDnsProvider === 'cloudflare'
|
||||
? 'When checked, upserts Cloudflare records (DNS-only): @ CNAME → ns.meshkee.com, plus www, business, customer, and api CNAMEs.'
|
||||
: 'When checked, upserts Arvan records: @ ANAME → ns.meshkee.com, plus www, business, customer, and api CNAMEs.'}
|
||||
</p>
|
||||
<div style={{ height: 12 }} />
|
||||
<div className={tableStyles.actionsRow}>
|
||||
|
||||
@@ -29,8 +29,10 @@ export interface UpdateBusinessPayload {
|
||||
export interface AddDomainPayload {
|
||||
host: string
|
||||
isPrimary?: boolean
|
||||
/** When true, upsert Meshkee tenant records in Arvan DNS. */
|
||||
/** When true, upsert Meshkee tenant records (@, www, business, customer, api). */
|
||||
updateDns?: boolean
|
||||
/** DNS host when updateDns is true. Default arvan. */
|
||||
dnsProvider?: 'arvan' | 'cloudflare'
|
||||
/** When set, provisions storefront deploy on the websites VM. */
|
||||
gitRepoUrl?: string
|
||||
}
|
||||
@@ -41,8 +43,10 @@ export interface DisableBusinessPayload {
|
||||
|
||||
export interface UpdateDomainPayload {
|
||||
host: string
|
||||
/** When true, upsert Meshkee tenant records in Arvan DNS. */
|
||||
/** When true, upsert Meshkee tenant records (@, www, business, customer, api). */
|
||||
updateDns?: boolean
|
||||
/** DNS host when updateDns is true. Default arvan. */
|
||||
dnsProvider?: 'arvan' | 'cloudflare'
|
||||
/** When set, provisions storefront deploy on the websites VM. */
|
||||
gitRepoUrl?: string
|
||||
}
|
||||
|
||||
@@ -17,8 +17,10 @@ export interface ListDomainsParams {
|
||||
export interface UpdateDomainPayload {
|
||||
host?: string
|
||||
expiresAt?: string
|
||||
/** When true, upsert Meshkee tenant records in Arvan DNS. */
|
||||
/** When true, upsert Meshkee tenant records (@, www, business, customer, api). */
|
||||
updateDns?: boolean
|
||||
/** DNS host when updateDns is true. Default arvan. */
|
||||
dnsProvider?: 'arvan' | 'cloudflare'
|
||||
/** When set, provisions storefront deploy on the websites VM. */
|
||||
gitRepoUrl?: string
|
||||
}
|
||||
|
||||
@@ -138,11 +138,11 @@ Add to `/etc/hosts` (one line per tenant):
|
||||
|------|------|
|
||||
| `/login` | Login |
|
||||
| `/` | Home |
|
||||
| `/businesses` | Businesses list (migrate-from-old + delete-data for portfolios/blogs(+news)/customers + categories; single-select). **Add/Edit domain** accepts optional Git repo URL → provisions storefront on websites VM and sets `deploy_slug`. Optional **Update DNS records** checkbox upserts Arvan DNS (`@` ANAME → `ns.meshkee.com`, `www` CNAME → apex, `business`/`customer`/`api` CNAMEs). |
|
||||
| `/businesses` | Businesses list (migrate-from-old + delete-data for portfolios/blogs(+news)/customers + categories; single-select). **Add/Edit domain** accepts optional Git repo URL → provisions storefront on websites VM and sets `deploy_slug`. Optional **Update DNS records** checkbox upserts tenant DNS (`@` → `ns.meshkee.com`, `www` CNAME → apex, `business`/`customer`/`api` CNAMEs) via **Arvan** or **Cloudflare** (switch; Cloudflare is DNS-only / not proxied). |
|
||||
| `/businesses/:businessId/invoices` | Business invoices list |
|
||||
| `/businesses/:businessId/invoices/new` | Issue invoice (full page) |
|
||||
| `/users` | Users (business filter: Customer vs Manager → Admin/Editor/Viewer; Admin assignable by super-admin only; owners locked) |
|
||||
| `/websites` | Websites / domains (Deploy when `deploy_slug` set). Edit domain can optionally update Arvan DNS. Overflow ⋯ includes website/dashboard links, **AI prompts**, and remove. **Parked domains** button: alias hosts 301 to the main domain. Per alias, choose **Arvan** or **Cloudflare** for DNS (`@` + `www` only, not proxied); SSL is always Let's Encrypt on the websites VM. |
|
||||
| `/websites` | Websites / domains (Deploy when `deploy_slug` set). Edit domain can optionally update DNS (Arvan or Cloudflare, same tenant records as Businesses). Overflow ⋯ includes website/dashboard links, **AI prompts**, and remove. **Parked domains** button: alias hosts 301 to the main domain. Per alias, choose **Arvan** or **Cloudflare** for DNS (`@` + `www` only, not proxied); SSL is always Let's Encrypt on the websites VM. |
|
||||
| `/templates` | Global AI prompt templates. Assign from Businesses or Websites ⋯ → **AI prompts** (add from library; public pack link). |
|
||||
| `/settings` | Platform settings (invoice templates + item templates) |
|
||||
| `/settings/invoice-templates/new` | Create invoice template |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding: 32px 0 48px;
|
||||
padding: 20px 0 28px;
|
||||
}
|
||||
|
||||
.rootDashed {
|
||||
@@ -10,7 +10,7 @@
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
gap: 12px;
|
||||
width: 100%;
|
||||
max-width: 880px;
|
||||
margin-inline: auto;
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
.rootDashedInline {
|
||||
max-width: 100%;
|
||||
padding: 24px 12px;
|
||||
padding: 12px 8px 16px;
|
||||
}
|
||||
|
||||
.messageDashed {
|
||||
@@ -55,36 +55,52 @@
|
||||
|
||||
.addBox {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
gap: 6px;
|
||||
width: 100%;
|
||||
max-width: 880px;
|
||||
min-height: 180px;
|
||||
padding: 32px 28px;
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 2px dashed rgba(var(--primary-rgb) / 0.38);
|
||||
border-radius: var(--radius);
|
||||
color: var(--primary);
|
||||
max-width: 480px;
|
||||
min-height: 76px;
|
||||
padding: 12px 14px;
|
||||
background: none;
|
||||
background-color: transparent;
|
||||
border-width: 2px;
|
||||
border-style: dashed;
|
||||
border-color: #64748b;
|
||||
border-radius: 12px;
|
||||
color: var(--primary, #0a1628);
|
||||
font-family: var(--font-ui);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background 0.2s ease,
|
||||
border-color 0.2s ease,
|
||||
transform 0.2s ease,
|
||||
box-shadow 0.2s ease;
|
||||
background-color 0.15s ease,
|
||||
border-color 0.15s ease,
|
||||
color 0.15s ease,
|
||||
box-shadow 0.15s ease,
|
||||
transform 0.15s ease;
|
||||
}
|
||||
|
||||
.addBox:hover {
|
||||
background: rgba(var(--primary-rgb) / 0.08);
|
||||
border-color: rgba(var(--primary-rgb) / 0.58);
|
||||
transform: translateY(-3px);
|
||||
box-shadow: var(--card-hover-shadow);
|
||||
a.addBox,
|
||||
button.addBox {
|
||||
background: none;
|
||||
background-color: transparent;
|
||||
border-width: 2px;
|
||||
border-style: dashed;
|
||||
border-color: #64748b;
|
||||
}
|
||||
|
||||
.addBox:hover,
|
||||
a.addBox:hover,
|
||||
button.addBox:hover {
|
||||
background-color: rgba(10, 22, 40, 0.07);
|
||||
border-style: dashed;
|
||||
border-color: #0a1628;
|
||||
color: #0a1628;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px rgba(15, 23, 42, 0.1);
|
||||
}
|
||||
|
||||
.addBox:focus-visible {
|
||||
@@ -96,16 +112,14 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
border-radius: 50%;
|
||||
background: rgba(var(--primary-rgb) / 0.12);
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.addLabel {
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.cell {
|
||||
@@ -127,4 +141,8 @@
|
||||
.addBox {
|
||||
max-width: min(100%, 640px);
|
||||
}
|
||||
|
||||
.addBox {
|
||||
max-width: 480px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ function EmptyStateContent({
|
||||
const addContent = (
|
||||
<>
|
||||
<span className={styles.addIcon} aria-hidden="true">
|
||||
<Plus size={28} strokeWidth={2} />
|
||||
<Plus size={20} strokeWidth={2} />
|
||||
</span>
|
||||
{actionLabel ? <span className={styles.addLabel}>{actionLabel}</span> : null}
|
||||
</>
|
||||
@@ -92,11 +92,11 @@ function EmptyStateContent({
|
||||
>
|
||||
<p className={styles.messageDashed}>{messageContent}</p>
|
||||
{actionTo ? (
|
||||
<Link to={actionTo} className={styles.addBox} onClick={onAction}>
|
||||
<Link to={actionTo} className={styles.addBox} data-empty-add="" onClick={onAction}>
|
||||
{addContent}
|
||||
</Link>
|
||||
) : (
|
||||
<button type="button" className={styles.addBox} onClick={onAction}>
|
||||
<button type="button" className={styles.addBox} data-empty-add="" onClick={onAction}>
|
||||
{addContent}
|
||||
</button>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user