import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:geolocator/geolocator.dart'; import 'package:image_picker/image_picker.dart'; import 'package:permission_handler/permission_handler.dart'; import '../../Utils/app_colors.dart'; import '../../Utils/dropdownTheme.dart'; class AddLiveAttendanceScreen extends StatefulWidget { const AddLiveAttendanceScreen({Key? key}) : super(key: key); @override State createState() => _AddLiveAttendanceScreenState(); } class _AddLiveAttendanceScreenState extends State { String? selectedType; Dropdowntheme ddtheme = Dropdowntheme(); final TextEditingController locationController = TextEditingController(); final TextEditingController descriptionController = TextEditingController(); final List types = ["Check In", "Check Out"]; final ImagePicker picker = ImagePicker(); XFile? proofFile; // store selected proof // computed labels String get locationHeading => selectedType == null ? "Location" : "$selectedType Location"; String get descriptionHeading => selectedType == null ? "Description" : "$selectedType Description"; String get proofButtonText => selectedType == null ? "Attach Proof" : "Attach $selectedType Proof"; bool get isSubmitEnabled => selectedType != null && locationController.text.trim().isNotEmpty && proofFile != null; // proof is required @override void initState() { super.initState(); locationController.addListener(() { setState(() {}); }); } @override void dispose() { locationController.dispose(); descriptionController.dispose(); super.dispose(); } void _showPicker(BuildContext context) { showModalBottomSheet( context: context, builder: (BuildContext bc) { return SafeArea( child: Wrap( children: [ ListTile( leading: const Icon(Icons.photo_camera), title: const Text('Camera'), onTap: () async { Navigator.of(context).pop(); final XFile? image = await picker.pickImage(source: ImageSource.camera); if (image != null) { setState(() => proofFile = image); } }, ), ListTile( leading: const Icon(Icons.photo_library), title: const Text('Gallery'), onTap: () async { Navigator.of(context).pop(); final XFile? image = await picker.pickImage(source: ImageSource.gallery); if (image != null) { setState(() => proofFile = image); } }, ), ], ), ); }, ); } Future getCurrentLocation() async { var status = await Permission.location.request(); if (status.isGranted) { Position position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high, ); return "${position.latitude.toStringAsFixed(7)}, ${position.longitude.toStringAsFixed(7)}"; } else { return "Permission denied"; } } /// New: submit function void submitAttendance() { print("==== Attendance Submitted ===="); print("Type: $selectedType"); print("Location: ${locationController.text}"); print("Description: ${descriptionController.text}"); print("Proof: ${proofFile?.path ?? 'No file'}"); print("============================="); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: AppBar( automaticallyImplyLeading: false, backgroundColor: const Color(0xFEFFFFFF), title: Row( children: [ InkResponse( onTap: () => Navigator.pop(context, true), child: SvgPicture.asset( "assets/svg/appbar_back_button.svg", height: 25, ), ), const SizedBox(width: 10), Text( "Add Live Attendance", style: TextStyle( fontSize: 18, fontFamily: "Plus Jakarta Sans", fontWeight: FontWeight.w600, color: AppColors.semi_black, ), ), ], ), ), body: SingleChildScrollView( padding: const EdgeInsets.all(18), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ /// Type Dropdown const Text("Type", style: TextStyle( fontSize: 15, fontFamily: "Plus Jakarta Sans", fontWeight: FontWeight.w500)), const SizedBox(height: 6), Container( padding: const EdgeInsets.symmetric(horizontal: 2), decoration: BoxDecoration( color: Colors.grey.shade100, borderRadius: BorderRadius.circular(8), ), child: DropdownButtonHideUnderline( child: DropdownButton2( isExpanded: true, hint: const Text("Select Type", overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 15, fontFamily: "Plus Jakarta Sans", fontWeight: FontWeight.w400), ), value: selectedType, items: types .map((e) => DropdownMenuItem( value: e, child: Text( e, style: TextStyle( fontSize: 14, ), overflow: TextOverflow.ellipsis, ) )) .toList(), onChanged: (val) => setState(() => selectedType = val), // buttonStyleData: ddtheme.buttonStyleData, iconStyleData: ddtheme.iconStyleData, // menuItemStyleData: ddtheme.menuItemStyleData, dropdownStyleData: ddtheme.dropdownStyleData, ), ), ), const SizedBox(height: 16), /// Location field Text(locationHeading, style: const TextStyle( fontSize: 15, fontFamily: "Plus Jakarta Sans", fontStyle: FontStyle.normal, fontWeight: FontWeight.w500 )), const SizedBox(height: 6), TextField( controller: locationController, readOnly: true, onTap: () async { String loc = await getCurrentLocation(); locationController.text = loc; }, decoration: _inputDecoration("Tap to get location"), ), const SizedBox(height: 16), /// Description Text(descriptionHeading, style: const TextStyle( fontSize: 15, fontFamily: "Plus Jakarta Sans", fontStyle: FontStyle.normal, fontWeight: FontWeight.w500 ) ), const SizedBox(height: 6), TextField( controller: descriptionController, maxLines: 3, decoration: _inputDecoration("Write Description"), ), const SizedBox(height: 20), /// Attach Proof SizedBox( width: double.infinity, child: OutlinedButton( onPressed: () => _showPicker(context), style: OutlinedButton.styleFrom( backgroundColor: Colors.blue.shade50, side: BorderSide(color: Colors.blue.shade200), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), padding: const EdgeInsets.symmetric(vertical: 14), ), child: Text(proofButtonText, style: const TextStyle( fontSize: 16, color: Colors.blue, fontFamily: "Plus Jakarta Sans", fontStyle: FontStyle.normal, fontWeight: FontWeight.w500 )), ), ), /// Show proof preview if (proofFile != null) ...[ const SizedBox(height: 10), Row( children: [ const Icon(Icons.check_circle, color: Colors.green), const SizedBox(width: 8), Expanded( child: Text( "Attached: ${proofFile!.name}", overflow: TextOverflow.ellipsis)), IconButton( icon: const Icon(Icons.close, color: Colors.red), onPressed: () => setState(() => proofFile = null), ), ], ) ], const SizedBox(height: 24), /// Submit button SizedBox( width: double.infinity, child: ElevatedButton( onPressed: isSubmitEnabled ? submitAttendance : null, style: ElevatedButton.styleFrom( backgroundColor: isSubmitEnabled ? Colors.blue : Colors.grey.shade400, padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8)), ), child: const Text("Submit", style: TextStyle( fontSize: 16, color: Colors.white, fontWeight: FontWeight.w500)), ), ), ], ), ), ); } InputDecoration _inputDecoration(String hint) { return InputDecoration( hintText: hint, hintStyle: const TextStyle( fontSize: 14, fontFamily: "Plus Jakarta Sans", fontStyle: FontStyle.normal, fontWeight: FontWeight.w400, color: Colors.grey, ), filled: true, fillColor: Colors.grey.shade100, enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide(color: Colors.blue), ), ); } }