Update: 2026-06-10 02:44:54

This commit is contained in:
Hamza-Ayed
2026-06-10 02:44:55 +03:00
parent 9bc7a31c94
commit a0473a8b0f
134 changed files with 1706 additions and 544 deletions

View File

@@ -0,0 +1,67 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:siro_rider/constant/colors.dart';
import 'package:siro_rider/controller/home/profile/invites_rewards_controller.dart';
class QRScannerPage extends StatefulWidget {
@override
_QRScannerPageState createState() => _QRScannerPageState();
}
class _QRScannerPageState extends State<QRScannerPage> {
final InvitesRewardsController controller = Get.find<InvitesRewardsController>();
bool _isScanned = false;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.black,
iconTheme: const IconThemeData(color: Colors.white),
title: Text("Scan QR Code".tr, style: const TextStyle(color: Colors.white)),
),
body: Stack(
children: [
MobileScanner(
onDetect: (capture) {
if (_isScanned) return;
final List<Barcode> barcodes = capture.barcodes;
for (final barcode in barcodes) {
if (barcode.rawValue != null) {
setState(() => _isScanned = true);
Get.back(); // close scanner page
controller.processScannedQRCode(barcode.rawValue!);
break;
}
}
},
),
Center(
child: Container(
width: 250,
height: 250,
decoration: BoxDecoration(
border: Border.all(color: AppColor.primaryColor, width: 3),
borderRadius: BorderRadius.circular(12),
),
),
),
Positioned(
bottom: 50,
left: 0,
right: 0,
child: Center(
child: Text(
"Align QR Code within the frame".tr,
style: const TextStyle(color: Colors.white, fontSize: 16),
),
),
),
],
),
);
}
}

View File

@@ -3,12 +3,18 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../constant/colors.dart';
import '../../../constant/links.dart';
import '../../../constant/style.dart';
import '../../../controller/home/profile/invit_controller.dart';
import '../../../controller/home/profile/invites_rewards_controller.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'qr_scanner_page.dart';
import '../../../print.dart';
class ShareAppPage extends StatelessWidget {
final InviteController controller = Get.put(InviteController());
final InvitesRewardsController rewardsController =
Get.put(InvitesRewardsController());
@override
Widget build(BuildContext context) {
@@ -42,6 +48,12 @@ class ShareAppPage extends StatelessWidget {
},
),
),
floatingActionButton: FloatingActionButton.extended(
backgroundColor: AppColor.primaryColor,
onPressed: () => Get.to(() => QRScannerPage()),
icon: const Icon(CupertinoIcons.qrcode_viewfinder, color: Colors.white),
label: Text("Scan QR".tr, style: const TextStyle(color: Colors.white)),
),
);
}
@@ -49,6 +61,8 @@ class ShareAppPage extends StatelessWidget {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildQRCodeSection(),
const SizedBox(height: 20),
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
@@ -74,8 +88,11 @@ class ShareAppPage extends StatelessWidget {
const SizedBox(height: 20),
_buildActionButtonsPassengers(),
const SizedBox(height: 20),
const SizedBox(height: 20),
_buildInvitationsListPassengers(context),
const SizedBox(height: 20),
_buildUnifiedRewardsList(),
const SizedBox(
height: 60), // Add padding for the floating action button
],
);
}
@@ -226,24 +243,35 @@ class ShareAppPage extends StatelessWidget {
}
Widget _buildInvitationsListPassengers(BuildContext context) {
return SizedBox(
height: Get.height * .4,
child: controller.driverInvitationDataToPassengers.isEmpty
? Center(
child: Text(
"No invitation found yet!".tr,
style: TextStyle(
color: AppColor.grayColor,
fontSize: 17,
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Invitations Sent".tr,
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: AppColor.writeColor,
)),
const SizedBox(height: 10),
controller.driverInvitationDataToPassengers.isEmpty
? Center(
child: Text(
"No invitation found yet!".tr,
style: TextStyle(
color: AppColor.grayColor,
fontSize: 17,
),
),
)
: ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: controller.driverInvitationDataToPassengers.length,
itemBuilder: (context, index) {
return _buildInvitationItemPassengers(context, index);
},
),
)
: ListView.builder(
itemCount: controller.driverInvitationDataToPassengers.length,
itemBuilder: (context, index) {
return _buildInvitationItemPassengers(context, index);
},
),
],
);
}
@@ -574,4 +602,136 @@ class ShareAppPage extends StatelessWidget {
// ),
// );
}
Widget _buildQRCodeSection() {
return GetBuilder<InvitesRewardsController>(
builder: (rewardsController) {
if (rewardsController.isLoading) {
return const Center(child: CupertinoActivityIndicator());
}
String qrData =
'https://${AppLink.appDomain}/?inviteCode=${rewardsController.referralCode ?? ''}';
return Center(
child: Column(
children: [
Text("Your QR Code".tr,
style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 10),
if (rewardsController.referralCode != null)
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
),
child: QrImageView(
data: qrData,
version: QrVersions.auto,
size: 200.0,
backgroundColor: Colors.white,
),
),
const SizedBox(height: 10),
if (rewardsController.referralCode != null)
Text(
rewardsController.referralCode!,
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
letterSpacing: 2),
),
],
),
);
},
);
}
Widget _buildUnifiedRewardsList() {
return GetBuilder<InvitesRewardsController>(
builder: (rewardsController) {
if (rewardsController.isLoading) {
return const Center(child: CupertinoActivityIndicator());
}
var filteredList = rewardsController.referrals;
if (filteredList.isEmpty) {
return const SizedBox(); // Hide if no valid rewards
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Reward Status".tr,
style:
const TextStyle(fontSize: 17, fontWeight: FontWeight.bold)),
const SizedBox(height: 10),
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: filteredList.length,
itemBuilder: (context, index) {
var ref = filteredList[index];
int trips = ref['trip_count'] ?? 0;
int target = ref['target_trips'] ?? 1;
bool canClaim = ref['can_claim'] ?? false;
bool isClaimed = ref['is_reward_claimed'] == 1;
return Container(
margin: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: CupertinoColors.systemGrey6,
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
ref['invited_user_type'] == 'driver'
? "Driver Referral".tr
: "Passenger Referral".tr,
style: const TextStyle(
fontWeight: FontWeight.bold)),
const SizedBox(height: 4),
Text("Trips: $trips / $target".tr,
style: const TextStyle(
color: CupertinoColors.secondaryLabel,
fontSize: 13)),
if (isClaimed)
Text("Reward Claimed".tr,
style: const TextStyle(
color: CupertinoColors.activeGreen,
fontSize: 12,
fontWeight: FontWeight.bold))
else if (!canClaim)
Text("Waiting for trips".tr,
style: const TextStyle(
color: CupertinoColors.systemOrange,
fontSize: 12))
else
Text("Reward Earned".tr,
style: const TextStyle(
color: CupertinoColors.activeGreen,
fontSize: 12,
fontWeight: FontWeight.bold))
],
),
),
],
),
);
},
),
],
);
},
);
}
}