LCOV - code coverage report
Current view: top level - lib/screens/score - member_statistics_screen.dart Coverage Total Hit
Test: lcov.info Lines: 0.0 % 256 0
Test Date: 2025-08-12 03:21:51 Functions: - 0 0

            Line data    Source code
       1              : import 'package:flutter/material.dart';
       2              : import 'package:provider/provider.dart';
       3              : import 'package:intl/intl.dart';
       4              : import 'package:fl_chart/fl_chart.dart';
       5              : 
       6              : import '../../services/auth_service.dart';
       7              : import '../../services/club_service.dart';
       8              : import '../../services/member_service.dart';
       9              : import '../../services/score_service.dart';
      10              : import '../../models/member_model.dart';
      11              : import '../../models/score_model.dart';
      12              : import 'score_entry_screen.dart';
      13              : 
      14              : class MemberStatisticsScreen extends StatefulWidget {
      15              :   final String memberId;
      16              : 
      17            0 :   const MemberStatisticsScreen({super.key, required this.memberId});
      18              : 
      19            0 :   @override
      20            0 :   State<MemberStatisticsScreen> createState() => _MemberStatisticsScreenState();
      21              : }
      22              : 
      23              : class _MemberStatisticsScreenState extends State<MemberStatisticsScreen>
      24              :     with SingleTickerProviderStateMixin {
      25              :   bool _isLoading = false;
      26              :   bool _isInit = false;
      27              :   late TabController _tabController;
      28              : 
      29              :   Member? _member;
      30              :   List<Score> _scores = [];
      31              :   ScoreStatistics? _statistics;
      32              : 
      33            0 :   @override
      34              :   void initState() {
      35            0 :     super.initState();
      36            0 :     _tabController = TabController(length: 2, vsync: this);
      37              :   }
      38              : 
      39            0 :   @override
      40              :   void dispose() {
      41            0 :     _tabController.dispose();
      42            0 :     super.dispose();
      43              :   }
      44              : 
      45            0 :   @override
      46              :   void didChangeDependencies() {
      47            0 :     super.didChangeDependencies();
      48            0 :     if (!_isInit) {
      49            0 :       _loadMemberData();
      50            0 :       _isInit = true;
      51              :     }
      52              :   }
      53              : 
      54            0 :   Future<void> _loadMemberData() async {
      55            0 :     setState(() {
      56            0 :       _isLoading = true;
      57              :     });
      58              : 
      59              :     try {
      60            0 :       final authService = Provider.of<AuthService>(context, listen: false);
      61            0 :       final clubService = Provider.of<ClubService>(context, listen: false);
      62            0 :       final memberService = Provider.of<MemberService>(context, listen: false);
      63            0 :       final scoreService = Provider.of<ScoreService>(context, listen: false);
      64              : 
      65            0 :       if (clubService.currentClub != null) {
      66              :         // 회원 정보 로드
      67            0 :         _member = await memberService.fetchMemberById(widget.memberId);
      68              : 
      69              :         // 점수 서비스 초기화
      70            0 :         scoreService.initialize(authService.token!);
      71              : 
      72              :         // 회원 점수 및 통계 로드
      73            0 :         await Future.wait([
      74            0 :           scoreService.fetchMemberScores(widget.memberId).then((scores) {
      75            0 :             _scores = scores;
      76              :           }),
      77            0 :           scoreService.fetchMemberStatistics(widget.memberId).then((stats) {
      78            0 :             _statistics = stats;
      79              :           }),
      80              :         ]);
      81              :       }
      82              :     } catch (e) {
      83            0 :       ScaffoldMessenger.of(
      84            0 :         context,
      85            0 :       ).showSnackBar(SnackBar(content: Text('데이터 로드 중 오류가 발생했습니다: $e')));
      86              :     } finally {
      87            0 :       setState(() {
      88            0 :         _isLoading = false;
      89              :       });
      90              :     }
      91              :   }
      92              : 
      93            0 :   @override
      94              :   Widget build(BuildContext context) {
      95            0 :     return Scaffold(
      96            0 :       appBar: AppBar(
      97            0 :         title: Text(_member?.name ?? '회원 통계'),
      98            0 :         bottom: TabBar(
      99            0 :           controller: _tabController,
     100              :           tabs: const [
     101              :             Tab(text: '통계'),
     102              :             Tab(text: '점수 기록'),
     103              :           ],
     104              :         ),
     105              :       ),
     106            0 :       body: _isLoading
     107              :           ? const Center(child: CircularProgressIndicator())
     108            0 :           : TabBarView(
     109            0 :               controller: _tabController,
     110            0 :               children: [_buildStatisticsTab(), _buildScoresTab()],
     111              :             ),
     112            0 :       floatingActionButton: FloatingActionButton(
     113            0 :         onPressed: () async {
     114            0 :           await Navigator.of(context).push(
     115            0 :             MaterialPageRoute(
     116            0 :               builder: (context) => ScoreEntryScreen(memberId: widget.memberId),
     117              :             ),
     118              :           );
     119              :           // 화면으로 돌아왔을 때 데이터 새로고침
     120            0 :           _loadMemberData();
     121              :         },
     122              :         backgroundColor: Colors.blue,
     123              :         child: const Icon(Icons.add, color: Colors.white),
     124              :       ),
     125              :     );
     126              :   }
     127              : 
     128            0 :   Widget _buildStatisticsTab() {
     129            0 :     if (_statistics == null) {
     130              :       return const Center(child: Text('통계 데이터가 없습니다'));
     131              :     }
     132              : 
     133            0 :     return RefreshIndicator(
     134            0 :       onRefresh: _loadMemberData,
     135            0 :       child: SingleChildScrollView(
     136              :         physics: const AlwaysScrollableScrollPhysics(),
     137              :         padding: const EdgeInsets.all(16.0),
     138            0 :         child: Column(
     139              :           crossAxisAlignment: CrossAxisAlignment.start,
     140            0 :           children: [
     141              :             // 회원 정보 카드
     142            0 :             if (_member != null) _buildMemberInfoCard(),
     143            0 :             const SizedBox(height: 24),
     144              : 
     145              :             // 주요 통계 카드
     146            0 :             _buildMainStatsCard(),
     147            0 :             const SizedBox(height: 24),
     148              : 
     149              :             // 추가 통계 정보
     150            0 :             if (_statistics!.additionalStats != null)
     151            0 :               _buildAdditionalStatsCard(),
     152              : 
     153              :             // 통계 그래프
     154            0 :             const SizedBox(height: 24),
     155            0 :             Card(
     156            0 :               child: Padding(
     157              :                 padding: const EdgeInsets.all(16.0),
     158            0 :                 child: Column(
     159              :                   crossAxisAlignment: CrossAxisAlignment.start,
     160            0 :                   children: [
     161              :                     const Text(
     162              :                       '점수 추이',
     163              :                       style: TextStyle(
     164              :                         fontSize: 16,
     165              :                         fontWeight: FontWeight.bold,
     166              :                       ),
     167              :                     ),
     168              :                     const SizedBox(height: 16),
     169            0 :                     SizedBox(height: 200, child: _buildScoreChart()),
     170              :                   ],
     171              :                 ),
     172              :               ),
     173              :             ),
     174              :           ],
     175              :         ),
     176              :       ),
     177              :     );
     178              :   }
     179              : 
     180            0 :   Widget _buildMemberInfoCard() {
     181            0 :     return Card(
     182              :       elevation: 2,
     183            0 :       shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
     184            0 :       child: Padding(
     185              :         padding: const EdgeInsets.all(16.0),
     186            0 :         child: Row(
     187            0 :           children: [
     188            0 :             CircleAvatar(
     189              :               radius: 30,
     190            0 :               backgroundColor: Colors.blue.shade100,
     191            0 :               backgroundImage: _member!.profileImage != null
     192            0 :                   ? NetworkImage(_member!.profileImage!)
     193              :                   : null,
     194            0 :               child: _member!.profileImage == null
     195            0 :                   ? Text(
     196            0 :                       _member!.name.isNotEmpty
     197            0 :                           ? _member!.name[0].toUpperCase()
     198              :                           : '?',
     199              :                       style: const TextStyle(
     200              :                         fontSize: 24,
     201              :                         color: Colors.blue,
     202              :                         fontWeight: FontWeight.bold,
     203              :                       ),
     204              :                     )
     205              :                   : null,
     206              :             ),
     207              :             const SizedBox(width: 16),
     208            0 :             Expanded(
     209            0 :               child: Column(
     210              :                 crossAxisAlignment: CrossAxisAlignment.start,
     211            0 :                 children: [
     212            0 :                   Text(
     213            0 :                     _member!.name,
     214              :                     style: const TextStyle(
     215              :                       fontSize: 20,
     216              :                       fontWeight: FontWeight.bold,
     217              :                     ),
     218              :                   ),
     219              :                   const SizedBox(height: 4),
     220            0 :                   Text(
     221            0 :                     _member!.email,
     222            0 :                     style: TextStyle(color: Colors.grey[600]),
     223              :                   ),
     224            0 :                   if (_member!.phone != null)
     225            0 :                     Text(
     226            0 :                       _member!.phone!,
     227            0 :                       style: TextStyle(color: Colors.grey[600]),
     228              :                     ),
     229              :                 ],
     230              :               ),
     231              :             ),
     232              :           ],
     233              :         ),
     234              :       ),
     235              :     );
     236              :   }
     237              : 
     238            0 :   Widget _buildMainStatsCard() {
     239            0 :     return Card(
     240              :       elevation: 2,
     241            0 :       shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
     242            0 :       child: Padding(
     243              :         padding: const EdgeInsets.all(16.0),
     244            0 :         child: Column(
     245              :           crossAxisAlignment: CrossAxisAlignment.start,
     246            0 :           children: [
     247              :             const Text(
     248              :               '주요 통계',
     249              :               style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
     250              :             ),
     251              :             const SizedBox(height: 16),
     252            0 :             Row(
     253            0 :               children: [
     254            0 :                 Expanded(
     255            0 :                   child: _buildStatItem(
     256              :                     label: '평균 점수',
     257            0 :                     value: _statistics!.average.toStringAsFixed(1),
     258              :                     icon: Icons.score,
     259              :                     color: Colors.blue,
     260              :                   ),
     261              :                 ),
     262            0 :                 Expanded(
     263            0 :                   child: _buildStatItem(
     264              :                     label: '최고 점수',
     265            0 :                     value: _statistics!.highScore.toString(),
     266              :                     icon: Icons.emoji_events,
     267              :                     color: Colors.amber,
     268              :                   ),
     269              :                 ),
     270              :               ],
     271              :             ),
     272              :             const SizedBox(height: 16),
     273            0 :             Row(
     274            0 :               children: [
     275            0 :                 Expanded(
     276            0 :                   child: _buildStatItem(
     277              :                     label: '최저 점수',
     278            0 :                     value: _statistics!.lowScore.toString(),
     279              :                     icon: Icons.arrow_downward,
     280              :                     color: Colors.red,
     281              :                   ),
     282              :                 ),
     283            0 :                 Expanded(
     284            0 :                   child: _buildStatItem(
     285              :                     label: '게임 수',
     286            0 :                     value: _statistics!.gamesPlayed.toString(),
     287              :                     icon: Icons.sports,
     288              :                     color: Colors.green,
     289              :                   ),
     290              :                 ),
     291              :               ],
     292              :             ),
     293              :           ],
     294              :         ),
     295              :       ),
     296              :     );
     297              :   }
     298              : 
     299            0 :   Widget _buildStatItem({
     300              :     required String label,
     301              :     required String value,
     302              :     required IconData icon,
     303              :     required Color color,
     304              :   }) {
     305            0 :     return Column(
     306            0 :       children: [
     307            0 :         Icon(icon, size: 32, color: color),
     308              :         const SizedBox(height: 8),
     309            0 :         Text(
     310              :           value,
     311            0 :           style: TextStyle(
     312              :             fontSize: 20,
     313              :             fontWeight: FontWeight.bold,
     314              :             color: color,
     315              :           ),
     316              :         ),
     317            0 :         Text(label, style: TextStyle(fontSize: 14, color: Colors.grey[600])),
     318              :       ],
     319              :     );
     320              :   }
     321              : 
     322            0 :   Widget _buildAdditionalStatsCard() {
     323            0 :     final additionalStats = _statistics!.additionalStats!;
     324              : 
     325            0 :     return Card(
     326              :       elevation: 2,
     327            0 :       shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
     328            0 :       child: Padding(
     329              :         padding: const EdgeInsets.all(16.0),
     330            0 :         child: Column(
     331              :           crossAxisAlignment: CrossAxisAlignment.start,
     332            0 :           children: [
     333              :             const Text(
     334              :               '추가 통계',
     335              :               style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
     336              :             ),
     337              :             const SizedBox(height: 16),
     338            0 :             ...additionalStats.entries.map((entry) {
     339            0 :               return Padding(
     340              :                 padding: const EdgeInsets.only(bottom: 8.0),
     341            0 :                 child: Row(
     342              :                   mainAxisAlignment: MainAxisAlignment.spaceBetween,
     343            0 :                   children: [
     344            0 :                     Text(entry.key, style: const TextStyle(fontSize: 16)),
     345            0 :                     Text(
     346            0 :                       entry.value.toString(),
     347              :                       style: const TextStyle(
     348              :                         fontSize: 16,
     349              :                         fontWeight: FontWeight.bold,
     350              :                       ),
     351              :                     ),
     352              :                   ],
     353              :                 ),
     354              :               );
     355              :             }),
     356              :           ],
     357              :         ),
     358              :       ),
     359              :     );
     360              :   }
     361              : 
     362            0 :   Widget _buildScoresTab() {
     363            0 :     if (_scores.isEmpty) {
     364              :       return const Center(child: Text('기록된 점수가 없습니다'));
     365              :     }
     366              : 
     367              :     // 날짜 기준으로 정렬 (최신순)
     368            0 :     final sortedScores = [..._scores];
     369            0 :     sortedScores.sort((a, b) => b.date.compareTo(a.date));
     370              : 
     371            0 :     return RefreshIndicator(
     372            0 :       onRefresh: _loadMemberData,
     373            0 :       child: ListView.builder(
     374              :         padding: const EdgeInsets.all(8.0),
     375            0 :         itemCount: sortedScores.length,
     376            0 :         itemBuilder: (context, index) {
     377            0 :           final score = sortedScores[index];
     378            0 :           return _buildScoreCard(score);
     379              :         },
     380              :       ),
     381              :     );
     382              :   }
     383              : 
     384            0 :   Widget _buildScoreCard(Score score) {
     385            0 :     final dateFormat = DateFormat('yyyy년 MM월 dd일');
     386              : 
     387            0 :     return Card(
     388              :       margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
     389            0 :       shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
     390            0 :       child: ExpansionTile(
     391            0 :         title: Row(
     392            0 :           children: [
     393            0 :             Text(
     394            0 :               score.totalScore.toString(),
     395              :               style: const TextStyle(
     396              :                 fontSize: 20,
     397              :                 fontWeight: FontWeight.bold,
     398              :                 color: Colors.blue,
     399              :               ),
     400              :             ),
     401              :             const SizedBox(width: 16),
     402            0 :             Expanded(
     403            0 :               child: Column(
     404              :                 crossAxisAlignment: CrossAxisAlignment.start,
     405            0 :                 children: [
     406            0 :                   Text(
     407            0 :                     dateFormat.format(score.date),
     408              :                     style: const TextStyle(fontSize: 14),
     409              :                   ),
     410            0 :                   if (score.notes != null && score.notes!.isNotEmpty)
     411            0 :                     Text(
     412            0 :                       score.notes!,
     413            0 :                       style: TextStyle(fontSize: 12, color: Colors.grey[600]),
     414              :                       maxLines: 1,
     415              :                       overflow: TextOverflow.ellipsis,
     416              :                     ),
     417              :                 ],
     418              :               ),
     419              :             ),
     420              :           ],
     421              :         ),
     422            0 :         children: [
     423            0 :           Padding(
     424              :             padding: const EdgeInsets.all(16.0),
     425            0 :             child: Column(
     426              :               crossAxisAlignment: CrossAxisAlignment.start,
     427            0 :               children: [
     428              :                 const Text(
     429              :                   '프레임 점수',
     430              :                   style: TextStyle(fontWeight: FontWeight.bold),
     431              :                 ),
     432              :                 const SizedBox(height: 8),
     433            0 :                 _buildFrameScores(score.frames),
     434            0 :                 if (score.notes != null && score.notes!.isNotEmpty) ...[
     435              :                   const SizedBox(height: 16),
     436              :                   const Text(
     437              :                     '메모',
     438              :                     style: TextStyle(fontWeight: FontWeight.bold),
     439              :                   ),
     440              :                   const SizedBox(height: 4),
     441            0 :                   Text(score.notes!),
     442              :                 ],
     443            0 :                 const SizedBox(height: 16),
     444            0 :                 Row(
     445              :                   mainAxisAlignment: MainAxisAlignment.end,
     446            0 :                   children: [
     447            0 :                     TextButton.icon(
     448              :                       icon: const Icon(Icons.edit, size: 16),
     449              :                       label: const Text('수정'),
     450            0 :                       onPressed: () {
     451              :                         // 점수 수정 기능 (추후 구현)
     452            0 :                         ScaffoldMessenger.of(context).showSnackBar(
     453              :                           const SnackBar(content: Text('점수 수정 기능은 아직 개발 중입니다')),
     454              :                         );
     455              :                       },
     456              :                     ),
     457              :                     const SizedBox(width: 8),
     458            0 :                     TextButton.icon(
     459              :                       icon: const Icon(
     460              :                         Icons.delete,
     461              :                         size: 16,
     462              :                         color: Colors.red,
     463              :                       ),
     464              :                       label: const Text(
     465              :                         '삭제',
     466              :                         style: TextStyle(color: Colors.red),
     467              :                       ),
     468            0 :                       onPressed: () {
     469            0 :                         _showDeleteConfirmationDialog(score);
     470              :                       },
     471              :                     ),
     472              :                   ],
     473              :                 ),
     474              :               ],
     475              :             ),
     476              :           ),
     477              :         ],
     478              :       ),
     479              :     );
     480              :   }
     481              : 
     482            0 :   Widget _buildFrameScores(List<int> frames) {
     483            0 :     return Container(
     484              :       padding: const EdgeInsets.all(8),
     485            0 :       decoration: BoxDecoration(
     486            0 :         color: Colors.grey[100],
     487            0 :         borderRadius: BorderRadius.circular(8),
     488              :       ),
     489            0 :       child: Row(
     490            0 :         children: List.generate(10, (index) {
     491            0 :           return Expanded(
     492            0 :             child: Container(
     493              :               padding: const EdgeInsets.symmetric(vertical: 8),
     494            0 :               decoration: BoxDecoration(
     495            0 :                 border: Border.all(color: Colors.grey[300]!),
     496              :               ),
     497            0 :               child: Column(
     498            0 :                 children: [
     499            0 :                   Text(
     500            0 :                     '${index + 1}',
     501            0 :                     style: TextStyle(fontSize: 10, color: Colors.grey[600]),
     502              :                   ),
     503              :                   const SizedBox(height: 4),
     504            0 :                   Text(
     505            0 :                     index < frames.length ? frames[index].toString() : '-',
     506              :                     style: const TextStyle(fontWeight: FontWeight.bold),
     507              :                     textAlign: TextAlign.center,
     508              :                   ),
     509              :                 ],
     510              :               ),
     511              :             ),
     512              :           );
     513              :         }),
     514              :       ),
     515              :     );
     516              :   }
     517              : 
     518            0 :   Widget _buildScoreChart() {
     519            0 :     if (_scores.isEmpty) {
     520              :       return const Center(child: Text('점수 데이터가 없습니다'));
     521              :     }
     522              : 
     523              :     // 날짜 기준으로 정렬 (오래된 순)
     524            0 :     final sortedScores = [..._scores];
     525            0 :     sortedScores.sort((a, b) => a.date.compareTo(b.date));
     526              : 
     527              :     // 최대 10개의 최근 점수만 표시
     528            0 :     final displayScores = sortedScores.length > 10
     529            0 :         ? sortedScores.sublist(sortedScores.length - 10)
     530              :         : sortedScores;
     531              : 
     532              :     // 최소/최대 점수 계산 (Y축 범위 설정용)
     533              :     final minScore =
     534            0 :         displayScores.map((s) => s.totalScore).reduce((a, b) => a < b ? a : b) -
     535              :         10;
     536              :     final maxScore =
     537            0 :         displayScores.map((s) => s.totalScore).reduce((a, b) => a > b ? a : b) +
     538              :         10;
     539              : 
     540              :     // 그래프 데이터 포인트 생성
     541            0 :     final spots = <FlSpot>[];
     542            0 :     for (int i = 0; i < displayScores.length; i++) {
     543            0 :       spots.add(FlSpot(i.toDouble(), displayScores[i].totalScore.toDouble()));
     544              :     }
     545              : 
     546            0 :     return LineChart(
     547            0 :       LineChartData(
     548            0 :         gridData: FlGridData(
     549              :           show: true,
     550              :           drawVerticalLine: true,
     551              :           horizontalInterval: 20,
     552              :           verticalInterval: 1,
     553              :         ),
     554            0 :         titlesData: FlTitlesData(
     555              :           show: true,
     556              :           rightTitles: const AxisTitles(
     557              :             sideTitles: SideTitles(showTitles: false),
     558              :           ),
     559              :           topTitles: const AxisTitles(
     560              :             sideTitles: SideTitles(showTitles: false),
     561              :           ),
     562            0 :           bottomTitles: AxisTitles(
     563            0 :             sideTitles: SideTitles(
     564              :               showTitles: true,
     565              :               reservedSize: 30,
     566              :               interval: 1,
     567            0 :               getTitlesWidget: (value, meta) {
     568            0 :                 final index = value.toInt();
     569            0 :                 if (index >= 0 && index < displayScores.length) {
     570            0 :                   return Text(
     571            0 :                     DateFormat('MM/dd').format(displayScores[index].date),
     572              :                     style: const TextStyle(fontSize: 10),
     573              :                   );
     574              :                 }
     575              :                 return const SizedBox();
     576              :               },
     577              :             ),
     578              :           ),
     579            0 :           leftTitles: AxisTitles(
     580            0 :             sideTitles: SideTitles(
     581              :               showTitles: true,
     582              :               interval: 50,
     583            0 :               getTitlesWidget: (value, meta) {
     584            0 :                 return Text(
     585            0 :                   value.toInt().toString(),
     586              :                   style: const TextStyle(fontSize: 10),
     587              :                 );
     588              :               },
     589              :               reservedSize: 40,
     590              :             ),
     591              :           ),
     592              :         ),
     593            0 :         borderData: FlBorderData(
     594              :           show: true,
     595            0 :           border: Border.all(color: Colors.grey.shade300),
     596              :         ),
     597              :         minX: 0,
     598            0 :         maxX: displayScores.length - 1.0,
     599            0 :         minY: minScore.toDouble(),
     600            0 :         maxY: maxScore.toDouble(),
     601            0 :         lineBarsData: [
     602            0 :           LineChartBarData(
     603              :             spots: spots,
     604              :             isCurved: false,
     605              :             color: Colors.blue,
     606              :             barWidth: 3,
     607              :             isStrokeCapRound: true,
     608              :             dotData: const FlDotData(show: true),
     609            0 :             belowBarData: BarAreaData(
     610              :               show: true,
     611            0 :               color: Colors.blue.withOpacity(0.2),
     612              :             ),
     613              :           ),
     614              :         ],
     615              :       ),
     616              :     );
     617              :   }
     618              : 
     619            0 :   void _showDeleteConfirmationDialog(Score score) {
     620            0 :     showDialog(
     621            0 :       context: context,
     622            0 :       builder: (context) => AlertDialog(
     623              :         title: const Text('점수 삭제'),
     624              :         content: const Text('이 점수 기록을 정말 삭제하시겠습니까?'),
     625            0 :         actions: [
     626            0 :           TextButton(
     627            0 :             onPressed: () => Navigator.of(context).pop(),
     628              :             child: const Text('취소'),
     629              :           ),
     630            0 :           TextButton(
     631            0 :             onPressed: () async {
     632            0 :               Navigator.of(context).pop();
     633              : 
     634              :               try {
     635            0 :                 final scoreService = Provider.of<ScoreService>(
     636              :                   context,
     637              :                   listen: false,
     638              :                 );
     639            0 :                 await scoreService.deleteScore(score.id);
     640              : 
     641              :                 // 데이터 새로고침
     642            0 :                 _loadMemberData();
     643              : 
     644            0 :                 if (mounted) {
     645            0 :                   ScaffoldMessenger.of(
     646              :                     context,
     647            0 :                   ).showSnackBar(const SnackBar(content: Text('점수가 삭제되었습니다')));
     648              :                 }
     649              :               } catch (e) {
     650            0 :                 ScaffoldMessenger.of(
     651              :                   context,
     652            0 :                 ).showSnackBar(SnackBar(content: Text('점수 삭제에 실패했습니다: $e')));
     653              :               }
     654              :             },
     655            0 :             style: TextButton.styleFrom(foregroundColor: Colors.red),
     656              :             child: const Text('삭제'),
     657              :           ),
     658              :         ],
     659              :       ),
     660              :     );
     661              :   }
     662              : }
        

Generated by: LCOV version 2.3.1-1