synor/apps/web/src/pages/Settings.tsx
Gulshan Yadav 48949ebb3f Initial commit: Synor blockchain monorepo
A complete blockchain implementation featuring:
- synord: Full node with GHOSTDAG consensus
- explorer-web: Modern React blockchain explorer with 3D DAG visualization
- CLI wallet and tools
- Smart contract SDK and example contracts (DEX, NFT, token)
- WASM crypto library for browser/mobile
2026-01-08 05:22:17 +05:30

192 lines
6.3 KiB
TypeScript

import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useWalletStore, type Network } from '../store/wallet';
export default function SettingsPage() {
const {
network,
rpcEndpoint,
setNetwork,
setRpcEndpoint,
deleteWallet,
} = useWalletStore();
const navigate = useNavigate();
const [customEndpoint, setCustomEndpoint] = useState(rpcEndpoint);
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
const [deleteConfirmText, setDeleteConfirmText] = useState('');
const handleNetworkChange = (newNetwork: Network) => {
setNetwork(newNetwork);
// Update default endpoint based on network
const defaultEndpoints: Record<Network, string> = {
mainnet: 'https://rpc.synor.cc',
testnet: 'https://testnet-rpc.synor.cc',
devnet: 'http://localhost:16110',
};
setRpcEndpoint(defaultEndpoints[newNetwork]);
setCustomEndpoint(defaultEndpoints[newNetwork]);
};
const handleSaveEndpoint = () => {
setRpcEndpoint(customEndpoint);
};
const handleDeleteWallet = () => {
if (deleteConfirmText === 'DELETE') {
deleteWallet();
navigate('/');
}
};
return (
<div className="max-w-2xl">
<h1 className="text-2xl font-bold mb-6">Settings</h1>
{/* Network Selection */}
<div className="card mb-6">
<h2 className="text-lg font-semibold mb-4">Network</h2>
<div className="grid grid-cols-3 gap-3">
{(['mainnet', 'testnet', 'devnet'] as Network[]).map((net) => (
<button
key={net}
onClick={() => handleNetworkChange(net)}
className={`p-4 rounded-lg border-2 transition-colors ${
network === net
? 'border-synor-500 bg-synor-900/30'
: 'border-slate-700 hover:border-slate-600'
}`}
>
<div className="flex items-center gap-2 mb-1">
<span
className={`w-2 h-2 rounded-full ${
net === 'mainnet'
? 'bg-green-500'
: net === 'testnet'
? 'bg-yellow-500'
: 'bg-blue-500'
}`}
></span>
<span className="font-medium capitalize">{net}</span>
</div>
<div className="text-xs text-slate-500">
{net === 'mainnet' && 'Production network'}
{net === 'testnet' && 'Test with fake SYNOR'}
{net === 'devnet' && 'Local development'}
</div>
</button>
))}
</div>
{network === 'mainnet' && (
<div className="mt-4 p-3 bg-yellow-900/30 border border-yellow-700 rounded-lg text-yellow-300 text-sm">
Mainnet is not yet launched. Switch to testnet or devnet.
</div>
)}
</div>
{/* RPC Endpoint */}
<div className="card mb-6">
<h2 className="text-lg font-semibold mb-4">RPC Endpoint</h2>
<div className="flex gap-3">
<input
type="text"
value={customEndpoint}
onChange={(e) => setCustomEndpoint(e.target.value)}
className="input flex-1"
placeholder="http://localhost:16110"
/>
<button
onClick={handleSaveEndpoint}
disabled={customEndpoint === rpcEndpoint}
className="btn btn-secondary"
>
Save
</button>
</div>
<p className="text-xs text-slate-500 mt-2">
Connect to a custom Synor node
</p>
</div>
{/* Security */}
<div className="card mb-6">
<h2 className="text-lg font-semibold mb-4">Security</h2>
<div className="space-y-4">
<div className="flex items-center justify-between p-3 bg-slate-900 rounded-lg">
<div>
<div className="font-medium">Auto-lock</div>
<div className="text-sm text-slate-500">
Lock wallet after inactivity
</div>
</div>
<select className="bg-slate-800 border border-slate-700 rounded px-3 py-2">
<option value="5">5 minutes</option>
<option value="15">15 minutes</option>
<option value="30">30 minutes</option>
<option value="60">1 hour</option>
<option value="0">Never</option>
</select>
</div>
</div>
</div>
{/* Danger Zone */}
<div className="card border-red-900">
<h2 className="text-lg font-semibold text-red-400 mb-4">Danger Zone</h2>
{!showDeleteConfirm ? (
<button
onClick={() => setShowDeleteConfirm(true)}
className="btn btn-danger"
>
Delete Wallet
</button>
) : (
<div className="space-y-4">
<div className="p-3 bg-red-900/30 border border-red-700 rounded-lg text-red-300 text-sm">
<strong>Warning:</strong> This will permanently delete your wallet
from this device. Make sure you have your recovery phrase backed up.
</div>
<div>
<label className="block text-sm text-slate-400 mb-2">
Type "DELETE" to confirm
</label>
<input
type="text"
value={deleteConfirmText}
onChange={(e) => setDeleteConfirmText(e.target.value)}
className="input"
placeholder="DELETE"
/>
</div>
<div className="flex gap-3">
<button
onClick={() => {
setShowDeleteConfirm(false);
setDeleteConfirmText('');
}}
className="btn btn-secondary flex-1"
>
Cancel
</button>
<button
onClick={handleDeleteWallet}
disabled={deleteConfirmText !== 'DELETE'}
className="btn btn-danger flex-1"
>
Confirm Delete
</button>
</div>
</div>
)}
</div>
{/* Version */}
<div className="mt-6 text-center text-sm text-slate-500">
Synor Web Wallet v0.1.0
</div>
</div>
);
}