25-7-28-2

This commit is contained in:
Hamza-Ayed
2025-07-28 12:21:28 +03:00
parent 660d60e1f5
commit 83a97baed1
549 changed files with 109870 additions and 0 deletions

144
lib/views/Rate/rate_app_page.dart Executable file
View File

@@ -0,0 +1,144 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../controller/rate/rate_app_controller.dart';
class RatingScreen extends StatelessWidget {
final RatingController ratingController = Get.put(RatingController());
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text(
"Rate Our App".tr,
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
child: SafeArea(
child: SingleChildScrollView(
child: Center(
child: Obx(() {
return Padding(
padding:
const EdgeInsets.symmetric(horizontal: 20, vertical: 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// App logo or visual
ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.asset(
'assets/images/logo.gif',
height: 120,
),
),
const SizedBox(height: 20),
// Rating Prompt
Text(
"How would you rate our app?".tr,
textAlign: TextAlign.center,
style: CupertinoTheme.of(context)
.textTheme
.navTitleTextStyle
.copyWith(fontSize: 18, fontWeight: FontWeight.w600),
),
const SizedBox(height: 20),
// Comment Box
CupertinoTextField(
controller: ratingController.comment,
placeholder: 'Write your comment here'.tr,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
border: Border.all(color: CupertinoColors.systemGrey4),
borderRadius: BorderRadius.circular(12),
color: CupertinoColors.white,
),
prefix: Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Icon(CupertinoIcons.pencil_ellipsis_rectangle,
color: CupertinoColors.systemGrey),
),
),
const SizedBox(height: 20),
// Star Rating Section
_buildRatingStars(),
const SizedBox(height: 30),
// Submit Button
CupertinoButton(
padding: const EdgeInsets.symmetric(
horizontal: 24, vertical: 14),
borderRadius: BorderRadius.circular(12),
color: CupertinoColors.activeGreen,
onPressed: () {
if (ratingController.userRating.value > 0) {
ratingController
.submitRating(ratingController.userRating.value);
Get.snackbar(
"Thank You!".tr,
"Your rating has been submitted.".tr,
backgroundColor: CupertinoColors.systemGrey6,
snackPosition: SnackPosition.BOTTOM,
margin: const EdgeInsets.all(16),
borderRadius: 12,
);
} else {
Get.snackbar(
"Error".tr,
"Please select a rating before submitting.".tr,
backgroundColor: CupertinoColors.systemRed,
snackPosition: SnackPosition.BOTTOM,
margin: const EdgeInsets.all(16),
borderRadius: 12,
);
}
},
child: Text(
"Submit Rating".tr,
style: const TextStyle(
color: CupertinoColors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
],
),
);
}),
),
),
),
);
}
// Widget for building rating stars with animations
Widget _buildRatingStars() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(5, (index) {
return GestureDetector(
onTap: () {
ratingController.userRating.value = index + 1;
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
margin: const EdgeInsets.symmetric(horizontal: 4),
child: Icon(
CupertinoIcons.star_fill,
size: 40,
color: index < ratingController.userRating.value
? CupertinoColors.systemYellow
: CupertinoColors.systemGrey3,
),
),
);
}),
);
}
}

View File

@@ -0,0 +1,258 @@
import 'package:sefer_driver/controller/home/captin/map_driver_controller.dart';
import 'package:sefer_driver/views/widgets/my_textField.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:get/get.dart';
import 'package:sefer_driver/constant/colors.dart';
import 'package:sefer_driver/views/widgets/elevated_btn.dart';
import 'package:sefer_driver/views/widgets/my_scafold.dart';
import '../../constant/style.dart';
import '../../controller/rate/rate_conroller.dart';
class RatePassenger extends StatelessWidget {
final RateController controller = Get.put(RateController());
RatePassenger({super.key});
@override
Widget build(BuildContext context) {
return MyScafolld(
title: 'Rate Passenger'.tr,
body: [
GetBuilder<RateController>(builder: (controller) {
return Positioned(
top: 40,
left: Get.width * .1,
right: Get.width * .1,
child: Container(
decoration: AppStyle.boxDecoration,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(4),
child: Container(
height: Get.height * .25,
decoration: AppStyle.boxDecoration1,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'${'Total price from '.tr}${Get.find<MapDriverController>().passengerName}',
style: AppStyle.title,
),
Container(
decoration: BoxDecoration(
border: Border.all(
width: 2,
color: AppColor.redColor,
)),
child: Padding(
padding: const EdgeInsets.all(4),
child: Text(
(double.parse(controller.price.toString()) -
double.parse(controller.price
.toString()) *
.12)
.toStringAsFixed(2),
style: AppStyle.number.copyWith(
color: AppColor.redColor,
textBaseline: TextBaseline.ideographic,
decoration: TextDecoration.lineThrough,
decorationColor: AppColor.redColor),
),
),
),
const SizedBox(
height: 10,
),
Container(
decoration: BoxDecoration(
border: Border.all(
width: 2,
color: AppColor.greenColor,
)),
child: Padding(
padding: const EdgeInsets.all(4),
child: Text(
Get.find<MapDriverController>()
.paymentAmount,
style: AppStyle.number,
),
),
),
const SizedBox(
height: 10,
),
Text(
'Exclusive offers and discounts always with the Sefer app'
.tr,
textAlign: TextAlign.center,
style: AppStyle.title
.copyWith(color: AppColor.redColor),
)
],
)),
),
controller.walletChecked != 'true'
? controller.ispassengerWantWalletFromDriver
? Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Text(
"How much Passenger pay?".tr,
style: AppStyle.title,
),
Form(
key: controller.formKey,
child: MyTextForm(
controller:
controller.passengerPayAmount,
label: "passenger amount to me".tr,
hint: "passenger amount to me".tr,
type: const TextInputType
.numberWithOptions(decimal: true),
),
),
MyElevatedButton(
title: "Press here".tr,
onPressed: () {
controller.addPassengerWallet();
},
)
],
),
),
)
: Container(
width: Get.width * .73,
decoration: AppStyle.boxDecoration1,
child: Column(
children: [
Text(
"Would the passenger like to settle the remaining fare using their wallet?"
.tr,
style: AppStyle.title,
textAlign: TextAlign.center,
),
MyElevatedButton(
title: "Press here".tr,
onPressed: () {
controller.passengerWantPay();
},
)
],
),
)
: const SizedBox(),
const SizedBox(
height: 20,
),
Center(
child: RatingBar.builder(
initialRating: 0,
itemCount: 5,
itemSize: 50,
itemPadding: const EdgeInsets.symmetric(horizontal: 2),
itemBuilder: (context, index) {
switch (index) {
case 0:
return const Icon(
Icons.sentiment_very_dissatisfied,
color: Colors.red,
);
case 1:
return const Icon(
Icons.sentiment_dissatisfied,
color: Colors.redAccent,
);
case 2:
return const Icon(
Icons.sentiment_neutral,
color: Colors.amber,
);
case 3:
return const Icon(
Icons.sentiment_satisfied,
color: Colors.lightGreen,
);
case 4:
return const Icon(
Icons.sentiment_very_satisfied,
color: Colors.green,
);
default:
return const Icon(
Icons.sentiment_neutral,
color: Colors.amber,
);
} //
},
onRatingUpdate: (rating) {
controller.selectRateItem(rating);
},
),
),
const SizedBox(
height: 20,
),
SizedBox(
width: Get.width * .75,
child: TextFormField(
maxLines: 4,
minLines: 1,
keyboardType: TextInputType.multiline,
controller: controller.comment,
decoration: InputDecoration(
labelText: 'Enter your Note'.tr,
hintText: 'Type something...',
prefixIcon: const Icon(
Icons.rate_review), // Add an icon as a prefix
suffixIcon: IconButton(
icon: const Icon(
Icons.clear,
color: AppColor.redColor,
), // Add an icon as a suffix
onPressed: () {
controller.comment.clear();
},
),
border:
const OutlineInputBorder(), // Add a border around the input field
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(
color:
Colors.blue), // Customize the border color
),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors
.green), // Customize the border color when focused
),
errorBorder: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors
.red), // Customize the border color when there's an error
),
),
),
),
const SizedBox(
height: 20,
),
MyElevatedButton(
title: 'Submit rating'.tr,
onPressed: () => controller.addRateToPassenger())
],
),
));
}),
],
isleading: false,
);
}
}

View File

@@ -0,0 +1,484 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sefer_driver/constant/colors.dart';
import 'package:sefer_driver/constant/info.dart';
import 'package:sefer_driver/constant/style.dart';
import 'package:sefer_driver/views/widgets/my_scafold.dart';
import 'package:sefer_driver/views/widgets/mycircular.dart';
import 'package:intl/intl.dart';
import '../../controller/home/captin/duration_controller .dart';
class RideCalculateDriver extends StatelessWidget {
RideCalculateDriver({super.key});
// DurationController durationController = Get.put(DurationController());
@override
Widget build(BuildContext context) {
Get.put(DurationController());
return MyScafolld(
title: 'Ride Summaries'.tr,
body: [
Center(
child: GetBuilder<DurationController>(
builder: (durationController) => durationController.isLoading
? const Center(child: MyCircularProgressIndicator())
: durationController.jsonData1.isEmpty ||
durationController.jsonData2.isEmpty
? Center(
child: Text('No data yet!'.tr),
)
: ListView(
// mainAxisAlignment: MainAxisAlignment.start,
// crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'${'Average of Hours of'.tr} ${AppInformation.appName}${' is ON for this month'.tr}${' ${durationController.jsonData1['message'][0]['day'].toString().split('-')[1]}'.tr}',
style: AppStyle.title,
textAlign: TextAlign.center,
),
Padding(
padding: const EdgeInsets.all(6),
child: Container(
decoration: AppStyle.boxDecoration1,
height: Get.height * .4,
child: LineChart(
duration: const Duration(milliseconds: 150),
curve: Curves.ease,
LineChartData(
lineBarsData: [
LineChartBarData(
isStepLineChart: true,
spots: durationController.chartData,
isCurved: true,
color: Colors
.deepPurpleAccent, // Custom color
barWidth: 3, // Thinner line
dotData: const FlDotData(
show:
true), // Show dots on each point
belowBarData: BarAreaData(
// Add gradient fill below the line
show: true,
color: AppColor.deepPurpleAccent,
),
isStrokeJoinRound: true,
shadow: const BoxShadow(
color: AppColor.yellowColor,
blurRadius: 4,
offset: Offset(2, 2),
),
),
],
showingTooltipIndicators: const [],
titlesData: FlTitlesData(
show: true,
topTitles: AxisTitles(
axisNameWidget: Text(
'Days'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
),
bottomTitles: AxisTitles(
axisNameWidget: Text(
'Total Hours on month'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30,
showTitles: true)),
leftTitles: AxisTitles(
axisNameWidget: Text(
'Counts of Hours on days'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30,
showTitles: true)),
),
gridData: const FlGridData(
show: true,
),
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(
color: AppColor.accentColor),
left: BorderSide(
color: AppColor.accentColor),
),
),
),
),
),
),
const SizedBox(
height: 5,
),
Padding(
padding: const EdgeInsets.all(6),
child: Container(
decoration: AppStyle.boxDecoration1,
height: Get.height * .4,
child: LineChart(
duration: const Duration(milliseconds: 150),
curve: Curves.ease,
LineChartData(
lineBarsData: [
LineChartBarData(
spots: durationController.chartRideCount,
// isCurved: true,
color: Colors
.deepPurpleAccent, // Custom color
barWidth: 3, // Thinner line
dotData: const FlDotData(
show:
true), // Show dots on each point
belowBarData: BarAreaData(
// Add gradient fill below the line
show: true,
color: AppColor.deepPurpleAccent,
),
isStrokeJoinRound: true,
shadow: const BoxShadow(
color: AppColor.yellowColor,
blurRadius: 4,
offset: Offset(2, 2),
),
),
],
showingTooltipIndicators: const [],
titlesData: FlTitlesData(
show: true,
topTitles: AxisTitles(
axisNameWidget: Text(
'Days'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
// sideTitles: const SideTitles(
// reservedSize: 30, showTitles: true),
),
bottomTitles: AxisTitles(
axisNameWidget: Text(
'${"Total rides on month".tr} = ${durationController.jsonData2['message'][0]['totalCount'].toString()}'
.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30,
showTitles: true)),
leftTitles: AxisTitles(
axisNameWidget: Text(
'Counts of rides on days'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30,
showTitles: true)),
),
gridData: const FlGridData(
show: true,
),
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(
color: AppColor.accentColor),
left: BorderSide(
color: AppColor.accentColor),
),
),
),
),
),
),
const SizedBox(
height: 5,
),
Padding(
padding: const EdgeInsets.all(6),
child: Container(
decoration: AppStyle.boxDecoration1,
height: Get.height * .4,
child: LineChart(
duration: const Duration(milliseconds: 150),
curve: Curves.ease,
LineChartData(
lineBarsData: [
LineChartBarData(
isStepLineChart: true,
spots: durationController
.chartRidePriceDriver,
isCurved: true,
isStrokeCapRound: true,
preventCurveOverShooting: true,
color: Colors
.deepPurpleAccent, // Custom color
barWidth: 3, // Thinner line
dotData: const FlDotData(
show:
true), // Show dots on each point
belowBarData: BarAreaData(
// Add gradient fill below the line
show: true,
color: AppColor.deepPurpleAccent,
),
isStrokeJoinRound: true,
shadow: const BoxShadow(
color: AppColor.yellowColor,
blurRadius: 4,
offset: Offset(2, 2),
),
),
],
showingTooltipIndicators: const [],
titlesData: FlTitlesData(
show: true,
topTitles: AxisTitles(
axisNameWidget: Text(
'Days'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
// sideTitles: const SideTitles(
// reservedSize: 30, showTitles: true),
),
bottomTitles: AxisTitles(
axisNameWidget: Text(
'${"Total budgets on month".tr} = ${durationController.jsonData2['message'][0]['totalPrice'].toString()}'
.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30,
showTitles: true)),
leftTitles: AxisTitles(
axisNameWidget: Text(
'Counts of budgets on days'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30,
showTitles: true)),
),
gridData: const FlGridData(
show: true,
),
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(
color: AppColor.accentColor),
left: BorderSide(
color: AppColor.accentColor),
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: AppStyle.boxDecoration1,
child: durationController.monthlyList.isEmpty
? SizedBox(
height: Get.height * .2,
child: Center(
child: Text(
"No data yet".tr,
style: AppStyle.title,
),
),
)
: DriverStatsTable(
monthlyList:
durationController.monthlyList,
)))
],
),
)
// BarChartWidget(),
),
],
isleading: true);
}
}
class DriverStatsTable extends StatelessWidget {
final List monthlyList;
const DriverStatsTable({Key? key, required this.monthlyList})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 5,
offset: const Offset(0, 3),
),
],
),
padding: const EdgeInsets.all(16),
child: DataTable(
columnSpacing: 12,
columns: [
DataColumn(label: Text('Statistic'.tr)),
DataColumn(label: Text('Value'.tr)),
],
rows: _buildRows(),
),
);
}
List<DataRow> _buildRows() {
return [
DataRow(cells: [
DataCell(Text(
'Total Orders'.tr,
style: AppStyle.title,
)),
DataCell(Text(
monthlyList[0]['total_orders'].toString(),
style: AppStyle.number,
)),
]),
DataRow(cells: [
DataCell(Text(
'Completed'.tr,
style: AppStyle.title,
)),
DataCell(Text(
monthlyList[0]['completed_orders'].toString(),
style: AppStyle.number,
)),
]),
DataRow(cells: [
DataCell(Text(
'Canceled Orders'.tr,
style: AppStyle.title,
)),
DataCell(Text(
monthlyList[0]['canceled_orders'].toString(),
style: AppStyle.number,
)),
]),
DataRow(cells: [
DataCell(Text(
'Rejected Orders'.tr,
style: AppStyle.title,
)),
DataCell(Text(
monthlyList[0]['rejected_orders'].toString(),
style: AppStyle.number,
)),
]),
DataRow(cells: [
DataCell(Text(
'Percent Rejected'.tr,
style: AppStyle.title,
)),
DataCell(Text(
'${(monthlyList[0]['percent_rejected']).toString()}%',
style: AppStyle.number.copyWith(
color: double.parse(monthlyList[0]['percent_canceled']) < .3
? AppColor.greenColor
: AppColor.redColor),
)),
]),
DataRow(cells: [
DataCell(Text(
'Percent Canceled'.tr,
style: AppStyle.title,
)),
DataCell(Text(
'${(monthlyList[0]['percent_canceled']).toString()}%',
style: AppStyle.number.copyWith(
color: double.parse(monthlyList[0]['percent_canceled']) < .3
? AppColor.greenColor
: AppColor.redColor),
)),
]),
DataRow(cells: [
DataCell(Text(
'Percent Completed'.tr,
style: AppStyle.title,
)),
DataCell(Text(
'${(monthlyList[0]['percent_completed']).toString()}%',
style: AppStyle.number.copyWith(
color: double.parse(monthlyList[0]['percent_completed']) > .7
? AppColor.greenColor
: AppColor.redColor),
)),
]),
];
}
}
class StaticDriverOrder extends StatelessWidget {
const StaticDriverOrder({
Key? key,
required this.title,
required this.jsonTitle,
}) : super(key: key);
final String title, jsonTitle;
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(8.0),
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 3,
blurRadius: 5,
offset: const Offset(0, 3), // changes position of shadow
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
title,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.black54,
),
),
const SizedBox(height: 8.0),
Text(
jsonTitle,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
],
),
);
}
}