Added font,Changed bg for sliding modal
This commit is contained in:
parent
f9d5d9b61f
commit
a1f20c960c
36
README.md
36
README.md
@ -1,36 +0,0 @@
|
|||||||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
First, run the development server:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run dev
|
|
||||||
# or
|
|
||||||
yarn dev
|
|
||||||
# or
|
|
||||||
pnpm dev
|
|
||||||
# or
|
|
||||||
bun dev
|
|
||||||
```
|
|
||||||
|
|
||||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
|
||||||
|
|
||||||
You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
|
|
||||||
|
|
||||||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
|
||||||
|
|
||||||
## Learn More
|
|
||||||
|
|
||||||
To learn more about Next.js, take a look at the following resources:
|
|
||||||
|
|
||||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
|
||||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
|
||||||
|
|
||||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
|
||||||
|
|
||||||
## Deploy on Vercel
|
|
||||||
|
|
||||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
|
||||||
|
|
||||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
|
||||||
@ -1,7 +1,614 @@
|
|||||||
|
// "use client";
|
||||||
|
// import Image from "next/image";
|
||||||
|
// import logo from "../assets/images.png"
|
||||||
|
// import React, { useState, useEffect } from 'react';
|
||||||
|
// const getStatusIcon = (status) => {
|
||||||
|
// switch (status) {
|
||||||
|
// case 'active':
|
||||||
|
// return <span className="text-green-500">●</span>;
|
||||||
|
// case 'inactive':
|
||||||
|
// return <span className="text-red-500">●</span>;
|
||||||
|
// case 'expired':
|
||||||
|
// return <span className="text-orange-500">●</span>;
|
||||||
|
// default:
|
||||||
|
// return <span>●</span>;
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// const ToggleSwitch = ({ checked, onChange }) => (
|
||||||
|
// <label className="relative inline-block cursor-pointer">
|
||||||
|
// <input
|
||||||
|
// type="checkbox"
|
||||||
|
// checked={checked}
|
||||||
|
// onChange={onChange}
|
||||||
|
// className="opacity-0 absolute w-full h-full"
|
||||||
|
// />
|
||||||
|
// <span
|
||||||
|
// className={`block w-10 h-5 rounded-full transition-colors duration-300 ${
|
||||||
|
// checked ? 'bg-green-500' : 'bg-gray-300'
|
||||||
|
// }`}
|
||||||
|
// >
|
||||||
|
// <span
|
||||||
|
// className={`block w-4 h-4 rounded-full bg-white absolute top-0.5 transition-all duration-300 ${
|
||||||
|
// checked ? 'left-5' : 'left-0.5'
|
||||||
|
// }`}
|
||||||
|
// ></span>
|
||||||
|
// </span>
|
||||||
|
// </label>
|
||||||
|
// );
|
||||||
|
// const SlidePanel = ({ isOpen, onClose, title, children, width = "w-96" }) => (
|
||||||
|
// <>
|
||||||
|
|
||||||
|
// {isOpen && (
|
||||||
|
// <div
|
||||||
|
// className="fixed inset-0 bg-black bg-opacity-50 z-40 transition-opacity"
|
||||||
|
// onClick={onClose}
|
||||||
|
// />
|
||||||
|
// )}
|
||||||
|
|
||||||
|
// <div
|
||||||
|
// className={`fixed top-0 right-0 h-full ${width} bg-white shadow-2xl z-50 transform transition-transform duration-300 ease-in-out ${
|
||||||
|
// isOpen ? 'translate-x-0' : 'translate-x-full'
|
||||||
|
// }`}
|
||||||
|
// >
|
||||||
|
// <div className="flex flex-col h-full">
|
||||||
|
|
||||||
|
// <div className="flex items-center justify-between p-6 border-b">
|
||||||
|
// <h2 className="text-xl font-semibold">{title}</h2>
|
||||||
|
// <button
|
||||||
|
// onClick={onClose}
|
||||||
|
// className="text-gray-400 hover:text-gray-600 text-2xl"
|
||||||
|
// >
|
||||||
|
// ×
|
||||||
|
// </button>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div className="flex-1 overflow-y-auto p-6">
|
||||||
|
// {children}
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// </>
|
||||||
|
// );
|
||||||
|
// const BrokerManagement = () => {
|
||||||
|
// const [activeMainTab, setActiveMainTab] = useState('Brokers');
|
||||||
|
// const [activeSubTab, setActiveSubTab] = useState('API Management');
|
||||||
|
// const [filterStatus, setFilterStatus] = useState('All');
|
||||||
|
// const [searchTerm, setSearchTerm] = useState('');
|
||||||
|
// const [isPanelOpen, setIsPanelOpen] = useState(false);
|
||||||
|
// const [editingBroker, setEditingBroker] = useState(null);
|
||||||
|
// const [showAddPanel, setShowAddPanel] = useState(false);
|
||||||
|
// const [showEditPanel, setShowEditPanel] = useState(false);
|
||||||
|
// const [formData, setFormData] = useState({
|
||||||
|
// name: '',
|
||||||
|
// apiId: '',
|
||||||
|
// broker: '',
|
||||||
|
// dateAdded: '',
|
||||||
|
// status: 'active',
|
||||||
|
// balance: '',
|
||||||
|
// onOff: true,
|
||||||
|
// secretKey: ''
|
||||||
|
// });
|
||||||
|
// const [brokers, setBrokers] = useState([
|
||||||
|
// { id: 1, name: 'MarketAxess', apiId: '88234', broker: 'Meta5', dateAdded: 'Feb 14, 2025', status: 'active', balance: '$150.25', onOff: true, secretKey: 'sk-41ZBkLjY...' },
|
||||||
|
// { id: 2, name: 'Tradeweb Markets', apiId: '89245', broker: 'Angel One', dateAdded: 'Mar 01, 2025', status: 'inactive', balance: '$175.50', onOff: true, secretKey: 'sk-98AbcDeF...' },
|
||||||
|
// { id: 3, name: 'MarketAxess', apiId: '88234', broker: 'Meta5', dateAdded: 'Feb 14, 2025', status: 'active', balance: '$150.25', onOff: false, secretKey: 'sk-34GhIjKl...' },
|
||||||
|
// { id: 4, name: 'Tradeweb Markets', apiId: '89245', broker: 'Zerodha', dateAdded: 'Mar 01, 2025', status: 'expired', balance: '$175.50', onOff: true, secretKey: 'sk-56MnOpQr...' },
|
||||||
|
// { id: 5, name: 'MarketAxess', apiId: '88234', broker: 'Dhan', dateAdded: 'Feb 14, 2025', status: 'active', balance: '$150.25', onOff: true, secretKey: 'sk-78RsTuVw...' },
|
||||||
|
// { id: 6, name: 'Tradeweb Markets', apiId: '89245', broker: 'Angel One', dateAdded: 'Mar 01, 2025', status: 'expired', balance: '$175.50', onOff: true, secretKey: 'sk-12XyZaBc...' },
|
||||||
|
// { id: 7, name: 'MarketAxess', apiId: '88234', broker: 'Dhan', dateAdded: 'Feb 14, 2025', status: 'active', balance: '$150.25', onOff: false, secretKey: 'sk-34DefGhi...' },
|
||||||
|
// { id: 8, name: 'Tradeweb Markets', apiId: '89245', broker: 'Angel One', dateAdded: 'Mar 01, 2025', status: 'expired', balance: '$175.50', onOff: true, secretKey: 'sk-56JklMno...' },
|
||||||
|
// { id: 9, name: 'MarketAxess', apiId: '88234', broker: 'Meta5', dateAdded: 'Feb 14, 2025', status: 'active', balance: '$150.25', onOff: true, secretKey: 'sk-78PqrStu...' },
|
||||||
|
// { id: 10, name: 'Tradeweb Markets', apiId: '89245', broker: 'Dhan', dateAdded: 'Mar 01, 2025', status: 'inactive', balance: '$175.50', onOff: true, secretKey: 'sk-98VwxYza...' },
|
||||||
|
// ]);
|
||||||
|
// const handleAddBroker = () => {
|
||||||
|
// setEditingBroker(null);
|
||||||
|
// setFormData({
|
||||||
|
// name: '',
|
||||||
|
// apiId: '',
|
||||||
|
// broker: '',
|
||||||
|
// dateAdded: new Date().toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }),
|
||||||
|
// status: 'active',
|
||||||
|
// balance: '$0.00',
|
||||||
|
// onOff: true,
|
||||||
|
// secretKey: ''
|
||||||
|
// });
|
||||||
|
// setIsPanelOpen(true);
|
||||||
|
// setShowAddPanel(true);
|
||||||
|
// setShowEditPanel(false);
|
||||||
|
// };
|
||||||
|
// const handleEditBroker = (broker) => {
|
||||||
|
// setEditingBroker(broker);
|
||||||
|
// setFormData({ ...broker });
|
||||||
|
// setIsPanelOpen(true);
|
||||||
|
// setShowAddPanel(false);
|
||||||
|
// setShowEditPanel(true);
|
||||||
|
// };
|
||||||
|
// const handleDeleteBroker = (id) => {
|
||||||
|
// if (window.confirm('Are you sure you want to delete this broker?')) {
|
||||||
|
// setBrokers(brokers.filter(b => b.id !== id));
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// const handleSaveBroker = () => {
|
||||||
|
// if (!formData.name || !formData.apiId || !formData.broker) {
|
||||||
|
// alert('Please fill in all required fields');
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (editingBroker) {
|
||||||
|
// setBrokers(brokers.map(b => b.id === editingBroker.id ? { ...formData, id: editingBroker.id } : b));
|
||||||
|
// } else {
|
||||||
|
// const newBroker = {
|
||||||
|
// ...formData,
|
||||||
|
// id: Math.max(...brokers.map(b => b.id)) + 1
|
||||||
|
// };
|
||||||
|
// setBrokers([...brokers, newBroker]);
|
||||||
|
// }
|
||||||
|
// setIsPanelOpen(false);
|
||||||
|
// setShowAddPanel(false);
|
||||||
|
// setShowEditPanel(false);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const handleToggle = (id) => {
|
||||||
|
// const updated=brokers.map(b =>
|
||||||
|
// b.id === id ? { ...b, onOff: !b.onOff } : b
|
||||||
|
// )
|
||||||
|
// setBrokers(updated);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const filteredBrokers = brokers.filter(broker => {
|
||||||
|
// const matchesSearch = broker.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
// broker.broker.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
// broker.apiId.includes(searchTerm);
|
||||||
|
|
||||||
|
// const matchesStatus = filterStatus === 'All' || broker.status.toLowerCase() === filterStatus.toLowerCase();
|
||||||
|
|
||||||
|
// return matchesSearch && matchesStatus;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const groupedBrokers = filteredBrokers.reduce((acc, broker) => {
|
||||||
|
// const key = `${broker.status}-${broker.onOff ? 'on' : 'off'}`;
|
||||||
|
// if (!acc[key]) acc[key] = [];
|
||||||
|
// acc[key].push(broker);
|
||||||
|
// return acc;
|
||||||
|
// }, {});
|
||||||
|
|
||||||
|
// const mainTabs = ['Dashboard', 'Brokers', 'Scan & Trade', 'Positions', 'AI Strategy Builder'];
|
||||||
|
// const subTabs = ['API Management', 'Risk Management', 'Hook Hub'];
|
||||||
|
// const statusFilters = ['All', 'Active', 'Inactive', 'Expired'];
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <div className="min-h-screen bg-gray-100 p-5 font-sans">
|
||||||
|
// <div className="flex justify-between items-center mb-5">
|
||||||
|
// <div className="flex items-center gap-8">
|
||||||
|
// <div className="w-16 h-16 rounded-lg flex items-center justify-center text-white font-bold text-xl">
|
||||||
|
// <Image src={logo} height={100} width={100}/>
|
||||||
|
// </div>
|
||||||
|
// <div className="flex gap-6">
|
||||||
|
// {mainTabs.map(tab => (
|
||||||
|
// <button
|
||||||
|
// key={tab}
|
||||||
|
// onClick={() => setActiveMainTab(tab)}
|
||||||
|
// className={`pb-2 transition-all ${
|
||||||
|
// activeMainTab === tab
|
||||||
|
// ? 'text-blue-600 font-semibold border-b-2 border-blue-600'
|
||||||
|
// : 'text-gray-600 hover:text-gray-900'
|
||||||
|
// }`}
|
||||||
|
// >
|
||||||
|
// {tab}
|
||||||
|
// </button>
|
||||||
|
// ))}
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// <div className="flex gap-4 items-center">
|
||||||
|
// <button className="text-gray-600 hover:text-gray-900 text-xl">📞</button>
|
||||||
|
// <button className="text-gray-600 hover:text-gray-900 text-xl">🔔</button>
|
||||||
|
// <div className="flex items-center gap-2">
|
||||||
|
// <span className="text-sm">NSE</span>
|
||||||
|
// <select className="px-2 py-1 border rounded">
|
||||||
|
// <option>✓</option>
|
||||||
|
// </select>
|
||||||
|
// </div>
|
||||||
|
// <button className="text-gray-600 hover:text-gray-900 text-xl">👤</button>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div className="flex justify-between items-center mb-5">
|
||||||
|
// <h3 className="text-xl font-semibold m-0">Brokers / API Management</h3>
|
||||||
|
// <div className="flex gap-6">
|
||||||
|
// {subTabs.map(tab => (
|
||||||
|
// <button
|
||||||
|
// key={tab}
|
||||||
|
// onClick={() => setActiveSubTab(tab)}
|
||||||
|
// className={`pb-2 transition-all ${
|
||||||
|
// activeSubTab === tab
|
||||||
|
// ? 'text-blue-600 font-semibold border-b-2 border-blue-600'
|
||||||
|
// : 'text-gray-600 hover:text-gray-900'
|
||||||
|
// }`}
|
||||||
|
// >
|
||||||
|
// {tab}
|
||||||
|
// </button>
|
||||||
|
// ))}
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div className="flex justify-between mb-5">
|
||||||
|
// <div className="flex gap-3">
|
||||||
|
// <input
|
||||||
|
// type="text"
|
||||||
|
// placeholder="Search"
|
||||||
|
// value={searchTerm}
|
||||||
|
// onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
|
// className="px-4 py-2 rounded border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
// />
|
||||||
|
// <button className="px-4 py-2 rounded border border-gray-300 bg-white hover:bg-gray-50">
|
||||||
|
// Filters ▼
|
||||||
|
// </button>
|
||||||
|
// </div>
|
||||||
|
// <div className="flex gap-3">
|
||||||
|
// {statusFilters.map(status => (
|
||||||
|
// <button
|
||||||
|
// key={status}
|
||||||
|
// onClick={() => setFilterStatus(status)}
|
||||||
|
// className={`px-4 py-2 rounded border transition-colors ${
|
||||||
|
// filterStatus === status
|
||||||
|
// ? 'bg-blue-100 border-blue-500 text-blue-700'
|
||||||
|
// : 'bg-white border-gray-300 hover:bg-gray-50'
|
||||||
|
// }`}
|
||||||
|
// >
|
||||||
|
// {status}
|
||||||
|
// </button>
|
||||||
|
// ))}
|
||||||
|
// <button className="px-4 py-2 rounded border border-gray-300 bg-white hover:bg-gray-50">
|
||||||
|
// Export CSV
|
||||||
|
// </button>
|
||||||
|
// <button
|
||||||
|
// onClick={handleAddBroker}
|
||||||
|
// className="px-4 py-2 rounded bg-blue-600 text-white hover:bg-blue-700 transition-colors"
|
||||||
|
// >
|
||||||
|
// Add Broker +
|
||||||
|
// </button>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div className="overflow-x-auto">
|
||||||
|
// <table className="w-full bg-white rounded-lg shadow">
|
||||||
|
// <thead>
|
||||||
|
// <tr className="bg-gray-50 border-b">
|
||||||
|
// <th className="px-4 py-3 text-left text-sm font-semibold text-gray-700">Name</th>
|
||||||
|
// <th className="px-4 py-3 text-left text-sm font-semibold text-gray-700">API ID</th>
|
||||||
|
// <th className="px-4 py-3 text-left text-sm font-semibold text-gray-700">Broker</th>
|
||||||
|
// <th className="px-4 py-3 text-left text-sm font-semibold text-gray-700">Date Added</th>
|
||||||
|
// <th className="px-4 py-3 text-left text-sm font-semibold text-gray-700">Status</th>
|
||||||
|
// <th className="px-4 py-3 text-left text-sm font-semibold text-gray-700">Balance</th>
|
||||||
|
// <th className="px-4 py-3 text-left text-sm font-semibold text-gray-700">Action</th>
|
||||||
|
// <th className="px-4 py-3 text-left text-sm font-semibold text-gray-700">On/Off</th>
|
||||||
|
// </tr>
|
||||||
|
// </thead>
|
||||||
|
// <tbody>
|
||||||
|
// {Object.entries(groupedBrokers).map(([groupKey, groupBrokers]) => (
|
||||||
|
// <React.Fragment key={groupKey}>
|
||||||
|
// {filterStatus !== 'All' && (
|
||||||
|
// <tr className="bg-gray-100">
|
||||||
|
// <td colSpan="8" className="px-4 py-2 text-sm font-semibold text-gray-600">
|
||||||
|
// {groupKey.split('-')[0].charAt(0).toUpperCase() + groupKey.split('-')[0].slice(1)} - {groupKey.split('-')[1].toUpperCase()}
|
||||||
|
// </td>
|
||||||
|
// </tr>
|
||||||
|
// )}
|
||||||
|
// {groupBrokers
|
||||||
|
// .sort((a,b)=> a.id - b.id )
|
||||||
|
// .map(broker => (
|
||||||
|
// <tr key={broker.id} className="border-b hover:bg-gray-50 transition-colors">
|
||||||
|
// <td className="px-4 py-3 text-sm">{broker.name}</td>
|
||||||
|
// <td className="px-4 py-3 text-sm">{broker.apiId}</td>
|
||||||
|
// <td className="px-4 py-3 text-sm">{broker.broker}</td>
|
||||||
|
// <td className="px-4 py-3 text-sm">{broker.dateAdded}</td>
|
||||||
|
// <td className="px-4 py-3 text-sm">{getStatusIcon(broker.status)}</td>
|
||||||
|
// <td className="px-4 py-3 text-sm">{broker.balance}</td>
|
||||||
|
// <td className="px-4 py-3 text-sm">
|
||||||
|
// <div className="flex gap-3">
|
||||||
|
// <button className="hover:scale-110 transition-transform">📋</button>
|
||||||
|
// <button
|
||||||
|
// onClick={() => handleEditBroker(broker)}
|
||||||
|
// className="hover:scale-110 transition-transform"
|
||||||
|
// >
|
||||||
|
// ✏️
|
||||||
|
// </button>
|
||||||
|
// <button
|
||||||
|
// onClick={() => handleDeleteBroker(broker.id)}
|
||||||
|
// className="hover:scale-110 transition-transform"
|
||||||
|
// >
|
||||||
|
// 🗑️
|
||||||
|
// </button>
|
||||||
|
// </div>
|
||||||
|
// </td>
|
||||||
|
// <td className="px-4 py-3 text-sm">
|
||||||
|
// <ToggleSwitch
|
||||||
|
// checked={broker.onOff}
|
||||||
|
// onChange={() => handleToggle(broker.id)}
|
||||||
|
// />
|
||||||
|
// </td>
|
||||||
|
// </tr>
|
||||||
|
// ))}
|
||||||
|
// </React.Fragment>
|
||||||
|
// ))}
|
||||||
|
// </tbody>
|
||||||
|
// </table>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div className="flex justify-between mt-5 text-xs text-gray-600">
|
||||||
|
// <div>Last Synced: May 26, 2025 12:30</div>
|
||||||
|
// <div className="flex gap-2">
|
||||||
|
// <button className="px-3 py-1 bg-blue-600 text-white rounded hover:bg-blue-700">1</button>
|
||||||
|
// <button className="px-3 py-1 bg-white border border-gray-300 rounded hover:bg-gray-50">2</button>
|
||||||
|
// <button className="px-3 py-1 bg-white border border-gray-300 rounded hover:bg-gray-50">▶</button>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <SlidePanel
|
||||||
|
// isOpen={isPanelOpen && showAddPanel}
|
||||||
|
// onClose={() => {
|
||||||
|
// setIsPanelOpen(false);
|
||||||
|
// setShowAddPanel(false);
|
||||||
|
// }}
|
||||||
|
// title="Add Broker"
|
||||||
|
// width="w-96"
|
||||||
|
// >
|
||||||
|
// <div className="space-y-4">
|
||||||
|
// <div>
|
||||||
|
// <label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
// Name *
|
||||||
|
// </label>
|
||||||
|
// <input
|
||||||
|
// type="text"
|
||||||
|
// value={formData.name}
|
||||||
|
// onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||||
|
// placeholder="Enter a Name"
|
||||||
|
// className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
// />
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div>
|
||||||
|
// <label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
// Select Broker *
|
||||||
|
// </label>
|
||||||
|
// <select
|
||||||
|
// value={formData.broker}
|
||||||
|
// onChange={(e) => setFormData({ ...formData, broker: e.target.value })}
|
||||||
|
// className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
// >
|
||||||
|
// <option value="">Select Broker</option>
|
||||||
|
// <option value="Meta5">Meta5</option>
|
||||||
|
// <option value="Angel One">Angel One</option>
|
||||||
|
// <option value="Zerodha">Zerodha</option>
|
||||||
|
// <option value="Dhan">Dhan</option>
|
||||||
|
// </select>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div className="border-t pt-4">
|
||||||
|
// <div className="flex justify-between items-center mb-2">
|
||||||
|
// <h3 className="text-sm font-medium text-gray-700">API Details</h3>
|
||||||
|
// <button className="text-xs text-blue-600 hover:text-blue-700">
|
||||||
|
// Help me connect to the API
|
||||||
|
// </button>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div className="space-y-4">
|
||||||
|
// <div>
|
||||||
|
// <label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
// API Key *
|
||||||
|
// </label>
|
||||||
|
// <input
|
||||||
|
// type="text"
|
||||||
|
// value={formData.apiId}
|
||||||
|
// onChange={(e) => setFormData({ ...formData, apiId: e.target.value })}
|
||||||
|
// placeholder="api_key_1234567890abcdefABCDE"
|
||||||
|
// className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
// />
|
||||||
|
// <p className="text-xs text-gray-500 mt-1">Date Created: {formData.dateAdded}</p>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div>
|
||||||
|
// <label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
// Secret API Key
|
||||||
|
// </label>
|
||||||
|
// <input
|
||||||
|
// type="text"
|
||||||
|
// value={formData.secretKey}
|
||||||
|
// onChange={(e) => setFormData({ ...formData, secretKey: e.target.value })}
|
||||||
|
// placeholder="sk-41ZBkLjY..."
|
||||||
|
// className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
// />
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div>
|
||||||
|
// <label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
// Balance
|
||||||
|
// </label>
|
||||||
|
// <input
|
||||||
|
// type="text"
|
||||||
|
// value={formData.balance}
|
||||||
|
// onChange={(e) => setFormData({ ...formData, balance: e.target.value })}
|
||||||
|
// placeholder="$0.00"
|
||||||
|
// className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
// />
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div>
|
||||||
|
// <label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
// Status
|
||||||
|
// </label>
|
||||||
|
// <select
|
||||||
|
// value={formData.status}
|
||||||
|
// onChange={(e) => setFormData({ ...formData, status: e.target.value })}
|
||||||
|
// className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
// >
|
||||||
|
// <option value="active">Active</option>
|
||||||
|
// <option value="inactive">Inactive</option>
|
||||||
|
// <option value="expired">Expired</option>
|
||||||
|
// </select>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div className="flex gap-3 pt-4">
|
||||||
|
// <button
|
||||||
|
// onClick={() => {
|
||||||
|
// setIsPanelOpen(false);
|
||||||
|
// setShowAddPanel(false);
|
||||||
|
// }}
|
||||||
|
// className="flex-1 px-4 py-2 border border-gray-300 rounded hover:bg-gray-50 transition-colors"
|
||||||
|
// >
|
||||||
|
// Cancel
|
||||||
|
// </button>
|
||||||
|
// <button
|
||||||
|
// onClick={handleSaveBroker}
|
||||||
|
// className="flex-1 px-4 py-2 bg-teal-500 text-white rounded hover:bg-teal-600 transition-colors"
|
||||||
|
// >
|
||||||
|
// Add
|
||||||
|
// </button>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// </SlidePanel>
|
||||||
|
|
||||||
|
// <SlidePanel
|
||||||
|
// isOpen={isPanelOpen && showEditPanel}
|
||||||
|
// onClose={() => {
|
||||||
|
// setIsPanelOpen(false);
|
||||||
|
// setShowEditPanel(false);
|
||||||
|
// }}
|
||||||
|
// title="Edit Broker"
|
||||||
|
// width="w-96"
|
||||||
|
// >
|
||||||
|
// <div className="space-y-4">
|
||||||
|
// <div>
|
||||||
|
// <label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
// Name *
|
||||||
|
// </label>
|
||||||
|
// <input
|
||||||
|
// type="text"
|
||||||
|
// value={formData.name}
|
||||||
|
// onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||||
|
// placeholder="Enter a Name"
|
||||||
|
// className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
// />
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div>
|
||||||
|
// <label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
// Select Broker *
|
||||||
|
// </label>
|
||||||
|
// <select
|
||||||
|
// value={formData.broker}
|
||||||
|
// onChange={(e) => setFormData({ ...formData, broker: e.target.value })}
|
||||||
|
// className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
// >
|
||||||
|
// <option value="">Select Broker</option>
|
||||||
|
// <option value="Meta5">Meta5</option>
|
||||||
|
// <option value="Angel One">Angel One</option>
|
||||||
|
// <option value="Zerodha">Zerodha</option>
|
||||||
|
// <option value="Dhan">Dhan</option>
|
||||||
|
// </select>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div className="border-t pt-4">
|
||||||
|
// <div className="flex justify-between items-center mb-2">
|
||||||
|
// <h3 className="text-sm font-medium text-gray-700">API Details</h3>
|
||||||
|
// <button className="text-xs text-blue-600 hover:text-blue-700">
|
||||||
|
// Help me connect to the API
|
||||||
|
// </button>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div className="space-y-4">
|
||||||
|
// <div>
|
||||||
|
// <label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
// API Key *
|
||||||
|
// </label>
|
||||||
|
// <input
|
||||||
|
// type="text"
|
||||||
|
// value={formData.apiId}
|
||||||
|
// onChange={(e) => setFormData({ ...formData, apiId: e.target.value })}
|
||||||
|
// placeholder="api_key_1234567890abcdefABCDE"
|
||||||
|
// className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
// />
|
||||||
|
// <p className="text-xs text-gray-500 mt-1">Date Modified: {formData.dateAdded}</p>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div>
|
||||||
|
// <label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
// Secret API Key
|
||||||
|
// </label>
|
||||||
|
// <input
|
||||||
|
// type="text"
|
||||||
|
// value={formData.secretKey}
|
||||||
|
// onChange={(e) => setFormData({ ...formData, secretKey: e.target.value })}
|
||||||
|
// placeholder="sk-41ZBkLjY..."
|
||||||
|
// className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
// />
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div>
|
||||||
|
// <label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
// Balance
|
||||||
|
// </label>
|
||||||
|
// <input
|
||||||
|
// type="text"
|
||||||
|
// value={formData.balance}
|
||||||
|
// onChange={(e) => setFormData({ ...formData, balance: e.target.value })}
|
||||||
|
// placeholder="$0.00"
|
||||||
|
// className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
// />
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div>
|
||||||
|
// <label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
// Status
|
||||||
|
// </label>
|
||||||
|
// <select
|
||||||
|
// value={formData.status}
|
||||||
|
// onChange={(e) => setFormData({ ...formData, status: e.target.value })}
|
||||||
|
// className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
// >
|
||||||
|
// <option value="active">Active</option>
|
||||||
|
// <option value="inactive">Inactive</option>
|
||||||
|
// <option value="expired">Expired</option>
|
||||||
|
// </select>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// <div className="flex gap-3 pt-4">
|
||||||
|
// <button
|
||||||
|
// onClick={() => {
|
||||||
|
// setIsPanelOpen(false);
|
||||||
|
// setShowEditPanel(false);
|
||||||
|
// }}
|
||||||
|
// className="flex-1 px-4 py-2 border border-gray-300 rounded hover:bg-gray-50 transition-colors"
|
||||||
|
// >
|
||||||
|
// Cancel
|
||||||
|
// </button>
|
||||||
|
// <button
|
||||||
|
// onClick={handleSaveBroker}
|
||||||
|
// className="flex-1 px-4 py-2 bg-teal-500 text-white rounded hover:bg-teal-600 transition-colors"
|
||||||
|
// >
|
||||||
|
// Save
|
||||||
|
// </button>
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// </SlidePanel>
|
||||||
|
// </div>
|
||||||
|
// );
|
||||||
|
// };
|
||||||
|
|
||||||
|
// export default BrokerManagement;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"use client";
|
"use client";
|
||||||
import Image from "next/image";
|
import Image from 'next/image';
|
||||||
import logo from "../assets/images.png"
|
import logo from "../assets/images.png"
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
|
||||||
const getStatusIcon = (status) => {
|
const getStatusIcon = (status) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 'active':
|
case 'active':
|
||||||
@ -14,6 +621,7 @@ const getStatusIcon = (status) => {
|
|||||||
return <span>●</span>;
|
return <span>●</span>;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const ToggleSwitch = ({ checked, onChange }) => (
|
const ToggleSwitch = ({ checked, onChange }) => (
|
||||||
<label className="relative inline-block cursor-pointer">
|
<label className="relative inline-block cursor-pointer">
|
||||||
<input
|
<input
|
||||||
@ -35,12 +643,12 @@ const ToggleSwitch = ({ checked, onChange }) => (
|
|||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
);
|
);
|
||||||
|
|
||||||
const SlidePanel = ({ isOpen, onClose, title, children, width = "w-96" }) => (
|
const SlidePanel = ({ isOpen, onClose, title, children, width = "w-96" }) => (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
{isOpen && (
|
{isOpen && (
|
||||||
<div
|
<div
|
||||||
className="fixed inset-0 bg-black bg-opacity-50 z-40 transition-opacity"
|
className="fixed inset-0 bg-gray-300 opacity-40 z-40 transition-opacity"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -51,7 +659,6 @@ const SlidePanel = ({ isOpen, onClose, title, children, width = "w-96" }) => (
|
|||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex flex-col h-full">
|
<div className="flex flex-col h-full">
|
||||||
|
|
||||||
<div className="flex items-center justify-between p-6 border-b">
|
<div className="flex items-center justify-between p-6 border-b">
|
||||||
<h2 className="text-xl font-semibold">{title}</h2>
|
<h2 className="text-xl font-semibold">{title}</h2>
|
||||||
<button
|
<button
|
||||||
@ -69,6 +676,7 @@ const SlidePanel = ({ isOpen, onClose, title, children, width = "w-96" }) => (
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
const BrokerManagement = () => {
|
const BrokerManagement = () => {
|
||||||
const [activeMainTab, setActiveMainTab] = useState('Brokers');
|
const [activeMainTab, setActiveMainTab] = useState('Brokers');
|
||||||
const [activeSubTab, setActiveSubTab] = useState('API Management');
|
const [activeSubTab, setActiveSubTab] = useState('API Management');
|
||||||
@ -88,6 +696,7 @@ const BrokerManagement = () => {
|
|||||||
onOff: true,
|
onOff: true,
|
||||||
secretKey: ''
|
secretKey: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
const [brokers, setBrokers] = useState([
|
const [brokers, setBrokers] = useState([
|
||||||
{ id: 1, name: 'MarketAxess', apiId: '88234', broker: 'Meta5', dateAdded: 'Feb 14, 2025', status: 'active', balance: '$150.25', onOff: true, secretKey: 'sk-41ZBkLjY...' },
|
{ id: 1, name: 'MarketAxess', apiId: '88234', broker: 'Meta5', dateAdded: 'Feb 14, 2025', status: 'active', balance: '$150.25', onOff: true, secretKey: 'sk-41ZBkLjY...' },
|
||||||
{ id: 2, name: 'Tradeweb Markets', apiId: '89245', broker: 'Angel One', dateAdded: 'Mar 01, 2025', status: 'inactive', balance: '$175.50', onOff: true, secretKey: 'sk-98AbcDeF...' },
|
{ id: 2, name: 'Tradeweb Markets', apiId: '89245', broker: 'Angel One', dateAdded: 'Mar 01, 2025', status: 'inactive', balance: '$175.50', onOff: true, secretKey: 'sk-98AbcDeF...' },
|
||||||
@ -100,6 +709,7 @@ const BrokerManagement = () => {
|
|||||||
{ id: 9, name: 'MarketAxess', apiId: '88234', broker: 'Meta5', dateAdded: 'Feb 14, 2025', status: 'active', balance: '$150.25', onOff: true, secretKey: 'sk-78PqrStu...' },
|
{ id: 9, name: 'MarketAxess', apiId: '88234', broker: 'Meta5', dateAdded: 'Feb 14, 2025', status: 'active', balance: '$150.25', onOff: true, secretKey: 'sk-78PqrStu...' },
|
||||||
{ id: 10, name: 'Tradeweb Markets', apiId: '89245', broker: 'Dhan', dateAdded: 'Mar 01, 2025', status: 'inactive', balance: '$175.50', onOff: true, secretKey: 'sk-98VwxYza...' },
|
{ id: 10, name: 'Tradeweb Markets', apiId: '89245', broker: 'Dhan', dateAdded: 'Mar 01, 2025', status: 'inactive', balance: '$175.50', onOff: true, secretKey: 'sk-98VwxYza...' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const handleAddBroker = () => {
|
const handleAddBroker = () => {
|
||||||
setEditingBroker(null);
|
setEditingBroker(null);
|
||||||
setFormData({
|
setFormData({
|
||||||
@ -116,6 +726,7 @@ const BrokerManagement = () => {
|
|||||||
setShowAddPanel(true);
|
setShowAddPanel(true);
|
||||||
setShowEditPanel(false);
|
setShowEditPanel(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEditBroker = (broker) => {
|
const handleEditBroker = (broker) => {
|
||||||
setEditingBroker(broker);
|
setEditingBroker(broker);
|
||||||
setFormData({ ...broker });
|
setFormData({ ...broker });
|
||||||
@ -123,11 +734,13 @@ const BrokerManagement = () => {
|
|||||||
setShowAddPanel(false);
|
setShowAddPanel(false);
|
||||||
setShowEditPanel(true);
|
setShowEditPanel(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteBroker = (id) => {
|
const handleDeleteBroker = (id) => {
|
||||||
if (window.confirm('Are you sure you want to delete this broker?')) {
|
if (window.confirm('Are you sure you want to delete this broker?')) {
|
||||||
setBrokers(brokers.filter(b => b.id !== id));
|
setBrokers(brokers.filter(b => b.id !== id));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSaveBroker = () => {
|
const handleSaveBroker = () => {
|
||||||
if (!formData.name || !formData.apiId || !formData.broker) {
|
if (!formData.name || !formData.apiId || !formData.broker) {
|
||||||
alert('Please fill in all required fields');
|
alert('Please fill in all required fields');
|
||||||
@ -149,9 +762,9 @@ const BrokerManagement = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleToggle = (id) => {
|
const handleToggle = (id) => {
|
||||||
const updated=brokers.map(b =>
|
const updated = brokers.map(b =>
|
||||||
b.id === id ? { ...b, onOff: !b.onOff } : b
|
b.id === id ? { ...b, onOff: !b.onOff } : b
|
||||||
)
|
);
|
||||||
setBrokers(updated);
|
setBrokers(updated);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -177,11 +790,20 @@ const BrokerManagement = () => {
|
|||||||
const statusFilters = ['All', 'Active', 'Inactive', 'Expired'];
|
const statusFilters = ['All', 'Active', 'Inactive', 'Expired'];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-100 p-5 font-sans">
|
<>
|
||||||
|
<style>{`
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:wght@300;400;500;600;700&display=swap');
|
||||||
|
|
||||||
|
* {
|
||||||
|
font-family: 'Be Vietnam Pro', sans-serif;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
|
||||||
|
<div className="min-h-screen bg-gray-100 p-5">
|
||||||
<div className="flex justify-between items-center mb-5">
|
<div className="flex justify-between items-center mb-5">
|
||||||
<div className="flex items-center gap-8">
|
<div className="flex items-center gap-8">
|
||||||
<div className="w-16 h-16 rounded-lg flex items-center justify-center text-white font-bold text-xl">
|
<div className="w-16 h-16 rounded-lg bg-blue-600 flex items-center justify-center text-white font-bold text-xl">
|
||||||
<Image src={logo} height={100} width={100}/>
|
LOGO
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-6">
|
<div className="flex gap-6">
|
||||||
{mainTabs.map(tab => (
|
{mainTabs.map(tab => (
|
||||||
@ -596,6 +1218,7 @@ const BrokerManagement = () => {
|
|||||||
</div>
|
</div>
|
||||||
</SlidePanel>
|
</SlidePanel>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +1,12 @@
|
|||||||
import { Geist, Geist_Mono } from "next/font/google";
|
import { Be_Vietnam_Pro } from "next/font/google";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
|
||||||
const geistSans = Geist({
|
const BeVietnamPro = Be_Vietnam_Pro({
|
||||||
variable: "--font-geist-sans",
|
variable: "--font-be-vietnam-pro",
|
||||||
subsets: ["latin"],
|
subsets: ["latin"],
|
||||||
|
weight:['100','200','300','400','500','600','700','800','900']
|
||||||
});
|
});
|
||||||
|
|
||||||
const geistMono = Geist_Mono({
|
|
||||||
variable: "--font-geist-mono",
|
|
||||||
subsets: ["latin"],
|
|
||||||
});
|
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
title: "Create Next App",
|
title: "Create Next App",
|
||||||
@ -18,10 +15,8 @@ export const metadata = {
|
|||||||
|
|
||||||
export default function RootLayout({ children }) {
|
export default function RootLayout({ children }) {
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en" className={BeVietnamPro}>
|
||||||
<body
|
<body>
|
||||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
// app/page.jsx
|
// app/page.jsx
|
||||||
import BrokerManagement from "./component/BrokerManagement";
|
import BrokerManagement from "./component/BrokerManagement";
|
||||||
export default function Home() {
|
export default function Home()
|
||||||
|
{
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
{/* */}
|
||||||
<BrokerManagement />
|
<BrokerManagement />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user