2026-09-21 16:33:51 -04:00
import 'package:flutter/material.dart' ;
import 'package:flutter_mobx/flutter_mobx.dart' ;
import 'package:intl/intl.dart' ;
import '../../../../core/theme/app_colors.dart' ;
import '../../../../core/widgets/medical_modal.dart' ;
import '../../../config/presentation/store/config_store.dart' ;
import '../../services/prescription_pdf_service.dart' ;
class PrescriptionModalView extends StatefulWidget {
final String patientName ;
final ConfigStore ? configStore ;
const PrescriptionModalView ({
super . key ,
required this . patientName ,
this . configStore ,
});
@ override
State < PrescriptionModalView > createState () => _PrescriptionModalViewState ();
}
class _PrescriptionModalViewState extends State < PrescriptionModalView > {
late final TextEditingController _patientController ;
late final TextEditingController _prescriptionController ;
late final FocusNode _prescriptionFocusNode ;
late final ConfigStore _configStore ;
bool _isPrinting = false ;
String ? _statusMessage ;
bool _hasError = false ;
@ override
void initState () {
super . initState ();
_patientController = TextEditingController ( text: widget . patientName );
_prescriptionController = TextEditingController ();
_prescriptionFocusNode = FocusNode ();
_configStore = widget . configStore ?? ConfigStore ();
_configStore . loadConfig ();
}
@ override
void dispose () {
_patientController . dispose ();
_prescriptionController . dispose ();
_prescriptionFocusNode . dispose ();
super . dispose ();
}
2026-09-22 08:38:19 -04:00
void _insertText ( String textToInsert ) {
2026-09-21 16:33:51 -04:00
final text = _prescriptionController . text ;
final selection = _prescriptionController . selection ;
int start = selection . start ;
int end = selection . end ;
if ( start < 0 || end < 0 ) {
start = text . length ;
end = text . length ;
}
2026-09-22 08:38:19 -04:00
final newText = text . replaceRange ( start , end , textToInsert );
final newOffset = start + textToInsert . length ;
2026-09-21 16:33:51 -04:00
_prescriptionController . value = TextEditingValue (
text: newText ,
selection: TextSelection . collapsed ( offset: newOffset ),
);
_prescriptionFocusNode . requestFocus ();
}
2026-09-22 08:38:19 -04:00
void _insertBullet () {
final text = _prescriptionController . text ;
final bullet = text . isEmpty || text . endsWith ( ' \n ' ) ? '• ' : ' \n • ' ;
_insertText ( bullet );
}
void _insertNextNumber () {
final text = _prescriptionController . text ;
final matches = RegExp ( r'(?:^|\n)\s*(\d+)\.' ). allMatches ( text );
int nextNumber = 1 ;
if ( matches . isNotEmpty ) {
final lastNum = int . tryParse ( matches . last . group ( 1 ) ?? '0' ) ?? 0 ;
nextNumber = lastNum + 1 ;
}
final prefix = text . isEmpty || text . endsWith ( ' \n ' ) ? ' $ nextNumber . ' : ' \n $ nextNumber . ' ;
_insertText ( prefix );
}
void _insertSubIndication () {
final text = _prescriptionController . text ;
final prefix = text . isEmpty || text . endsWith ( ' \n ' ) ? ' - ' : ' \n - ' ;
_insertText ( prefix );
}
void _insertDosageQuick ( String dosage ) {
final text = _prescriptionController . text ;
final selection = _prescriptionController . selection ;
int start = selection . start ;
String toInsert = dosage ;
if ( start > 0 && text . isNotEmpty && start <= text . length ) {
final prevChar = text [ start - 1 ];
if ( prevChar != ' ' && prevChar != ' \n ' ) {
toInsert = ' $ dosage ' ;
}
}
_insertText ( toInsert );
}
2026-09-21 16:33:51 -04:00
Future < void > _handlePrint () async {
final patient = _patientController . text . trim ();
final prescription = _prescriptionController . text . trim ();
if ( patient . isEmpty ) {
setState (() {
_statusMessage = 'Debe indicar el nombre del paciente.' ;
_hasError = true ;
});
return ;
}
if ( prescription . isEmpty ) {
setState (() {
_statusMessage = 'Debe redactar los medicamentos e indicaciones de la receta.' ;
_hasError = true ;
});
return ;
}
setState (() {
_isPrinting = true ;
_statusMessage = 'Generando receta médica en formato oficial...' ;
_hasError = false ;
});
try {
await PrescriptionPdfService . printPrescription (
doctorName: _configStore . nombreDoctor ,
specialty: _configStore . especialidad ,
subspecialty: _configStore . descripEspecialidad ,
generalContact: _configStore . descripGeneral ,
patientName: patient ,
prescriptionText: prescription ,
);
if ( mounted ) {
setState (() {
_isPrinting = false ;
_statusMessage = 'Receta generada con éxito.' ;
_hasError = false ;
});
}
} catch ( e ) {
if ( mounted ) {
setState (() {
_isPrinting = false ;
_statusMessage = 'Error al generar la receta: $ e ' ;
_hasError = true ;
});
}
}
}
@ override
Widget build ( BuildContext context ) {
final formattedDate = DateFormat ( 'dd/MM/yyyy' ). format ( DateTime . now ());
return Observer (
builder: ( _ ) {
return MedicalModalDialog (
maxWidth: 820 ,
maxHeight: 650 ,
title: 'Emisión de Receta Médica' ,
titleIcon: Container (
padding: const EdgeInsets . all ( 8 ),
decoration: BoxDecoration (
color: const Color ( 0xFF00A65A ). withValues ( alpha: 0.12 ),
borderRadius: BorderRadius . circular ( 10 ),
),
child: const Icon (
Icons . medication_rounded ,
color: Color ( 0xFF00A65A ),
size: 20 ,
),
),
subtitle: const Text (
'Redacte la prescripción para imprimir en talonario media carta institucional' ,
style: TextStyle ( fontSize: 12 , color: AppColors . textMuted ),
),
bottomBar: Container (
padding: const EdgeInsets . symmetric ( horizontal: 20 , vertical: 12 ),
decoration: const BoxDecoration (
color: Color ( 0xFFF8FAFC ),
border: Border ( top: BorderSide ( color: Color ( 0xFFE2E8F0 ))),
),
child: Row (
children: [
Container (
padding: const EdgeInsets . all ( 4 ),
decoration: BoxDecoration (
color: _hasError
? AppColors . error . withValues ( alpha: 0.12 )
: const Color ( 0xFF00A65A ). withValues ( alpha: 0.12 ),
shape: BoxShape . circle ,
),
child: Icon (
_hasError
? Icons . error_outline_rounded
: Icons . check_circle_outline_rounded ,
size: 15 ,
color: _hasError ? AppColors . error : const Color ( 0xFF00A65A ),
),
),
const SizedBox ( width: 8 ),
Expanded (
child: Text (
_statusMessage ??
( _isPrinting
? 'Preparando documento para impresión...'
: 'Listo para emitir la receta médica' ),
style: TextStyle (
fontSize: 12 ,
fontWeight: FontWeight . w600 ,
color: _hasError ? AppColors . error : AppColors . textSecondary ,
),
),
),
Container (
padding: const EdgeInsets . symmetric ( horizontal: 8 , vertical: 4 ),
decoration: BoxDecoration (
color: Colors . white ,
borderRadius: BorderRadius . circular ( 6 ),
border: Border . all ( color: const Color ( 0xFFE2E8F0 )),
),
child: const Row (
mainAxisSize: MainAxisSize . min ,
children: [
Icon ( Icons . keyboard_outlined , size: 12 , color: AppColors . textMuted ),
SizedBox ( width: 4 ),
Text (
'ESC para salir' ,
style: TextStyle (
fontSize: 11 ,
color: AppColors . textMuted ,
fontWeight: FontWeight . w500 ,
),
),
],
),
),
const SizedBox ( width: 12 ),
ElevatedButton . icon (
onPressed: _isPrinting ? null : _handlePrint ,
icon: _isPrinting
? const SizedBox (
width: 16 ,
height: 16 ,
child: CircularProgressIndicator (
strokeWidth: 2 ,
color: Colors . white ,
),
)
: const Icon ( Icons . print_rounded , size: 16 ),
label: Text (
_isPrinting ? 'Generando...' : 'Crear / Imprimir Receta' ,
style: const TextStyle ( fontWeight: FontWeight . w600 , fontSize: 12.5 ),
),
style: ElevatedButton . styleFrom (
backgroundColor: const Color ( 0xFF00A65A ),
foregroundColor: Colors . white ,
padding: const EdgeInsets . symmetric ( horizontal: 16 , vertical: 12 ),
shape: RoundedRectangleBorder ( borderRadius: BorderRadius . circular ( 8 )),
elevation: 0 ,
),
),
],
),
),
child: SingleChildScrollView (
padding: const EdgeInsets . all ( 20 ),
child: Column (
crossAxisAlignment: CrossAxisAlignment . stretch ,
children: [
// Membrete Informativo del Médico (Vista preliminar institucional)
Container (
padding: const EdgeInsets . all ( 16 ),
decoration: BoxDecoration (
color: const Color ( 0xFFF8FAFC ),
borderRadius: BorderRadius . circular ( 12 ),
border: Border . all ( color: const Color ( 0xFFE2E8F0 )),
),
child: Column (
children: [
Text (
_configStore . nombreDoctor . isNotEmpty
? _configStore . nombreDoctor
: 'Dr. Luis A. Castro Sosa' ,
textAlign: TextAlign . center ,
style: const TextStyle (
fontSize: 18 ,
fontWeight: FontWeight . w700 ,
color: AppColors . textPrimary ,
letterSpacing: - 0.3 ,
),
),
if ( _configStore . especialidad . isNotEmpty ) ...[
const SizedBox ( height: 2 ),
Text (
_configStore . especialidad . toUpperCase (),
textAlign: TextAlign . center ,
style: const TextStyle (
fontSize: 11.5 ,
fontWeight: FontWeight . w600 ,
color: AppColors . primary ,
letterSpacing: 0.5 ,
),
),
],
if ( _configStore . descripEspecialidad . isNotEmpty ) ...[
const SizedBox ( height: 2 ),
Text (
_configStore . descripEspecialidad . toUpperCase (),
textAlign: TextAlign . center ,
style: const TextStyle (
fontSize: 10 ,
color: AppColors . textMuted ,
),
),
],
const SizedBox ( height: 4 ),
Text (
'Fecha: $ formattedDate ' ,
style: const TextStyle (
fontSize: 11 ,
fontWeight: FontWeight . w500 ,
color: AppColors . textSecondary ,
),
),
],
),
),
const SizedBox ( height: 16 ),
// Campo Paciente
Row (
children: [
Container (
padding: const EdgeInsets . symmetric ( horizontal: 10 , vertical: 8 ),
decoration: BoxDecoration (
color: const Color ( 0xFF00A65A ). withValues ( alpha: 0.1 ),
borderRadius: BorderRadius . circular ( 8 ),
),
child: const Text (
'Rx' ,
style: TextStyle (
fontSize: 14 ,
fontWeight: FontWeight . w800 ,
color: Color ( 0xFF00A65A ),
),
),
),
const SizedBox ( width: 12 ),
Expanded (
child: TextField (
controller: _patientController ,
decoration: InputDecoration (
labelText: 'Paciente' ,
hintText: 'Nombre del paciente' ,
isDense: true ,
floatingLabelBehavior: FloatingLabelBehavior . always ,
filled: true ,
fillColor: Colors . white ,
contentPadding: const EdgeInsets . symmetric ( horizontal: 12 , vertical: 12 ),
border: OutlineInputBorder (
borderRadius: BorderRadius . circular ( 8 ),
borderSide: const BorderSide ( color: Color ( 0xFFE2E8F0 )),
),
enabledBorder: OutlineInputBorder (
borderRadius: BorderRadius . circular ( 8 ),
borderSide: const BorderSide ( color: Color ( 0xFFE2E8F0 )),
),
focusedBorder: OutlineInputBorder (
borderRadius: BorderRadius . circular ( 8 ),
borderSide: const BorderSide ( color: AppColors . primary , width: 1.5 ),
),
),
style: const TextStyle ( fontSize: 13 , fontWeight: FontWeight . w600 ),
),
),
],
),
const SizedBox ( height: 16 ),
2026-09-22 08:38:19 -04:00
// Sección de Medicamentos y Redacción Inteligente
2026-09-21 16:33:51 -04:00
Row (
mainAxisAlignment: MainAxisAlignment . spaceBetween ,
children: [
const Text (
2026-09-22 08:38:19 -04:00
'Medicamentos e Indicaciones:' ,
2026-09-21 16:33:51 -04:00
style: TextStyle (
fontSize: 13 ,
fontWeight: FontWeight . w700 ,
color: AppColors . textPrimary ,
),
),
2026-09-22 08:38:19 -04:00
ValueListenableBuilder < TextEditingValue > (
valueListenable: _prescriptionController ,
builder: ( context , val , _ ) {
if ( val . text . isEmpty ) return const SizedBox . shrink ();
return InkWell (
onTap: () {
_prescriptionController . clear ();
},
borderRadius: BorderRadius . circular ( 4 ),
child: const Padding (
padding: EdgeInsets . symmetric ( horizontal: 6 , vertical: 2 ),
child: Row (
children: [
Icon ( Icons . clear_all_rounded , size: 14 , color: AppColors . textMuted ),
SizedBox ( width: 4 ),
Text (
'Limpiar lienzo' ,
style: TextStyle ( fontSize: 11 , color: AppColors . textMuted , fontWeight: FontWeight . w500 ),
),
],
),
),
);
},
2026-09-21 16:33:51 -04:00
),
],
),
2026-09-22 08:38:19 -04:00
const SizedBox ( height: 8 ),
2026-09-21 16:33:51 -04:00
2026-09-22 08:38:19 -04:00
// Editor de Receta con Toolbar Inteligente Integrada
Container (
decoration: BoxDecoration (
color: Colors . white ,
borderRadius: BorderRadius . circular ( 10 ),
border: Border . all ( color: const Color ( 0xFFCBD5E1 )),
boxShadow: [
BoxShadow (
color: Colors . black . withValues ( alpha: 0.02 ),
blurRadius: 4 ,
offset: const Offset ( 0 , 2 ),
),
],
),
child: Column (
crossAxisAlignment: CrossAxisAlignment . stretch ,
children: [
// Barra de herramientas superior
Container (
padding: const EdgeInsets . symmetric ( horizontal: 8 , vertical: 6 ),
decoration: const BoxDecoration (
color: Color ( 0xFFF8FAFC ),
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 < String > (
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 ),
),
),
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 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 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' )),
],
),
),
),
// Lienzo de prescripción
TextField (
controller: _prescriptionController ,
focusNode: _prescriptionFocusNode ,
maxLines: 12 ,
minLines: 8 ,
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\n 2. Tamsulosina 0.4mg (30 cápsulas) \n - Tomar 1 cápsula cada 24 horas después de la cena.' ,
hintStyle: TextStyle ( color: Color ( 0xFF94A3B8 ), fontSize: 12.5 ),
border: InputBorder . none ,
contentPadding: EdgeInsets . all ( 14 ),
),
),
],
2026-09-21 16:33:51 -04:00
),
),
],
),
),
);
},
);
}
}
2026-09-22 08:38:19 -04:00
class _ToolbarActionBtn extends StatelessWidget {
final IconData icon ;
final String label ;
final String tooltip ;
final VoidCallback onTap ;
const _ToolbarActionBtn ({
required this . icon ,
required this . label ,
required this . tooltip ,
required this . onTap ,
});
@ override
Widget build ( BuildContext context ) {
return Tooltip (
message: tooltip ,
child: InkWell (
onTap: onTap ,
borderRadius: BorderRadius . circular ( 6 ),
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: Row (
mainAxisSize: MainAxisSize . min ,
children: [
Icon ( icon , size: 14 , color: AppColors . primary ),
const SizedBox ( width: 4 ),
Text (
label ,
style: const TextStyle (
fontSize: 11.5 ,
fontWeight: FontWeight . w600 ,
color: AppColors . textPrimary ,
),
),
],
),
),
),
);
}
}
class _QuickChip extends StatelessWidget {
final String label ;
final VoidCallback onTap ;
const _QuickChip ({
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 ,
),
),
),
),
);
}
}