feat: slicing profile page
This commit is contained in:
parent
26ed9797b8
commit
dbb3bd8c90
|
@ -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/navigation/bindings/navigation_binding.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/view/register_page.dart';
|
||||
import 'package:quiz_app/feature/search/binding/search_binding.dart';
|
||||
|
@ -44,6 +45,7 @@ class AppPages {
|
|||
HomeBinding(),
|
||||
SearchBinding(),
|
||||
HistoryBinding(),
|
||||
ProfileBinding(),
|
||||
],
|
||||
middlewares: [AuthMiddleware()],
|
||||
)
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -1,10 +1,106 @@
|
|||
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});
|
||||
|
||||
@override
|
||||
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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue