From f1ac6c429ec8ec6eb9be2684382c22fba226ee45 Mon Sep 17 00:00:00 2001 From: mnsrulz Date: Wed, 17 Apr 2024 03:05:13 +0000 Subject: [PATCH] menu bar with logout and some minor tweeks in the trades grid --- src/app/api/watchlist/route.ts | 12 +++ src/app/routes.tsx | 184 ++++++++++++++++++++++++++++++++- src/components/trades.tsx | 6 +- src/lib/socket.ts | 2 +- src/lib/types.ts | 1 + src/lib/useTrades.ts | 6 +- 6 files changed, 203 insertions(+), 8 deletions(-) diff --git a/src/app/api/watchlist/route.ts b/src/app/api/watchlist/route.ts index 58752cc..3327260 100644 --- a/src/app/api/watchlist/route.ts +++ b/src/app/api/watchlist/route.ts @@ -31,4 +31,16 @@ export async function POST(request: Request) { }) } return NextResponse.json(inputJson); +} + +//may be better to expose as a separte endoint?? +export async function DELETE(request: Request) { + const inputJson: AddToWatchlistRequest = await request.json(); + const { symbol } = inputJson; + await prisma.watchlist.delete({ + where: { + symbol + } + }); + return NextResponse.json(inputJson); } \ No newline at end of file diff --git a/src/app/routes.tsx b/src/app/routes.tsx index 13b02c9..3e4c56d 100644 --- a/src/app/routes.tsx +++ b/src/app/routes.tsx @@ -12,7 +12,25 @@ import { } from 'react-router-dom'; import { StaticRouter } from 'react-router-dom/server'; -import { ButtonGroup, Button } from '@mui/material'; +import { ButtonGroup, Button, AppBar, Avatar, Container, IconButton, Menu, MenuItem, Toolbar, Tooltip } from '@mui/material'; +import { useState } from 'react'; +import MenuIcon from '@mui/icons-material/Menu'; +import AdbIcon from '@mui/icons-material/Adb'; +import AccountCircle from '@mui/icons-material/AccountCircle'; +import { signOut } from 'next-auth/react' + +/* + + + +*/ + +const pages = [ + { title: 'Home', href: '/' }, + { title: 'Trades', href: '/trades' }, + { title: 'History', href: '/history' } +]; +const settings = ['Profile', 'Logout']; function Router(props: { children?: React.ReactNode }) { const { children } = props; @@ -74,14 +92,172 @@ function CurrentRoute() { } export default function TabsRouter() { + const [anchorElNav, setAnchorElNav] = useState(null); + const [anchorElUser, setAnchorElUser] = useState(null); + + const handleOpenNavMenu = (event: React.MouseEvent) => { + setAnchorElNav(event.currentTarget); + }; + const handleOpenUserMenu = (event: React.MouseEvent) => { + setAnchorElUser(event.currentTarget); + }; + + const handleCloseNavMenu = () => { + setAnchorElNav(null); + }; + + const handleCloseUserMenu = () => { + setAnchorElUser(null); + }; + + const handleSignout = () => { + handleCloseUserMenu(); + signOut(); + } + return ( - - {/* + {/* } /> */} + {/* - + */} + + + + {/* */} + {/* + MZ + */} + + + + + + + {pages.map((page) => ( + + {/* {page.title} */} + {page.title} + {/* */} + + ))} + + + + + LOGO + + + {pages.map((page) => ( + + ))} + + + + + + + + + + {/* {settings.map((setting) => ( + + {setting} + + ))} */} + + Sign Out + + + + + + ); } \ No newline at end of file diff --git a/src/components/trades.tsx b/src/components/trades.tsx index dc52559..2d28bdf 100644 --- a/src/components/trades.tsx +++ b/src/components/trades.tsx @@ -49,7 +49,7 @@ export const TradeList = () => { // { field: 'strikePrice', width: 90, headerName: 'Strike Price', type: 'number', valueFormatter: currencyFormatter }, // { field: 'numberOfContracts', width: 60, sortable: false, filterable: false, hideable: false, headerName: 'Size', type: 'number' }, { field: 'contractPrice', width: 60, headerName: 'Price', type: 'number', valueFormatter: currencyFormatter }, - { field: 'lastContractPrice', width: 60, headerName: 'Price', type: 'number', valueFormatter: currencyFormatter }, + { field: 'lastContractPrice', width: 80, headerName: 'Last Price', type: 'number', valueFormatter: currencyFormatter }, { field: 'buyCost', width: 70, headerName: 'Buy Cost', type: 'number', valueFormatter: fixedCurrencyFormatter }, { field: 'sellCost', width: 70, headerName: 'Sell Cost', type: 'number', valueFormatter: fixedCurrencyFormatter }, { @@ -64,6 +64,10 @@ export const TradeList = () => { field: 'actualProfitPerDay', width: 70, headerName: 'PnL/day', type: 'number', valueFormatter: currencyFormatter, renderCell: (p) => }, + { + field: 'remainingProfitPerDay', width: 70, headerName: 'Remaining PnL/day', type: 'number', valueFormatter: currencyFormatter, + renderCell: (p) => + }, { field: 'maximumRisk', width: 60, headerName: 'Risk', type: 'number', valueFormatter: fixedCurrencyFormatter, renderCell: (p) => diff --git a/src/lib/socket.ts b/src/lib/socket.ts index b272135..afeb311 100644 --- a/src/lib/socket.ts +++ b/src/lib/socket.ts @@ -84,7 +84,7 @@ export const useMyStockList = () => { }, []); const removeFromWatchlist = useCallback((item: SearchTickerItem) => { - ky.delete(`/api/watchlist`, { json: item }).json().then(r => setMyTickers(mytickers.filter(i => i.symbol != item.symbol))); + ky.delete(`/api/watchlist`, { json: item }).json().then(r => setMyTickers((ii) => ii.filter(i => i.symbol != item.symbol))); }, []); return { mytickers, addToWatchlist, removeFromWatchlist }; diff --git a/src/lib/types.ts b/src/lib/types.ts index 121ca9d..1beedf0 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -9,6 +9,7 @@ export interface ITradeView extends Trade { actualProfit: number actualAnnualizedReturn: number actualProfitPerDay: number + remainingProfitPerDay: number buyCost: number, sellCost: number, isClosed: boolean, diff --git a/src/lib/useTrades.ts b/src/lib/useTrades.ts index d676d05..19b1ebf 100644 --- a/src/lib/useTrades.ts +++ b/src/lib/useTrades.ts @@ -7,7 +7,7 @@ import { ITradeView } from "./types"; const SellContracts = ['PUT_SELL', 'CALL_SELL']; -export const mapTradeToView = (trade: Trade): ITradeView => { +export const mapTradeToView = (trade: Trade): ITradeView => { const isSellContract = SellContracts.includes(trade.contractType); const sellCost = isSellContract ? (Number(trade.contractPrice) * 100 * trade.numberOfContracts) : 0; const buyCost = (isSellContract && trade.contractPriceAtClose) ? (Number(trade.contractPriceAtClose) * 100 * trade.numberOfContracts) : NaN; @@ -27,6 +27,7 @@ export const mapTradeToView = (trade: Trade): ITradeView => { const maxAnnualizedReturn = (sellCost / maximumRisk) * (365 / tradeDays); const actualAnnualizedReturn = (actualProfit / maximumRisk) * (365 / actualTradeDays); const actualProfitPerDay = (actualProfit / actualTradeDays); + const remainingProfitPerDay = actualProfit > 0 ? ((maximumProfit - actualProfit) / (tradeDays - actualTradeDays)) : NaN; return { ...trade, @@ -40,7 +41,8 @@ export const mapTradeToView = (trade: Trade): ITradeView => { actualProfitPerDay, isClosed, maxReturn, - actualProfit + actualProfit, + remainingProfitPerDay } }