E32221324_Iot_Running/lib/screens/profile_screen.dart

266 lines
9.9 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_core/firebase_core.dart';
import '../screens/auth/login_screen.dart';
import 'edit_profile_screen.dart';
class ProfileScreen extends StatefulWidget {
const ProfileScreen({super.key});
@override
State<ProfileScreen> createState() => _ProfileScreenState();
}
class _ProfileScreenState extends State<ProfileScreen> {
String? username;
String? gender;
String? email;
@override
void initState() {
super.initState();
_fetchUserData();
}
Future<void> _fetchUserData() async {
final user = FirebaseAuth.instance.currentUser;
if (user != null) {
final doc = await FirebaseFirestore.instance.collection('users').doc(user.uid).get();
setState(() {
username = doc['username'];
gender = doc['gender'];
email = user.email;
});
}
}
Future<void> _logout() async {
final shouldLogout = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Konfirmasi Logout'),
content: const Text('Apakah kamu yakin ingin keluar dari akun ini?'),
actions: [
TextButton(onPressed: () => Navigator.pop(context, false), child: const Text('Batal')),
ElevatedButton(onPressed: () => Navigator.pop(context, true), child: const Text('Logout')),
],
),
);
if (shouldLogout == true) {
await FirebaseAuth.instance.signOut();
if (!mounted) return;
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (_) => const LoginScreen()),
(route) => false,
);
}
}
Widget _buildInfoRow(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: const TextStyle(
fontSize: 14,
color: Colors.grey,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 4),
Text(
value,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
),
],
),
);
}
Future<void> _refreshData() async {
await _fetchUserData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: PreferredSize(
preferredSize: const Size.fromHeight(100),
child: Container(
decoration: const BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20),
),
),
padding: const EdgeInsets.only(top: 40, left: 20, right: 20, bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Profile",
style: const TextStyle(
color: Colors.white,
fontSize: 22,
fontWeight: FontWeight.bold,
),
),
Row(
children: [
IconButton(
tooltip: 'Edit Profil',
onPressed: () async {
final updated = await Navigator.push(
context,
MaterialPageRoute(builder: (_) => const EditProfileScreen()),
);
if (updated == true) {
_fetchUserData();
}
},
icon: const Icon(Icons.edit, color: Colors.white, size: 24),
),
IconButton(
tooltip: 'Logout',
onPressed: _logout,
icon: const Icon(Icons.logout, color: Colors.white, size: 24),
),
],
)
],
),
),
),
body: RefreshIndicator(
onRefresh: _refreshData,
child: ListView(
padding: const EdgeInsets.all(20),
children: [
username == null || gender == null || email == null
? const Center(child: CircularProgressIndicator())
: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 20),
CircleAvatar(
radius: 40,
backgroundColor: Colors.blue,
child: Text(
username![0].toUpperCase(),
style: const TextStyle(fontSize: 32, color: Colors.white),
),
),
const SizedBox(height: 16),
Text(
username!,
style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
),
const SizedBox(height: 24),
Card(
color: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
elevation: 6,
shadowColor: Colors.blueAccent.withOpacity(0.4),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildInfoRow("Username", username!),
const Divider(),
_buildInfoRow("Gender", gender!),
const Divider(),
_buildInfoRow("Email", email!),
const Divider(),
FutureBuilder<DocumentSnapshot>(
future: FirebaseFirestore.instance
.collection("users")
.doc(FirebaseAuth.instance.currentUser?.uid)
.get(),
builder: (context, snapshot) {
String rfidText = "Belum terdaftar";
if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
final data = snapshot.data?.data() as Map<String, dynamic>?;
if (data != null && data.containsKey("idGelang")) {
rfidText = data["idGelang"];
}
}
return _buildInfoRow("UID RFID", rfidText);
},
),
],
),
),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () async {
final user = FirebaseAuth.instance.currentUser;
if (user != null) {
final db = FirebaseDatabase.instanceFor(
app: Firebase.app(),
databaseURL: "https://ta-running-default-rtdb.asia-southeast1.firebasedatabase.app",
);
final gelangRef = db.ref("/gelang");
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("Menunggu scan gelang di alat..."),
duration: Duration(seconds: 3),
),
);
StreamSubscription<DatabaseEvent>? sub;
sub = gelangRef.onValue.listen((event) async {
final data = event.snapshot.value;
if (data != null && data is String) {
final rfid = data;
await FirebaseFirestore.instance
.collection("users")
.doc(user.uid)
.set({"idGelang": rfid}, SetOptions(merge: true));
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Gelang berhasil didaftarkan: $rfid"),
duration: const Duration(seconds: 3),
),
);
await sub?.cancel();
}
});
}
},
child: const Text("Daftarkan RFID"),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 12),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
),
),
],
),
],
),
),
);
}
}