Skip to content

vvduth/dukem-stock

Repository files navigation

πŸ“ˆ Dukem Stock

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/

Dukem Stock Dashboard

✨ Features

πŸ” Stock Search & Discovery

  • 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

πŸ“Š Market Visualization

  • 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

⭐ Watchlist Management

  • Personal Watchlists: Add/remove stocks to your watchlist
  • Persistent Storage: MongoDB-backed watchlist with user authentication
  • Duplicate Prevention: Compound indexes prevent duplicate entries

πŸ“° Personalized News

  • 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

πŸ” Authentication

  • 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

🎨 Modern UI/UX

  • 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

πŸ› οΈ Tech Stack

Frontend

  • 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

Backend

  • 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

External APIs

  • Market Data: Finnhub API
  • Charts: TradingView Widgets
  • Symbol Conversion: Custom Finnhub ↔ TradingView mapping

πŸ“ Project Structure

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

πŸš€ Getting Started

Prerequisites

  • Node.js 20+
  • MongoDB database
  • Finnhub API key
  • Gemini API key (optional, for AI features)

Installation

  1. Clone the repository
git clone https://github.com/vvduth/dukem-stock.git
cd dukem-stock
  1. Install dependencies
npm install
  1. 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
  1. Run the development server
npm run dev
  1. Run Inngest dev server (in separate terminal)
npx inngest-cli@latest dev
  1. Open the app

Navigate to http://localhost:3000

πŸ“ Key Features Implementation

Stock Search

// 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
});

Symbol Mapping

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
}

Daily News Job

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
  }
);

🎯 API Endpoints

  • GET /api/inngest - Inngest webhook endpoint
  • Server Actions (via Next.js):
    • searchStocks(query) - Search stocks
    • getNews(symbols) - Fetch news
    • getWatchlistSymbolsByEmail(email) - Get user watchlist

πŸ”§ Configuration

TradingView Widgets

Widget configurations are stored in /lib/constants.ts:

  • SYMBOL_INFO_WIDGET_CONFIG
  • CANDLE_CHART_WIDGET_CONFIG
  • BASELINE_WIDGET_CONFIG
  • TECHNICAL_ANALYSIS_WIDGET_CONFIG
  • COMPANY_PROFILE_WIDGET_CONFIG
  • COMPANY_FINANCIALS_WIDGET_CONFIG

Inngest Jobs

  • Sign-up Email: Triggered on user creation
  • Daily News Summary: Runs daily at 12 PM UTC

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“„ License

This project is open source and available under the MIT License.

πŸ™ Acknowledgments

πŸ“§ Contact

For questions or feedback, please open an issue on GitHub.


Built using Next.js and modern web technologies.

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published