diff --git a/broker.js b/broker.js
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/assets/HookNestLogo.png b/public/assets/HookNestLogo.png
similarity index 100%
rename from src/app/assets/HookNestLogo.png
rename to public/assets/HookNestLogo.png
diff --git a/public/file.svg b/public/file.svg
deleted file mode 100644
index 004145c..0000000
--- a/public/file.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/globe.svg b/public/globe.svg
deleted file mode 100644
index 567f17b..0000000
--- a/public/globe.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/next.svg b/public/next.svg
deleted file mode 100644
index 5174b28..0000000
--- a/public/next.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/vercel.svg b/public/vercel.svg
deleted file mode 100644
index 7705396..0000000
--- a/public/vercel.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/window.svg b/public/window.svg
deleted file mode 100644
index b2b2a44..0000000
--- a/public/window.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/app/Brokers/page.js b/src/app/Brokers/page.js
index 28eccad..c42a47e 100644
--- a/src/app/Brokers/page.js
+++ b/src/app/Brokers/page.js
@@ -1,364 +1,7 @@
'use client';
-import React, { useState } from 'react';
-import { X, Plus, Edit2, Copy, Trash2, MoreVertical, Search, Filter } from 'lucide-react';
+import BrokerManagement from '@/components/brokers/BrokerManagement';
-export default function BrokerManagement() {
- const [brokers, setBrokers] = useState([
- { id: 'BR301', name: 'Techbonds Markets', broker: 'Masak', dateAdded: 'Feb 16, 2025', status: 'active', balance: '$978.50', apiKey: 'api_key_123456789abcdef', secretKey: 'sk_412345LH...', dateCreated: '04/12/2025' },
- { id: 'BR295', name: 'Techbonds Markets', broker: 'AngelOne', dateAdded: 'Mar 02, 2025', status: 'expired', balance: '$978.50', apiKey: 'api_key_987654321fedcba', secretKey: 'sk_987654LH...', dateCreated: '03/02/2025' },
- { id: 'BR298', name: 'MarketEases', broker: 'Masak', dateAdded: 'Feb 14, 2025', status: 'active', balance: '$102.25', apiKey: 'api_key_111222333444555', secretKey: 'sk_111222LH...', dateCreated: '02/14/2025' },
- { id: 'BR293', name: 'Techbonds Markets', broker: 'Zerodha', dateAdded: 'Mar 03, 2025', status: 'inactive', balance: '$978.50', apiKey: 'api_key_555444333222111', secretKey: 'sk_555444LH...', dateCreated: '03/03/2025' },
- { id: 'BR297', name: 'Techbonds Markets', broker: 'Dhan', dateAdded: 'Feb 14, 2025', status: 'active', balance: '$102.25', apiKey: 'api_key_666777888999000', secretKey: 'sk_666777LH...', dateCreated: '02/14/2025' },
- { id: 'BR292', name: 'Techbonds Markets', broker: 'AngelOne', dateAdded: 'Mar 02, 2025', status: 'inactive', balance: '$978.50', apiKey: 'api_key_000999888777666', secretKey: 'sk_000999LH...', dateCreated: '03/02/2025' },
- ]);
-
- const [isSlideOpen, setIsSlideOpen] = useState(false);
- const [slideMode, setSlideMode] = useState('add');
- const [selectedBroker, setSelectedBroker] = useState(null);
- const [searchTerm, setSearchTerm] = useState('');
- const [filterStatus, setFilterStatus] = useState('all');
-
- const [formData, setFormData] = useState({
- name: '',
- broker: '',
- apiKey: '',
- secretKey: '',
- });
-
- const handleAdd = () => {
- setSlideMode('add');
- setFormData({ name: '', broker: '', apiKey: '', secretKey: '' });
- setIsSlideOpen(true);
- };
-
- const handleEdit = (broker) => {
- setSlideMode('edit');
- setSelectedBroker(broker);
- setFormData({
- name: broker.name,
- broker: broker.broker,
- apiKey: broker.apiKey,
- secretKey: broker.secretKey,
- });
- setIsSlideOpen(true);
- };
-
- const handleSubmit = () => {
- if (slideMode === 'add') {
- const newBroker = {
- id: `BR${Math.floor(Math.random() * 1000)}`,
- name: formData.name,
- broker: formData.broker,
- dateAdded: new Date().toLocaleDateString('en-US', { month: 'short', day: '2-digit', year: 'numeric' }),
- status: 'active',
- balance: '$0.00',
- apiKey: formData.apiKey,
- secretKey: formData.secretKey,
- dateCreated: new Date().toLocaleDateString('en-US'),
- };
- setBrokers([...brokers, newBroker]);
- } else if (selectedBroker) {
- setBrokers(brokers.map(b =>
- b.id === selectedBroker.id
- ? { ...b, name: formData.name, broker: formData.broker, apiKey: formData.apiKey, secretKey: formData.secretKey }
- : b
- ));
- }
- setIsSlideOpen(false);
- };
-
- const handleDelete = (id) => {
- setBrokers(brokers.filter(b => b.id !== id));
- };
-
- const toggleStatus = (id) => {
- setBrokers(brokers.map(b =>
- b.id === id
- ? { ...b, status: b.status === 'active' ? 'inactive' : 'active' }
- : b
- ));
- };
-
- const filteredBrokers = brokers.filter(broker => {
- const matchesSearch = broker.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
- broker.broker.toLowerCase().includes(searchTerm.toLowerCase());
- const matchesFilter = filterStatus === 'all' || broker.status === filterStatus;
- return matchesSearch && matchesFilter;
- });
-
- return (
-
- {/* Header Section */}
-
-
-
Brokers / API Management
-
-
-
- {/* Filters and Search */}
-
-
-
- setSearchTerm(e.target.value)}
- className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-teal-500"
- />
-
-
-
-
-
-
-
-
-
-
- {/* Table */}
-
-
-
-
- | Name |
- API ID |
- Broker |
- Date Added |
- Status |
- Balance |
- |
- |
- |
- On/Off |
-
-
-
- {filteredBrokers.map((broker) => (
-
- | {broker.name} |
- {broker.id} |
-
-
-
- {broker.broker.charAt(0)}
-
- {broker.broker}
-
- |
- {broker.dateAdded} |
-
-
- |
- {broker.balance} |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
- ))}
-
-
-
-
- {/* Slide-in Panel */}
- {isSlideOpen && (
- <>
- {/* Overlay */}
-
setIsSlideOpen(false)}
- >
-
- {/* Slide Panel */}
-
-
- {/* Header */}
-
-
- {slideMode === 'add' ? 'Add Broker' : 'Edit Broker'}
-
-
-
-
- {/* Content */}
-
-
- Choose your preferred exchange to add a broker.
-
-
- {/* Broker Details */}
-
-
Broker Details
-
-
-
- setFormData({ ...formData, name: e.target.value })}
- className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-teal-500"
- />
-
-
-
-
-
-
-
-
- {/* API Details */}
-
-
-
API Details
- {slideMode === 'edit' && (
-
- )}
- {slideMode === 'add' && (
-
- )}
-
-
-
-
-
setFormData({ ...formData, apiKey: e.target.value })}
- className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-teal-500"
- />
- {slideMode === 'edit' && selectedBroker && (
-
Date Created: {selectedBroker.dateCreated}
- )}
-
-
-
-
- setFormData({ ...formData, secretKey: e.target.value })}
- className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-teal-500"
- />
-
-
-
-
- {/* Footer */}
-
-
-
-
-
-
- >
- )}
-
- );
+export default function BrokersPage() {
+ return ;
}
\ No newline at end of file
diff --git a/src/app/components/NavList.jsx b/src/app/components/NavList.jsx
deleted file mode 100644
index 3a50e81..0000000
--- a/src/app/components/NavList.jsx
+++ /dev/null
@@ -1,32 +0,0 @@
-"use client";
-import Link from "next/link";
-import { usePathname } from "next/navigation";
-import { motion } from "framer-motion";
-
-export default function NavList({ list_items }) {
- const pathname = usePathname();
-
- return (
-
- );
-}
diff --git a/src/app/constants/broker.js b/src/app/constants/broker.js
deleted file mode 100644
index 7e65ec0..0000000
--- a/src/app/constants/broker.js
+++ /dev/null
@@ -1,27 +0,0 @@
-export const BROKER_OPTIONS = ['Masak', 'AngelOne', 'Zerodha', 'Dhan'];
-
-export const STATUS_TYPES = {
- ACTIVE: 'active',
- INACTIVE: 'inactive',
- EXPIRED: 'expired',
-};
-
-export const STATUS_COLORS = {
- [STATUS_TYPES.ACTIVE]: 'bg-green-500',
- [STATUS_TYPES.EXPIRED]: 'bg-red-500',
- [STATUS_TYPES.INACTIVE]: 'bg-yellow-500',
-};
-
-export const INITIAL_BROKERS = [
- {
- id: 'BR301',
- name: 'Techbonds Markets',
- broker: 'Masak',
- dateAdded: 'Feb 16, 2025',
- status: 'active',
- balance: '$978.50',
- apiKey: 'api_key_123456789abcdef',
- secretKey: 'sk_412345LH...',
- dateCreated: '04/12/2025',
- },
-];
\ No newline at end of file
diff --git a/src/app/favicon.ico b/src/app/favicon.ico
deleted file mode 100644
index 718d6fe..0000000
Binary files a/src/app/favicon.ico and /dev/null differ
diff --git a/src/app/globals.css b/src/app/globals.css
index aea1e91..f3b9b21 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -1,87 +1,5 @@
@import "tailwindcss";
@theme {
- /* Gray */
- --color-gray-50: #f9fafb;
- --color-gray-100: #f3f4f6;
- --color-gray-200: #e5e7eb;
- --color-gray-300: #d1d5db;
- --color-gray-400: #9ca3af;
- --color-gray-500: #6b7280;
- --color-gray-600: #4b5563;
- --color-gray-700: #374151;
- --color-gray-800: #1f2937;
- --color-gray-900: #111827;
-
- /* Red */
- --color-red-50: #fef2f2;
- --color-red-100: #fee2e2;
- --color-red-200: #fecaca;
- --color-red-300: #fca5a5;
- --color-red-400: #f87171;
- --color-red-500: #ef4444;
- --color-red-600: #dc2626;
- --color-red-700: #b91c1c;
- --color-red-800: #991b1b;
- --color-red-900: #7f1d1d;
-
- /* Green */
- --color-green-50: #f0fdf4;
- --color-green-100: #dcfce7;
- --color-green-200: #bbf7d0;
- --color-green-300: #86efac;
- --color-green-400: #4ade80;
- --color-green-500: #22c55e;
- --color-green-600: #16a34a;
- --color-green-700: #15803d;
- --color-green-800: #166534;
- --color-green-900: #14532d;
-
- /* Blue */
- --color-blue-50: #eff6ff;
- --color-blue-100: #dbeafe;
- --color-blue-200: #bfdbfe;
- --color-blue-300: #93c5fd;
- --color-blue-400: #60a5fa;
- --color-blue-500: #3b82f6;
- --color-blue-600: #2563eb;
- --color-blue-700: #1d4ed8;
- --color-blue-800: #1e40af;
- --color-blue-900: #1e3a8a;
-
- /* Yellow */
- --color-yellow-50: #fefce8;
- --color-yellow-100: #fef9c3;
- --color-yellow-200: #fef08a;
- --color-yellow-300: #fde047;
- --color-yellow-400: #facc15;
- --color-yellow-500: #eab308;
- --color-yellow-600: #ca8a04;
- --color-yellow-700: #a16207;
- --color-yellow-800: #854d0e;
- --color-yellow-900: #713f12;
-
- /* Purple */
- --color-purple-50: #faf5ff;
- --color-purple-100: #f3e8ff;
- --color-purple-200: #e9d5ff;
- --color-purple-300: #d8b4fe;
- --color-purple-400: #c084fc;
- --color-purple-500: #a855f7;
- --color-purple-600: #9333ea;
- --color-purple-700: #7e22ce;
- --color-purple-800: #6b21a8;
- --color-purple-900: #581c87;
-
- /* Orange */
- --color-orange-50: #fff7ed;
- --color-orange-100: #ffedd5;
- --color-orange-200: #fed7aa;
- --color-orange-300: #fdba74;
- --color-orange-400: #fb923c;
- --color-orange-500: #f97316;
- --color-orange-600: #ea580c;
- --color-orange-700: #c2410c;
- --color-orange-800: #9a3412;
- --color-orange-900: #7c2d12;
+
}
diff --git a/src/app/layout.js b/src/app/layout.js
index 79e56c0..c577afb 100644
--- a/src/app/layout.js
+++ b/src/app/layout.js
@@ -1,6 +1,6 @@
import "./globals.css";
import { Geist, Geist_Mono } from "next/font/google";
-import Header from "./layouts/Header";
+import Header from "../layouts/Header";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
diff --git a/src/app/layouts/Header.jsx b/src/app/layouts/Header.jsx
deleted file mode 100644
index 3d83cf1..0000000
--- a/src/app/layouts/Header.jsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import NavList from "../components/NavList";
-
-import Image from "next/image";
-import logo from '../assets/HookNestLogo.png'
-
-export default function Header(){
- const list_items=[
- {id:1,name:"Dashboard",routeLink:"/"},
- {id:2,name:"Brokers",routeLink:"/Brokers"},
- {id:3,name:"Scan & Tracks",routeLink:"/Scan_Tracks"},
- {id:4,name:"Positions",routeLink:"/Positions"},
- {id:5,name:"AI Strategy Builder",routeLink:"/AIStrategyBuilder"},
- ]
- return (
-
- )
-}
\ No newline at end of file
diff --git a/src/components/brokers/BrokerAvatar.js b/src/components/brokers/BrokerAvatar.js
new file mode 100644
index 0000000..9ebba16
--- /dev/null
+++ b/src/components/brokers/BrokerAvatar.js
@@ -0,0 +1,12 @@
+'use client';
+
+export default function BrokerAvatar({ brokerName }) {
+ return (
+
+
+ {brokerName.charAt(0)}
+
+
{brokerName}
+
+ );
+}
diff --git a/src/components/brokers/BrokerForm.js b/src/components/brokers/BrokerForm.js
new file mode 100644
index 0000000..9e7b057
--- /dev/null
+++ b/src/components/brokers/BrokerForm.js
@@ -0,0 +1,86 @@
+'use client';
+
+import FormInput from '@/components/ui/FormInput';
+import FormSelect from '@/components/ui/FormSelect';
+import { BROKER_OPTIONS, STATUS_OPTIONS } from '@/constants/brokers';
+
+export default function BrokerForm({ formData, onChange, mode, selectedBroker }) {
+ return (
+ <>
+
+ Choose your preferred exchange to add a broker.
+
+
+
+
Broker Details
+
+ onChange({ ...formData, name: val })}
+ placeholder="Enter a Name"
+ required
+ />
+
+ onChange({ ...formData, broker: val })}
+ options={BROKER_OPTIONS}
+ placeholder="Select Broker"
+ />
+
+ onChange({ ...formData, balance: val })}
+ placeholder="$0.00"
+ type="text"
+ />
+
+ onChange({ ...formData, status: val })}
+ options={STATUS_OPTIONS}
+ placeholder="Select Status"
+ />
+
+
+
+
+
API Details
+ {mode === 'edit' ? (
+
+ ) : (
+
+ )}
+
+
+
onChange({ ...formData, apiKey: val })}
+ placeholder="api_key_1234567890abcdef"
+ helperText={
+ mode === 'edit' && selectedBroker
+ ? `Date Created: ${selectedBroker.dateCreated}`
+ : ''
+ }
+ />
+
+ onChange({ ...formData, secretKey: val })}
+ placeholder="sk_412345LH..."
+ type="password"
+ />
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/src/components/brokers/BrokerManagement.js b/src/components/brokers/BrokerManagement.js
new file mode 100644
index 0000000..4fd8968
--- /dev/null
+++ b/src/components/brokers/BrokerManagement.js
@@ -0,0 +1,224 @@
+"use client";
+
+import { useState } from "react";
+import BrokerTable from "./BrokerTable";
+import SearchBar from "./SearchBar";
+import StatusFilter from "./StatusFilter";
+import SlidePanel from "@/components/ui/SlidePanel";
+import BrokerForm from "./BrokerForm";
+import { Plus, Download, SlidersHorizontal } from "lucide-react";
+import { filterBrokers, createNewBroker } from "@/utils/brokerHelpers";
+import { INITIAL_BROKERS } from "@/constants/brokers";
+
+export default function BrokerManagement() {
+ // Broker state
+ const [brokers, setBrokers] = useState(INITIAL_BROKERS);
+
+ // Slide panel state
+ const [isSlideOpen, setIsSlideOpen] = useState(false);
+ const [slideMode, setSlideMode] = useState("add");
+ const [selectedBroker, setSelectedBroker] = useState(null);
+
+ // Filter state - default to 'active'
+ const [searchTerm, setSearchTerm] = useState("");
+ const [filterStatus, setFilterStatus] = useState("active");
+
+ // Hidden rows state
+ const [hiddenRows, setHiddenRows] = useState([]);
+
+ // Form state
+ const [formData, setFormData] = useState({
+ name: "",
+ broker: "",
+ apiKey: "",
+ secretKey: "",
+ balance: "$0.00",
+ status: "active",
+ });
+
+ // Event handlers
+ const handleAdd = () => {
+ setSlideMode("add");
+ setFormData({
+ name: "",
+ broker: "",
+ apiKey: "",
+ secretKey: "",
+ balance: "$0.00",
+ status: "active",
+ });
+ setIsSlideOpen(true);
+ };
+
+ const handleEdit = (broker) => {
+ setSlideMode("edit");
+ setSelectedBroker(broker);
+ setFormData({
+ name: broker.name,
+ broker: broker.broker,
+ apiKey: broker.apiKey,
+ secretKey: broker.secretKey,
+ balance: broker.balance,
+ status: broker.status,
+ });
+ setIsSlideOpen(true);
+ };
+
+ const handleSubmit = () => {
+ if (slideMode === "add") {
+ const newBroker = {
+ ...createNewBroker(formData),
+ balance: formData.balance,
+ status: formData.status,
+ };
+ setBrokers([...brokers, newBroker]);
+ } else if (selectedBroker) {
+ setBrokers(
+ brokers.map((b) =>
+ b.id === selectedBroker.id
+ ? {
+ ...b,
+ name: formData.name,
+ broker: formData.broker,
+ apiKey: formData.apiKey,
+ secretKey: formData.secretKey,
+ balance: formData.balance,
+ status: formData.status,
+ }
+ : b
+ )
+ );
+ }
+ setIsSlideOpen(false);
+ };
+
+ const handleDelete = (id) => {
+ setBrokers(brokers.filter((b) => b.id !== id));
+ setHiddenRows(hiddenRows.filter((rowId) => rowId !== id));
+ };
+
+ const toggleStatus = (id) => {
+ setBrokers(
+ brokers.map((b) =>
+ b.id === id
+ ? { ...b, status: b.status === "active" ? "inactive" : "active" }
+ : b
+ )
+ );
+ };
+
+ const toggleVisibility = (id) => {
+ setHiddenRows((prev) =>
+ prev.includes(id) ? prev.filter((rowId) => rowId !== id) : [...prev, id]
+ );
+ };
+
+ const handleExportCSV = () => {
+ // CSV export logic
+ const headers = [
+ "Name",
+ "API ID",
+ "Broker",
+ "Date Added",
+ "Status",
+ "Balance",
+ ];
+ const csvContent = [
+ headers.join(","),
+ ...filteredBrokers.map((b) =>
+ [b.name, b.id, b.broker, b.dateAdded, b.status, b.balance].join(",")
+ ),
+ ].join("\n");
+
+ const blob = new Blob([csvContent], { type: "text/csv" });
+ const url = window.URL.createObjectURL(blob);
+ const a = document.createElement("a");
+ a.href = url;
+ a.download = "brokers.csv";
+ a.click();
+ };
+
+ // Filter brokers
+ const filteredBrokers = filterBrokers(brokers, searchTerm, filterStatus);
+
+ return (
+
+ {/* Header */}
+
+
+
+
+ Brokers / API Management
+
+
+
+
+
+
+
+ {/* Filters */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Table */}
+
+
+ {/* Slide Panel */}
+
setIsSlideOpen(false)}
+ title={slideMode === "add" ? "Add Broker" : "Edit Broker"}
+ onSubmit={handleSubmit}
+ onCancel={() => setIsSlideOpen(false)}
+ submitLabel={slideMode === "add" ? "Add" : "Save"}
+ >
+
+
+
+
+
+ );
+}
diff --git a/src/components/brokers/BrokerTable.js b/src/components/brokers/BrokerTable.js
new file mode 100644
index 0000000..a4ab2ef
--- /dev/null
+++ b/src/components/brokers/BrokerTable.js
@@ -0,0 +1,54 @@
+'use client';
+
+import TableRow from './TableRow';
+
+export default function BrokerTable({ brokers, onEdit, onDelete, onToggleStatus, onToggleVisibility, hiddenRows }) {
+ return (
+
+
+
+
+ |
+ Name
+ |
+
+ API ID
+ |
+
+ Broker
+ |
+
+ Date Added
+ |
+
+ Status
+ |
+
+ Balance
+ |
+
+ Actions
+ |
+
+ On/Off
+ |
+
+
+
+ {brokers.map((broker,index) => (
+
+ ))}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/brokers/SearchBar.js b/src/components/brokers/SearchBar.js
new file mode 100644
index 0000000..0fe82ca
--- /dev/null
+++ b/src/components/brokers/SearchBar.js
@@ -0,0 +1,21 @@
+'use client';
+
+import { Search } from 'lucide-react';
+
+export default function SearchBar({ searchTerm, onSearchChange }) {
+ return (
+
+
+ onSearchChange(e.target.value)}
+ className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-teal-500"
+ />
+
+ );
+}
diff --git a/src/components/brokers/StatusFilter.js b/src/components/brokers/StatusFilter.js
new file mode 100644
index 0000000..161115e
--- /dev/null
+++ b/src/components/brokers/StatusFilter.js
@@ -0,0 +1,36 @@
+'use client';
+
+import { Filter } from 'lucide-react';
+
+export default function StatusFilter({ activeFilter, onFilterChange }) {
+ const filters = [
+ { value: 'all', label: 'All' },
+ { value: 'active', label: 'Active' },
+ { value: 'inactive', label: 'Inactive' },
+ { value: 'expired', label: 'Expired' }
+ ];
+
+ return (
+ <>
+ {/* */}
+
+ {filters.map((filter) => (
+
+ ))}
+
+ >
+ );
+}
diff --git a/src/components/brokers/StatusIndicator.js b/src/components/brokers/StatusIndicator.js
new file mode 100644
index 0000000..dbfaa79
--- /dev/null
+++ b/src/components/brokers/StatusIndicator.js
@@ -0,0 +1,11 @@
+'use client';
+
+import { STATUS_COLORS } from '@/constants/brokers';
+
+export default function StatusIndicator({ status }) {
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/brokers/TableRow.js b/src/components/brokers/TableRow.js
new file mode 100644
index 0000000..b0cfd7c
--- /dev/null
+++ b/src/components/brokers/TableRow.js
@@ -0,0 +1,64 @@
+'use client';
+
+import { Edit2, Trash2, Eye, EyeOff } from 'lucide-react';
+import BrokerAvatar from './BrokerAvatar';
+import StatusIndicator from './StatusIndicator';
+import ToggleSwitch from '@/components/ui/ToggleSwitch';
+
+export default function TableRow({ index,broker, onEdit, onDelete, onToggleStatus, onToggleVisibility, isHidden }) {
+ if (isHidden) return null;
+
+ return (
+
+ |
+ {broker.name}
+ |
+
+ {broker.id}
+ |
+
+
+ |
+
+ {broker.dateAdded}
+ |
+
+
+ |
+
+ {broker.balance}
+ |
+
+
+
+
+
+
+ |
+
+ onToggleStatus(broker.id)}
+ />
+ |
+
+ );
+}
diff --git a/src/components/ui/Button.js b/src/components/ui/Button.js
new file mode 100644
index 0000000..e69de29
diff --git a/src/components/ui/FormInput.js b/src/components/ui/FormInput.js
new file mode 100644
index 0000000..7b75d21
--- /dev/null
+++ b/src/components/ui/FormInput.js
@@ -0,0 +1,29 @@
+'use client';
+
+export default function FormInput({
+ label,
+ value,
+ onChange,
+ placeholder,
+ type = "text",
+ required = false,
+ helperText
+}) {
+ return (
+
+
+
onChange(e.target.value)}
+ className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-teal-500"
+ />
+ {helperText && (
+
{helperText}
+ )}
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/ui/FormSelect.js b/src/components/ui/FormSelect.js
new file mode 100644
index 0000000..7ea0f6f
--- /dev/null
+++ b/src/components/ui/FormSelect.js
@@ -0,0 +1,23 @@
+'use client';
+
+export default function FormSelect({ label, value, onChange, options, placeholder }) {
+ return (
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/ui/SlidePanel.js b/src/components/ui/SlidePanel.js
new file mode 100644
index 0000000..a10dde3
--- /dev/null
+++ b/src/components/ui/SlidePanel.js
@@ -0,0 +1,57 @@
+'use client';
+
+import { X } from 'lucide-react';
+
+export default function SlidePanel({
+ isOpen,
+ onClose,
+ title,
+ children,
+ onSubmit,
+ submitLabel,
+ onCancel
+}) {
+ if (!isOpen) return null;
+
+ return (
+ <>
+
+
+
+
+
+
{title}
+
+
+
+
+ {children}
+
+
+
+
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/src/components/ui/ToggleSwitch.js b/src/components/ui/ToggleSwitch.js
new file mode 100644
index 0000000..dc5d85b
--- /dev/null
+++ b/src/components/ui/ToggleSwitch.js
@@ -0,0 +1,18 @@
+'use client';
+
+export default function ToggleSwitch({ isActive, onToggle }) {
+ return (
+
+ );
+}
diff --git a/src/constants/brokers.js b/src/constants/brokers.js
new file mode 100644
index 0000000..868334e
--- /dev/null
+++ b/src/constants/brokers.js
@@ -0,0 +1,84 @@
+export const BROKER_OPTIONS = ['Masak', 'AngelOne', 'Zerodha', 'Dhan'];
+
+export const STATUS_OPTIONS = ['active', 'inactive', 'expired'];
+
+export const STATUS_TYPES = {
+ ACTIVE: 'active',
+ INACTIVE: 'inactive',
+ EXPIRED: 'expired',
+};
+
+export const STATUS_COLORS = {
+ [STATUS_TYPES.ACTIVE]: 'bg-green-500',
+ [STATUS_TYPES.EXPIRED]: 'bg-red-500',
+ [STATUS_TYPES.INACTIVE]: 'bg-yellow-500',
+};
+
+export const INITIAL_BROKERS = [
+ {
+ id: 'BR301',
+ name: 'Techbonds Markets',
+ broker: 'Masak',
+ dateAdded: 'Feb 16, 2025',
+ status: 'active',
+ balance: '$978.50',
+ apiKey: 'api_key_123456789abcdef',
+ secretKey: 'sk_412345LH...',
+ dateCreated: '04/12/2025',
+ },
+ {
+ id: 'BR295',
+ name: 'Techbonds Markets',
+ broker: 'AngelOne',
+ dateAdded: 'Mar 02, 2025',
+ status: 'expired',
+ balance: '$978.50',
+ apiKey: 'api_key_987654321fedcba',
+ secretKey: 'sk_987654LH...',
+ dateCreated: '03/02/2025',
+ },
+ {
+ id: 'BR298',
+ name: 'MarketEases',
+ broker: 'Masak',
+ dateAdded: 'Feb 14, 2025',
+ status: 'active',
+ balance: '$102.25',
+ apiKey: 'api_key_111222333444555',
+ secretKey: 'sk_111222LH...',
+ dateCreated: '02/14/2025',
+ },
+ {
+ id: 'BR293',
+ name: 'Techbonds Markets',
+ broker: 'Zerodha',
+ dateAdded: 'Mar 03, 2025',
+ status: 'inactive',
+ balance: '$978.50',
+ apiKey: 'api_key_555444333222111',
+ secretKey: 'sk_555444LH...',
+ dateCreated: '03/03/2025',
+ },
+ {
+ id: 'BR297',
+ name: 'Techbonds Markets',
+ broker: 'Dhan',
+ dateAdded: 'Feb 14, 2025',
+ status: 'active',
+ balance: '$102.25',
+ apiKey: 'api_key_666777888999000',
+ secretKey: 'sk_666777LH...',
+ dateCreated: '02/14/2025',
+ },
+ {
+ id: 'BR292',
+ name: 'Techbonds Markets',
+ broker: 'AngelOne',
+ dateAdded: 'Mar 02, 2025',
+ status: 'inactive',
+ balance: '$978.50',
+ apiKey: 'api_key_000999888777666',
+ secretKey: 'sk_000999LH...',
+ dateCreated: '03/02/2025',
+ },
+];
diff --git a/src/hooks/useBroker.js b/src/hooks/useBroker.js
new file mode 100644
index 0000000..4cb3d9b
--- /dev/null
+++ b/src/hooks/useBroker.js
@@ -0,0 +1,41 @@
+'use client';
+
+import { useState } from 'react';
+import { INITIAL_BROKERS } from '@/constants/brokers';
+import {
+ createNewBroker,
+ updateBrokerData
+} from '@/utils/brokerHelpers';
+
+export function useBrokers() {
+ const [brokers, setBrokers] = useState(INITIAL_BROKERS);
+
+ const addBroker = (formData) => {
+ const newBroker = createNewBroker(formData);
+ setBrokers(prev => [...prev, newBroker]);
+ };
+
+ const updateBroker = (brokerId, formData) => {
+ setBrokers(prev => updateBrokerData(prev, brokerId, formData));
+ };
+
+ const deleteBroker = (id) => {
+ setBrokers(prev => prev.filter(b => b.id !== id));
+ };
+
+ const toggleBrokerStatus = (id) => {
+ setBrokers(prev => prev.map(b =>
+ b.id === id
+ ? { ...b, status: b.status === 'active' ? 'inactive' : 'active' }
+ : b
+ ));
+ };
+
+ return {
+ brokers,
+ addBroker,
+ updateBroker,
+ deleteBroker,
+ toggleBrokerStatus,
+ };
+}
\ No newline at end of file
diff --git a/src/layouts/Header.js b/src/layouts/Header.js
new file mode 100644
index 0000000..3d33002
--- /dev/null
+++ b/src/layouts/Header.js
@@ -0,0 +1,38 @@
+'use client';
+
+import NavList from "./NavList";
+import { Bell, User } from 'lucide-react';
+
+export default function Header() {
+ const list_items = [
+ { id: 1, name: "Dashboard", routeLink: "/" },
+ { id: 2, name: "Brokers", routeLink: "/Brokers" },
+ { id: 3, name: "Scan & Tracks", routeLink: "/Scan_Tracks" },
+ { id: 4, name: "Positions", routeLink: "/Positions" },
+ { id: 5, name: "AI Strategy Builder", routeLink: "/AIStrategyBuilder" },
+ ];
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/layouts/NavList.js b/src/layouts/NavList.js
new file mode 100644
index 0000000..2add074
--- /dev/null
+++ b/src/layouts/NavList.js
@@ -0,0 +1,40 @@
+'use client';
+
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+import { motion } from "framer-motion";
+
+export default function NavList({ list_items }) {
+ const pathname = usePathname();
+
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/src/utils/brokerHelpers.js b/src/utils/brokerHelpers.js
new file mode 100644
index 0000000..9569d37
--- /dev/null
+++ b/src/utils/brokerHelpers.js
@@ -0,0 +1,48 @@
+export function filterBrokers(brokers, searchTerm, filterStatus) {
+ return brokers.filter(broker => {
+ const matchesSearch =
+ broker.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
+ broker.broker.toLowerCase().includes(searchTerm.toLowerCase());
+
+ const matchesFilter =
+ filterStatus === 'all' || broker.status === filterStatus;
+
+ return matchesSearch && matchesFilter;
+ });
+}
+
+export function generateBrokerId() {
+ return `BR${Math.floor(Math.random() * 1000)}`;
+}
+
+export function createNewBroker(formData) {
+ return {
+ id: generateBrokerId(),
+ name: formData.name,
+ broker: formData.broker,
+ dateAdded: new Date().toLocaleDateString('en-US', {
+ month: 'short',
+ day: '2-digit',
+ year: 'numeric'
+ }),
+ status: 'active',
+ balance: '$0.00',
+ apiKey: formData.apiKey,
+ secretKey: formData.secretKey,
+ dateCreated: new Date().toLocaleDateString('en-US'),
+ };
+}
+
+export function updateBrokerData(brokers, brokerId, formData) {
+ return brokers.map(b =>
+ b.id === brokerId
+ ? {
+ ...b,
+ name: formData.name,
+ broker: formData.broker,
+ apiKey: formData.apiKey,
+ secretKey: formData.secretKey
+ }
+ : b
+ );
+}
\ No newline at end of file