diff --git a/lib/features/insurance_auth/services/insurance_auth_pdf_service.dart b/lib/features/insurance_auth/services/insurance_auth_pdf_service.dart index a4e1c8e..d28239f 100644 --- a/lib/features/insurance_auth/services/insurance_auth_pdf_service.dart +++ b/lib/features/insurance_auth/services/insurance_auth_pdf_service.dart @@ -34,10 +34,10 @@ class InsuranceAuthPdfService { const pageFormat = PdfPageFormat( 8.5 * PdfPageFormat.inch, 11.0 * PdfPageFormat.inch, - marginLeft: 54, - marginRight: 54, - marginTop: 20, - marginBottom: 20, + marginLeft: 28, + marginRight: 28, + marginTop: 16, + marginBottom: 16, ); // Tipografías estándar con fallback a fuentes base PDF si no hay conexión a internet @@ -76,7 +76,7 @@ class InsuranceAuthPdfService { // Mitad superior de la hoja (máximo 5.5 pulgadas / 396 pt) pw.ConstrainedBox( constraints: const pw.BoxConstraints( - maxHeight: 5.5 * PdfPageFormat.inch - 36, + maxHeight: 5.5 * PdfPageFormat.inch - 32, ), child: pw.Column( mainAxisSize: pw.MainAxisSize.min, diff --git a/lib/features/prescription/presentation/views/prescription_modal_view.dart b/lib/features/prescription/presentation/views/prescription_modal_view.dart index 6cc0e0f..1c499f4 100644 --- a/lib/features/prescription/presentation/views/prescription_modal_view.dart +++ b/lib/features/prescription/presentation/views/prescription_modal_view.dart @@ -1,3 +1,4 @@ +import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:intl/intl.dart'; @@ -28,6 +29,7 @@ class _PrescriptionModalViewState extends State { bool _isPrinting = false; String? _statusMessage; bool _hasError = false; + bool _showPosologyPanel = false; @override void initState() { @@ -106,6 +108,21 @@ class _PrescriptionModalViewState extends State { _insertText(toInsert); } + Widget _buildPosologyCategoryRow({ + required String badgeLabel, + required Color badgeBgColor, + required Color badgeTextColor, + required List items, + }) { + return _PosologyCategoryRowWidget( + badgeLabel: badgeLabel, + badgeBgColor: badgeBgColor, + badgeTextColor: badgeTextColor, + items: items, + onSelected: _insertDosageQuick, + ); + } + Future _handlePrint() async { final patient = _patientController.text.trim(); final prescription = _prescriptionController.text.trim(); @@ -456,155 +473,139 @@ class _PrescriptionModalViewState extends State { borderRadius: BorderRadius.vertical(top: Radius.circular(9)), border: Border(bottom: BorderSide(color: Color(0xFFE2E8F0))), ), - child: Wrap( - spacing: 6, - runSpacing: 6, - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - // 1. Número consecutivo - _ToolbarActionBtn( - icon: Icons.format_list_numbered_rounded, - label: '1. Número', - tooltip: 'Agregar siguiente número consecutivo (1., 2., ...)', - onTap: _insertNextNumber, - ), - // Viñeta (Mantiene texto exacto para compatibilidad con tests) - _ToolbarActionBtn( - icon: Icons.format_list_bulleted_rounded, - label: 'Insertar viñeta (•)', - tooltip: 'Insertar viñeta de indicación secundaria', - onTap: _insertBullet, - ), - // Sub-indicación (Dosis) - _ToolbarActionBtn( - icon: Icons.subdirectory_arrow_right_rounded, - label: '↳ Dosis', - tooltip: 'Indentar indicación de dosis (- )', - onTap: _insertSubIndication, - ), - // Separador vertical - Container( - height: 18, - width: 1, - margin: const EdgeInsets.symmetric(horizontal: 2), - color: const Color(0xFFCBD5E1), - ), - // Menú desplegable de Posologías frecuentes - PopupMenuButton( - tooltip: 'Plantillas y frases de posología rápida', - onSelected: _insertDosageQuick, - position: PopupMenuPosition.under, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), - itemBuilder: (context) => [ - const PopupMenuItem( - enabled: false, - height: 28, - child: Text( - '-- HORARIOS FRECUENTES --', - style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold, color: AppColors.primary), - ), + child: ScrollConfiguration( + behavior: const MaterialScrollBehavior().copyWith( + dragDevices: { + PointerDeviceKind.touch, + PointerDeviceKind.mouse, + PointerDeviceKind.trackpad, + PointerDeviceKind.stylus, + }, + ), + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + physics: const BouncingScrollPhysics(), + child: Row( + children: [ + // 1. Número consecutivo + _ToolbarActionBtn( + icon: Icons.format_list_numbered_rounded, + label: '1. Número', + tooltip: 'Agregar siguiente número consecutivo (1., 2., ...)', + onTap: _insertNextNumber, ), - const PopupMenuItem(value: 'cada 8 horas', height: 32, child: Text('cada 8 horas', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: 'cada 12 horas', height: 32, child: Text('cada 12 horas', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: 'cada 24 horas', height: 32, child: Text('cada 24 horas', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: '1 vez al día (en la mañana)', height: 32, child: Text('1 vez al día (en la mañana)', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: '1 vez al día (en la noche)', height: 32, child: Text('1 vez al día (en la noche)', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: 'antes de acostarse', height: 32, child: Text('antes de acostarse', style: TextStyle(fontSize: 12.5))), - const PopupMenuDivider(height: 8), - const PopupMenuItem( - enabled: false, - height: 28, - child: Text( - '-- DURACIÓN TRATAMIENTO --', - style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold, color: AppColors.primary), - ), + const SizedBox(width: 6), + // Viñeta (Mantiene texto exacto para compatibilidad con tests) + _ToolbarActionBtn( + icon: Icons.format_list_bulleted_rounded, + label: 'Insertar viñeta (•)', + tooltip: 'Insertar viñeta de indicación secundaria', + onTap: _insertBullet, ), - const PopupMenuItem(value: 'por 3 días', height: 32, child: Text('por 3 días', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: 'por 5 días', height: 32, child: Text('por 5 días', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: 'por 7 días', height: 32, child: Text('por 7 días', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: 'por 10 días', height: 32, child: Text('por 10 días', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: 'por 14 días', height: 32, child: Text('por 14 días', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: 'por 30 días', height: 32, child: Text('por 30 días', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: 'según dolor o necesidad (SOS)', height: 32, child: Text('según dolor o necesidad (SOS)', style: TextStyle(fontSize: 12.5))), - const PopupMenuDivider(height: 8), - const PopupMenuItem( - enabled: false, - height: 28, - child: Text( - '-- INDICACIONES ESPECIALES --', - style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold, color: AppColors.primary), - ), + const SizedBox(width: 6), + // Sub-indicación (Dosis) + _ToolbarActionBtn( + icon: Icons.subdirectory_arrow_right_rounded, + label: '↳ Dosis', + tooltip: 'Indentar indicación de dosis (- )', + onTap: _insertSubIndication, + ), + const SizedBox(width: 6), + // Separador vertical + Container( + height: 18, + width: 1, + margin: const EdgeInsets.symmetric(horizontal: 2), + color: const Color(0xFFCBD5E1), + ), + const SizedBox(width: 6), + // Botón alternador del panel de posologías + _ToolbarActionBtn( + icon: Icons.tune_rounded, + label: _showPosologyPanel ? 'Ocultar posologías ▲' : '⏱ Posologías rápidas ▼', + tooltip: _showPosologyPanel + ? 'Ocultar el panel de atajos de posología' + : 'Mostrar atajos de horario, duración e indicaciones', + isActive: _showPosologyPanel, + onTap: () { + setState(() { + _showPosologyPanel = !_showPosologyPanel; + }); + }, ), - const PopupMenuItem(value: 'con alimentos', height: 32, child: Text('con alimentos', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: 'en ayunas (30 min antes de desayunar)', height: 32, child: Text('en ayunas (30 min antes de desayunar)', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: 'con abundante agua', height: 32, child: Text('con abundante agua', style: TextStyle(fontSize: 12.5))), - const PopupMenuItem(value: 'no suspender sin indicación médica', height: 32, child: Text('no suspender sin indicación médica', style: TextStyle(fontSize: 12.5))), ], - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(6), - border: Border.all(color: const Color(0xFFCBD5E1)), - ), - child: const Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon(Icons.timer_outlined, size: 14, color: AppColors.primary), - SizedBox(width: 4), - Text( - 'Posología ▼', - style: TextStyle( - fontSize: 11.5, - fontWeight: FontWeight.w600, - color: AppColors.textPrimary, - ), - ), - ], - ), - ), ), - ], - ), - ), - - // Chips de inserción de 1 toque (frecuencias y formatos más comunes) - Container( - width: double.infinity, - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 5), - decoration: const BoxDecoration( - color: Color(0xFFF1F5F9), - border: Border(bottom: BorderSide(color: Color(0xFFE2E8F0))), - ), - child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Row( - children: [ - const Text( - 'Rápido: ', - style: TextStyle(fontSize: 10.5, fontWeight: FontWeight.w700, color: AppColors.textMuted), - ), - _QuickChip(label: '1 tableta', onTap: () => _insertDosageQuick('1 tableta')), - _QuickChip(label: '1 cápsula', onTap: () => _insertDosageQuick('1 cápsula')), - _QuickChip(label: '1 ampolla', onTap: () => _insertDosageQuick('1 ampolla')), - _QuickChip(label: 'c/8h', onTap: () => _insertDosageQuick('cada 8 horas')), - _QuickChip(label: 'c/12h', onTap: () => _insertDosageQuick('cada 12 horas')), - _QuickChip(label: 'c/24h', onTap: () => _insertDosageQuick('cada 24 horas')), - _QuickChip(label: 'x 7 días', onTap: () => _insertDosageQuick('por 7 días')), - _QuickChip(label: 'x 14 días', onTap: () => _insertDosageQuick('por 14 días')), - _QuickChip(label: 'En ayunas', onTap: () => _insertDosageQuick('en ayunas')), - _QuickChip(label: 'Con agua', onTap: () => _insertDosageQuick('con abundante agua')), - ], ), ), ), + // Panel Desplegable de Posología Categorizada + if (_showPosologyPanel) + Container( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), + decoration: const BoxDecoration( + color: Color(0xFFF8FAFC), + border: Border(bottom: BorderSide(color: Color(0xFFE2E8F0))), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Fila 1: Horarios / Frecuencia + _buildPosologyCategoryRow( + badgeLabel: '🕒 Horario', + badgeBgColor: const Color(0xFFEFF6FF), + badgeTextColor: const Color(0xFF1D4ED8), + items: const [ + 'cada 8 horas', + 'cada 12 horas', + 'cada 24 horas', + '1 vez al día (mañana)', + '1 vez al día (noche)', + 'al acostarse', + ], + ), + const SizedBox(height: 6), + // Fila 2: Duración + _buildPosologyCategoryRow( + badgeLabel: '📅 Duración', + badgeBgColor: const Color(0xFFF0FDF4), + badgeTextColor: const Color(0xFF15803D), + items: const [ + 'por 3 días', + 'por 5 días', + 'por 7 días', + 'por 10 días', + 'por 14 días', + 'por 30 días', + 'SOS (según dolor)', + ], + ), + const SizedBox(height: 6), + // Fila 3: Forma e Indicación Especial + _buildPosologyCategoryRow( + badgeLabel: '💡 Indicación', + badgeBgColor: const Color(0xFFFFFBEB), + badgeTextColor: const Color(0xFFB45309), + items: const [ + '1 tableta', + '1 cápsula', + '1 ampolla', + 'con alimentos', + 'en ayunas (30 min antes)', + 'con abundante agua', + 'no suspender', + ], + ), + ], + ), + ), + // Lienzo de prescripción TextField( controller: _prescriptionController, focusNode: _prescriptionFocusNode, maxLines: 12, - minLines: 8, + minLines: 7, style: const TextStyle(fontSize: 13.5, height: 1.5, color: AppColors.textPrimary), decoration: const InputDecoration( hintText: '1. Ciprofloxacina 500mg (14 tabletas)\n - Tomar 1 tableta cada 12 horas por 7 días con abundante agua.\n\n2. Tamsulosina 0.4mg (30 cápsulas)\n - Tomar 1 cápsula cada 24 horas después de la cena.', @@ -630,12 +631,14 @@ class _ToolbarActionBtn extends StatelessWidget { final String label; final String tooltip; final VoidCallback onTap; + final bool isActive; const _ToolbarActionBtn({ required this.icon, required this.label, required this.tooltip, required this.onTap, + this.isActive = false, }); @override @@ -648,9 +651,12 @@ class _ToolbarActionBtn extends StatelessWidget { child: Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( - color: Colors.white, + color: isActive ? AppColors.primary.withValues(alpha: 0.08) : Colors.white, borderRadius: BorderRadius.circular(6), - border: Border.all(color: const Color(0xFFCBD5E1)), + border: Border.all( + color: isActive ? AppColors.primary : const Color(0xFFCBD5E1), + width: isActive ? 1.2 : 1.0, + ), ), child: Row( mainAxisSize: MainAxisSize.min, @@ -659,10 +665,10 @@ class _ToolbarActionBtn extends StatelessWidget { const SizedBox(width: 4), Text( label, - style: const TextStyle( + style: TextStyle( fontSize: 11.5, fontWeight: FontWeight.w600, - color: AppColors.textPrimary, + color: isActive ? AppColors.primary : AppColors.textPrimary, ), ), ], @@ -673,39 +679,209 @@ class _ToolbarActionBtn extends StatelessWidget { } } -class _QuickChip extends StatelessWidget { +class _PosologyChip extends StatelessWidget { final String label; final VoidCallback onTap; - const _QuickChip({ + const _PosologyChip({ required this.label, required this.onTap, }); @override Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.only(right: 5), - child: InkWell( - onTap: onTap, - borderRadius: BorderRadius.circular(12), - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - border: Border.all(color: const Color(0xFFCBD5E1)), - ), - child: Text( - label, - style: const TextStyle( - fontSize: 11, - fontWeight: FontWeight.w600, - color: AppColors.textSecondary, + return InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(6), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3.5), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(6), + border: Border.all(color: const Color(0xFFCBD5E1)), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.02), + blurRadius: 2, + offset: const Offset(0, 1), ), + ], + ), + child: Text( + label, + style: const TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: AppColors.textPrimary, ), ), ), ); } } + +class _PosologyCategoryRowWidget extends StatefulWidget { + final String badgeLabel; + final Color badgeBgColor; + final Color badgeTextColor; + final List items; + final ValueChanged onSelected; + + const _PosologyCategoryRowWidget({ + required this.badgeLabel, + required this.badgeBgColor, + required this.badgeTextColor, + required this.items, + required this.onSelected, + }); + + @override + State<_PosologyCategoryRowWidget> createState() => _PosologyCategoryRowWidgetState(); +} + +class _PosologyCategoryRowWidgetState extends State<_PosologyCategoryRowWidget> { + final ScrollController _scrollController = ScrollController(); + bool _canScrollLeft = false; + bool _canScrollRight = false; + + @override + void initState() { + super.initState(); + _scrollController.addListener(_updateScrollIndicators); + WidgetsBinding.instance.addPostFrameCallback((_) => _updateScrollIndicators()); + } + + void _updateScrollIndicators() { + if (!mounted || !_scrollController.hasClients) return; + final pos = _scrollController.position; + final canLeft = pos.pixels > 3; + final canRight = pos.pixels < (pos.maxScrollExtent - 3); + if (canLeft != _canScrollLeft || canRight != _canScrollRight) { + setState(() { + _canScrollLeft = canLeft; + _canScrollRight = canRight; + }); + } + } + + void _scroll(double delta) { + if (!_scrollController.hasClients) return; + _scrollController.animateTo( + (_scrollController.offset + delta).clamp(0.0, _scrollController.position.maxScrollExtent), + duration: const Duration(milliseconds: 220), + curve: Curves.easeOutCubic, + ); + } + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // Category Badge + Container( + width: 82, + padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 2.5), + decoration: BoxDecoration( + color: widget.badgeBgColor, + borderRadius: BorderRadius.circular(4), + border: Border.all(color: widget.badgeTextColor.withValues(alpha: 0.25)), + ), + child: Text( + widget.badgeLabel, + style: TextStyle( + fontSize: 9.5, + fontWeight: FontWeight.w700, + color: widget.badgeTextColor, + ), + ), + ), + const SizedBox(width: 6), + + // Botón flecha izquierda cuando hay contenido antes + if (_canScrollLeft) ...[ + InkWell( + onTap: () => _scroll(-120), + borderRadius: BorderRadius.circular(10), + child: Container( + padding: const EdgeInsets.all(2), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + border: Border.all(color: const Color(0xFFCBD5E1)), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.04), + blurRadius: 2, + ), + ], + ), + child: const Icon(Icons.chevron_left, size: 14, color: AppColors.textPrimary), + ), + ), + const SizedBox(width: 4), + ], + + // Área de desplazamiento horizontal + Expanded( + child: ScrollConfiguration( + behavior: const MaterialScrollBehavior().copyWith( + dragDevices: { + PointerDeviceKind.touch, + PointerDeviceKind.mouse, + PointerDeviceKind.trackpad, + PointerDeviceKind.stylus, + }, + ), + child: SingleChildScrollView( + controller: _scrollController, + scrollDirection: Axis.horizontal, + physics: const BouncingScrollPhysics(), + child: Row( + children: widget.items.map((item) { + return Padding( + padding: const EdgeInsets.only(right: 5), + child: _PosologyChip( + label: item, + onTap: () => widget.onSelected(item), + ), + ); + }).toList(), + ), + ), + ), + ), + + // Botón flecha derecha cuando hay contenido después + if (_canScrollRight) ...[ + const SizedBox(width: 4), + InkWell( + onTap: () => _scroll(120), + borderRadius: BorderRadius.circular(10), + child: Container( + padding: const EdgeInsets.all(2), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + border: Border.all(color: const Color(0xFFCBD5E1)), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.04), + blurRadius: 2, + ), + ], + ), + child: const Icon(Icons.chevron_right, size: 14, color: AppColors.textPrimary), + ), + ), + ], + ], + ); + } +} diff --git a/lib/features/prescription/services/prescription_pdf_service.dart b/lib/features/prescription/services/prescription_pdf_service.dart index 83e6a39..1d229b7 100644 --- a/lib/features/prescription/services/prescription_pdf_service.dart +++ b/lib/features/prescription/services/prescription_pdf_service.dart @@ -30,10 +30,10 @@ class PrescriptionPdfService { const pageFormat = PdfPageFormat( 8.5 * PdfPageFormat.inch, 11.0 * PdfPageFormat.inch, - marginLeft: 54, - marginRight: 54, - marginTop: 20, - marginBottom: 20, + marginLeft: 28, + marginRight: 28, + marginTop: 16, + marginBottom: 16, ); // Tipografías estándar con fallback a fuentes base PDF si no hay conexión a internet @@ -73,7 +73,7 @@ class PrescriptionPdfService { // Mitad superior de la hoja (máximo 5.5 pulgadas / 396 pt) pw.ConstrainedBox( constraints: const pw.BoxConstraints( - maxHeight: 5.5 * PdfPageFormat.inch - 36, + maxHeight: 5.5 * PdfPageFormat.inch - 32, ), child: pw.Column( mainAxisSize: pw.MainAxisSize.min, diff --git a/lib/features/referrals/services/department_referral_pdf_service.dart b/lib/features/referrals/services/department_referral_pdf_service.dart index f2958f5..2dbb9de 100644 --- a/lib/features/referrals/services/department_referral_pdf_service.dart +++ b/lib/features/referrals/services/department_referral_pdf_service.dart @@ -29,10 +29,10 @@ class DepartmentReferralPdfService { const pageFormat = PdfPageFormat( 8.5 * PdfPageFormat.inch, 11.0 * PdfPageFormat.inch, - marginLeft: 54, - marginRight: 54, - marginTop: 20, - marginBottom: 20, + marginLeft: 28, + marginRight: 28, + marginTop: 16, + marginBottom: 16, ); // Tipografías estándar con fallback a fuentes base PDF si no hay conexión a internet @@ -71,7 +71,7 @@ class DepartmentReferralPdfService { // Mitad superior de la hoja (máximo 5.5 pulgadas / 396 pt) pw.ConstrainedBox( constraints: const pw.BoxConstraints( - maxHeight: 5.5 * PdfPageFormat.inch - 36, + maxHeight: 5.5 * PdfPageFormat.inch - 32, ), child: pw.Column( mainAxisSize: pw.MainAxisSize.min, diff --git a/lib/features/referrals/services/doctor_referral_pdf_service.dart b/lib/features/referrals/services/doctor_referral_pdf_service.dart index c96e7d8..0630257 100644 --- a/lib/features/referrals/services/doctor_referral_pdf_service.dart +++ b/lib/features/referrals/services/doctor_referral_pdf_service.dart @@ -29,10 +29,10 @@ class DoctorReferralPdfService { const pageFormat = PdfPageFormat( 8.5 * PdfPageFormat.inch, 11.0 * PdfPageFormat.inch, - marginLeft: 54, - marginRight: 54, - marginTop: 20, - marginBottom: 20, + marginLeft: 28, + marginRight: 28, + marginTop: 16, + marginBottom: 16, ); // Tipografías estándar con fallback a fuentes base PDF si no hay conexión a internet @@ -71,7 +71,7 @@ class DoctorReferralPdfService { // Mitad superior de la hoja (máximo 5.5 pulgadas / 396 pt) pw.ConstrainedBox( constraints: const pw.BoxConstraints( - maxHeight: 5.5 * PdfPageFormat.inch - 36, + maxHeight: 5.5 * PdfPageFormat.inch - 32, ), child: pw.Column( mainAxisSize: pw.MainAxisSize.min, diff --git a/test/features/prescription_test.dart b/test/features/prescription_test.dart index 78fcf7c..52b2152 100644 --- a/test/features/prescription_test.dart +++ b/test/features/prescription_test.dart @@ -103,6 +103,9 @@ void main() { }); testWidgets('inserts sequential numbers and sub-indication dosis', (tester) async { + await tester.binding.setSurfaceSize(const Size(1024, 800)); + addTearDown(() => tester.binding.setSurfaceSize(null)); + final configStore = ConfigStore(); await tester.pumpWidget( MaterialApp( @@ -134,6 +137,12 @@ void main() { await tester.pump(); expect(find.text('1. \n2. \n - '), findsOneWidget); + // Open posology panel + final posologyToggleBtn = find.text('⏱ Posologías rápidas ▼'); + expect(posologyToggleBtn, findsOneWidget); + await tester.tap(posologyToggleBtn); + await tester.pump(); + // Tap quick dosage chip final chip = find.text('1 tableta'); expect(chip, findsOneWidget);