import 'package:flutter/material.dart'; import 'package:mobile_monitoring/core/constants/colors.dart'; /// Custom Switch - Switch widget yang reusable class CustomSwitch extends StatelessWidget { final bool value; final ValueChanged? onChanged; final Color? activeColor; final Color? inactiveColor; const CustomSwitch({ super.key, required this.value, this.onChanged, this.activeColor, this.inactiveColor, }); @override Widget build(BuildContext context) { return Switch( value: value, onChanged: onChanged, activeTrackColor: activeColor ?? AppColors.primary, inactiveThumbColor: inactiveColor ?? AppColors.mediumGray, ); } } /// Labeled Switch - Switch dengan label class LabeledSwitch extends StatelessWidget { final String label; final bool value; final ValueChanged? onChanged; final String? description; final IconData? icon; const LabeledSwitch({ super.key, required this.label, required this.value, this.onChanged, this.description, this.icon, }); @override Widget build(BuildContext context) { return InkWell( onTap: onChanged != null ? () => onChanged!(!value) : null, child: Padding( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), child: Row( children: [ if (icon != null) ...[ Icon( icon, color: AppColors.textSecondary, size: 24, ), const SizedBox(width: 12), ], Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w500, color: AppColors.textPrimary, ), ), if (description != null) ...[ const SizedBox(height: 4), Text( description!, style: const TextStyle( fontSize: 12, color: AppColors.textSecondary, ), ), ], ], ), ), CustomSwitch( value: value, onChanged: onChanged, ), ], ), ), ); } } /// Custom Checkbox - Checkbox yang reusable class CustomCheckbox extends StatelessWidget { final bool value; final ValueChanged? onChanged; final Color? activeColor; const CustomCheckbox({ super.key, required this.value, this.onChanged, this.activeColor, }); @override Widget build(BuildContext context) { return Checkbox( value: value, onChanged: onChanged, activeColor: activeColor ?? AppColors.primary, ); } } /// Labeled Checkbox - Checkbox dengan label class LabeledCheckbox extends StatelessWidget { final String label; final bool value; final ValueChanged? onChanged; const LabeledCheckbox({ super.key, required this.label, required this.value, this.onChanged, }); @override Widget build(BuildContext context) { return InkWell( onTap: onChanged != null ? () => onChanged!(!value) : null, child: Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Row( children: [ CustomCheckbox( value: value, onChanged: onChanged, ), const SizedBox(width: 8), Expanded( child: Text( label, style: const TextStyle( fontSize: 14, color: AppColors.textPrimary, ), ), ), ], ), ), ); } } /// Custom Radio - Radio button yang reusable class CustomRadio extends StatefulWidget { final T value; final T initialGroupValue; final ValueChanged? onChanged; final Color? activeColor; const CustomRadio({ super.key, required this.value, required this.initialGroupValue, this.onChanged, this.activeColor, }); @override State> createState() => _CustomRadioState(); } class _CustomRadioState extends State> { late T _groupValue; @override void initState() { super.initState(); _groupValue = widget.initialGroupValue; } @override Widget build(BuildContext context) { return GestureDetector( onTap: widget.onChanged != null ? () { setState(() { _groupValue = widget.value; }); widget.onChanged!(widget.value); } : null, child: Container( width: 20, height: 20, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: _groupValue == widget.value ? (widget.activeColor ?? AppColors.primary) : AppColors.borderDark, width: 2, ), ), child: _groupValue == widget.value ? Center( child: Container( width: 10, height: 10, decoration: BoxDecoration( shape: BoxShape.circle, color: widget.activeColor ?? AppColors.primary, ), ), ) : null, ), ); } } /// Labeled Radio - Radio button dengan label class LabeledRadio extends StatelessWidget { final String label; final T value; final T initialGroupValue; final ValueChanged? onChanged; const LabeledRadio({ super.key, required this.label, required this.value, required this.initialGroupValue, this.onChanged, }); @override Widget build(BuildContext context) { return InkWell( onTap: onChanged != null ? () => onChanged!(value) : null, child: Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Row( children: [ CustomRadio( value: value, initialGroupValue: initialGroupValue, onChanged: onChanged, ), const SizedBox(width: 8), Expanded( child: Text( label, style: const TextStyle( fontSize: 14, color: AppColors.textPrimary, ), ), ), ], ), ), ); } }