develop #1

Merged
akhdanre merged 104 commits from develop into main 2025-07-10 12:38:53 +07:00
4 changed files with 178 additions and 3 deletions
Showing only changes of commit 26ed9797b8 - Show all commits

View File

@ -1,5 +1,6 @@
import 'package:get/get_navigation/src/routes/get_route.dart';
import 'package:quiz_app/app/middleware/auth_middleware.dart';
import 'package:quiz_app/feature/history/binding/history_binding.dart';
import 'package:quiz_app/feature/home/binding/home_binding.dart';
import 'package:quiz_app/feature/home/view/home_page.dart';
import 'package:quiz_app/feature/login/bindings/login_binding.dart';
@ -42,6 +43,7 @@ class AppPages {
NavbarBinding(),
HomeBinding(),
SearchBinding(),
HistoryBinding(),
],
middlewares: [AuthMiddleware()],
)

View File

@ -0,0 +1,9 @@
import 'package:get/get.dart';
import 'package:quiz_app/feature/history/controller/history_controller.dart';
class HistoryBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => HistoryController());
}
}

View File

@ -0,0 +1,46 @@
import 'package:get/get.dart';
class HistoryItem {
final String title;
final String date;
final int score;
final int totalQuestions;
final String duration;
HistoryItem({
required this.title,
required this.date,
required this.score,
required this.totalQuestions,
required this.duration,
});
}
class HistoryController extends GetxController {
final historyList = <HistoryItem>[].obs;
@override
void onInit() {
super.onInit();
loadDummyHistory();
}
void loadDummyHistory() {
historyList.value = [
HistoryItem(
title: "Fisika Dasar",
date: "24 April 2025",
score: 8,
totalQuestions: 10,
duration: "5m 21s",
),
HistoryItem(
title: "Sejarah Indonesia",
date: "22 April 2025",
score: 7,
totalQuestions: 10,
duration: "4m 35s",
),
];
}
}

View File

@ -1,10 +1,128 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:quiz_app/feature/history/controller/history_controller.dart';
class HistoryView extends StatelessWidget {
class HistoryView extends GetView<HistoryController> {
const HistoryView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold();
return Scaffold(
backgroundColor: const Color(0xFFF8F9FB),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(16),
child: Obx(() {
final historyList = controller.historyList;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Riwayat Kuis",
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
const Text(
"Lihat kembali hasil kuis yang telah kamu kerjakan",
style: TextStyle(
fontSize: 14,
color: Colors.grey,
),
),
const SizedBox(height: 20),
if (historyList.isEmpty)
const Expanded(
child: Center(
child: Text(
"Belum ada kuis yang dikerjakan.",
style: TextStyle(fontSize: 16, color: Colors.grey),
),
),
)
else
Expanded(
child: ListView.builder(
itemCount: historyList.length,
itemBuilder: (context, index) {
final item = historyList[index];
return _buildHistoryCard(item);
},
),
)
],
);
}),
),
),
);
}
Widget _buildHistoryCard(HistoryItem item) {
return Container(
margin: const EdgeInsets.only(bottom: 16),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 4,
offset: Offset(0, 2),
)
],
),
child: Row(
children: [
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: Colors.blue.shade100,
shape: BoxShape.circle,
),
child: const Icon(Icons.history, color: Colors.blue),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
item.title,
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
),
const SizedBox(height: 4),
Text(
item.date,
style: const TextStyle(fontSize: 12, color: Colors.grey),
),
const SizedBox(height: 8),
Row(
children: [
const Icon(Icons.check_circle, size: 14, color: Colors.green),
const SizedBox(width: 4),
Text(
"Skor: ${item.score}/${item.totalQuestions}",
style: const TextStyle(fontSize: 12),
),
const SizedBox(width: 16),
const Icon(Icons.timer, size: 14, color: Colors.grey),
const SizedBox(width: 4),
Text(
item.duration,
style: const TextStyle(fontSize: 12),
),
],
),
],
),
)
],
),
);
}
}