AV: precise recolor to spec — warm dark backgrounds (#1c1815/#231d18/#26201a/#15110e) + gold #F0A623 / orange #D85A30 accents + warm text (#FBEFE0/#C9BBA8/#8a7e6e). 138 component files + 36 token swaps.
This commit is contained in:
@@ -75,7 +75,7 @@ function DomainsContent() {
|
||||
load();
|
||||
}
|
||||
|
||||
if (loading) return <div className="min-h-screen bg-[#0a0a0a] flex items-center justify-center"><div className="w-8 h-8 border-2 border-[#ffb800] border-t-transparent rounded-full animate-spin" /></div>;
|
||||
if (loading) return <div className="min-h-screen bg-[#0a0a0a] flex items-center justify-center"><div className="w-8 h-8 border-2 border-[#F0A623] border-t-transparent rounded-full animate-spin" /></div>;
|
||||
if (!user) return null;
|
||||
|
||||
return (
|
||||
@@ -86,41 +86,41 @@ function DomainsContent() {
|
||||
<h1 className="text-xl font-bold">Sending Domains</h1>
|
||||
<Link href="/admin/email" className="text-xs text-[#555] hover:text-[#888]">← Email</Link>
|
||||
</div>
|
||||
<button onClick={() => setShowAddForm(true)} className="px-3 py-1.5 bg-[#ffb800] rounded text-xs font-medium hover:bg-blue-500">+ Add Domain</button>
|
||||
<button onClick={() => setShowAddForm(true)} className="px-3 py-1.5 bg-[#F0A623] rounded text-xs font-medium hover:bg-blue-500">+ Add Domain</button>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<select value={filterSite} onChange={e => setFilterSite(e.target.value)} className="px-2 py-1 bg-[#111] border border-[#252525] rounded text-xs text-[#888] focus:outline-none">
|
||||
<select value={filterSite} onChange={e => setFilterSite(e.target.value)} className="px-2 py-1 bg-[#111] border border-[#3a322b] rounded text-xs text-[#888] focus:outline-none">
|
||||
<option value="">All Sites</option>
|
||||
{SITES.map(s => <option key={s} value={s}>{s}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{showAddForm && (
|
||||
<form onSubmit={handleAddDomain} className="bg-[#111] border border-[#252525] rounded-lg p-4 space-y-3">
|
||||
<form onSubmit={handleAddDomain} className="bg-[#111] border border-[#3a322b] rounded-lg p-4 space-y-3">
|
||||
<h3 className="text-sm font-semibold">Add Rotation Domain</h3>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label className="text-xs text-[#888] block mb-1">Site *</label>
|
||||
<select required value={addForm.site} onChange={e => setAddForm(p => ({ ...p, site: e.target.value }))} className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#252525] rounded text-xs text-white focus:outline-none">
|
||||
<select required value={addForm.site} onChange={e => setAddForm(p => ({ ...p, site: e.target.value }))} className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#3a322b] rounded text-xs text-white focus:outline-none">
|
||||
<option value="">Select…</option>
|
||||
{SITES.map(s => <option key={s} value={s}>{s}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-[#888] block mb-1">Domain *</label>
|
||||
<input required value={addForm.domain} onChange={e => setAddForm(p => ({ ...p, domain: e.target.value }))} placeholder="mail.example.com" className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#252525] rounded text-xs text-white focus:outline-none focus:border-[#ffb800]" />
|
||||
<input required value={addForm.domain} onChange={e => setAddForm(p => ({ ...p, domain: e.target.value }))} placeholder="mail.example.com" className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#3a322b] rounded text-xs text-white focus:outline-none focus:border-[#F0A623]" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-[#888] block mb-1">Type</label>
|
||||
<select value={addForm.domain_type} onChange={e => setAddForm(p => ({ ...p, domain_type: e.target.value }))} className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#252525] rounded text-xs text-white focus:outline-none">
|
||||
<select value={addForm.domain_type} onChange={e => setAddForm(p => ({ ...p, domain_type: e.target.value }))} className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#3a322b] rounded text-xs text-white focus:outline-none">
|
||||
{['subdomain','sister_domain','primary'].map(t => <option key={t} value={t}>{t}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<button type="submit" disabled={saving} className="px-3 py-1.5 bg-[#ffb800] rounded text-xs font-medium hover:bg-blue-500 disabled:opacity-50">{saving ? 'Saving…' : 'Add Domain'}</button>
|
||||
<button type="button" onClick={() => setShowAddForm(false)} className="px-3 py-1.5 bg-[#1a1a1a] border border-[#252525] rounded text-xs text-[#888] hover:text-white">Cancel</button>
|
||||
<button type="submit" disabled={saving} className="px-3 py-1.5 bg-[#F0A623] rounded text-xs font-medium hover:bg-blue-500 disabled:opacity-50">{saving ? 'Saving…' : 'Add Domain'}</button>
|
||||
<button type="button" onClick={() => setShowAddForm(false)} className="px-3 py-1.5 bg-[#231d18] border border-[#3a322b] rounded text-xs text-[#888] hover:text-white">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
@@ -131,10 +131,10 @@ function DomainsContent() {
|
||||
<div className="bg-[#111] border border-yellow-400/30 rounded-lg p-5 w-80 space-y-3">
|
||||
<h3 className="text-sm font-semibold text-yellow-400">⚠ Override DNS Verification</h3>
|
||||
<p className="text-xs text-[#888]">This allows sending before DNS is verified. Use with caution.</p>
|
||||
<textarea value={bypassReason} onChange={e => setBypassReason(e.target.value)} placeholder="Reason for bypass…" rows={3} className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#252525] rounded text-xs text-white focus:outline-none" />
|
||||
<textarea value={bypassReason} onChange={e => setBypassReason(e.target.value)} placeholder="Reason for bypass…" rows={3} className="w-full px-2 py-1.5 bg-[#0a0a0a] border border-[#3a322b] rounded text-xs text-white focus:outline-none" />
|
||||
<div className="flex gap-2">
|
||||
<button onClick={() => setBypass(showBypass)} disabled={!bypassReason} className="px-3 py-1.5 bg-yellow-600 rounded text-xs font-medium hover:bg-yellow-500 disabled:opacity-50">Set Bypass</button>
|
||||
<button onClick={() => setShowBypass(null)} className="px-3 py-1.5 bg-[#1a1a1a] border border-[#252525] rounded text-xs text-[#888] hover:text-white">Cancel</button>
|
||||
<button onClick={() => setShowBypass(null)} className="px-3 py-1.5 bg-[#231d18] border border-[#3a322b] rounded text-xs text-[#888] hover:text-white">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -142,12 +142,12 @@ function DomainsContent() {
|
||||
|
||||
<div className="space-y-2">
|
||||
{loadingData ? (
|
||||
<div className="bg-[#111] border border-[#252525] rounded-lg p-8 text-center text-[#555] text-xs">Loading…</div>
|
||||
<div className="bg-[#111] border border-[#3a322b] rounded-lg p-8 text-center text-[#555] text-xs">Loading…</div>
|
||||
) : domains.length === 0 ? (
|
||||
<div className="bg-[#111] border border-[#252525] rounded-lg p-8 text-center text-[#555] text-xs">No domains found</div>
|
||||
<div className="bg-[#111] border border-[#3a322b] rounded-lg p-8 text-center text-[#555] text-xs">No domains found</div>
|
||||
) : domains.map((d: any) => (
|
||||
<div key={d.id} className="bg-[#111] border border-[#252525] rounded-lg overflow-hidden">
|
||||
<div className="px-4 py-3 flex items-center gap-3 cursor-pointer hover:bg-[#161616]" onClick={() => setExpanded(expanded === d.id ? null : d.id)}>
|
||||
<div key={d.id} className="bg-[#111] border border-[#3a322b] rounded-lg overflow-hidden">
|
||||
<div className="px-4 py-3 flex items-center gap-3 cursor-pointer hover:bg-[#231d18]" onClick={() => setExpanded(expanded === d.id ? null : d.id)}>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<span className="text-sm font-medium text-white">{d.domain}</span>
|
||||
@@ -156,7 +156,7 @@ function DomainsContent() {
|
||||
<span className={`px-1.5 py-0.5 rounded text-xs ${d.dns_fully_verified ? 'bg-green-400/10 text-green-400' : 'bg-yellow-400/10 text-yellow-400'}`}>{d.dns_fully_verified ? 'DNS OK' : 'DNS Pending'}</span>
|
||||
{d.blacklisted && <span className="px-1.5 py-0.5 bg-red-400/10 text-red-400 rounded text-xs">Blacklisted</span>}
|
||||
{d.bypass_verification && <span className="px-1.5 py-0.5 bg-yellow-400/10 text-yellow-400 rounded text-xs">Bypass Active</span>}
|
||||
<span className={`px-1.5 py-0.5 rounded text-xs ${d.is_active ? 'bg-green-400/10 text-green-400' : 'bg-[#1a1a1a] text-[#555]'}`}>{d.is_active ? 'Active' : 'Inactive'}</span>
|
||||
<span className={`px-1.5 py-0.5 rounded text-xs ${d.is_active ? 'bg-green-400/10 text-green-400' : 'bg-[#231d18] text-[#555]'}`}>{d.is_active ? 'Active' : 'Inactive'}</span>
|
||||
</div>
|
||||
<div className="flex gap-3 mt-1 text-xs text-[#555]">
|
||||
<span>Health: {d.health_score}/100</span>
|
||||
@@ -167,7 +167,7 @@ function DomainsContent() {
|
||||
</div>
|
||||
|
||||
{expanded === d.id && (
|
||||
<div className="border-t border-[#1a1a1a] px-4 py-3 space-y-3">
|
||||
<div className="border-t border-[#231d18] px-4 py-3 space-y-3">
|
||||
{/* DNS checks */}
|
||||
<div className="grid grid-cols-2 gap-x-6">
|
||||
<DnsRow label="SPF" valid={d.spf_valid} checkedAt={d.spf_checked_at} />
|
||||
@@ -178,7 +178,7 @@ function DomainsContent() {
|
||||
</div>
|
||||
|
||||
{/* DNS helper panel */}
|
||||
<div className="bg-[#0a0a0a] border border-[#1a1a1a] rounded p-3 space-y-2">
|
||||
<div className="bg-[#0a0a0a] border border-[#231d18] rounded p-3 space-y-2">
|
||||
<p className="text-xs font-semibold text-[#888]">DNS Record Helper (GoDaddy)</p>
|
||||
<div className="space-y-1 text-xs text-[#555] font-mono">
|
||||
<p>SPF: <span className="text-[#888]">v=spf1 include:sendgrid.net ~all</span></p>
|
||||
@@ -197,10 +197,10 @@ function DomainsContent() {
|
||||
|
||||
{/* Actions */}
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
<button onClick={() => runVerify(d.id)} disabled={verifying === d.id} className="px-3 py-1.5 bg-[#1a1208] border border-[#2a3a50] rounded text-xs text-[#ffb800] hover:bg-[#0d1a2d] disabled:opacity-50">
|
||||
<button onClick={() => runVerify(d.id)} disabled={verifying === d.id} className="px-3 py-1.5 bg-[#231d18] border border-[#2a3a50] rounded text-xs text-[#F0A623] hover:bg-[#0d1a2d] disabled:opacity-50">
|
||||
{verifying === d.id ? 'Verifying…' : 'Run Full Verification'}
|
||||
</button>
|
||||
<button onClick={() => toggleActive(d.id, d.is_active)} disabled={!d.dns_fully_verified && !d.bypass_verification && !d.is_active} className="px-3 py-1.5 bg-[#1a1a1a] border border-[#252525] rounded text-xs text-[#888] hover:text-white disabled:opacity-30">
|
||||
<button onClick={() => toggleActive(d.id, d.is_active)} disabled={!d.dns_fully_verified && !d.bypass_verification && !d.is_active} className="px-3 py-1.5 bg-[#231d18] border border-[#3a322b] rounded text-xs text-[#888] hover:text-white disabled:opacity-30">
|
||||
{d.is_active ? 'Deactivate' : 'Activate'}
|
||||
</button>
|
||||
<button onClick={() => setShowBypass(d.id)} className="px-3 py-1.5 bg-yellow-900/30 border border-yellow-400/20 rounded text-xs text-yellow-400 hover:bg-yellow-900/50">
|
||||
@@ -219,7 +219,7 @@ function DomainsContent() {
|
||||
|
||||
export default function EmailDomainsPage() {
|
||||
return (
|
||||
<Suspense fallback={<div className="min-h-screen bg-[#0a0a0a] flex items-center justify-center"><div className="w-8 h-8 border-2 border-[#ffb800] border-t-transparent rounded-full animate-spin" /></div>}>
|
||||
<Suspense fallback={<div className="min-h-screen bg-[#0a0a0a] flex items-center justify-center"><div className="w-8 h-8 border-2 border-[#F0A623] border-t-transparent rounded-full animate-spin" /></div>}>
|
||||
<DomainsContent />
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user