import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../../../theme/app_colors.dart'; import '../../../l10n/app_localizations.dart'; /// 날짜 선택 필드 위젯 /// 탭하면 날짜 선택기가 표시되며, 선택된 날짜를 보기 좋은 형식으로 표시합니다. class DatePickerField extends StatelessWidget { final DateTime selectedDate; final Function(DateTime) onDateSelected; final String label; final String? hintText; final DateTime? firstDate; final DateTime? lastDate; final bool enabled; final FocusNode? focusNode; final Color? backgroundColor; final EdgeInsetsGeometry? contentPadding; final String? dateFormat; final Color? primaryColor; const DatePickerField({ super.key, required this.selectedDate, required this.onDateSelected, required this.label, this.hintText, this.firstDate, this.lastDate, this.enabled = true, this.focusNode, this.backgroundColor, this.contentPadding, this.dateFormat, this.primaryColor, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final effectivePrimaryColor = primaryColor ?? theme.primaryColor; final localizations = AppLocalizations.of(context); final effectiveDateFormat = dateFormat ?? localizations.dateFormatFull; final locale = Localizations.localeOf(context); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.darkNavy, ), ), const SizedBox(height: 8), InkWell( focusNode: focusNode, onTap: enabled ? () async { final DateTime? picked = await showDatePicker( context: context, initialDate: selectedDate, firstDate: firstDate ?? DateTime.now().subtract(const Duration(days: 365 * 10)), lastDate: lastDate ?? DateTime.now().add(const Duration(days: 365 * 10)), builder: (BuildContext context, Widget? child) { return Theme( data: ThemeData.light().copyWith( colorScheme: ColorScheme.light( primary: effectivePrimaryColor, onPrimary: Colors.white, surface: Colors.white, onSurface: Colors.black, ), ), child: child!, ); }, ); if (picked != null && picked != selectedDate) { onDateSelected(picked); } } : null, borderRadius: BorderRadius.circular(16), child: Container( padding: contentPadding ?? const EdgeInsets.all(16), decoration: BoxDecoration( color: backgroundColor ?? AppColors.surfaceColorAlt, borderRadius: BorderRadius.circular(16), border: Border.all( color: AppColors.borderColor.withValues(alpha: 0.7), width: 1.5, ), ), child: Row( children: [ Expanded( child: Text( DateFormat(effectiveDateFormat, locale.toString()) .format(selectedDate), style: TextStyle( fontSize: 16, color: enabled ? AppColors.textPrimary : AppColors.textMuted, ), ), ), Icon( Icons.calendar_today, size: 20, color: enabled ? AppColors.navyGray : AppColors.textMuted, ), ], ), ), ), ], ); } } /// 날짜 범위 선택 필드 위젯 /// 시작일과 종료일을 선택할 수 있는 필드입니다. class DateRangePickerField extends StatelessWidget { final DateTime? startDate; final DateTime? endDate; final Function(DateTime?) onStartDateSelected; final Function(DateTime?) onEndDateSelected; final String startLabel; final String endLabel; final bool enabled; final Color? primaryColor; const DateRangePickerField({ super.key, required this.startDate, required this.endDate, required this.onStartDateSelected, required this.onEndDateSelected, this.startLabel = '시작일', this.endLabel = '종료일', this.enabled = true, this.primaryColor, }); @override Widget build(BuildContext context) { return Row( children: [ Expanded( child: _DateRangeItem( date: startDate, label: startLabel, enabled: enabled, primaryColor: primaryColor, onDateSelected: onStartDateSelected, firstDate: DateTime.now().subtract(const Duration(days: 365)), lastDate: endDate ?? DateTime.now().add(const Duration(days: 365 * 2)), ), ), const SizedBox(width: 12), Expanded( child: _DateRangeItem( date: endDate, label: endLabel, enabled: enabled && startDate != null, primaryColor: primaryColor, onDateSelected: onEndDateSelected, firstDate: startDate ?? DateTime.now(), lastDate: DateTime.now().add(const Duration(days: 365 * 2)), ), ), ], ); } } class _DateRangeItem extends StatelessWidget { final DateTime? date; final String label; final bool enabled; final Color? primaryColor; final Function(DateTime?) onDateSelected; final DateTime firstDate; final DateTime lastDate; const _DateRangeItem({ required this.date, required this.label, required this.enabled, required this.primaryColor, required this.onDateSelected, required this.firstDate, required this.lastDate, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final effectivePrimaryColor = primaryColor ?? theme.primaryColor; return InkWell( onTap: enabled ? () async { final DateTime? picked = await showDatePicker( context: context, initialDate: date ?? DateTime.now(), firstDate: firstDate, lastDate: lastDate, builder: (BuildContext context, Widget? child) { return Theme( data: ThemeData.light().copyWith( colorScheme: ColorScheme.light( primary: effectivePrimaryColor, onPrimary: Colors.white, surface: Colors.white, onSurface: Colors.black, ), ), child: child!, ); }, ); if (picked != null) { onDateSelected(picked); } } : null, borderRadius: BorderRadius.circular(16), child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColors.surfaceColorAlt, borderRadius: BorderRadius.circular(16), border: Border.all( color: AppColors.borderColor.withValues(alpha: 0.7), width: 1.5, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: TextStyle( fontSize: 12, color: AppColors.textSecondary, ), ), const SizedBox(height: 4), Text( date != null ? DateFormat(AppLocalizations.of(context).dateFormatShort) .format(date!) : AppLocalizations.of(context).dateSelect, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, color: date != null ? AppColors.textPrimary : AppColors.textMuted, ), ), ], ), ), ); } }