541 lines
23 KiB
Dart
541 lines
23 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:page_transition/page_transition.dart';
|
|
|
|
import 'package:image_picker/image_picker.dart';
|
|
import 'package:piring/Login/login_form.dart';
|
|
import 'package:piring/bloc/nav/bottom_nav.dart';
|
|
import 'package:piring/kalori/tambahbismillah.dart';
|
|
|
|
import 'package:piring/model/user.dart';
|
|
import 'package:piring/profile/editprofile.dart';
|
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
class Profile extends StatefulWidget {
|
|
const Profile({super.key});
|
|
|
|
@override
|
|
State<Profile> createState() => _ProfileState();
|
|
}
|
|
|
|
class _ProfileState extends State<Profile> {
|
|
String Nama = '';
|
|
String Email = '';
|
|
String tglLahir = '';
|
|
String BB = '';
|
|
String TB = '';
|
|
String telp = '';
|
|
String username = '';
|
|
|
|
Future<void> loadUserData() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final userDataString = prefs.getString('user_data');
|
|
|
|
if (userDataString != null) {
|
|
final userData = UserData.fromJson(json.decode(userDataString));
|
|
print(userData.nama);
|
|
|
|
setState(() {
|
|
Nama = userData.nama;
|
|
Email = userData.email;
|
|
tglLahir = userData.tglLahir;
|
|
BB = userData.beratBadan;
|
|
TB = userData.tinggiBadan;
|
|
telp = userData.noTelp;
|
|
username = userData.username;
|
|
});
|
|
}
|
|
}
|
|
|
|
Future<void> logoutUser() async {
|
|
// Hapus token akses dari Shared Preferences
|
|
final prefs = await SharedPreferences.getInstance();
|
|
prefs.remove('access_token');
|
|
prefs.remove('user_data'); // Jika ada data pengguna lain yang perlu dihapus
|
|
|
|
// Arahkan pengguna kembali ke halaman login
|
|
Navigator.of(context).pushAndRemoveUntil(
|
|
PageTransition(
|
|
child: const LoginForm(),
|
|
type: PageTransitionType.fade,
|
|
duration: const Duration(milliseconds: 500),
|
|
),
|
|
(route) => false, // Hapus seluruh riwayat navigasi
|
|
);
|
|
}
|
|
|
|
final scaffoldKey = GlobalKey<ScaffoldState>();
|
|
XFile? _imageFile;
|
|
Future<void> _getImageFromGallery() async {
|
|
final picker = ImagePicker();
|
|
final pickedFile = await picker.pickImage(source: ImageSource.gallery);
|
|
|
|
if (pickedFile != null) {
|
|
setState(() {
|
|
_imageFile = pickedFile;
|
|
});
|
|
|
|
// Simpan path gambar yang dipilih
|
|
_saveImagePath(pickedFile.path);
|
|
}
|
|
}
|
|
|
|
Future<void> _saveImagePath(String imagePath) async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.setString('profile_image', imagePath);
|
|
}
|
|
|
|
Future<void> loadProfileImage() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final imagePath = prefs.getString('profile_image');
|
|
|
|
if (imagePath != null) {
|
|
setState(() {
|
|
_imageFile = XFile(imagePath);
|
|
});
|
|
}
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
loadUserData();
|
|
loadProfileImage();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
bottomNavigationBar: const BottomNavBar(selected: 4),
|
|
key: scaffoldKey,
|
|
backgroundColor: const Color.fromARGB(255, 255, 172, 63),
|
|
body: SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.max,
|
|
children: [
|
|
Container(
|
|
margin: EdgeInsets.only(top: 30),
|
|
alignment: Alignment.topCenter,
|
|
child: GestureDetector(
|
|
onTap: () {
|
|
print("Tapped on circle image");
|
|
_getImageFromGallery();
|
|
},
|
|
child: Container(
|
|
width: 120,
|
|
height: 120,
|
|
clipBehavior: Clip.antiAlias,
|
|
decoration: const BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
),
|
|
child: _imageFile != null
|
|
? Image.file(
|
|
File(_imageFile!.path),
|
|
fit: BoxFit.cover,
|
|
)
|
|
: const Icon(
|
|
Icons.camera_alt,
|
|
size: 40.0,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Container(
|
|
height: 620,
|
|
child: Stack(
|
|
children: [
|
|
Center(
|
|
child: Material(
|
|
color: Colors.transparent,
|
|
elevation: 4,
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.only(
|
|
bottomLeft: Radius.circular(0),
|
|
bottomRight: Radius.circular(0),
|
|
topLeft: Radius.circular(35),
|
|
topRight: Radius.circular(30),
|
|
),
|
|
),
|
|
child: Container(
|
|
width: 389,
|
|
height: 600,
|
|
decoration: const BoxDecoration(
|
|
color: Colors.white,
|
|
boxShadow: [
|
|
BoxShadow(
|
|
blurRadius: 4,
|
|
color: Color(0x33000000),
|
|
offset: Offset(0, 2),
|
|
spreadRadius: 4,
|
|
)
|
|
],
|
|
borderRadius: BorderRadius.only(
|
|
bottomLeft: Radius.circular(0),
|
|
bottomRight: Radius.circular(0),
|
|
topLeft: Radius.circular(35),
|
|
topRight: Radius.circular(30),
|
|
),
|
|
),
|
|
child: Stack(
|
|
children: [
|
|
Container(
|
|
margin: const EdgeInsets.only(top: 40),
|
|
alignment: Alignment.topCenter,
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Container(
|
|
child: Text(
|
|
username,
|
|
style: const TextStyle(
|
|
fontSize: 18,
|
|
fontFamily: 'Readex Pro',
|
|
color: Colors.black),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const Padding(
|
|
padding:
|
|
EdgeInsetsDirectional.fromSTEB(0, 100, 0, 0),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
children: [
|
|
Padding(
|
|
padding: EdgeInsetsDirectional.fromSTEB(
|
|
30, 0, 0, 0),
|
|
child: Text(
|
|
'Data Diri',
|
|
style: TextStyle(
|
|
fontSize: 18,
|
|
fontFamily: 'Readex Pro',
|
|
fontWeight: FontWeight.w600),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
|
30, 135, 0, 0),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
children: [
|
|
const Text(
|
|
'Nama',
|
|
style: TextStyle(
|
|
fontSize: 12, fontFamily: 'Readex Pro'),
|
|
),
|
|
const Padding(
|
|
padding: EdgeInsetsDirectional.fromSTEB(
|
|
49, 0, 0, 0),
|
|
child: Text(
|
|
':',
|
|
style: TextStyle(fontSize: 14),
|
|
),
|
|
),
|
|
Padding(
|
|
padding:
|
|
const EdgeInsetsDirectional.fromSTEB(
|
|
10, 0, 0, 0),
|
|
child: Text(
|
|
Nama,
|
|
style: const TextStyle(
|
|
fontFamily: 'Readex Pro',
|
|
fontSize: 12),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
|
30, 160, 0, 0),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
children: [
|
|
const Text(
|
|
'Email',
|
|
style: TextStyle(
|
|
fontFamily: 'Readex Pro', fontSize: 12),
|
|
),
|
|
const Padding(
|
|
padding: EdgeInsetsDirectional.fromSTEB(
|
|
52, 0, 0, 0),
|
|
child: Text(
|
|
':',
|
|
style: TextStyle(fontSize: 14),
|
|
),
|
|
),
|
|
Padding(
|
|
padding:
|
|
const EdgeInsetsDirectional.fromSTEB(
|
|
10, 0, 0, 0),
|
|
child: Text(
|
|
Email,
|
|
style: const TextStyle(
|
|
fontFamily: 'Readex Pro',
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
|
30, 185, 0, 0),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
children: [
|
|
const Text(
|
|
'Tanggal Lahir',
|
|
style: TextStyle(
|
|
fontFamily: 'Readex Pro',
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
const Padding(
|
|
padding: EdgeInsetsDirectional.fromSTEB(
|
|
7, 0, 0, 0),
|
|
child: Text(
|
|
':',
|
|
style: TextStyle(fontSize: 14),
|
|
),
|
|
),
|
|
Padding(
|
|
padding:
|
|
const EdgeInsetsDirectional.fromSTEB(
|
|
8, 0, 0, 0),
|
|
child: Text(
|
|
tglLahir,
|
|
style: const TextStyle(
|
|
fontFamily: 'Readex Pro',
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
|
30, 210, 0, 0),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
children: [
|
|
const Text(
|
|
'Berat Badan',
|
|
style: TextStyle(
|
|
fontFamily: 'Readex Pro',
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
const Padding(
|
|
padding: EdgeInsetsDirectional.fromSTEB(
|
|
15, 0, 0, 0),
|
|
child: Text(
|
|
':',
|
|
style: TextStyle(fontSize: 14),
|
|
),
|
|
),
|
|
Padding(
|
|
padding:
|
|
const EdgeInsetsDirectional.fromSTEB(
|
|
8, 0, 0, 0),
|
|
child: Text(
|
|
BB,
|
|
style: const TextStyle(
|
|
fontFamily: 'Readex Pro',
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
|
30, 235, 0, 0),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
children: [
|
|
const Text(
|
|
'Tinggi Badan',
|
|
style: TextStyle(
|
|
fontFamily: 'Readex Pro',
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
const Padding(
|
|
padding: EdgeInsetsDirectional.fromSTEB(
|
|
10, 0, 0, 0),
|
|
child: Text(
|
|
':',
|
|
style: TextStyle(fontSize: 14),
|
|
),
|
|
),
|
|
Padding(
|
|
padding:
|
|
const EdgeInsetsDirectional.fromSTEB(
|
|
6, 0, 0, 0),
|
|
child: Text(
|
|
TB,
|
|
style: const TextStyle(
|
|
fontFamily: 'Readex Pro',
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
|
30, 260, 0, 0),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
children: [
|
|
const Text(
|
|
'No HP',
|
|
style: TextStyle(
|
|
fontFamily: 'Readex Pro',
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
const Padding(
|
|
padding: EdgeInsetsDirectional.fromSTEB(
|
|
47, 0, 0, 0),
|
|
child: Text(
|
|
':',
|
|
style: TextStyle(
|
|
fontFamily: 'Readex Pro',
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
),
|
|
Padding(
|
|
padding:
|
|
const EdgeInsetsDirectional.fromSTEB(
|
|
5, 0, 0, 0),
|
|
child: Text(
|
|
telp,
|
|
style: const TextStyle(
|
|
fontFamily: 'Readex Pro',
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Align(
|
|
alignment:
|
|
const AlignmentDirectional(0.00, -1.00),
|
|
child: Padding(
|
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
|
0, 300, 0, 0),
|
|
child: ElevatedButton(
|
|
onPressed: () {
|
|
Navigator.pushReplacementNamed(
|
|
context, '/editprofile');
|
|
},
|
|
style: ElevatedButton.styleFrom(
|
|
fixedSize: const Size(200, 45),
|
|
primary: const Color.fromARGB(255, 255, 140,
|
|
57), // Atur warna latar belakang tombol
|
|
onPrimary:
|
|
Colors.white, // Atur warna teks tombol
|
|
padding: const EdgeInsets.all(
|
|
16), // Atur padding tombol
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(
|
|
8), // Atur sudut tombol
|
|
),
|
|
elevation: 3,
|
|
textStyle: const TextStyle(
|
|
fontSize: 12, // Atur ukuran teks tombol
|
|
fontWeight: FontWeight
|
|
.bold, // Atur ketebalan teks tombol
|
|
fontFamily: 'Readex Pro',
|
|
),
|
|
),
|
|
child: const Text(
|
|
'Edit Profile'), // Teks yang akan ditampilkan pada tombol
|
|
),
|
|
),
|
|
),
|
|
Align(
|
|
alignment:
|
|
const AlignmentDirectional(0.00, -1.00),
|
|
child: Padding(
|
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
|
0, 360, 0, 0),
|
|
child: ElevatedButton(
|
|
onPressed: () {
|
|
logoutUser();
|
|
},
|
|
style: ElevatedButton.styleFrom(
|
|
fixedSize: const Size(200, 45),
|
|
primary: const Color.fromARGB(255, 255, 48,
|
|
48), // Atur warna latar belakang tombol
|
|
onPrimary:
|
|
Colors.white, // Atur warna teks tombol
|
|
padding: const EdgeInsets.all(
|
|
16), // Atur padding tombol
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(
|
|
8), // Atur sudut tombol
|
|
),
|
|
elevation: 3,
|
|
textStyle: const TextStyle(
|
|
fontSize: 11, // Atur ukuran teks tombol
|
|
fontWeight: FontWeight
|
|
.bold, // Atur ketebalan teks tombol
|
|
),
|
|
),
|
|
child: const Text(
|
|
'Logout'), // Teks yang akan ditampilkan pada tombol
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Container(
|
|
child: ElevatedButton(
|
|
child: Text('bismillah'),
|
|
onPressed: () {
|
|
Navigator.pushReplacement(
|
|
context,
|
|
MaterialPageRoute(
|
|
builder: (context) => TambahBismillah(
|
|
nama: '',
|
|
),
|
|
));
|
|
},
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|