feat: slicing profile page

This commit is contained in:
akhdanre 2025-04-26 16:25:26 +07:00
parent 26ed9797b8
commit dbb3bd8c90
4 changed files with 126 additions and 2 deletions

View File

@ -7,6 +7,7 @@ import 'package:quiz_app/feature/login/bindings/login_binding.dart';
import 'package:quiz_app/feature/login/view/login_page.dart'; import 'package:quiz_app/feature/login/view/login_page.dart';
import 'package:quiz_app/feature/navigation/bindings/navigation_binding.dart'; import 'package:quiz_app/feature/navigation/bindings/navigation_binding.dart';
import 'package:quiz_app/feature/navigation/views/navbar_view.dart'; import 'package:quiz_app/feature/navigation/views/navbar_view.dart';
import 'package:quiz_app/feature/profile/binding/profile_binding.dart';
import 'package:quiz_app/feature/register/binding/register_binding.dart'; import 'package:quiz_app/feature/register/binding/register_binding.dart';
import 'package:quiz_app/feature/register/view/register_page.dart'; import 'package:quiz_app/feature/register/view/register_page.dart';
import 'package:quiz_app/feature/search/binding/search_binding.dart'; import 'package:quiz_app/feature/search/binding/search_binding.dart';
@ -44,6 +45,7 @@ class AppPages {
HomeBinding(), HomeBinding(),
SearchBinding(), SearchBinding(),
HistoryBinding(), HistoryBinding(),
ProfileBinding(),
], ],
middlewares: [AuthMiddleware()], middlewares: [AuthMiddleware()],
) )

View File

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

View File

@ -0,0 +1,17 @@
import 'package:get/get.dart';
class ProfileController extends GetxController {
final userName = 'Alhidan Robbani'.obs;
final email = 'alhidan@example.com'.obs;
final totalQuizzes = 12.obs;
final avgScore = 85.obs;
void logout() {
print("Logout pressed");
}
void editProfile() {
print("Edit profile pressed");
}
}

View File

@ -1,10 +1,106 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:quiz_app/feature/profile/controller/profile_controller.dart';
class ProfileView extends StatelessWidget { class ProfileView extends GetView<ProfileController> {
const ProfileView({super.key}); const ProfileView({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold(); return Scaffold(
backgroundColor: const Color(0xFFF8F9FB),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(20),
child: Obx(() {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 20),
_buildAvatar(),
const SizedBox(height: 12),
Text(
controller.userName.value,
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 4),
Text(
controller.email.value,
style: const TextStyle(fontSize: 14, color: Colors.grey),
),
const SizedBox(height: 24),
_buildStats(),
const SizedBox(height: 32),
_buildActionButton("Edit Profil", Icons.edit, controller.editProfile),
const SizedBox(height: 12),
_buildActionButton("Logout", Icons.logout, controller.logout, isDestructive: true),
],
);
}),
),
),
);
}
Widget _buildAvatar() {
return const CircleAvatar(
radius: 45,
backgroundColor: Colors.blueAccent,
child: Icon(Icons.person, size: 50, color: Colors.white),
);
}
Widget _buildStats() {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 6,
offset: Offset(0, 2),
),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildStatItem("Total Quiz", controller.totalQuizzes.value.toString()),
const SizedBox(width: 16),
_buildStatItem("Skor Rata-rata", "${controller.avgScore.value}%"),
],
),
);
}
Widget _buildStatItem(String label, String value) {
return Column(
children: [
Text(value, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 4),
Text(label, style: const TextStyle(fontSize: 13, color: Colors.grey)),
],
);
}
Widget _buildActionButton(String title, IconData icon, VoidCallback onPressed, {bool isDestructive = false}) {
return SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
icon: Icon(icon, color: isDestructive ? Colors.red : Colors.white),
label: Text(
title,
style: TextStyle(color: isDestructive ? Colors.red : Colors.white),
),
onPressed: onPressed,
style: ElevatedButton.styleFrom(
backgroundColor: isDestructive ? Colors.red.shade50 : Colors.blueAccent,
padding: const EdgeInsets.symmetric(vertical: 14),
side: isDestructive ? const BorderSide(color: Colors.red) : BorderSide.none,
),
),
);
} }
} }