import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../utils/colors.dart'; import 'custom_text.dart'; // same styled Txt widget you use class CustomDateFieldWidget extends StatefulWidget { final TextEditingController controller; final String label; final IconData icon; final String dateFormat; final String? Function(String?)? validator; final bool? required; // Added required attribute const CustomDateFieldWidget({ Key? key, required this.controller, required this.label, required this.icon, this.dateFormat = 'yyyy-MM-dd', this.validator, this.required, // Added required parameter }) : super(key: key); @override State createState() => _CustomDateFieldWidgetState(); } class _CustomDateFieldWidgetState extends State with SingleTickerProviderStateMixin { bool _isFocused = false; bool _hasContent = false; late AnimationController _animationController; late Animation _scaleAnimation; @override void initState() { super.initState(); _animationController = AnimationController( duration: const Duration(milliseconds: 200), vsync: this, ); _scaleAnimation = Tween(begin: 1.0, end: 1.02).animate( CurvedAnimation(parent: _animationController, curve: Curves.easeInOut), ); widget.controller.addListener(() { setState(() { _hasContent = widget.controller.text.isNotEmpty; }); }); } @override void dispose() { _animationController.dispose(); super.dispose(); } Future _pickDate() async { FocusScope.of(context).unfocus(); if (widget.dateFormat == "yyyy") { final selectedYear = await showDialog( context: context, builder: (context) { return Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: SizedBox( width: 300, height: 400, child: YearPicker( firstDate: DateTime(2000), lastDate: DateTime(DateTime.now().year), selectedDate: DateTime.tryParse(widget.controller.text) ?? DateTime.now(), onChanged: (DateTime dateTime) { Navigator.pop(context, dateTime.year); }, ), ), ); }, ); if (selectedYear != null) { widget.controller.text = selectedYear.toString(); } } else { DateTime? pickedDate = await showDatePicker( context: context, initialDate: DateTime.tryParse(widget.controller.text) ?? DateTime.now(), firstDate: DateTime.now(), lastDate: DateTime(2100), builder: (context, child) { return Theme( data: Theme.of(context).copyWith( colorScheme: const ColorScheme.light( primary: Color(0xFF5B259F), ), ), child: child!, ); }, ); if (pickedDate != null) { widget.controller.text = DateFormat(widget.dateFormat).format(pickedDate); } } } // Helper method to get label with required indicator String get _labelWithIndicator { if (widget.required == null) { return widget.label; // No indicator if not specified } return widget.required! ? '${widget.label} *' : '${widget.label} (Optional)'; } @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 5.0), child: AnimatedBuilder( animation: _scaleAnimation, builder: (context, child) { return Transform.scale( scale: _scaleAnimation.value, child: GestureDetector( onTap: () async { setState(() => _isFocused = true); _animationController.forward(); await _pickDate(); setState(() => _isFocused = false); _animationController.reverse(); }, child: AbsorbPointer( child: TextField( controller: widget.controller, style: const TextStyle( fontFamily: 'Poppins', fontSize: 16, //color: Colors.black87, fontWeight: FontWeight.w500, ), decoration: InputDecoration( filled: true, fillColor: _isFocused ? Theme.of(context).brightness == Brightness.dark? AppColors.blackBackgroundColor: AppColors.whiteBackgroundColor : Theme.of(context).brightness == Brightness.dark? AppColors.blackBackgroundColor.withOpacity(.5): AppColors.whiteBackgroundColor.withOpacity(.5), prefixIcon: Icon( widget.icon, color: _isFocused || _hasContent ?Theme.of(context).brightness == Brightness.dark? AppColors.whiteBackgroundColor: const Color(0xFF5B259F) : const Color(0xFFA2A2A2), size: 22, ), label: Txt( text: _labelWithIndicator, // Using the helper method style: TextStyle( color: _isFocused || _hasContent ? Theme.of(context).brightness == Brightness.dark? AppColors.whiteBackgroundColor: const Color(0xFF5B259F) : const Color(0xFFA2A2A2), fontSize: _isFocused || _hasContent ? 11 : 14, fontFamily: 'Poppins', fontWeight: _isFocused || _hasContent ? FontWeight.w600 : FontWeight.w400, ), ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.grey.shade200, width: 1.5, ), borderRadius: BorderRadius.circular(12), ), focusedBorder: OutlineInputBorder( borderSide: const BorderSide( color: Color(0xFF5B259F), width: 2.0, ), borderRadius: BorderRadius.circular(12), ), errorBorder: OutlineInputBorder( borderSide: const BorderSide( color: Colors.red, width: 1.5, ), borderRadius: BorderRadius.circular(12), ), focusedErrorBorder: OutlineInputBorder( borderSide: const BorderSide( color: Colors.red, width: 2.0, ), borderRadius: BorderRadius.circular(12), ), contentPadding: const EdgeInsets.symmetric( horizontal: 16, vertical: 18, ), ), ), ), ), ); }, ), ); } }