FarisaRahmaSari_E31222327/BBS/lib/view/home/home_view_backup.dart

631 lines
54 KiB
Dart
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:qyuota/config/colors.dart';
import 'package:qyuota/config/images.dart';
import 'package:qyuota/config/text_style.dart';
import 'package:qyuota/view/home/clockin_view.dart';
import 'package:qyuota/view/home/clockout_view.dart';
import 'package:qyuota/view/home/cutipage.dart';
import 'package:qyuota/view/home/statuscuti.dart';
import 'package:qyuota/view/home/timespent_view.dart';
import 'package:qyuota/view/home/daftar_absensi.dart';
import 'package:qyuota/view/home/profile_view.dart';
import 'package:qyuota/services/auth_service.dart';
import 'package:intl/intl.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:qyuota/config/api_config.dart';
class Announcement {
final String title;
final String content;
Announcement({
required this.title,
required this.content,
});
factory Announcement.fromJson(Map<String, dynamic> json) {
return Announcement(
title: json['title'] ?? '',
content: json['content'] ?? '',
);
}
}
class HomeView extends StatefulWidget {
const HomeView({Key? key}) : super(key: key);
@override
State<HomeView> createState() => _HomeViewState();
}
final List<String> imageList = [
'assets/images/aa1.jpg', // Gantilah dengan path gambar yang sesuai
'assets/images/aa2.jpg',
'assets/images/aa3.jpg',
];
class _HomeViewState extends State<HomeView> {
Map<String, dynamic>? userData;
Announcement? latestAnnouncement;
int totalPresensi = 0;
int totalCuti = 0;
@override
void initState() {
super.initState();
_loadUserData();
fetchLatestAnnouncement();
fetchDashboardStats();
}
Future<void> _loadUserData() async {
final data = await AuthService().getUserData();
setState(() {
userData = data;
});
}
Future<void> fetchLatestAnnouncement() async {
try {
final token = await AuthService().getToken();
if (token == null) return;
final response = await http.get(
Uri.parse('${ApiConfig.baseUrl}/api/mobile/announcements/latest'),
headers: ApiConfig.authHeaders(token),
);
if (response.statusCode == 200) {
final data = json.decode(response.body);
if (data['success'] && data['data'] != null) {
setState(() {
latestAnnouncement = Announcement.fromJson(data['data']);
});
}
}
} catch (e) {
print('Error fetching announcement: $e');
}
}
Future<void> fetchDashboardStats() async {
try {
final token = await AuthService().getToken();
if (token == null) {
print('Token is null');
return;
}
print('Fetching dashboard stats...');
print('URL: ${ApiConfig.baseUrl}/api/mobile/dashboard/stats');
final response = await http.get(
Uri.parse('${ApiConfig.baseUrl}/api/mobile/dashboard/stats'),
headers: ApiConfig.authHeaders(token),
);
print('Response status code: ${response.statusCode}');
print('Response body: ${response.body}');
if (response.statusCode == 200) {
final data = json.decode(response.body);
print('Decoded data: $data');
print('Data type: ${data.runtimeType}');
if (data['data'] != null) {
print('Total presensi: ${data['data']['total_presensi']}');
print('Total cuti: ${data['data']['total_cuti']}');
setState(() {
totalPresensi = data['data']['total_presensi'] ?? 0;
totalCuti = data['data']['total_cuti'] ?? 0;
});
print('State updated - totalPresensi: $totalPresensi, totalCuti: $totalCuti');
} else {
print('Data field is null in response');
}
} else {
print('Error fetching stats: ${response.statusCode}');
print('Error response body: ${response.body}');
}
} catch (e, stackTrace) {
print('Error fetching stats: $e');
print('Stack trace: $stackTrace');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: ConstColors.primaryColor,
actions: [
IconButton(
icon: Icon(Icons.person, color: Colors.white),
onPressed: () {
Get.to(() => const ProfileView());
},
),
],
),
body: Stack(
alignment: Alignment.center,
children: [
Column(
children: [
SizedBox(
height: 300,
child: Container(
color: ConstColors.primaryColor,
child: Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: Column(
children: [
SizedBox(height: MediaQuery.of(context).padding.top),
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Halo, ${userData?['name'] ?? 'User'}",
style: GoogleFonts.poppins(
fontSize: 20,
fontWeight: FontWeight.w600,
color: ConstColors.whiteColor,
letterSpacing: 0.5,
),
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 4),
Text(
"${userData?['email'] ?? ''}",
style: GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w400,
color: ConstColors.whiteColor,
letterSpacing: 0.3,
),
overflow: TextOverflow.ellipsis,
),
],
),
),
],
),
const SizedBox(height: 10),
Container(
height: 180,
width: Get.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: ConstColors.whiteColor.withOpacity(0.23),
),
gradient: LinearGradient(
colors: [
ConstColors.whiteColor.withOpacity(0.23),
ConstColors.whiteColor.withOpacity(0.05),
],
),
),
child: Padding(
padding: const EdgeInsets.all(15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Hello Welcome!",
style: pRegular14.copyWith(
fontSize: 16,
color: ConstColors.whiteColor,
),
),
const SizedBox(height: 8),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Icon(Icons.calendar_today,
color: Colors.white, size: 18),
const SizedBox(width: 8),
Expanded(
flex: 3,
child: Text(
"${DateFormat('dd MMM yyyy').format(DateTime.now())}",
style: const TextStyle(
color: Colors.white,
fontSize: 14,
),
overflow: TextOverflow.ellipsis,
),
),
Expanded(
flex: 2,
child: Text(
"(08:00 - 17:30)",
style: const TextStyle(
color: Colors.white,
fontSize: 13,
),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.end,
),
),
const SizedBox(width: 8),
Icon(Icons.access_time,
color: Colors.white.withOpacity(0.5),
size: 24),
],
),
],
),
),
const SizedBox(height: 20),
Row(
children: [
Expanded(
child: ElevatedButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ClockinView(),
),
);
},
icon: Icon(Icons.login, color: Colors.white, size: 20),
label: Text(
"Clock In",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
style: ElevatedButton.styleFrom(
backgroundColor: ConstColors.skyColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
bottomLeft: Radius.circular(10),
),
),
padding: EdgeInsets.symmetric(vertical: 12, horizontal: 8),
elevation: 0,
),
),
),
Container(
height: 45,
width: 1,
color: Colors.white,
),
Expanded(
child: ElevatedButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ClockoutView(),
),
);
},
icon: Icon(Icons.logout, color: Colors.white, size: 20),
label: Text(
"Clock Out",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
style: ElevatedButton.styleFrom(
backgroundColor: ConstColors.skyColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(10),
bottomRight: Radius.circular(10),
),
),
padding: EdgeInsets.symmetric(vertical: 12, horizontal: 8),
elevation: 0,
),
),
),
],
),
]),
),
),
],
),
),
),
Expanded(
child: RefreshIndicator(
onRefresh: () async {
await _loadUserData();
await fetchDashboardStats();
await fetchLatestAnnouncement();
},
child: ListView(
padding: EdgeInsets.zero,
physics: const AlwaysScrollableScrollPhysics(),
children: [
Padding(
padding: const EdgeInsets.only(top: 5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: Get.height * 0.12,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Get.width * 0.04,
vertical: 6,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: _buildMenuButton(
"Status\nCuti",
Icons.assignment,
Colors.blue[700]!,
() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StatusCuti(),
),
);
},
),
),
SizedBox(width: 16),
Expanded(
child: _buildMenuButton(
"Pengajuan\nCuti",
Icons.beach_access,
Colors.orange[700]!,
() {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Cutipage()),
);
},
),
),
SizedBox(width: 16),
Expanded(
child: _buildMenuButton(
"Daftar\nAbsensi",
Icons.list_alt,
Colors.green[700]!,
() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DaftarAbsensiPage(),
),
);
},
),
),
],
),
),
),
const SizedBox(height: 5),
Container(
margin: EdgeInsets.symmetric(
horizontal: Get.width * 0.04,
vertical: Get.height * 0.01,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Ringkasan",
style: pSemiBold18.copyWith(
fontSize: Get.width * 0.04,
color: Colors.black87,
),
),
SizedBox(height: 12),
Row(
children: [
_buildInfoCard(
"Total Presensi",
totalPresensi.toString(),
"Hari",
Colors.green[100]!,
Colors.green[700]!,
),
SizedBox(width: 12),
_buildInfoCard(
"Total Cuti",
totalCuti.toString(),
"Pengajuan",
Colors.orange[100]!,
Colors.orange[700]!,
),
],
),
],
),
),
const SizedBox(height: 12),
Container(
margin: EdgeInsets.symmetric(
horizontal: Get.width * 0.04,
),
child: Text(
"Pengumuman",
style: pSemiBold18.copyWith(
fontSize: Get.width * 0.04,
color: Colors.black,
),
),
),
const SizedBox(height: 6),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(color: Colors.white, width: 1),
),
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
latestAnnouncement?.title ?? "Tidak ada pengumuman",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
const SizedBox(height: 6),
Text(
latestAnnouncement?.content ?? "",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
),
),
const SizedBox(height: 16),
],
),
),
],
),
),
),
],
),
),
],
),
);
}
Widget _buildInfoCard(String title, String value, String unit, Color bgColor, Color textColor) {
return Expanded(
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: bgColor,
borderRadius: BorderRadius.circular(12),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: TextStyle(
color: textColor,
fontSize: Get.width * 0.03,
),
),
SizedBox(height: 8),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
value,
style: TextStyle(
color: textColor,
fontSize: Get.width * 0.07,
fontWeight: FontWeight.bold,
),
),
SizedBox(width: 4),
Text(
unit,
style: TextStyle(
color: textColor,
fontSize: Get.width * 0.03,
),
),
],
),
],
),
),
);
}
}
Widget _buildMenuButton(
String label, IconData icon, Color color, VoidCallback onTap) {
return InkWell(
onTap: onTap,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 3),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.15),
spreadRadius: 1,
blurRadius: 3,
offset: Offset(0, 2),
),
],
),
child: Icon(
icon,
color: color,
size: 24,
),
),
SizedBox(height: 4),
Text(
label,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 10,
color: Colors.black87,
fontWeight: FontWeight.w500,
height: 1.1,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
);
}