200 lines
8.1 KiB
JavaScript
200 lines
8.1 KiB
JavaScript
import React, { useState } from 'react';
|
|
import { gatewayHealth } from '../../services/apiClient';
|
|
import { GATEWAY_URL } from '../../auth/authConfig';
|
|
|
|
const tabs = [
|
|
{ id: 'general', label: 'General' },
|
|
{ id: 'connection', label: 'Connection' },
|
|
{ id: 'notifications', label: 'Notifications' },
|
|
{ id: 'security', label: 'Security' },
|
|
];
|
|
|
|
export default function Settings({ sessionUser, sessionToken, onSignOut }) {
|
|
const [activeTab, setActiveTab] = useState('general');
|
|
const [tenantId, setTenantId] = useState(localStorage.getItem('adplatform_tenantId') || '');
|
|
const [healthResult, setHealthResult] = useState(null);
|
|
const [testing, setTesting] = useState(false);
|
|
|
|
const saveTenantId = () => {
|
|
if (tenantId.trim()) {
|
|
localStorage.setItem('adplatform_tenantId', tenantId.trim());
|
|
} else {
|
|
localStorage.removeItem('adplatform_tenantId');
|
|
}
|
|
};
|
|
|
|
const testConnection = async () => {
|
|
setTesting(true);
|
|
setHealthResult(null);
|
|
const result = await gatewayHealth();
|
|
setHealthResult(result);
|
|
setTesting(false);
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<div className="view-header">
|
|
<h1>Settings</h1>
|
|
</div>
|
|
|
|
<div className="settings-layout">
|
|
<nav className="settings-nav">
|
|
{tabs.map(tab => (
|
|
<button
|
|
key={tab.id}
|
|
className={`settings-nav-item ${activeTab === tab.id ? 'active' : ''}`}
|
|
onClick={() => setActiveTab(tab.id)}
|
|
>
|
|
{tab.label}
|
|
</button>
|
|
))}
|
|
</nav>
|
|
|
|
<div className="settings-content">
|
|
{activeTab === 'general' && (
|
|
<>
|
|
<div className="settings-section">
|
|
<h3>Profile</h3>
|
|
<div className="setting-row">
|
|
<div className="setting-info">
|
|
<div className="setting-label">Display Name</div>
|
|
<div className="setting-desc">{sessionUser?.name || 'Not set'}</div>
|
|
</div>
|
|
</div>
|
|
<div className="setting-row">
|
|
<div className="setting-info">
|
|
<div className="setting-label">Email</div>
|
|
<div className="setting-desc">{sessionUser?.email || 'Not set'}</div>
|
|
</div>
|
|
</div>
|
|
<div className="setting-row">
|
|
<div className="setting-info">
|
|
<div className="setting-label">Role</div>
|
|
<div className="setting-desc">{sessionUser?.role || 'User'}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="settings-section">
|
|
<h3>Tenant Configuration</h3>
|
|
<div className="form-group">
|
|
<label>Tenant ID (Google Ads Customer ID)</label>
|
|
<div className="input-row">
|
|
<input
|
|
className="form-input"
|
|
type="text"
|
|
value={tenantId}
|
|
onChange={e => setTenantId(e.target.value)}
|
|
placeholder="e.g. 123-456-7890"
|
|
/>
|
|
<button className="btn btn-primary btn-sm" onClick={saveTenantId}>Save</button>
|
|
</div>
|
|
<div style={{ fontSize: '13px', color: 'var(--color-text-muted)', marginTop: '-12px' }}>
|
|
This ID is sent as X-Tenant-Id header with API requests.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)}
|
|
|
|
{activeTab === 'connection' && (
|
|
<>
|
|
<div className="settings-section">
|
|
<h3>Gateway Connection</h3>
|
|
<div className="setting-row">
|
|
<div className="setting-info">
|
|
<div className="setting-label">Gateway URL</div>
|
|
<div className="setting-value">{GATEWAY_URL}</div>
|
|
</div>
|
|
</div>
|
|
<div className="setting-row">
|
|
<div className="setting-info">
|
|
<div className="setting-label">Connection Test</div>
|
|
<div className="setting-desc">Verify the gateway is reachable and responding.</div>
|
|
</div>
|
|
<button className="btn btn-sm btn-outline" onClick={testConnection} disabled={testing}>
|
|
{testing ? 'Testing…' : 'Test Connection'}
|
|
</button>
|
|
</div>
|
|
{healthResult && (
|
|
<div className={healthResult.ok ? 'info-box' : 'error-box'} style={{ marginTop: '12px' }}>
|
|
{healthResult.ok
|
|
? '✓ Gateway is healthy and responding.'
|
|
: `✗ Connection failed: ${healthResult.error}`}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="settings-section">
|
|
<h3>Session Information</h3>
|
|
<div className="session-info-detailed">
|
|
<div className="detail-item">
|
|
<span className="detail-label">Session Token</span>
|
|
<span className="detail-value mono" style={{ wordBreak: 'break-all', fontSize: '12px' }}>
|
|
{sessionToken ? sessionToken.substring(0, 32) + '…' : 'None'}
|
|
</span>
|
|
</div>
|
|
<div className="detail-item">
|
|
<span className="detail-label">User ID</span>
|
|
<span className="detail-value mono">{sessionUser?.userId || '—'}</span>
|
|
</div>
|
|
<div className="detail-item">
|
|
<span className="detail-label">Client ID</span>
|
|
<span className="detail-value mono">{sessionUser?.clientId || '—'}</span>
|
|
</div>
|
|
<div className="detail-item">
|
|
<span className="detail-label">Session ID</span>
|
|
<span className="detail-value mono">{sessionUser?.sessionId || '—'}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)}
|
|
|
|
{activeTab === 'notifications' && (
|
|
<div className="settings-section">
|
|
<h3>Notification Preferences</h3>
|
|
<div className="setting-row">
|
|
<div className="setting-info">
|
|
<div className="setting-label">Campaign Alerts</div>
|
|
<div className="setting-desc">Receive alerts when campaigns need attention.</div>
|
|
</div>
|
|
<span style={{ fontSize: '13px', color: 'var(--color-text-muted)' }}>Coming soon</span>
|
|
</div>
|
|
<div className="setting-row">
|
|
<div className="setting-info">
|
|
<div className="setting-label">Budget Warnings</div>
|
|
<div className="setting-desc">Get notified when budgets are nearly exhausted.</div>
|
|
</div>
|
|
<span style={{ fontSize: '13px', color: 'var(--color-text-muted)' }}>Coming soon</span>
|
|
</div>
|
|
<div className="setting-row">
|
|
<div className="setting-info">
|
|
<div className="setting-label">Weekly Summary</div>
|
|
<div className="setting-desc">Receive a weekly performance summary email.</div>
|
|
</div>
|
|
<span style={{ fontSize: '13px', color: 'var(--color-text-muted)' }}>Coming soon</span>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{activeTab === 'security' && (
|
|
<>
|
|
<div className="settings-section">
|
|
<h3>Authentication</h3>
|
|
<div className="setting-row">
|
|
<div className="setting-info">
|
|
<div className="setting-label">Sign Out</div>
|
|
<div className="setting-desc">End your current session and return to the login page.</div>
|
|
</div>
|
|
<button className="btn btn-sm btn-danger" onClick={onSignOut}>Sign Out</button>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|