78 lines
2.7 KiB
Dart
78 lines
2.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:sudoku_app/models/game_rank_dto.dart';
|
|
import 'package:sudoku_app/services/puzzle_service.dart';
|
|
|
|
class RankingScreen extends StatefulWidget {
|
|
const RankingScreen({super.key});
|
|
|
|
@override
|
|
State<RankingScreen> createState() => _RankingScreenState();
|
|
}
|
|
|
|
class _RankingScreenState extends State<RankingScreen> {
|
|
final PuzzleService _puzzleService = PuzzleService();
|
|
// FutureBuilder를 사용하여 비동기 데이터를 쉽게 처리
|
|
late Future<List<GameRankDto>> _rankingFuture;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
// 화면이 로드될 때 스도쿠의 전체 랭킹을 가져옴 (contextId = null)
|
|
_rankingFuture = _puzzleService.fetchRanks('SUDOKU', null);
|
|
}
|
|
|
|
// 점수(초)를 'mm:ss' 형식으로 변환
|
|
String _formatScore(int seconds) {
|
|
final min = (seconds ~/ 60).toString().padLeft(2, '0');
|
|
final sec = (seconds % 60).toString().padLeft(2, '0');
|
|
return '$min:$sec';
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('스도쿠 전체 랭킹')),
|
|
body: FutureBuilder<List<GameRankDto>>(
|
|
future: _rankingFuture,
|
|
builder: (context, snapshot) {
|
|
// 로딩 중일 때
|
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
|
return const Center(child: CircularProgressIndicator());
|
|
}
|
|
// 에러 발생 시
|
|
if (snapshot.hasError) {
|
|
return Center(child: Text('랭킹 로딩 실패: ${snapshot.error}'));
|
|
}
|
|
// 데이터가 없거나 비어있을 때
|
|
if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
|
return const Center(child: Text('등록된 랭킹이 없습니다.'));
|
|
}
|
|
|
|
// 성공적으로 데이터를 가져왔을 때
|
|
final ranks = snapshot.data!;
|
|
return ListView.builder(
|
|
itemCount: ranks.length,
|
|
itemBuilder: (context, index) {
|
|
final rank = ranks[index];
|
|
return ListTile(
|
|
leading: Text(
|
|
'${index + 1}.',
|
|
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
|
),
|
|
title: Text(rank.playerName, style: const TextStyle(fontSize: 18)),
|
|
trailing: Text(
|
|
_formatScore(rank.primaryScore), // 시간(초)을 mm:ss로 표시
|
|
style: const TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.bold,
|
|
color: Colors.blue,
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
} |