Skip to content

πŸŒ™ Ramadan Clock - Modern web app for viewing Sehri & Iftar schedules during Ramadan. Features calendar view, location filtering, PDF export, and admin dashboard. Built with Next.js, MongoDB, and shadcn/ui.

Notifications You must be signed in to change notification settings

montasim/ramadan-clock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

75 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸŒ™ Ramadan Clock - Sehri & Iftar Time Viewer

A modern web application for viewing and managing Sehri & Iftar schedules during Ramadan. Built with Next.js 16, PostgreSQL, and shadcn/ui. Features Aladhan API integration for fetching prayer times and support for all 64 districts of Bangladesh.

✨ Features

Public Features

  • Today's Schedule: View today's Sehri and Iftar times at a glance
  • Full Calendar: Browse complete schedule in a table format
  • Location Filter: Filter schedules by city/location
  • PDF Download: Download schedules as PDF for offline use
  • Dark Mode: Toggle between light and dark themes
  • Mobile Responsive: Works seamlessly on all devices
  • SSR: Server-side rendered pages for optimal SEO and performance

Admin Features

  • Secure Login: Password-protected admin dashboard
  • File Upload: Upload schedules via JSON or CSV files
  • Drag & Drop: Easy file upload with drag and drop support
  • Validation: Real-time validation with error reporting
  • Preview: Preview data before confirming upload
  • Sample Templates: Download sample JSON/CSV templates
  • Dashboard: View statistics and recent uploads

πŸ› οΈ Technology Stack

  • Framework: Next.js 16 (App Router)
  • Language: TypeScript
  • Database: PostgreSQL (via Prisma ORM)
  • UI Components: shadcn/ui + Tailwind CSS v4
  • Authentication: NextAuth.js
  • API Integration: Aladhan API for prayer times
  • Hadith Integration: hadithapi.pages.dev for random hadiths
  • File Parsing: PapaParse (CSV), native JSON parser
  • PDF Generation: jsPDF + jspdf-autotable
  • Validation: Zod
  • Rate Limiting: Token bucket algorithm
  • Caching: Multi-layered caching strategy
  • Time Handling: moment.js + moment-timezone
  • Deployment: Vercel-ready

πŸš€ Getting Started

Prerequisites

  • Node.js 18+
  • PostgreSQL database (local or cloud)
  • pnpm (recommended) or npm

Installation

  1. Clone the repository

    git clone <repository-url>
    cd ramadan-clock
  2. Install dependencies

    pnpm install
  3. Set up environment variables

    cp .env.example .env.local

    Edit .env.local with your configuration. See Environment Variables section for all available options.

  4. Generate Prisma client

    pnpm db:generate
  5. Push schema to database

    pnpm db:push
  6. Seed initial data (optional)

    pnpm db:seed

    This creates:

    • Admin user (email: admin@example.com, password: admin123)
    • Sample time entries for testing
  7. Run the development server

    pnpm dev

    Open http://localhost:3000 to see the app.

Development Tips

Caching Issues?

If you don't see UI changes appearing immediately, use the clean development command:

pnpm dev:clean

For comprehensive cache clearing:

pnpm clean:all

πŸ“– See the Cache Troubleshooting Guide for detailed instructions.

πŸ“ Project Structure

ramadan-clock/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ (home)/              # Public pages
β”‚   β”‚   β”œβ”€β”€ calendar/        # Full schedule calendar
β”‚   β”‚   └── contact/         # Contact page
β”‚   β”œβ”€β”€ admin/               # Admin dashboard
β”‚   β”‚   β”œβ”€β”€ dashboard/       # Dashboard overview
β”‚   β”‚   β”œβ”€β”€ fetch/           # Fetch from Aladhan API
β”‚   β”‚   β”œβ”€β”€ import/          # Import from files
β”‚   β”‚   └── upload/          # Upload schedules
β”‚   β”œβ”€β”€ api/                 # API routes
β”‚   β”‚   β”œβ”€β”€ auth/            # NextAuth authentication
β”‚   β”‚   β”œβ”€β”€ cache/           # Cache debugging
β”‚   β”‚   β”œβ”€β”€ hadith/          # Hadith API
β”‚   β”‚   β”œβ”€β”€ health/          # Health check
β”‚   β”‚   β”œβ”€β”€ pdf/             # PDF generation
β”‚   β”‚   β”œβ”€β”€ prayer-times/    # Prayer times API
β”‚   β”‚   β”œβ”€β”€ progress/        # Progress tracking
β”‚   β”‚   └── schedule/        # Schedule CRUD
β”‚   β”œβ”€β”€ auth/                # Login page
β”‚   └── layout.tsx           # Root layout
β”œβ”€β”€ actions/                 # Server actions
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ admin/               # Admin-specific components
β”‚   β”œβ”€β”€ public/              # Public page components
β”‚   β”œβ”€β”€ seo/                 # SEO components
β”‚   β”œβ”€β”€ shared/              # Shared components
β”‚   └── ui/                  # shadcn/ui components
β”œβ”€β”€ features/                # Feature-based architecture (DDD)
β”‚   └── schedule/            # Schedule domain logic
β”‚       β”œβ”€β”€ domain/          # Domain entities & value objects
β”‚       β”œβ”€β”€ repositories/    # Data access layer
β”‚       β”œβ”€β”€ services/        # Business logic
β”‚       └── use-cases/      # Application use cases
β”œβ”€β”€ hooks/                   # Custom React hooks
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ api/                 # API utilities & middleware
β”‚   β”œβ”€β”€ cache/               # Caching system
β”‚   β”œβ”€β”€ config/              # Configuration modules
β”‚   β”œβ”€β”€ errors/              # Error handling
β”‚   β”œβ”€β”€ guards/              # Authorization guards
β”‚   β”œβ”€β”€ logger/              # Logging system
β”‚   β”œβ”€β”€ parsers/             # File parsers
β”‚   β”œβ”€β”€ progress/            # Progress tracking
β”‚   └── utils.ts             # Utility functions
β”œβ”€β”€ prisma/
β”‚   β”œβ”€β”€ schema.prisma        # Database schema
β”‚   └── seed.ts              # Seed script
└── docs/                    # Documentation
    β”œβ”€β”€ api/                 # API documentation
    └── *.md                 # Feature guides

πŸ“Š Database Schema

TimeEntry

  • id: UUID
  • date: String (YYYY-MM-DD)
  • sehri: String (HH:mm)
  • iftar: String (HH:mm)
  • location: String (nullable)
  • createdAt: DateTime
  • Unique index on (date, location)

AdminUser

  • id: UUID
  • email: String (unique)
  • password: String (hashed)
  • createdAt: DateTime

UploadLog

  • id: UUID
  • fileName: String
  • rowCount: Int
  • status: String (success/partial/failed)
  • errors: String (JSON)
  • uploadedAt: DateTime

RamadanSettings

  • id: UUID
  • startDate: String (YYYY-MM-DD format)
  • endDate: String (YYYY-MM-DD format)
  • createdAt: DateTime
  • updatedAt: DateTime

πŸ“€ File Upload Format

JSON Format

[
  {
    "date": "2026-03-01",
    "sehri": "04:45",
    "iftar": "18:12",
    "location": "Dhaka"
  }
]

CSV Format

date,sehri,iftar,location
2026-03-01,04:45,18:12,Dhaka

Validation Rules

  • Required fields: date, sehri, iftar
  • Optional: location
  • Date format: YYYY-MM-DD
  • Time format: HH:mm
  • Max rows: 1000 per upload
  • File size: Max 1MB
  • No duplicates: (date + location) must be unique

πŸ” Admin Access

Default admin credentials (change in production!):

  • Email: admin@example.com
  • Password: admin123

Access admin dashboard at: /admin/dashboard

🌐 Routes

Public Routes

  • / - Today's Sehri & Iftar
  • /calendar - Full schedule calendar
  • /location/[city] - Location-specific schedule

Admin Routes (Protected)

  • /auth/login - Admin login
  • /admin/dashboard - Dashboard overview
  • /admin/import - Import schedules from files
  • /admin/fetch - Fetch schedules from Aladhan API
  • /admin/upload - Upload schedules with preview

API Routes

  • /api/auth/[...nextauth] - Authentication
  • /api/hadith - Get random hadith
  • /api/health - Health check endpoint
  • /api/pdf - PDF generation
  • /api/prayer-times/fetch - Fetch prayer times from Aladhan API
  • /api/prayer-times/preview - Preview prayer times before import
  • /api/schedule - Schedule CRUD operations
  • /api/schedule/[id] - Single schedule operations
  • /api/schedule/batch - Batch operations
  • /api/progress/[id] - Progress tracking for long operations
  • /api/progress/create - Create new progress operation
  • /api/cache/debug - Cache debugging and statistics

πŸ“± Features Breakdown

Home Page

  • Real-time today's schedule display
  • Location selector dropdown
  • Quick links to location pages
  • PDF download button
  • Responsive card layout

Calendar Page

  • Full schedule table
  • Today highlight badge
  • Past/Upcoming status indicators
  • Location filter
  • Sortable columns

Location Pages

  • City-specific schedules
  • Dynamic metadata for SEO
  • Static generation for performance
  • Back navigation

Admin Dashboard

  • Total entries count
  • Number of locations
  • Recent uploads table
  • Status badges (Success/Partial/Failed)
  • Quick upload button
  • Ramadan settings management

Upload System

  • Drag & drop interface
  • JSON and CSV support
  • Real-time validation
  • Error reporting by row
  • Preview table (first 10 entries)
  • Confirm dialog before upload
  • Sample file downloads

PDF Export

  • Clean A4 layout
  • Header with app title
  • Date/location info
  • Formatted table with all entries
  • Page numbers
  • Generation timestamp footer
  • Custom filename
  • Location-specific exports

Aladhan API Integration

  • Fetch prayer times for all 64 Bangladesh districts
  • Multiple fetch modes:
    • Date Range: Fetch for specific date range
    • Multi-Month: Fetch for multiple months
    • Hijri Month: Fetch for specific Hijri month
  • Configurable rate limiting with presets:
    • Conservative: 6 req/min
    • Balanced: 12 req/min
    • Aggressive: 20 req/min
    • Fast: 300 req/min
    • Turbo: 600 req/min
  • Progress tracking for large operations
  • Automatic retry with exponential backoff
  • Token bucket rate limiting
  • Parallel district processing with controlled concurrency

Hadith Integration

  • Random hadith from multiple collections:
    • Sahih Bukhari
    • Sahih Muslim
    • Abu Dawud
    • Tirmidhi
    • Nasai
    • Ibn Majah
  • Cached responses (1 hour TTL)
  • Rate limited (10 req/min)
  • English translations with source references

⏰ Schedule Display Logic

The application uses intelligent logic to display sehri and iftar times based on the current time and user's location. Here's how it works across different pages:

Core Server Actions

getScheduleDisplayData(location?)

Returns both today's and tomorrow's schedules along with time status flags:

{
  today: TimeEntry | null,      // Today's schedule entry
  tomorrow: TimeEntry | null,   // Tomorrow's schedule entry
  sehriPassed: boolean,         // Whether today's sehri time has passed
  iftarPassed: boolean          // Whether today's iftar time has passed
}

Logic:

  1. Fetches today's schedule based on current date (YYYY-MM-DD format)
  2. Fetches tomorrow's schedule (date + 1 day)
  3. Compares current time with sehri/iftar times to determine status
  4. Returns formatted times in 12-hour format (e.g., "04:45 AM")

getTodayOrNextDaySchedule(location?)

Returns the appropriate schedule for display:

  • Returns today's schedule if iftar time hasn't passed yet
  • Returns tomorrow's schedule if today's iftar time has passed
  • Returns null if no schedule is found

getFullSchedule(location?)

Returns all schedule entries, optionally filtered by location:

  • Ordered by date ascending
  • Returns formatted times in 12-hour format
  • Used for calendar tables and location-specific pages

Time Comparison Logic

hasSehriPassed(schedule) and hasIftarPassed(schedule)

These helper functions determine if a specific time has passed:

// Parse time string (HH:mm format)
const [hours, minutes] = time.split(':').map(Number);

// Create date object with target time
const targetTime = new Date();
targetTime.setHours(hours, minutes, 0, 0);

// Compare with current time
return now >= targetTime;

Note: Time comparisons use the server's system time (Asia/Dhaka timezone).

Page-Specific Display Logic

Home Page (/)

The home page displays the most relevant schedule based on current time:

  1. Fetches both today's and tomorrow's schedules via getScheduleDisplayData()
  2. Determines display schedule:
    • If iftarPassed is false: Shows today's sehri and iftar
    • If iftarPassed is true: Shows tomorrow's sehri and iftar
  3. Visual indicators:
    • Sehri card shows "Passed β€” fast has begun" if sehri time has passed
    • Sehri card shows "End time β€” fast begins" if sehri time is upcoming
    • Iftar card shows "Start time β€” fast breaks"
  4. Countdown timers: Displayed only when within 1 hour of target time
  5. Passed schedule card: Shows today's times in a separate card if iftar has passed

Calendar Page (/calendar)

The calendar page displays the full schedule in a table format:

  1. Main cards: Uses getTodayOrNextDaySchedule() to show today's or tomorrow's schedule
  2. Table rows: Each row shows status based on time comparison:
    • Passed (red): Past dates or today after iftar time
    • Today (blue): Today before iftar time, or tomorrow after sehri time
    • Tomorrow (amber): Tomorrow before sehri time
    • Upcoming (default): Future dates beyond tomorrow
  3. Inline status logic (lines 171-238 in app/(home)/calendar/page.tsx):
    // Parse times
    const sehriTime = parseTime(entry.sehri);  // { hours, minutes }
    const iftarTime = parseTime(entry.iftar); // { hours, minutes }
    
    // Get current time
    const now = new Date();
    const currentHours = now.getHours();
    const currentMinutes = now.getMinutes();
    
    // Check if time has passed
    const isTimePast = (hours, minutes) => 
      currentHours > hours || (currentHours === hours && currentMinutes >= minutes);

Location Pages (/location/[city])

Location-specific pages use the same logic as the calendar page but filtered by city:

  1. Validation: Checks if the city exists in the database via getLocations()
  2. Filtered data: All queries include the location parameter
  3. Static generation: Uses generateStaticParams() to pre-render all location pages
  4. Status logic: Identical to calendar page (passed/today/tomorrow/upcoming)

Countdown Timer Component

The CountdownTimer component provides real-time countdown:

Features:

  • Only visible when within 1 hour of target time
  • Updates every second
  • Automatically handles next day if target time has passed
  • Format: HH:MM:SS with pulsing clock icon

Logic:

// Calculate time difference
const diff = targetDate.getTime() - now.getTime();
const oneHourMs = 60 * 60 * 1000;

// Show only if within 1 hour
if (diff <= oneHourMs && diff > 0) {
  // Display countdown
}

Time Formatting

All times are stored in 24-hour format (HH:mm) in the database and converted to 12-hour format for display:

// lib/utils.ts
export function formatTime12Hour(time: string): string {
  const [hours, minutes] = time.split(":").map(Number);
  const period = hours >= 12 ? "PM" : "AM";
  const displayHours = hours % 12 || 12;
  return `${displayHours}:${minutes.toString().padStart(2, "0")} ${period}`;
}

Example: "04:45" β†’ "4:45 AM", "18:12" β†’ "6:12 PM"

Location Filtering

Location filtering works consistently across all pages:

  1. Location parameter: Passed via URL query param (?location=Dhaka) or route param (/location/Dhaka)
  2. Server action filtering: All data fetching functions accept optional location parameter
  3. "All Locations": When no location is specified, shows entries from all locations
  4. Location list: Dynamically fetched from database via getLocations()

Data Flow Summary

User Request
    ↓
Server Component (page.tsx)
    ↓
Server Action (time-entries.ts)
    ↓
Prisma Query (PostgreSQL)
    ↓
Time Formatting & Status Calculation
    ↓
Client Component (countdown timer, UI)
    ↓
Display to User

🌍 Bangladesh Districts Support

The application supports all 64 districts of Bangladesh across 8 divisions:

Divisions

  • Barisal: Barguna, Barisal, Bhola, Jhalokati, Patuakhali, Pirojpur
  • Chittagong: Bandarban, Brahmanbaria, Chandpur, Chittagong, Comilla, Cox's Bazar, Feni, Khagrachari, Lakshmipur, Noakhali, Rangamati
  • Dhaka: Dhaka, Faridpur, Gazipur, Gopalganj, Kishoreganj, Madaripur, Manikganj, Munshiganj, Narayanganj, Narsingdi, Rajbari, Shariatpur, Tangail
  • Khulna: Bagerhat, Chuadanga, Jessore, Jhenaidah, Khulna, Kushtia, Magura, Meherpur, Narail, Satkhira
  • Mymensingh: Jamalpur, Mymensingh, Netrokona, Sherpur
  • Rajshahi: Bogra, Chapainawabganj, Joypurhat, Naogaon, Natore, Pabna, Rajshahi, Sirajganj
  • Rangpur: Dinajpur, Gaibandha, Kurigram, Lalmonirhat, Nilphamari, Panchagarh, Rangpur, Thakurgaon
  • Sylhet: Habiganj, Moulvibazar, Sunamganj, Sylhet

Location Features

  • Geographic coordinates for accurate prayer times
  • Division-based organization
  • Location-specific schedules
  • Dynamic location pages with SEO metadata
  • Location filtering across all pages

πŸ—οΈ Advanced Architecture & Complex Logic Features

This application implements several sophisticated architectural patterns and complex logic systems to ensure scalability, maintainability, and performance. Below are detailed explanations of these advanced features.

API Architecture & Middleware System

The application implements a robust API architecture with a composable middleware pipeline in lib/api/middleware.ts.

Middleware Pipeline

The middleware system follows a functional composition pattern where each middleware wraps the handler:

// Compose multiple middleware functions
export function compose(...middlewares: Array<(handler: NextHandler) => NextHandler>) {
  return (handler: NextHandler): NextHandler => {
    return middlewares.reduceRight(
      (acc, middleware) => middleware(acc),
      handler
    );
  };
}

Available Middleware

  1. Request ID Middleware (withRequestId)

    • Generates unique request IDs for tracing
    • Adds x-request-id header to both request and response
    • Supports external request ID propagation
  2. Rate Limiting Middleware (withRateLimit)

    • In-memory rate limiting using sliding window algorithm
    • Configurable limits and time windows
    • Returns rate limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
    • Automatic retry-after calculation for 429 responses
  3. Authentication Middleware (withAuth)

    • Integrates with NextAuth.js session management
    • Supports optional admin role checking
    • Injects session data into request headers for downstream use
  4. Validation Middleware (withValidation)

    • Zod schema validation for query/body parameters
    • Detailed error reporting with field-level validation errors
    • Supports validation of both query and body data
  5. Error Handling Middleware (withErrorHandler)

    • Catches and transforms all errors to standardized API responses
    • Adds response time tracking via X-Response-Time header
    • Distinguishes between operational and programming errors
  6. Logging Middleware (withLogging)

    • Logs all incoming requests with method, URL, and user agent
    • Logs successful responses with status and duration
    • Logs errors with full context

Standardized API Responses

All API responses follow a consistent structure defined in lib/api/api-response.ts:

interface ApiResponse<T> {
  success: boolean;
  data?: T;
  error?: {
    code: string;
    message: string;
    details?: any;
  };
  meta?: {
    requestId: string;
    timestamp: string;
  };
}

Response helpers include:

External API Client

The ExternalApiClient provides robust external API integration:

Features:

  • Timeout Handling: Configurable request timeouts with AbortController
  • Retry Logic: Exponential backoff retry for transient failures
  • Caching: Built-in in-memory caching with TTL support
  • Configurable Retry Options: Custom retryable status codes, delays, and multipliers

Retry Strategy:

const defaultRetryOptions = {
  maxRetries: 3,
  initialDelay: 1000,      // 1 second
  maxDelay: 10000,         // 10 seconds
  backoffMultiplier: 2,    // Exponential
  retryableStatuses: [408, 429, 500, 502, 503, 504]
};

Security Headers

Comprehensive security headers are implemented in lib/api/security-headers.ts:

  • X-Content-Type-Options: Prevents MIME type sniffing
  • X-Frame-Options: Prevents clickjacking (DENY)
  • X-XSS-Protection: Enables XSS filtering
  • Referrer-Policy: Controls referrer information
  • Permissions-Policy: Restricts browser features
  • Content-Security-Policy: Comprehensive CSP policy
  • CORS Support: Configurable CORS headers with preflight handling

Cache Implementation Strategy

The application implements a multi-layered caching strategy for optimal performance.

Cache Configuration

Centralized cache configuration in lib/cache/cache-config.ts:

const CACHE_DURATIONS = {
  SHORT: 60,      // 1 minute - frequently changing data
  MEDIUM: 300,    // 5 minutes - moderately changing data
  LONG: 900,      // 15 minutes - rarely changing data
  VERY_LONG: 1800,// 30 minutes - very rarely changing data
  HOUR: 3600,     // 1 hour - static data
};

const CACHE_TAGS = {
  SCHEDULE: 'schedule',
  LOCATIONS: 'locations',
  STATS: 'stats',
  HADITH: 'hadith',
  PDF: 'pdf',
};

Cache Helpers

Utility functions in lib/cache/cache-helpers.ts:

Cache Monitoring

The CacheMonitor class provides comprehensive cache performance tracking:

Features:

  • Hit/miss tracking per cache key
  • Hit rate calculation
  • Overall cache statistics
  • Per-key statistics
  • Metrics export as JSON
  • Decorator support for class methods

Usage Example:

// Record hits/misses manually
CacheMonitor.recordHit('schedule:dhaka');
CacheMonitor.recordMiss('schedule:dhaka');

// Get statistics
const stats = CacheMonitor.getOverallStats();
// { hits: 100, misses: 20, hitRate: '83.33%', total: 120 }

// Wrap a function with monitoring
const monitoredFn = withCacheMonitoring(
  async () => await fetchData(),
  'data-fetch'
);

Cache Cleanup

The CacheCleanup class manages periodic cache maintenance:

Features:

  • Automatic cleanup of expired cache entries
  • Periodic cleanup scheduling (default: 1 hour)
  • Manual cleanup triggering
  • Cleanup status monitoring
  • External API cache cleanup

Initialization:

import { initializeCacheCleanup } from '@/lib/cache';

// Auto-initializes on server start
initializeCacheCleanup();

// Or manually schedule
CacheCleanup.schedulePeriodicCleanup(3600000); // 1 hour

SEO & Metadata System

The application implements a comprehensive SEO strategy for maximum search engine visibility.

Metadata Generation

The lib/seo/metadata.ts module provides metadata generators:

Features:

  • Open Graph tags for social media sharing
  • Twitter Card support
  • Canonical URL generation
  • Dynamic keyword generation
  • Robots meta configuration
  • Favicon and manifest configuration

JSON-LD Structured Data

The lib/seo/schemas.ts module generates JSON-LD schemas:

Available Schemas:

Feature-Based Architecture (DDD)

The application follows Domain-Driven Design (DDD) principles with a feature-based architecture in features/schedule/.

Architecture Layers

features/schedule/
β”œβ”€β”€ domain/
β”‚   β”œβ”€β”€ entities/           # Domain entities with business logic
β”‚   β”œβ”€β”€ value-objects/      # Value objects with validation
β”‚   └── types/              # Domain types and interfaces
β”œβ”€β”€ repositories/           # Data access layer
β”œβ”€β”€ services/               # Business logic services
└── use-cases/             # Application use cases

Domain Entities

The TimeEntry entity encapsulates schedule data with domain logic:

Features:

Value Objects

The LocationVO value object encapsulates location logic:

Features:

  • Null-safe location handling
  • Display name generation
  • Validation and normalization
  • Equality comparison
  • Static factory methods: create(), all()

Services

The ScheduleService contains business logic:

Methods:

Use Cases

Use cases encapsulate application-level logic:

Error Handling System

The application implements a comprehensive error handling system in lib/errors/app-error.ts.

Custom Error Classes

All errors extend the base AppError class:

Features:

  • HTTP status code mapping
  • Operational vs programming error distinction
  • Error cause chaining
  • JSON serialization
  • Type guard: isAppError()
  • Error converter: toAppError()

Parser System

The application uses a factory pattern for file parsing in lib/parsers/index.ts.

Parser Factory

The ParserFactory manages parser registration and selection:

Features:

  • Automatic parser selection based on file extension
  • Extensible parser registration
  • Support for multiple file formats (JSON, CSV)
  • Type-safe parsing with ParsedScheduleEntry interface

Available Parsers:

Usage:

const parser = ParserFactory.getParser('schedule.json');
const entries = await parser.parse(fileContent);

Logging System

A comprehensive logging system is implemented in lib/logger/logger.ts.

Logger Features

  • Multiple Log Levels: error, warn, info, debug
  • Environment-Aware: Different behavior for dev/test/production
  • Console Logging: Color-coded output for development
  • Context Support: Structured logging with context objects
  • Child Loggers: Create loggers with default context
  • Production-Ready: Placeholder for external service integration (Sentry, Datadog)

Usage:

import { logger, createLogger } from '@/lib/logger';

// Global logger
logger.error('Error message', { context: 'value' }, error);

// Child logger with context
const apiLogger = createLogger('api');
apiLogger.info('API request', { endpoint: '/schedule' });

Configuration Management

Centralized configuration management in lib/config/index.ts.

Configuration Modules

Guards & Authorization

The application implements a dual-layer guard system in lib/guards/.

Client-Side Guards

The DashboardGuard component protects client-side routes:

Features:

  • Session checking
  • Redirect to login if unauthenticated
  • Loading state during authentication check
  • Configurable options (requireAdmin)

Server-Side Guards

The dashboardGuard function protects server components:

Features:

  • Server-side session validation
  • Early return for unauthenticated requests
  • Type-safe options

Advanced Schedule Logic

The schedule display system implements sophisticated time-based logic.

Time Comparison Logic

Using moment.js for accurate time comparisons:

// Check if sehri/iftar time has passed
isSehriPassed(referenceDate?: Date): boolean {
  const now = referenceDate ? moment(referenceDate) : moment();
  const sehriTime = moment(this.sehri, 'HH:mm');
  sehriTime.set({
    year: now.year(),
    month: now.month(),
    date: now.date(),
  });
  return now.isSameOrAfter(sehriTime);
}

Smart Schedule Selection

The getTodayOrNextDaySchedule() method intelligently selects the appropriate schedule:

Logic:

  1. Fetch today's schedule
  2. Check if today's iftar has passed
  3. If iftar passed, return tomorrow's schedule
  4. Otherwise, return today's schedule

Display Data Structure

The ScheduleDisplayData interface provides complete display information:

interface ScheduleDisplayData {
  today: TimeEntry | null;
  tomorrow: TimeEntry | null;
  sehriPassed: boolean;
  iftarPassed: boolean;
}

Countdown Timer

The CountdownTimer component provides real-time countdown:

Features:

  • Only visible within 1 hour of target time
  • Updates every second
  • Automatically handles next day transitions
  • Format: HH:MM:SS with pulsing clock icon

Rate Limiter Implementation

The RateLimiter class provides in-memory rate limiting:

Features:

  • Sliding window algorithm
  • Per-identifier tracking (IP or user ID)
  • Configurable limits and time windows
  • Automatic cleanup of expired entries
  • Store size monitoring
  • Singleton pattern for global instance

Usage:

const rateLimiter = new RateLimiter();
const result = await rateLimiter.checkLimit('user:123', 100, 60000);
// { allowed: true, remaining: 99, resetAt: Date }

API Validation System

Comprehensive validation using Zod schemas in lib/validations/api-schemas.ts.

Features:

  • Request validation schemas
  • Response validation schemas
  • Type-safe validation
  • Detailed error reporting

Security Features

  1. Input Sanitization: sanitizeInput() prevents XSS attacks
  2. URL Validation: sanitizeUrl() prevents open redirects
  3. IP Detection: getClientIp() handles various proxy headers
  4. User Agent: getUserAgent() extracts user agent information

Performance Optimizations

  1. Next.js Caching: Uses unstable_cache for data caching
  2. Static Generation: Location pages pre-rendered with generateStaticParams()
  3. Cache Tags: Selective cache invalidation
  4. Stale-While-Revalidate: Background revalidation for improved UX
  5. External API Caching: Built-in caching with TTL

Monitoring & Observability

  1. Request Tracking: Unique request IDs for tracing
  2. Response Time: X-Response-Time header
  3. Cache Metrics: Hit/miss tracking and hit rate calculation
  4. Structured Logging: Context-aware logging throughout the application
  5. Error Tracking: Comprehensive error logging with context

🎨 UI Components

Built with shadcn/ui:

  • Card, Button, Table, Dialog
  • Alert, Toast (Sonner), Tabs
  • Select, Badge, Skeleton
  • Dropdown Menu, Input, Label

πŸ”’ Security

  • Admin routes protected by NextAuth middleware
  • Password hashing with bcryptjs
  • Server-side validation
  • File type restrictions
  • File size limits
  • Rate limiting with token bucket algorithm
  • Request ID tracking
  • Security headers (CSP, CORS, XSS protection)
  • Input sanitization
  • IP-based rate limiting

πŸš€ Deployment

Vercel

  1. Push code to GitHub
  2. Import project in Vercel
  3. Set environment variables (see Environment Variables section)
  4. Deploy

Environment Variables for Production

DATABASE_URL="postgresql://<user>:<password>@<host>:<port>/<database>"
NEXTAUTH_SECRET="<generate-with-openssl-rand-base64-32>"
NEXTAUTH_URL="https://your-domain.com"
ADMIN_EMAIL="admin@example.com"
ADMIN_PASSWORD="secure-password"
TIMEZONE="Asia/Dhaka"
RAMADAN_START_DATE="2026-02-19"
RAMADAN_END_DATE="2026-03-20"
ALLOWED_ORIGINS="https://your-domain.com"

Recommended Database Providers

πŸ“ Scripts

pnpm dev          # Start development server
pnpm build        # Build for production
pnpm start        # Start production server
pnpm lint         # Run ESLint
pnpm db:generate  # Generate Prisma client
pnpm db:push      # Push schema to database
pnpm db:seed      # Seed initial data

πŸ”§ Environment Variables

Required Variables

Variable Description Example
DATABASE_URL PostgreSQL connection string postgresql://user:pass@localhost:5432/ramadan-clock
NEXTAUTH_SECRET Secret for session encryption Generate with openssl rand -base64 32
NEXTAUTH_URL Application URL http://localhost:3000
ADMIN_EMAIL Admin login email admin@example.com
ADMIN_PASSWORD Admin login password secure-password

Optional Variables

Variable Description Default
NODE_ENV Environment mode development
TIMEZONE Application timezone Asia/Dhaka
ALLOWED_ORIGINS CORS allowed origins (comma-separated) http://localhost:3000
RAMADAN_START_DATE Ramadan start date (YYYY-MM-DD) -
RAMADAN_END_DATE Ramadan end date (YYYY-MM-DD) -
PROJECT_REPO_URL Project repository URL -
DEVELOPER_NAME Developer name -
DEVELOPER_BIO Developer bio -
DEVELOPER_GITHUB GitHub profile URL -
DEVELOPER_LINKEDIN LinkedIn profile URL -
DEVELOPER_EMAIL Contact email -

Note: Aladhan API configuration is hardcoded in lib/config/app.config.ts and includes:

  • Base URL: https://api.aladhan.com/v1
  • Method: ISNA (Islamic Society of North America)
  • Country: Bangladesh
  • Timezone: Asia/Dhaka
  • Rate limiting: Token bucket with 50 capacity, 5 tokens/second

To modify these settings, edit the ALADHAN_CONFIG object in the configuration file directly.

See Also

πŸ“š Documentation

Feature Guides

API Documentation

🀝 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

  • Built for the Muslim community during Ramadan
  • Inspired by the need for accurate prayer time information
  • Made with ❀️ using modern web technologies

Ramadan Mubarak! πŸŒ™

About

πŸŒ™ Ramadan Clock - Modern web app for viewing Sehri & Iftar schedules during Ramadan. Features calendar view, location filtering, PDF export, and admin dashboard. Built with Next.js, MongoDB, and shadcn/ui.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages