From d6d6323077996f19e43de32254ec1b1da6cd677c Mon Sep 17 00:00:00 2001 From: "Mr. Algorithm" <11aravipratapsingh@gmail.com> Date: Sun, 1 Feb 2026 04:20:04 +0530 Subject: [PATCH] feat: implement watchlist sorting by symbol --- app/(root)/watchlist/page.tsx | 35 +-------- components/watchlist/WatchlistManager.tsx | 95 +++++++++++++++++++++++ 2 files changed, 99 insertions(+), 31 deletions(-) create mode 100644 components/watchlist/WatchlistManager.tsx diff --git a/app/(root)/watchlist/page.tsx b/app/(root)/watchlist/page.tsx index 08ad167..c1ffdb2 100644 --- a/app/(root)/watchlist/page.tsx +++ b/app/(root)/watchlist/page.tsx @@ -2,11 +2,10 @@ import React, { Suspense } from 'react'; import { auth } from '@/lib/better-auth/auth'; import { headers } from 'next/headers'; import { redirect } from 'next/navigation'; -import { getUserWatchlist, isStockInWatchlist, removeFromWatchlist } from '@/lib/actions/watchlist.actions'; +import { getUserWatchlist } from '@/lib/actions/watchlist.actions'; import { getUserAlerts } from '@/lib/actions/alert.actions'; import { getNews } from '@/lib/actions/finnhub.actions'; -import TradingViewWatchlist from '@/components/watchlist/TradingViewWatchlist'; -import WatchlistStockChip from '@/components/watchlist/WatchlistStockChip'; +import WatchlistManager from '@/components/watchlist/WatchlistManager'; import AlertsPanel from '@/components/watchlist/AlertsPanel'; import NewsGrid from '@/components/watchlist/NewsGrid'; import SearchCommand from '@/components/SearchCommand'; @@ -23,16 +22,14 @@ export default async function WatchlistPage() { const userId = session.user.id; - // Parallel data fetching // Parallel data fetching const [watchlistItems, alerts, news] = await Promise.all([ getUserWatchlist(userId), getUserAlerts(userId), - getNews() // Initial news fetch, maybe refine later to use watchlist symbols + getNews() // Initial news fetch ]); const watchlistSymbols = watchlistItems.map((item: any) => item.symbol); - // const watchlistData = await getWatchlistData(watchlistSymbols); // OPTIMIZATION: Removed to prevent 429 errors. Widget handles data. // Fallback news if watchlist has items const relevantNews = watchlistSymbols.length > 0 ? await getNews(watchlistSymbols) : news; @@ -56,31 +53,7 @@ export default async function WatchlistPage() { {/* Main Content - Watchlist Table */}
- {/* Manage Watchlist Section */} -
-

- Manage Symbols - {watchlistSymbols.length} -

- {watchlistSymbols.length > 0 ? ( -
- {watchlistItems.map((item: any) => ( - - ))} -
- ) : ( -

No stocks in watchlist.

- )} -
- - {/* TradingView Widget */} -
- -
+
{/* News Section */} diff --git a/components/watchlist/WatchlistManager.tsx b/components/watchlist/WatchlistManager.tsx new file mode 100644 index 0000000..b3ac88b --- /dev/null +++ b/components/watchlist/WatchlistManager.tsx @@ -0,0 +1,95 @@ +'use client'; + +import React, { useState, useMemo } from 'react'; +import WatchlistStockChip from './WatchlistStockChip'; +import TradingViewWatchlist from './TradingViewWatchlist'; +import { Button } from '@/components/ui/button'; +import { ArrowDownAZ, ArrowUpZA, ArrowUpDown } from 'lucide-react'; +import { WatchlistItem } from '@/database/models/watchlist.model'; + +interface WatchlistManagerProps { + initialItems: WatchlistItem[]; // Using the DB model type directly or a simplified version + userId: string; +} + +export default function WatchlistManager({ initialItems, userId }: WatchlistManagerProps) { + // Sort state: 'asc' (A-Z), 'desc' (Z-A), or null (added order/default) + const [sortOrder, setSortOrder] = useState<'asc' | 'desc' | null>(null); + + const toggleSort = () => { + if (sortOrder === null) setSortOrder('asc'); + else if (sortOrder === 'asc') setSortOrder('desc'); + else setSortOrder(null); + }; + + const sortedItems = useMemo(() => { + if (!sortOrder) return initialItems; + + return [...initialItems].sort((a, b) => { + if (sortOrder === 'asc') { + return a.symbol.localeCompare(b.symbol); + } else { + return b.symbol.localeCompare(a.symbol); + } + }); + }, [initialItems, sortOrder]); + + const watchlistSymbols = sortedItems.map((item) => item.symbol); + + return ( +
+
+
+

+ Manage Symbols + + {watchlistSymbols.length} + +

+ +
+ + {watchlistSymbols.length > 0 ? ( +
+ {sortedItems.map((item) => ( + + ))} +
+ ) : ( +

No stocks in watchlist.

+ )} +
+ +
+ +
+
+ ); +}