A modern, full-stack stock market tracking and analysis platform built with Next.js 15, featuring real-time market data, watchlists, personalized news, and comprehensive stock analysis tools.
π Live Demo: https://dukem-stock.vercel.app/
- Real-time Search: Search stocks using Finnhub API with autocomplete
- Popular Stocks: Browse top 10 popular stocks when no query is provided
- Keyboard Shortcuts: Quick access with
Cmd/Ctrl + K
- Interactive Charts: Multiple TradingView widgets including:
- Market Overview
- Stock Heatmaps
- Candlestick Charts
- Baseline Charts
- Technical Analysis
- Company Profiles: Detailed company information and financials
- Real-time Data: Live market quotes and price updates
- Personal Watchlists: Add/remove stocks to your watchlist
- Persistent Storage: MongoDB-backed watchlist with user authentication
- Duplicate Prevention: Compound indexes prevent duplicate entries
- Daily News Summary: Scheduled emails at 12 PM UTC daily
- Company-Specific News: Get news for stocks in your watchlist
- Smart Distribution: Round-robin news fetching (max 6 articles per user)
- AI-Powered Summaries: Gemini AI integration for personalized content
- Market News Fallback: General market news when no watchlist exists
- Better Auth Integration: Secure email/password authentication
- User Profiles: Store investment goals, risk tolerance, and preferences
- Country Selection: International support with country-specific features
- Personalized Onboarding: AI-generated welcome emails
- Responsive Design: Mobile-first approach with Tailwind CSS
- Dark Mode: Custom dark theme optimized for trading
- ShadCN Components: Beautiful, accessible UI components
- Command Palette: Quick navigation and search
- Framework: Next.js 15 (App Router, React 19, Turbopack)
- Styling: Tailwind CSS 4 with custom animations
- UI Components: Radix UI + ShadCN
- State Management: React Hooks
- Forms: React Hook Form
- Icons: Lucide React
- Runtime: Node.js with Next.js API Routes
- Database: MongoDB with Mongoose ODM
- Authentication: Better Auth
- Job Scheduling: Inngest (cron jobs & event-driven functions)
- Email: Nodemailer
- AI Integration: Google Gemini API
- Market Data: Finnhub API
- Charts: TradingView Widgets
- Symbol Conversion: Custom Finnhub β TradingView mapping
dukem-stock/
βββ app/
β βββ (auth)/ # Authentication pages
β β βββ sign-in/
β β βββ sign-up/
β βββ (root)/ # Main application
β β βββ page.tsx # Dashboard
β β βββ stocks/
β β βββ [symbol]/ # Stock details page
β βββ api/
β β βββ inngest/ # Inngest function handlers
β βββ globals.css
β βββ layout.tsx
βββ components/
β βββ forms/ # Form components
β βββ ui/ # ShadCN components
β βββ Header.tsx
β βββ SearchCommand.tsx # Cmd+K search
β βββ TradingViewWidget.tsx
β βββ WatchlistButton.tsx
βββ database/
β βββ models/
β β βββ watchlist.model.ts
β βββ mongoose.ts # Database connection
βββ lib/
β βββ actions/ # Server actions
β β βββ auth.action.ts
β β βββ finnhub.actions.ts
β β βββ user.actions.ts
β β βββ watchlist.actions.ts
β βββ better-auth/ # Auth configuration
β βββ inngest/ # Job definitions
β βββ nodemailer/ # Email templates
β βββ constants.ts # Widget configs
β βββ utils.ts # Utility functions
βββ hooks/ # Custom React hooks
βββ middleware/ # Auth middleware
βββ types/
βββ global.d.ts # TypeScript definitions
- Node.js 20+
- MongoDB database
- Finnhub API key
- Gemini API key (optional, for AI features)
- Clone the repository
git clone https://github.com/vvduth/dukem-stock.git
cd dukem-stock- Install dependencies
npm install- Set up environment variables
Create a .env.local file:
# Database
MONGODB_URI=your_mongodb_connection_string
# Finnhub API
NEXT_PUBLIC_FINNHUB_API_KEY=your_finnhub_api_key
# Better Auth
BETTER_AUTH_SECRET=your_secret_key
BETTER_AUTH_URL=http://localhost:3000
# Gemini AI (optional)
GEMINI_API_KEY=your_gemini_api_key
# Email (optional)
NODEMAILER_EMAIL=ducthai060501@gmail.com
NODEMAILER_PASSWORD=rdfgfzysrbrmpnxv- Run the development server
npm run dev- Run Inngest dev server (in separate terminal)
npx inngest-cli@latest dev- Open the app
Navigate to http://localhost:3000
// Uses React cache for optimal performance
export const searchStocks = cache(async (query?: string) => {
// Returns popular stocks if no query
// Searches Finnhub API with query
// Maps to StockWithWatchlistStatus
});The app handles symbol format differences between Finnhub and TradingView:
// Finnhub: FIA1S.HE β TradingView: OMXH:FIA1S
export function finnhubToTradingViewSymbol(symbol: string) {
// Maps exchange suffixes to prefixes
// Supports multiple international exchanges
}export const sendDailyNewsSummary = inngest.createFunction(
{ id: "daily-news-summary" },
[{ event: "app/send.daily.news" }, { cron: "0 12 * * *" }],
async ({ step }) => {
// 1. Get all users
// 2. Fetch personalized news per user
// 3. Summarize with AI
// 4. Send emails
}
);GET /api/inngest- Inngest webhook endpoint- Server Actions (via Next.js):
searchStocks(query)- Search stocksgetNews(symbols)- Fetch newsgetWatchlistSymbolsByEmail(email)- Get user watchlist
Widget configurations are stored in /lib/constants.ts:
SYMBOL_INFO_WIDGET_CONFIGCANDLE_CHART_WIDGET_CONFIGBASELINE_WIDGET_CONFIGTECHNICAL_ANALYSIS_WIDGET_CONFIGCOMPANY_PROFILE_WIDGET_CONFIGCOMPANY_FINANCIALS_WIDGET_CONFIG
- Sign-up Email: Triggered on user creation
- Daily News Summary: Runs daily at 12 PM UTC
Contributions are welcome! Please feel free to submit a Pull Request.
This project is open source and available under the MIT License.
- Finnhub for market data API
- TradingView for interactive charts
- Vercel for hosting
- ShadCN for UI components
For questions or feedback, please open an issue on GitHub.
Built using Next.js and modern web technologies.
