import 'package:flutter/material.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:superport/utils/constants.dart'; import 'package:superport/core/extensions/license_expiry_summary_extensions.dart'; import 'package:superport/data/models/dashboard/license_expiry_summary.dart'; /// 라이선스 만료 알림 배너 위젯 (ShadCN UI) class LicenseExpiryAlert extends StatelessWidget { final LicenseExpirySummary summary; const LicenseExpiryAlert({ super.key, required this.summary, }); @override Widget build(BuildContext context) { if (summary.alertLevel == 0) { return const SizedBox.shrink(); // 알림이 필요없으면 숨김 } return GestureDetector( onTap: () => _navigateToLicenses(context), child: Container( margin: const EdgeInsets.all(16.0), child: ShadCard( backgroundColor: _getAlertBackgroundColor(summary.alertLevel), border: Border.all( color: _getAlertBorderColor(summary.alertLevel), width: 1.0, ), padding: const EdgeInsets.all(16.0), child: Row( children: [ Icon( _getAlertIcon(summary.alertLevel), color: _getAlertIconColor(summary.alertLevel), size: 24, ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _getAlertTitle(summary.alertLevel), style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: _getAlertTextColor(summary.alertLevel), ), ), const SizedBox(height: 4), Text( summary.alertMessage, style: TextStyle( fontSize: 14, color: _getAlertTextColor(summary.alertLevel).withValues(alpha: 0.8 * 255), ), ), if (summary.alertLevel > 1) ...[ const SizedBox(height: 8), Text( '상세 내용을 확인하려면 탭하세요', style: TextStyle( fontSize: 12, fontStyle: FontStyle.italic, color: _getAlertTextColor(summary.alertLevel).withValues(alpha: 0.6 * 255), ), ), ], ], ), ), _buildStatsBadges(), const SizedBox(width: 8), Icon( Icons.arrow_forward_ios, size: 16, color: _getAlertTextColor(summary.alertLevel).withValues(alpha: 0.6 * 255), ), ], ), ), ), ); } /// 통계 배지들 생성 Widget _buildStatsBadges() { return Row( children: [ if (summary.expired > 0) Padding( padding: const EdgeInsets.only(left: 4), child: ShadBadge( backgroundColor: Colors.red.shade100, child: Text( '만료 ${summary.expired}', style: const TextStyle(fontSize: 10, fontWeight: FontWeight.bold), ), ), ), if (summary.expiring7Days > 0) Padding( padding: const EdgeInsets.only(left: 4), child: ShadBadge( backgroundColor: Colors.orange.shade100, child: Text( '7일 ${summary.expiring7Days}', style: const TextStyle(fontSize: 10, fontWeight: FontWeight.bold), ), ), ), if (summary.expiring30Days > 0) Padding( padding: const EdgeInsets.only(left: 4), child: ShadBadge( backgroundColor: Colors.yellow.shade100, child: Text( '30일 ${summary.expiring30Days}', style: const TextStyle(fontSize: 10, fontWeight: FontWeight.bold), ), ), ), ], ); } /// 유지보수 일정 화면으로 이동 void _navigateToLicenses(BuildContext context) { Navigator.pushNamed(context, Routes.maintenanceSchedule); } /// 알림 레벨별 배경색 Color _getAlertBackgroundColor(int level) { switch (level) { case 3: return Colors.red.shade50; case 2: return Colors.orange.shade50; case 1: return Colors.yellow.shade50; default: return Colors.green.shade50; } } /// 알림 레벨별 테두리색 Color _getAlertBorderColor(int level) { switch (level) { case 3: return Colors.red.shade200; case 2: return Colors.orange.shade200; case 1: return Colors.yellow.shade200; default: return Colors.green.shade200; } } /// 알림 레벨별 아이콘 IconData _getAlertIcon(int level) { switch (level) { case 3: return Icons.error; case 2: return Icons.warning; case 1: return Icons.info; default: return Icons.check_circle; } } /// 알림 레벨별 아이콘 색상 Color _getAlertIconColor(int level) { switch (level) { case 3: return Colors.red.shade600; case 2: return Colors.orange.shade600; case 1: return Colors.yellow.shade700; default: return Colors.green.shade600; } } /// 알림 레벨별 텍스트 색상 Color _getAlertTextColor(int level) { switch (level) { case 3: return Colors.red.shade800; case 2: return Colors.orange.shade800; case 1: return Colors.yellow.shade800; default: return Colors.green.shade800; } } /// 알림 레벨별 타이틀 String _getAlertTitle(int level) { switch (level) { case 3: return '유지보수 만료 위험'; case 2: return '유지보수 만료 경고'; case 1: return '유지보수 만료 주의'; default: return '유지보수 정상'; } } }