Skip to content

rubixscript/react-native-pdf-report

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

11 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

React Native PDF Report Library

npm version License: MIT

A versatile and customizable React Native PDF report generation library for any tracking app - pomodoro, expenses, skills, reading, habits, fitness, and more!

Features

  • πŸ“Š Universal Tracking: Works with any type of tracking app
  • 🎨 Fully Customizable: Custom labels, colors, and terminology
  • πŸ“± Beautiful UI: Modern, responsive modal with smooth animations
  • πŸŒ“ Dark Mode: Full dark mode support
  • πŸ“ˆ Multiple Report Types: Summary, monthly, yearly, custom range, and item-specific reports
  • ⚑ Type-Safe: Written in TypeScript with comprehensive type definitions
  • 🎯 Flexible Data Model: Generic data structures that adapt to your app's needs
  • 🧩 Modular Architecture: Clean, maintainable code with reusable components
  • 🎣 Custom Hooks: Powerful hooks for form management and logic
  • πŸ› οΈ Utility Functions: Built-in formatters, validators, and helpers
  • πŸ’ͺ Production Ready: Battle-tested and optimized for performance

Installation

npm install @rubixscript/react-native-pdf-report

Peer Dependencies

npm install expo-linear-gradient @expo/vector-icons @react-native-community/datetimepicker

Quick Start

import React, { useState } from 'react';
import { View, Button } from 'react-native';
import { PDFReportModal, DataItem, ActivitySession, ReportLabels } from '@rubixscript/react-native-pdf-report';

export default function App() {
  const [showModal, setShowModal] = useState(false);

  // Your tracking data
  const data: DataItem[] = [
    {
      id: '1',
      title: 'My Item',
      subtitle: 'Category or Author',
      progress: 75,
      total: 100,
      current: 75,
      startDate: new Date(),
    },
  ];

  const sessions: ActivitySession[] = [
    {
      id: 's1',
      itemId: '1',
      date: new Date(),
      duration: 60,
      value: 10,
    },
  ];

  // Customize labels for your app
  const labels: ReportLabels = {
    itemLabel: 'Task',
    itemLabelPlural: 'Tasks',
    sessionLabel: 'Session',
    sessionLabelPlural: 'Sessions',
    reportTitle: 'Activity Report',
  };

  const handleGenerateReport = (options) => {
    console.log('Generate PDF with options:', options);
    // Implement your PDF generation logic here
  };

  return (
    <View>
      <Button title="Generate Report" onPress={() => setShowModal(true)} />

      <PDFReportModal
        visible={showModal}
        onClose={() => setShowModal(false)}
        darkMode={false}
        data={data}
        sessions={sessions}
        onGenerateReport={handleGenerateReport}
        labels={labels}
        primaryColor="#007AFF"
      />
    </View>
  );
}

Use Cases

This library is perfect for:

  • πŸ“š Reading Trackers - Track books, pages read, reading sessions
  • πŸ… Pomodoro Apps - Track work sessions, focus time, productivity
  • πŸ’° Expense Trackers - Track spending, budgets, transactions
  • 🎯 Skill Trackers - Track learning progress, practice sessions
  • πŸƒ Fitness Apps - Track workouts, exercises, progress
  • βœ… Habit Trackers - Track daily habits, streaks, consistency
  • ⏰ Time Trackers - Track time spent on projects, tasks
  • πŸ“ Journal Apps - Track entries, moods, reflections
  • And many more!

Examples

Pomodoro / Productivity Tracker

const pomodoroLabels: ReportLabels = {
  itemLabel: 'Task',
  itemLabelPlural: 'Tasks',
  sessionLabel: 'Pomodoro Session',
  sessionLabelPlural: 'Pomodoro Sessions',
  reportTitle: 'Productivity Report',
  summaryLabel: 'Productivity Summary',
  progressLabel: 'Pomodoros Completed',
  durationLabel: 'Focus Time',
  totalLabel: 'Total Tasks',
};

const tasks: DataItem[] = [
  {
    id: '1',
    title: 'Complete Project Proposal',
    subtitle: 'Work Project',
    progress: 60,
    total: 10, // total pomodoros
    current: 6, // completed pomodoros
    category: 'Work',
    color: '#E74C3C',
  },
];

<PDFReportModal
  labels={pomodoroLabels}
  data={tasks}
  sessions={pomodoroSessions}
  primaryColor="#E74C3C"
  {...otherProps}
/>

Expense Tracker

const expenseLabels: ReportLabels = {
  itemLabel: 'Category',
  itemLabelPlural: 'Categories',
  sessionLabel: 'Transaction',
  sessionLabelPlural: 'Transactions',
  reportTitle: 'Expense Report',
  summaryLabel: 'Financial Summary',
  progressLabel: 'Amount Spent',
};

const categories: DataItem[] = [
  {
    id: '1',
    title: 'Groceries',
    subtitle: 'Food & Beverages',
    progress: 75, // % of budget used
    total: 500, // budget
    current: 375, // spent
    category: 'Food',
    color: '#2ECC71',
  },
];

const expenses: ActivitySession[] = [
  {
    id: 'e1',
    itemId: '1',
    date: new Date(),
    value: 85.50, // expense amount
    notes: 'Weekly grocery shopping',
  },
];

<PDFReportModal
  labels={expenseLabels}
  data={categories}
  sessions={expenses}
  primaryColor="#2ECC71"
  {...otherProps}
/>

Skill Tracker

const skillLabels: ReportLabels = {
  itemLabel: 'Skill',
  itemLabelPlural: 'Skills',
  sessionLabel: 'Practice Session',
  sessionLabelPlural: 'Practice Sessions',
  reportTitle: 'Skill Development Report',
  progressLabel: 'Skill Points Earned',
  durationLabel: 'Practice Time',
};

const skills: DataItem[] = [
  {
    id: '1',
    title: 'JavaScript',
    subtitle: 'Programming Language',
    progress: 75,
    total: 100,
    current: 75,
    category: 'Programming',
    metadata: {
      level: 'Advanced',
      hoursInvested: 250,
    },
  },
];

<PDFReportModal
  labels={skillLabels}
  data={skills}
  sessions={practiceSessions}
  primaryColor="#8B5CF6"
  {...otherProps}
/>

Reading Tracker (Legacy Support)

const readingLabels: ReportLabels = {
  itemLabel: 'Book',
  itemLabelPlural: 'Books',
  sessionLabel: 'Reading Session',
  sessionLabelPlural: 'Reading Sessions',
  reportTitle: 'Reading Report',
  progressLabel: 'Pages Read',
  durationLabel: 'Reading Time',
};

// You can also use the legacy Book and ReadingSession types
// They are aliases for DataItem and ActivitySession

API Reference

PDFReportModal Props

Prop Type Required Default Description
visible boolean Yes - Controls modal visibility
onClose () => void Yes - Callback when modal is closed
darkMode boolean Yes - Enable dark mode
data DataItem[] Yes - Array of items to track
sessions ActivitySession[] Yes - Array of activity sessions
onGenerateReport (options: ReportOptions) => void Yes - Callback with report configuration
labels ReportLabels No Default labels Custom text labels
reportTypes ReportTypeConfig[] No Default types Custom report type configs
userName string No - User name for personalization
primaryColor string No #007AFF Primary theme color
accentColor string No - Accent theme color

DataItem Type

interface DataItem {
  id: string;                    // Unique identifier
  title: string;                 // Main title (book title, task name, etc.)
  subtitle?: string;             // Subtitle (author, category, etc.)
  imageUri?: string;             // Optional image URL
  progress?: number;             // Progress percentage (0-100)
  total?: number;                // Total units (pages, hours, etc.)
  current?: number;              // Current units completed
  startDate?: Date | string;     // Start date
  completedDate?: Date | string; // Completion date
  notes?: string[];              // Notes array
  category?: string;             // Category
  color?: string;                // Color for UI
  metadata?: Record<string, any>; // Custom metadata
  isPinned?: boolean;            // Pinned status
  [key: string]: any;            // Additional custom fields
}

ActivitySession Type

interface ActivitySession {
  id: string;                    // Unique identifier
  itemId: string;                // Reference to DataItem
  date: Date | string;           // Session date
  startValue?: number;           // Start value (page, time, etc.)
  endValue?: number;             // End value
  duration?: number;             // Duration in minutes
  value?: number;                // Numeric value (amount, points, etc.)
  notes?: string;                // Session notes
  imageUrl?: string;             // Optional image
  metadata?: Record<string, any>; // Custom metadata
  [key: string]: any;            // Additional custom fields
}

ReportLabels Type

interface ReportLabels {
  itemLabel?: string;            // e.g., "Book", "Task", "Expense"
  itemLabelPlural?: string;      // e.g., "Books", "Tasks"
  sessionLabel?: string;         // e.g., "Session", "Transaction"
  sessionLabelPlural?: string;   // e.g., "Sessions", "Transactions"
  reportTitle?: string;          // e.g., "Reading Report"
  summaryLabel?: string;         // e.g., "Summary"
  progressLabel?: string;        // e.g., "Pages Read"
  durationLabel?: string;        // e.g., "Reading Time"
  totalLabel?: string;           // e.g., "Total Books"
}

ReportOptions Type

interface ReportOptions {
  type: ReportType;              // 'summary' | 'monthly' | 'yearly' | 'custom' | 'item-details'
  startDate?: Date;              // For custom reports
  endDate?: Date;                // For custom reports
  includeCharts?: boolean;       // Include charts in report
  includeSessionDetails?: boolean; // Include session details
  includeItemDetails?: boolean;  // Include item details
  includeAchievements?: boolean; // Include achievements
  itemId?: string;               // For item-specific reports
  customTitle?: string;          // Custom report title
  labels?: ReportLabels;         // Labels for the report
}

Customization

Custom Report Types

You can define custom report types with your own icons and descriptions:

const customReportTypes: ReportTypeConfig[] = [
  {
    type: 'summary',
    title: '🎯 My Custom Summary',
    description: 'All-time statistics',
    icon: '🎯',
  },
  {
    type: 'monthly',
    title: 'πŸ“… Monthly Review',
    description: 'This month\'s progress',
    icon: 'πŸ“…',
  },
  // ... more custom types
];

<PDFReportModal
  reportTypes={customReportTypes}
  {...otherProps}
/>

Custom Colors

<PDFReportModal
  primaryColor="#FF6B6B"
  accentColor="#4ECDC4"
  {...otherProps}
/>

Flexible Data Model

The library uses a flexible data model that can store any custom fields:

const customData: DataItem[] = [
  {
    id: '1',
    title: 'My Item',
    subtitle: 'Subtitle',
    // Add any custom fields
    customField: 'custom value',
    rating: 5,
    tags: ['tag1', 'tag2'],
    metadata: {
      // Store complex custom data
      anyData: 'you need',
    },
  },
];

UI Features

  • ✨ Modern Design: Beautiful card-based UI with smooth animations
  • 🎨 Customizable Colors: Change primary and accent colors to match your brand
  • πŸŒ“ Dark Mode: Full dark mode support throughout
  • πŸ“± Responsive: Works perfectly on all screen sizes
  • ⌨️ Accessibility: Touch-friendly with proper accessibility labels
  • πŸ”„ Smooth Transitions: Animated modal with slide transitions
  • πŸ“… Date Pickers: Native date pickers for custom date ranges
  • βœ… Smart Validation: Form validation with helpful error messages

Fixed Issues (v2.0.0)

  • βœ… Modal Overlay Issue: Fixed modal not opening properly due to overlay blocking interaction
  • βœ… Generic Library: Transformed from reading-specific to universal tracking library
  • βœ… Improved Aesthetics: Enhanced UI with better spacing, colors, and typography
  • βœ… Better Accessibility: Improved touch targets and visual feedback
  • βœ… Type Safety: Comprehensive TypeScript types for better DX

Migrating from v1.x

If you're upgrading from v1.x (reading-specific version):

// OLD (v1.x)
import { Book, ReadingSession } from '@rubixscript/react-native-pdf-report';

const books: Book[] = [...];
const sessions: ReadingSession[] = [...];

<PDFReportModal books={books} readingSessions={sessions} />

// NEW (v2.x) - Backward compatible
import { Book, ReadingSession } from '@rubixscript/react-native-pdf-report';

const books: Book[] = [...]; // Still works!
const sessions: ReadingSession[] = [...]; // Still works!

<PDFReportModal data={books} sessions={sessions} />

// OR use new generic types
import { DataItem, ActivitySession } from '@rubixscript/react-native-pdf-report';

const data: DataItem[] = [...];
const sessions: ActivitySession[] = [...];

<PDFReportModal data={data} sessions={sessions} labels={customLabels} />

The Book and ReadingSession types are still available as aliases for backward compatibility.

Examples Directory

Check out the examples/ directory for complete working examples:

  • reading-tracker.tsx - Reading tracking app
  • pomodoro-tracker.tsx - Productivity/pomodoro app
  • expense-tracker.tsx - Expense tracking app
  • skill-tracker.tsx - Skill development app

Architecture

This library follows a modular architecture for maintainability and extensibility:

  • 8 Modular Components: Each with a single responsibility
  • 2 Custom Hooks: useReportForm and useReportTypes
  • Utility Functions: Formatters, validators, and constants
  • Type-Safe: Comprehensive TypeScript definitions

The main PDFReportModal component has been reduced from 795 lines to just 272 lines through modularization!

For detailed architecture documentation, see ARCHITECTURE.md.

Component Structure

PDFReportModal (Main Orchestrator)
β”œβ”€β”€ ModalHeader
β”œβ”€β”€ ScrollView
β”‚   β”œβ”€β”€ ReportTypeSelector
β”‚   β”œβ”€β”€ DateRangeSelector (conditional)
β”‚   β”œβ”€β”€ ItemSelector (conditional)
β”‚   β”œβ”€β”€ CustomTitleInput
β”‚   └── ReportOptionsToggles
└── ModalFooter

Using Individual Components

All components are exported and can be used independently:

import {
  ReportTypeSelector,
  DateRangeSelector,
  ItemSelector,
  CustomTitleInput,
  ReportOptionsToggles,
  ModalHeader,
  ModalFooter,
} from '@rubixscript/react-native-pdf-report';

Using Custom Hooks

import { useReportForm, useReportTypes } from '@rubixscript/react-native-pdf-report';

// In your component
const { selectedReportType, handleGenerateReport, ... } = useReportForm({
  visible,
  labels,
  onGenerateReport,
  onClose,
});

Using Utilities

import {
  formatDate,
  formatDuration,
  formatCurrency,
  validateDateRange,
  DEFAULT_LABELS,
} from '@rubixscript/react-native-pdf-report';

Contributing

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

When contributing, please:

  • Follow the modular architecture patterns
  • Keep components small and focused (< 150 lines)
  • Add TypeScript types for all props
  • Write tests for new functionality
  • Update documentation

License

MIT Β© RubixScript Team

Links

Support

If you find this library helpful, please give it a ⭐ on GitHub!

For questions and support, please open an issue on GitHub.

About

React Native PDF report library

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •