152 lines
5.1 KiB
Dart
152 lines
5.1 KiB
Dart
// transit_home_page.dart — الصفحة الرئيسية لتبويب "مواصلاتي"
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
|
|
import '../../constant/colors.dart';
|
|
import '../../constant/style.dart';
|
|
import '../../controller/transit/transit_controller.dart';
|
|
import '../../controller/transit/transit_models.dart';
|
|
import '../widgets/my_scafold.dart';
|
|
import 'transit_org_browse_page.dart';
|
|
import 'transit_routes_page.dart';
|
|
|
|
class TransitHomePage extends StatelessWidget {
|
|
const TransitHomePage({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
Get.put(TransitController());
|
|
|
|
return GetBuilder<TransitController>(
|
|
builder: (c) => MyScafolld(
|
|
title: 'Mawasalati'.tr,
|
|
isleading: true,
|
|
body: [
|
|
Column(
|
|
children: [
|
|
Expanded(
|
|
child: RefreshIndicator(
|
|
onRefresh: c.fetchMyEnrollments,
|
|
child: c.isLoadingEnrollments
|
|
? const Center(child: CircularProgressIndicator())
|
|
: c.myEnrollments.isEmpty
|
|
? _emptyState(c)
|
|
: ListView(
|
|
padding: const EdgeInsets.all(16),
|
|
children: [
|
|
Text('My Memberships'.tr,
|
|
style: AppStyle.headTitle2.copyWith(fontSize: 18)),
|
|
const SizedBox(height: 12),
|
|
...c.myEnrollments.map((e) => _enrollmentCard(e, c)),
|
|
const SizedBox(height: 20),
|
|
_addOrgTile(),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _emptyState(TransitController c) {
|
|
return ListView(
|
|
padding: const EdgeInsets.all(24),
|
|
children: [
|
|
const SizedBox(height: 60),
|
|
Icon(Icons.directions_bus_filled_outlined,
|
|
size: 72, color: AppColor.grayColor),
|
|
const SizedBox(height: 16),
|
|
Text(
|
|
'Not enrolled in any institution yet'.tr,
|
|
textAlign: TextAlign.center,
|
|
style: AppStyle.title.copyWith(fontWeight: FontWeight.bold),
|
|
),
|
|
const SizedBox(height: 8),
|
|
Text(
|
|
'Activate your membership in your university or institution to track your bus live'.tr,
|
|
textAlign: TextAlign.center,
|
|
style: AppStyle.subtitle.copyWith(color: AppColor.grayColor),
|
|
),
|
|
const SizedBox(height: 20),
|
|
_addOrgTile(),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _addOrgTile() {
|
|
return Card(
|
|
color: AppColor.cardColor,
|
|
elevation: 0,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(14),
|
|
side: BorderSide(color: AppColor.borderColor),
|
|
),
|
|
child: ListTile(
|
|
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
|
leading: CircleAvatar(
|
|
backgroundColor: AppColor.accentColor.withOpacity(0.15),
|
|
child: Icon(Icons.add, color: AppColor.accentColor),
|
|
),
|
|
title: Text('Join a new institution'.tr, style: AppStyle.title),
|
|
subtitle: Text('University, school, or hotel'.tr, style: AppStyle.subtitle),
|
|
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
|
|
onTap: () => Get.to(() => const TransitOrgBrowsePage()),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _enrollmentCard(TransitEnrollment e, TransitController c) {
|
|
Color statusColor;
|
|
String statusText;
|
|
switch (e.status) {
|
|
case 'active':
|
|
statusColor = AppColor.greenColor;
|
|
statusText = 'Active'.tr;
|
|
break;
|
|
case 'pending':
|
|
statusColor = AppColor.yellowColor;
|
|
statusText = 'Pending Review'.tr;
|
|
break;
|
|
default:
|
|
statusColor = AppColor.redColor;
|
|
statusText = 'Suspended'.tr;
|
|
}
|
|
|
|
return Card(
|
|
margin: const EdgeInsets.only(bottom: 12),
|
|
color: AppColor.cardColor,
|
|
elevation: 0,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(14),
|
|
side: BorderSide(color: AppColor.borderColor),
|
|
),
|
|
child: ListTile(
|
|
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
|
leading: CircleAvatar(
|
|
backgroundColor: AppColor.primaryColor.withOpacity(0.1),
|
|
child: Icon(Icons.school_outlined, color: AppColor.primaryColor),
|
|
),
|
|
title: Text(e.orgName, style: AppStyle.title.copyWith(fontWeight: FontWeight.bold)),
|
|
subtitle: Row(
|
|
children: [
|
|
Container(
|
|
width: 8,
|
|
height: 8,
|
|
decoration: BoxDecoration(color: statusColor, shape: BoxShape.circle),
|
|
),
|
|
const SizedBox(width: 6),
|
|
Text(statusText, style: AppStyle.subtitle.copyWith(color: statusColor)),
|
|
],
|
|
),
|
|
trailing: e.status == 'active' ? const Icon(Icons.arrow_forward_ios, size: 16) : null,
|
|
onTap: e.status == 'active'
|
|
? () => Get.to(() => TransitRoutesPage(orgId: e.orgId, orgName: e.orgName))
|
|
: null,
|
|
),
|
|
);
|
|
}
|
|
}
|