import React, { ReactNode } from 'react' import { Card, CardContent, CardHeader, Button, Typography, FormControl, FormControlLabel, Radio, RadioGroup, TextField, Box, Chip, Divider, Grid, useTheme } from '@mui/material' import { styled } from '@mui/material/styles' // Type definitions interface DateRange { startDate: Date endDate: Date } interface QuickAction { label: string handler: () => void } interface CustomQuickActions { single?: QuickAction[] range?: QuickAction[] } interface Labels { filterLabel?: string singleDateLabel?: string rangeDateLabel?: string selectDateLabel?: string fromLabel?: string toLabel?: string todayLabel?: string yesterdayLabel?: string last7DaysLabel?: string last30DaysLabel?: string periodLabel?: string exportHelpText?: string } interface ReportGeneratorProps { // Required props reportTitle: string filterType: 'single' | 'range' selectedDate: Date dateRange: DateRange onFilterTypeChange: (filterType: 'single' | 'range') => void onSingleDateChange: (date: Date) => void onDateRangeChange: (dateRange: DateRange) => void onGeneratePDF: () => void // Optional props dengan default values maxWidth?: string showQuickActions?: boolean customQuickActions?: CustomQuickActions | null periodFormat?: string downloadButtonText?: string cardShadow?: string primaryColor?: string // Optional helper functions formatDateForInput?: ((date: Date) => string) | null getReportPeriodText?: (() => string) | null // Additional customization className?: string style?: React.CSSProperties children?: ReactNode // Loading state isGenerating?: boolean // Custom labels labels?: Labels } // Custom styled components yang responsif terhadap theme const StyledCard = styled(Card)(({ theme }) => ({ margin: '0 0 24px', boxShadow: theme.palette.mode === 'dark' ? '0 2px 10px rgba(20, 21, 33, 0.3)' : '0 2px 10px rgba(58, 53, 65, 0.1)', borderRadius: '8px', backgroundColor: theme.palette.mode === 'dark' ? theme.palette.background.paper : '#ffffff' })) const PurpleButton = styled(Button)(({ theme }) => ({ backgroundColor: '#36175e', color: 'white', textTransform: 'none', fontWeight: 500, padding: '8px 24px', '&:hover': { backgroundColor: '#2d1350', opacity: 0.9 }, '&:disabled': { backgroundColor: theme.palette.mode === 'dark' ? '#444' : '#ccc', color: theme.palette.mode === 'dark' ? '#888' : '#666' } })) const QuickActionButton = styled(Button)(({ theme }) => ({ backgroundColor: theme.palette.mode === 'dark' ? 'rgba(231, 227, 252, 0.08)' : '#f8f7fa', color: theme.palette.mode === 'dark' ? theme.palette.text.secondary : '#6f6b7d', textTransform: 'none', fontSize: '0.875rem', padding: '6px 16px', borderRadius: '6px', '&:hover': { backgroundColor: theme.palette.mode === 'dark' ? 'rgba(231, 227, 252, 0.16)' : '#ebe9f1' } })) const InfoBox = styled(Box)(({ theme }) => ({ marginTop: theme.spacing(3), padding: theme.spacing(2), backgroundColor: theme.palette.mode === 'dark' ? 'rgba(231, 227, 252, 0.04)' : '#f8f7fa', borderRadius: theme.shape.borderRadius, border: theme.palette.mode === 'dark' ? '1px solid rgba(231, 227, 252, 0.12)' : 'none' })) const ReportGeneratorComponent: React.FC = ({ // Required props reportTitle, filterType, selectedDate, dateRange, onFilterTypeChange, onSingleDateChange, onDateRangeChange, onGeneratePDF, // Optional props dengan default values maxWidth = '1024px', showQuickActions = true, customQuickActions = null, periodFormat = 'id-ID', downloadButtonText = 'Download PDF', cardShadow, primaryColor = '#36175e', // Optional helper functions formatDateForInput = null, getReportPeriodText = null, // Additional customization className = '', style = {}, children = null, // Loading state isGenerating = false, // Custom labels labels = { filterLabel: 'Filter Tanggal:', singleDateLabel: 'Hari Tunggal', rangeDateLabel: 'Rentang Tanggal', selectDateLabel: 'Pilih Tanggal:', fromLabel: 'Dari:', toLabel: 'Sampai:', todayLabel: 'Hari Ini', yesterdayLabel: 'Kemarin', last7DaysLabel: '7 Hari Terakhir', last30DaysLabel: '30 Hari Terakhir', periodLabel: 'Periode:', exportHelpText: 'Klik tombol download untuk mengeksport laporan ke PDF' } }) => { const theme = useTheme() // Dynamic colors berdasarkan theme const textPrimary = theme.palette.text.primary const textSecondary = theme.palette.text.secondary const dynamicCardShadow = cardShadow || (theme.palette.mode === 'dark' ? '0 2px 10px rgba(20, 21, 33, 0.3)' : '0 2px 10px rgba(58, 53, 65, 0.1)') // Default format date function const defaultFormatDateForInput = (date: Date): string => { return date.toISOString().split('T')[0] } // Default period text function const defaultGetReportPeriodText = (): string => { if (filterType === 'single') { return selectedDate.toLocaleDateString(periodFormat, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) } else { return `${dateRange.startDate.toLocaleDateString(periodFormat)} - ${dateRange.endDate.toLocaleDateString(periodFormat)}` } } // Use provided functions or defaults const formatDate = formatDateForInput || defaultFormatDateForInput const getPeriodText = getReportPeriodText || defaultGetReportPeriodText // Quick action handlers const handleToday = (): void => { onSingleDateChange(new Date()) } const handleYesterday = (): void => { const yesterday = new Date() yesterday.setDate(yesterday.getDate() - 1) onSingleDateChange(yesterday) } const handleLast7Days = (): void => { const today = new Date() const weekAgo = new Date() weekAgo.setDate(today.getDate() - 6) onDateRangeChange({ startDate: weekAgo, endDate: today }) } const handleLast30Days = (): void => { const today = new Date() const monthAgo = new Date() monthAgo.setDate(today.getDate() - 29) onDateRangeChange({ startDate: monthAgo, endDate: today }) } // Default quick actions const defaultQuickActions: CustomQuickActions = { single: [ { label: labels.todayLabel || 'Hari Ini', handler: handleToday }, { label: labels.yesterdayLabel || 'Kemarin', handler: handleYesterday } ], range: [ { label: labels.last7DaysLabel || '7 Hari Terakhir', handler: handleLast7Days }, { label: labels.last30DaysLabel || '30 Hari Terakhir', handler: handleLast30Days } ] } const quickActions = customQuickActions || defaultQuickActions return ( Generator {reportTitle} } action={ {isGenerating ? 'Generating...' : downloadButtonText} } sx={{ pb: 2 }} /> {/* Filter Controls */} {labels.filterLabel || 'Filter Tanggal:'} onFilterTypeChange(e.target.value as 'single' | 'range')} sx={{ gap: 3 }} > } label={ {labels.singleDateLabel || 'Hari Tunggal'} } /> } label={ {labels.rangeDateLabel || 'Rentang Tanggal'} } /> {/* Single Date Filter */} {filterType === 'single' && ( {labels.selectDateLabel || 'Pilih Tanggal:'} onSingleDateChange(new Date(e.target.value))} size='small' sx={{ '& .MuiOutlinedInput-root': { '&.Mui-focused fieldset': { borderColor: primaryColor }, '& fieldset': { borderColor: theme.palette.mode === 'dark' ? 'rgba(231, 227, 252, 0.22)' : theme.palette.divider } }, '& .MuiInputBase-input': { color: textPrimary } }} /> {showQuickActions && ( {quickActions.single?.map((action, index) => ( {action.label} ))} )} )} {/* Date Range Filter */} {filterType === 'range' && ( {labels.fromLabel || 'Dari:'} onDateRangeChange({ ...dateRange, startDate: new Date(e.target.value) }) } size='small' sx={{ '& .MuiOutlinedInput-root': { '&.Mui-focused fieldset': { borderColor: primaryColor }, '& fieldset': { borderColor: theme.palette.mode === 'dark' ? 'rgba(231, 227, 252, 0.22)' : theme.palette.divider } }, '& .MuiInputBase-input': { color: textPrimary } }} /> {labels.toLabel || 'Sampai:'} onDateRangeChange({ ...dateRange, endDate: new Date(e.target.value) }) } size='small' sx={{ '& .MuiOutlinedInput-root': { '&.Mui-focused fieldset': { borderColor: primaryColor }, '& fieldset': { borderColor: theme.palette.mode === 'dark' ? 'rgba(231, 227, 252, 0.22)' : theme.palette.divider } }, '& .MuiInputBase-input': { color: textPrimary } }} /> {showQuickActions && ( {quickActions.range?.map((action, index) => ( {action.label} ))} )} )} {labels.periodLabel || 'Periode:'}{' '} {labels.exportHelpText || 'Klik tombol download untuk mengeksport laporan ke PDF'} {/* Custom content dapat ditambahkan di sini */} {children} ) } export default ReportGeneratorComponent