import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/providers/auth_provider.dart'; import '../../../core/services/realtime_service.dart'; import '../../../core/theme/app_theme.dart'; import '../../../core/widgets/gradient_app_bar.dart'; import '../../../models/job.dart'; import 'lab_jobs_repository.dart'; class LabJobsInboundScreen extends ConsumerStatefulWidget { const LabJobsInboundScreen({super.key}); @override ConsumerState createState() => _LabJobsInboundScreenState(); } class _LabJobsInboundScreenState extends ConsumerState { late Future> _future; bool _acceptingAll = false; late UnsubFn _unsub; @override void initState() { super.initState(); _load(); final tenantId = ref.read(authProvider).activeTenant!.tenant.id; _unsub = RealtimeService.instance.watch( 'jobs', filter: "lab_tenant_id='$tenantId'", onEvent: (_) { if (mounted) _load(); }, ); } @override void dispose() { _unsub(); super.dispose(); } void _load() { final tenantId = ref.read(authProvider).activeTenant!.tenant.id; setState(() { _future = LabJobsRepository.instance.listInbound(tenantId, status: 'pending'); }); } Future _acceptJob(Job job) async { try { await LabJobsRepository.instance.acceptJob(job); _load(); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('İş kabul edildi')), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Hata: $e')), ); } } } Future _bulkAccept() async { final tenantId = ref.read(authProvider).activeTenant!.tenant.id; setState(() => _acceptingAll = true); try { await LabJobsRepository.instance.bulkAcceptPending(tenantId); _load(); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Tüm işler kabul edildi')), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Hata: $e')), ); } } finally { if (mounted) setState(() => _acceptingAll = false); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.background, appBar: GradientAppBar( title: 'Gelen İşler', category: 'LABORATUVAR', ), floatingActionButton: FloatingActionButton.extended( onPressed: _acceptingAll ? null : _bulkAccept, icon: _acceptingAll ? const SizedBox( width: 18, height: 18, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white), ) : const Icon(Icons.done_all), label: Text(_acceptingAll ? 'Kabul ediliyor...' : 'Tümünü Kabul Et'), backgroundColor: AppColors.pending, foregroundColor: Colors.white, ), body: RefreshIndicator( onRefresh: () async => _load(), child: FutureBuilder>( future: _future, builder: (ctx, snap) { if (snap.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (snap.hasError) { return Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Text('Hata: ${snap.error}'), const SizedBox(height: 12), FilledButton( onPressed: _load, child: const Text('Tekrar Dene'), ), ], ), ); } final jobs = snap.data!; if (jobs.isEmpty) { return Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.inbox_outlined, size: 64, color: AppColors.textMuted), const SizedBox(height: 16), Text( 'Bekleyen iş yok', style: TextStyle( fontSize: 16, color: AppColors.textSecondary), ), ], ), ); } return ListView.builder( padding: const EdgeInsets.fromLTRB(16, 16, 16, 80), itemCount: jobs.length, itemBuilder: (ctx, i) { final job = jobs[i]; return _InboundJobCard( job: job, onAccept: () => _acceptJob(job), ); }, ); }, ), ), ); } } class _InboundJobCard extends StatefulWidget { const _InboundJobCard({required this.job, required this.onAccept}); final Job job; final VoidCallback onAccept; @override State<_InboundJobCard> createState() => _InboundJobCardState(); } class _InboundJobCardState extends State<_InboundJobCard> { bool _accepting = false; String _formatDate(DateTime dt) => '${dt.day.toString().padLeft(2, '0')}.${dt.month.toString().padLeft(2, '0')}.${dt.year}'; @override Widget build(BuildContext context) { final job = widget.job; return Semantics( label: job.patientCode, button: true, excludeSemantics: true, child: Dismissible( key: ValueKey(job.id), direction: DismissDirection.endToStart, background: Container( alignment: Alignment.centerRight, padding: const EdgeInsets.only(right: 20), margin: const EdgeInsets.only(bottom: 8), decoration: BoxDecoration( color: AppColors.success, borderRadius: BorderRadius.circular(12), ), child: const Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.check, color: Colors.white, size: 28), SizedBox(height: 4), Text('Kabul Et', style: TextStyle(color: Colors.white, fontSize: 12)), ], ), ), confirmDismiss: (_) async { setState(() => _accepting = true); try { await LabJobsRepository.instance.acceptJob(job); return true; } catch (e) { if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Hata: $e')), ); } return false; } finally { if (mounted) setState(() => _accepting = false); } }, child: Card( margin: const EdgeInsets.only(bottom: 8), child: Padding( padding: const EdgeInsets.all(14), child: Row( children: [ CircleAvatar( backgroundColor: AppColors.pendingBg, child: const Icon(Icons.assignment_outlined, color: AppColors.pending), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( job.patientCode, style: const TextStyle(fontWeight: FontWeight.bold), ), const SizedBox(height: 2), Text( job.clinicName ?? 'Klinik', style: TextStyle( color: AppColors.textSecondary, fontSize: 13), ), const SizedBox(height: 4), Row( children: [ _Chip( label: job.prostheticType.label, color: AppColors.inProgressBg, textColor: AppColors.inProgress, ), const SizedBox(width: 6), _Chip( label: '${job.memberCount} üye', color: AppColors.background, textColor: AppColors.textSecondary, ), ], ), const SizedBox(height: 4), Text( _formatDate(job.dateCreated), style: TextStyle( color: AppColors.textMuted, fontSize: 12), ), ], ), ), const SizedBox(width: 8), _accepting ? const SizedBox( width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2), ) : FilledButton( onPressed: widget.onAccept, style: FilledButton.styleFrom( backgroundColor: AppColors.success, padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 8), minimumSize: Size.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), child: const Text('Kabul Et', style: TextStyle(fontSize: 13)), ), ], ), ), ), ), ); } } class _Chip extends StatelessWidget { const _Chip( {required this.label, required this.color, required this.textColor}); final String label; final Color color; final Color textColor; @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration( color: color, borderRadius: BorderRadius.circular(10), ), child: Text(label, style: TextStyle( color: textColor, fontSize: 11, fontWeight: FontWeight.w500)), ); } }