SettingsPage.tsx
1 /** 2 * Settings Page - Console settings for Central Bank Governors 3 */ 4 import { useState } from 'react'; 5 import { useGovernanceStore } from '../store/governance'; 6 7 type NetworkOption = 'mainnet' | 'testnet' | 'devnet'; 8 9 export function SettingsPage() { 10 const { connectedWallet, disconnectWallet } = useGovernanceStore(); 11 12 const [selectedNetwork, setSelectedNetwork] = useState<NetworkOption>('mainnet'); 13 const [notificationsEnabled, setNotificationsEnabled] = useState(true); 14 const [emailNotifications, setEmailNotifications] = useState(true); 15 const [proposalAlerts, setProposalAlerts] = useState(true); 16 const [mintingAlerts, setMintingAlerts] = useState(true); 17 const [sessionTimeout, setSessionTimeout] = useState(30); 18 19 const networks: { id: NetworkOption; name: string; url: string }[] = [ 20 { id: 'mainnet', name: 'Mainnet', url: 'https://rpc.ac-dc.network' }, 21 { id: 'testnet', name: 'Testnet', url: 'https://testnet-rpc.ac-dc.network' }, 22 { id: 'devnet', name: 'Devnet', url: 'https://devnet-rpc.ac-dc.network' }, 23 ]; 24 25 const handleSaveSettings = () => { 26 // TODO: Save settings to local storage or backend 27 console.log('Saving settings:', { 28 selectedNetwork, 29 notificationsEnabled, 30 emailNotifications, 31 proposalAlerts, 32 mintingAlerts, 33 sessionTimeout, 34 }); 35 }; 36 37 const handleClearSession = () => { 38 if (confirm('Are you sure you want to clear your session? You will need to reconnect your wallet.')) { 39 disconnectWallet(); 40 localStorage.clear(); 41 window.location.reload(); 42 } 43 }; 44 45 return ( 46 <div className="max-w-4xl mx-auto p-6"> 47 <h1 className="text-2xl font-bold text-text-primary mb-8">Console Settings</h1> 48 49 {/* Connected Wallet Section */} 50 <section className="mb-8"> 51 <h2 className="text-lg font-semibold text-text-primary mb-4">Connected Wallet</h2> 52 <div className="bg-card rounded-xl p-6"> 53 {connectedWallet ? ( 54 <div className="flex items-center justify-between"> 55 <div> 56 <div className="text-text-secondary text-sm">Wallet Address</div> 57 <div className="text-text-primary font-mono mt-1">{connectedWallet}</div> 58 </div> 59 <button 60 onClick={() => disconnectWallet()} 61 className="px-4 py-2 bg-error/20 text-error rounded-lg hover:bg-error/30" 62 > 63 Disconnect 64 </button> 65 </div> 66 ) : ( 67 <div className="text-center py-4"> 68 <p className="text-text-secondary mb-4">No wallet connected</p> 69 <button className="px-6 py-2 bg-alpha text-text-primary rounded-lg hover:bg-alpha-dark"> 70 Connect Wallet 71 </button> 72 </div> 73 )} 74 </div> 75 </section> 76 77 {/* Network Selection Section */} 78 <section className="mb-8"> 79 <h2 className="text-lg font-semibold text-text-primary mb-4">Network Selection</h2> 80 <div className="bg-card rounded-xl p-6"> 81 <div className="space-y-3"> 82 {networks.map((network) => ( 83 <label 84 key={network.id} 85 className={`flex items-center justify-between p-4 rounded-lg cursor-pointer transition-colors ${ 86 selectedNetwork === network.id 87 ? 'bg-alpha/20 border border-alpha' 88 : 'bg-card-hover hover:bg-border' 89 }`} 90 > 91 <div className="flex items-center gap-3"> 92 <input 93 type="radio" 94 name="network" 95 value={network.id} 96 checked={selectedNetwork === network.id} 97 onChange={() => setSelectedNetwork(network.id)} 98 className="w-4 h-4 text-alpha" 99 /> 100 <div> 101 <div className="text-text-primary font-medium">{network.name}</div> 102 <div className="text-text-secondary text-sm">{network.url}</div> 103 </div> 104 </div> 105 {selectedNetwork === network.id && ( 106 <div className="flex items-center gap-2"> 107 <div className="w-2 h-2 rounded-full bg-success" /> 108 <span className="text-success text-sm">Connected</span> 109 </div> 110 )} 111 </label> 112 ))} 113 </div> 114 </div> 115 </section> 116 117 {/* Notification Preferences Section */} 118 <section className="mb-8"> 119 <h2 className="text-lg font-semibold text-text-primary mb-4">Notification Preferences</h2> 120 <div className="bg-card rounded-xl p-6 space-y-4"> 121 <div className="flex items-center justify-between"> 122 <div> 123 <div className="text-text-primary">Enable Notifications</div> 124 <div className="text-text-secondary text-sm">Receive in-app notifications</div> 125 </div> 126 <button 127 onClick={() => setNotificationsEnabled(!notificationsEnabled)} 128 className={`relative w-12 h-6 rounded-full transition-colors ${ 129 notificationsEnabled ? 'bg-alpha' : 'bg-card-hover' 130 }`} 131 > 132 <div 133 className={`absolute top-0.5 w-5 h-5 rounded-full bg-text-primary transition-transform ${ 134 notificationsEnabled ? 'translate-x-6' : 'translate-x-0.5' 135 }`} 136 /> 137 </button> 138 </div> 139 140 <div className="flex items-center justify-between"> 141 <div> 142 <div className="text-text-primary">Email Notifications</div> 143 <div className="text-text-secondary text-sm">Receive email alerts for important events</div> 144 </div> 145 <button 146 onClick={() => setEmailNotifications(!emailNotifications)} 147 className={`relative w-12 h-6 rounded-full transition-colors ${ 148 emailNotifications ? 'bg-alpha' : 'bg-card-hover' 149 }`} 150 > 151 <div 152 className={`absolute top-0.5 w-5 h-5 rounded-full bg-text-primary transition-transform ${ 153 emailNotifications ? 'translate-x-6' : 'translate-x-0.5' 154 }`} 155 /> 156 </button> 157 </div> 158 159 <div className="flex items-center justify-between"> 160 <div> 161 <div className="text-text-primary">Proposal Alerts</div> 162 <div className="text-text-secondary text-sm">Get notified about new proposals</div> 163 </div> 164 <button 165 onClick={() => setProposalAlerts(!proposalAlerts)} 166 className={`relative w-12 h-6 rounded-full transition-colors ${ 167 proposalAlerts ? 'bg-alpha' : 'bg-card-hover' 168 }`} 169 > 170 <div 171 className={`absolute top-0.5 w-5 h-5 rounded-full bg-text-primary transition-transform ${ 172 proposalAlerts ? 'translate-x-6' : 'translate-x-0.5' 173 }`} 174 /> 175 </button> 176 </div> 177 178 <div className="flex items-center justify-between"> 179 <div> 180 <div className="text-text-primary">Minting Alerts</div> 181 <div className="text-text-secondary text-sm">Get notified about minting requests</div> 182 </div> 183 <button 184 onClick={() => setMintingAlerts(!mintingAlerts)} 185 className={`relative w-12 h-6 rounded-full transition-colors ${ 186 mintingAlerts ? 'bg-alpha' : 'bg-card-hover' 187 }`} 188 > 189 <div 190 className={`absolute top-0.5 w-5 h-5 rounded-full bg-text-primary transition-transform ${ 191 mintingAlerts ? 'translate-x-6' : 'translate-x-0.5' 192 }`} 193 /> 194 </button> 195 </div> 196 </div> 197 </section> 198 199 {/* Session Management Section */} 200 <section className="mb-8"> 201 <h2 className="text-lg font-semibold text-text-primary mb-4">Session Management</h2> 202 <div className="bg-card rounded-xl p-6 space-y-6"> 203 <div> 204 <div className="flex justify-between items-center mb-2"> 205 <div className="text-text-primary">Session Timeout</div> 206 <span className="text-alpha-light">{sessionTimeout} minutes</span> 207 </div> 208 <input 209 type="range" 210 min="5" 211 max="60" 212 value={sessionTimeout} 213 onChange={(e) => setSessionTimeout(parseInt(e.target.value))} 214 className="w-full h-2 bg-card-hover rounded-lg appearance-none cursor-pointer" 215 /> 216 <div className="flex justify-between text-sm text-text-secondary mt-1"> 217 <span>5 min</span> 218 <span>60 min</span> 219 </div> 220 </div> 221 222 <div className="pt-4 border-t border-border"> 223 <button 224 onClick={handleClearSession} 225 className="w-full py-2 bg-error/20 text-error rounded-lg hover:bg-error/30" 226 > 227 Clear Session Data 228 </button> 229 <p className="text-text-secondary text-sm mt-2 text-center"> 230 This will disconnect your wallet and clear all local data 231 </p> 232 </div> 233 </div> 234 </section> 235 236 {/* Save Button */} 237 <div className="flex justify-end"> 238 <button 239 onClick={handleSaveSettings} 240 className="px-6 py-2 bg-alpha text-text-primary rounded-lg hover:bg-alpha-dark transition-colors" 241 > 242 Save Settings 243 </button> 244 </div> 245 </div> 246 ); 247 }