Merge pull request 'haroon_dev' (#212) from haroon_dev into master
Reviewed-on: https://34.17.182.140/Haroon6138/HMG_Patient_App_New/pulls/212pull/214/head
|
Before Width: | Height: | Size: 202 KiB After Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 220 KiB After Width: | Height: | Size: 221 KiB |
|
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 183 KiB |
|
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 228 KiB |
@ -0,0 +1,6 @@
|
||||
<svg width="56" height="56" viewBox="0 0 56 56" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="56" height="56" rx="28" fill="white"/>
|
||||
<rect width="56" height="56" rx="28" fill="white"/>
|
||||
<rect x="0.5" y="0.5" width="55" height="55" rx="27.5" stroke="#2E3039" stroke-opacity="0.13" stroke-dasharray="2 2"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M28 18.25C28.4142 18.25 28.75 18.5858 28.75 19V26.25H36C36.4142 26.25 36.75 26.5858 36.75 27C36.75 27.4142 36.4142 27.75 36 27.75H28.75V35C28.75 35.4142 28.4142 35.75 28 35.75C27.5858 35.75 27.25 35.4142 27.25 35V27.75H20C19.5858 27.75 19.25 27.4142 19.25 27C19.25 26.5858 19.5858 26.25 20 26.25H27.25V19C27.25 18.5858 27.5858 18.25 28 18.25Z" fill="#161616" stroke="#2E3039" stroke-width="0.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 835 B |
@ -0,0 +1,6 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="40" height="40" rx="10" fill="#EFEFF0"/>
|
||||
<path d="M18.9994 9.25C16.0999 9.25 13.7494 11.6005 13.7494 14.5C13.7494 17.3995 16.0999 19.75 18.9994 19.75C21.8989 19.75 24.2494 17.3995 24.2494 14.5C24.2494 11.6005 21.8989 9.25 18.9994 9.25Z" fill="#8F9AA3"/>
|
||||
<path d="M22.4393 22.3825L22.4269 22.3899C22.3982 22.4063 22.3715 22.4164 22.3391 22.4232L22.3222 22.4264C21.5275 22.5747 20.3099 23.081 19.8772 24.4469C19.436 25.84 20.178 26.9751 20.7397 27.5414L20.9312 27.7346C21.045 27.8493 21.1019 27.9066 21.1231 27.9808C21.1442 28.055 21.1262 28.1337 21.09 28.2912L21.0601 28.4219C20.9887 28.7329 20.9096 29.2541 20.9862 29.8241C21.0509 30.3047 21.0832 30.545 20.9935 30.6475C20.9039 30.75 20.7005 30.75 20.2937 30.75L14.5901 30.75C12.7718 30.75 11.366 29.8556 10.1945 28.7396C9.51551 28.0927 9.17705 27.3646 9.26185 26.5888C9.3416 25.8592 9.78025 25.2637 10.2419 24.8118C10.9801 24.0893 12.0577 23.4813 12.7705 23.0792C12.9331 22.9875 13.0768 22.9064 13.1931 22.8372C14.4979 22.0602 15.93 21.5691 17.3945 21.3625C18.4583 21.2125 19.5401 21.2125 20.6039 21.3625C21.0835 21.4302 21.8204 21.628 22.365 21.7855C22.4184 21.801 22.4451 21.8087 22.4641 21.8172C22.6658 21.9073 22.7022 22.1856 22.5303 22.3244C22.5142 22.3375 22.4892 22.3525 22.4393 22.3825Z" fill="#8F9AA3"/>
|
||||
<path d="M27.3627 22.245C27.12 21.7533 26.67 21.25 25.9982 21.25C25.3273 21.25 24.8762 21.7522 24.6315 22.2431L23.9345 23.6487L23.9282 23.6547C23.9233 23.6592 23.9176 23.6639 23.9113 23.6687C23.9049 23.6734 23.8987 23.6775 23.893 23.681L23.8859 23.6851L22.6351 23.8946C22.0941 23.9855 21.5068 24.2757 21.3091 24.8998C21.1123 25.5211 21.4213 26.0967 21.8065 26.4851L22.7841 27.4708C22.7875 27.4778 22.792 27.4888 22.7959 27.5027C22.8003 27.5181 22.8024 27.5314 22.8031 27.5401L22.524 28.7572C22.397 29.3106 22.3883 30.0742 22.9815 30.5106C23.5783 30.9496 24.3047 30.7069 24.7916 30.4156L25.9668 29.7142C26.0142 29.6859 26.0283 29.702 26.0294 29.7135L27.2061 30.4159C27.6913 30.7048 28.4194 30.9516 29.0171 30.5123C29.6116 30.0753 29.5995 29.3093 29.4735 28.7579L29.1942 27.5401C29.1949 27.5314 29.197 27.5181 29.2014 27.5027C29.2053 27.4888 29.2098 27.4778 29.2132 27.4708L30.1889 26.487L30.1899 26.486C30.5775 26.0974 30.8877 25.521 30.6893 24.8985C30.4905 24.275 29.9028 23.9855 29.3626 23.8947L28.1075 23.6844L28.0992 23.6798C28.0935 23.6763 28.0874 23.6722 28.0811 23.6676C28.0789 23.6659 28.0766 23.6642 28.0745 23.6625C28.0709 23.6596 28.0675 23.6567 28.0645 23.654L28.0587 23.6484L27.3632 22.2459L27.3627 22.245Z" fill="#8F9AA3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@ -0,0 +1,9 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="40" height="40" rx="10" fill="#2E3039"/>
|
||||
<path d="M16 20C15.4477 20 15 20.4477 15 21C15 21.5523 15.4477 22 16 22H16.009C16.5613 22 17.009 21.5523 17.009 21C17.009 20.4477 16.5613 20 16.009 20H16Z" fill="white"/>
|
||||
<path d="M19.9955 20C19.4432 20 18.9955 20.4477 18.9955 21C18.9955 21.5523 19.4432 22 19.9955 22H20.0045C20.5568 22 21.0045 21.5523 21.0045 21C21.0045 20.4477 20.5568 20 20.0045 20H19.9955Z" fill="white"/>
|
||||
<path d="M23.991 20C23.4387 20 22.991 20.4477 22.991 21C22.991 21.5523 23.4387 22 23.991 22H24C24.5523 22 25 21.5523 25 21C25 20.4477 24.5523 20 24 20H23.991Z" fill="white"/>
|
||||
<path d="M16 24C15.4477 24 15 24.4477 15 25C15 25.5523 15.4477 26 16 26H16.009C16.5613 26 17.009 25.5523 17.009 25C17.009 24.4477 16.5613 24 16.009 24H16Z" fill="white"/>
|
||||
<path d="M19.9955 24C19.4432 24 18.9955 24.4477 18.9955 25C18.9955 25.5523 19.4432 26 19.9955 26H20.0045C20.5568 26 21.0045 25.5523 21.0045 25C21.0045 24.4477 20.5568 24 20.0045 24H19.9955Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.75 10C14.75 9.58579 14.4142 9.25 14 9.25C13.5858 9.25 13.25 9.58579 13.25 10V10.6348C12.4452 10.8629 11.7665 11.2336 11.2015 11.8444C10.4236 12.6853 10.0778 13.7479 9.91225 15.0795C9.74998 16.3843 9.74999 18.0565 9.75 20.19V20.81C9.74999 22.9435 9.74998 24.6157 9.91225 25.9205C10.0778 27.2521 10.4236 28.3147 11.2015 29.1556C11.9871 30.0049 12.9928 30.3901 14.2513 30.573C15.4693 30.75 17.0255 30.75 18.9892 30.75H21.0108C22.9745 30.75 24.5307 30.75 25.7487 30.573C27.0072 30.3901 28.0129 30.0049 28.7985 29.1556C29.5764 28.3147 29.9222 27.2521 30.0878 25.9205C30.25 24.6157 30.25 22.9435 30.25 20.8099V20.1901C30.25 18.0565 30.25 16.3843 30.0878 15.0795C29.9222 13.7479 29.5764 12.6853 28.7985 11.8444C28.2335 11.2336 27.5548 10.8629 26.75 10.6348V10C26.75 9.58579 26.4142 9.25 26 9.25C25.5858 9.25 25.25 9.58579 25.25 10V10.3659C24.1139 10.25 22.716 10.25 21.0108 10.25L18.9892 10.25C17.284 10.25 15.8861 10.25 14.75 10.3659V10ZM13.2786 12.2058C13.3681 12.52 13.6572 12.75 14 12.75C14.4142 12.75 14.75 12.4142 14.75 12V11.8746C15.811 11.7516 17.1824 11.75 19.05 11.75L20.95 11.75C22.8176 11.75 24.189 11.7516 25.25 11.8746V12C25.25 12.4142 25.5858 12.75 26 12.75C26.3428 12.75 26.6319 12.52 26.7214 12.2058C27.1287 12.3679 27.438 12.5826 27.6973 12.8629C28.1704 13.3744 28.4505 14.0759 28.5982 15.2564C28.5661 15.2522 28.5333 15.25 28.5 15.25L11.5 15.25C11.4667 15.25 11.4339 15.2522 11.4018 15.2564C11.5495 14.0759 11.8296 13.3744 12.3027 12.8629C12.562 12.5826 12.8713 12.3679 13.2786 12.2058ZM11.2901 16.7202C11.2506 17.6832 11.25 18.8363 11.25 20.2432V20.7568C11.25 22.9551 11.2514 24.5339 11.4008 25.7354C11.5482 26.9208 11.8285 27.6244 12.3027 28.1371C12.7692 28.6414 13.3973 28.9331 14.467 29.0886C15.5648 29.2481 17.0119 29.25 19.05 29.25H20.95C22.9881 29.25 24.4352 29.2481 25.533 29.0886C26.6027 28.9331 27.2308 28.6414 27.6973 28.1371C28.1715 27.6244 28.4518 26.9208 28.5992 25.7354C28.7486 24.5339 28.75 22.9551 28.75 20.7568V20.2432C28.75 18.8363 28.7494 17.6832 28.7099 16.7202C28.6433 16.7396 28.5728 16.75 28.5 16.75L11.5 16.75C11.4272 16.75 11.3567 16.7396 11.2901 16.7202Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
@ -0,0 +1,71 @@
|
||||
class LiveCareClinicScheduleResponse {
|
||||
int? iD;
|
||||
int? serviceID;
|
||||
int? dayOfWeek;
|
||||
String? dayOfWeekStr;
|
||||
bool? isActive;
|
||||
String? createdOn;
|
||||
String? createdBy;
|
||||
bool? projectOutSA;
|
||||
String? dayOfWeekStrN;
|
||||
List<ShiftTimings>? shiftTimings;
|
||||
|
||||
LiveCareClinicScheduleResponse({this.iD, this.serviceID, this.dayOfWeek, this.dayOfWeekStr, this.isActive, this.createdOn, this.createdBy, this.projectOutSA, this.dayOfWeekStrN, this.shiftTimings});
|
||||
|
||||
LiveCareClinicScheduleResponse.fromJson(Map<String, dynamic> json) {
|
||||
iD = json['ID'];
|
||||
serviceID = json['ServiceID'];
|
||||
dayOfWeek = json['DayOfWeek'];
|
||||
dayOfWeekStr = json['DayOfWeekStr'];
|
||||
isActive = json['IsActive'];
|
||||
createdOn = json['CreatedOn'];
|
||||
createdBy = json['CreatedBy'];
|
||||
projectOutSA = json['ProjectOutSA'];
|
||||
dayOfWeekStrN = json['DayOfWeekStrN'];
|
||||
if (json['ShiftTimings'] != null) {
|
||||
shiftTimings = <ShiftTimings>[];
|
||||
json['ShiftTimings'].forEach((v) {
|
||||
shiftTimings!.add(new ShiftTimings.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['ID'] = this.iD;
|
||||
data['ServiceID'] = this.serviceID;
|
||||
data['DayOfWeek'] = this.dayOfWeek;
|
||||
data['DayOfWeekStr'] = this.dayOfWeekStr;
|
||||
data['IsActive'] = this.isActive;
|
||||
data['CreatedOn'] = this.createdOn;
|
||||
data['CreatedBy'] = this.createdBy;
|
||||
data['ProjectOutSA'] = this.projectOutSA;
|
||||
data['DayOfWeekStrN'] = this.dayOfWeekStrN;
|
||||
if (this.shiftTimings != null) {
|
||||
data['ShiftTimings'] = this.shiftTimings!.map((v) => v.toJson()).toList();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class ShiftTimings {
|
||||
String? endTime;
|
||||
int? shiftID;
|
||||
String? startTime;
|
||||
|
||||
ShiftTimings({this.endTime, this.shiftID, this.startTime});
|
||||
|
||||
ShiftTimings.fromJson(Map<String, dynamic> json) {
|
||||
endTime = json['EndTime'];
|
||||
shiftID = json['ShiftID'];
|
||||
startTime = json['StartTime'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['EndTime'] = this.endTime;
|
||||
data['ShiftID'] = this.shiftID;
|
||||
data['StartTime'] = this.startTime;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
class AppointmentRatedResponseModel {
|
||||
int? appointmentNo;
|
||||
int? clinicID;
|
||||
int? doctorID;
|
||||
bool? isAllowedToRate;
|
||||
bool? isAppointmentRated;
|
||||
int? projectID;
|
||||
|
||||
AppointmentRatedResponseModel({this.appointmentNo, this.clinicID, this.doctorID, this.isAllowedToRate, this.isAppointmentRated, this.projectID});
|
||||
|
||||
AppointmentRatedResponseModel.fromJson(Map<String, dynamic> json) {
|
||||
appointmentNo = json['AppointmentNo'];
|
||||
clinicID = json['ClinicID'];
|
||||
doctorID = json['DoctorID'];
|
||||
isAllowedToRate = json['IsAllowedToRate'];
|
||||
isAppointmentRated = json['IsAppointmentRated'];
|
||||
projectID = json['ProjectID'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['AppointmentNo'] = this.appointmentNo;
|
||||
data['ClinicID'] = this.clinicID;
|
||||
data['DoctorID'] = this.doctorID;
|
||||
data['IsAllowedToRate'] = this.isAllowedToRate;
|
||||
data['IsAppointmentRated'] = this.isAppointmentRated;
|
||||
data['ProjectID'] = this.projectID;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
class RemoteFileLoader extends AssetLoader {
|
||||
@override
|
||||
Future<Map<String, dynamic>?> load(String path, Locale locale) async {
|
||||
final directory = await getApplicationDocumentsDirectory();
|
||||
|
||||
// easy_localization uses toLanguageTag() which gives 'en-US' or 'ar-SA'
|
||||
final fileName = "${locale.toLanguageTag()}.json";
|
||||
final file = File("${directory.path}/$fileName");
|
||||
|
||||
if (await file.exists()) {
|
||||
final String jsonString = await file.readAsString();
|
||||
return jsonDecode(jsonString);
|
||||
} else {
|
||||
// If the download failed or hasn't happened yet, load from local assets
|
||||
// path is the 'path' property from the EasyLocalization widget
|
||||
final localData = await rootBundle.loadString('$path/$fileName');
|
||||
return jsonDecode(localData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/core/api_consts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
class TranslationService {
|
||||
// Replace with your actual hosting URL
|
||||
static final String baseUrl = ApiConsts.googleCloudStorageENTranslationFileBaseURL;
|
||||
|
||||
static Future<void> downloadTranslations() async {
|
||||
final directory = await getApplicationDocumentsDirectory();
|
||||
|
||||
// Ensure these match your locale codes exactly (en-US, ar-SA)
|
||||
List<String> files = ["en-US.json", "ar-SA.json"];
|
||||
|
||||
for (String fileName in files) {
|
||||
try {
|
||||
final String timestamp = DateTime.now().millisecondsSinceEpoch.toString();
|
||||
String url = "$baseUrl/$fileName?v=$timestamp";
|
||||
debugPrint(url);
|
||||
// final response = await http.get(Uri.parse("$baseUrl/$fileName"));
|
||||
final response = await http.get(Uri.parse(url));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final file = File("${directory.path}/$fileName");
|
||||
await file.writeAsBytes(response.bodyBytes);
|
||||
} else {
|
||||
print("Failed to download $fileName: Status ${response.statusCode}");
|
||||
}
|
||||
} catch (e) {
|
||||
print("Network error while downloading $fileName: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,181 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/core/app_export.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/appointments/widgets/doctor_row_appointment_rating.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class AppointmentRatingWidget extends StatefulWidget {
|
||||
const AppointmentRatingWidget({super.key, required this.patientAppointmentHistoryResponseModel});
|
||||
|
||||
final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
|
||||
|
||||
@override
|
||||
State<AppointmentRatingWidget> createState() => _AppointmentRatingWidgetState();
|
||||
}
|
||||
|
||||
class _AppointmentRatingWidgetState extends State<AppointmentRatingWidget> {
|
||||
late MyAppointmentsViewModel myAppointmentsViewModel;
|
||||
late BookAppointmentsViewModel bookAppointmentsViewModel;
|
||||
|
||||
int rating = 0;
|
||||
String notes = "";
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context, listen: false);
|
||||
bookAppointmentsViewModel = Provider.of<BookAppointmentsViewModel>(context, listen: false);
|
||||
return SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.6,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Scrollable main content
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 0.0, left: 0, right: 0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
// Doctor row
|
||||
Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 24.r,
|
||||
hasShadow: false,
|
||||
),
|
||||
child: BuildDoctorRowAppointmentRating(
|
||||
patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel,
|
||||
)),
|
||||
|
||||
SizedBox(height: 16),
|
||||
|
||||
// Rating box
|
||||
Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 24.r,
|
||||
hasShadow: false,
|
||||
),
|
||||
width: double.infinity,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.rateTheDoctor.tr(context: context).toText16(isBold: true),
|
||||
SizedBox(height: 12),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
...List.generate(
|
||||
5,
|
||||
(index) => AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 1000),
|
||||
switchInCurve: Curves.elasticOut,
|
||||
switchOutCurve: Curves.elasticIn,
|
||||
transitionBuilder: (Widget child, Animation<double> animation) {
|
||||
return ScaleTransition(child: child, scale: animation);
|
||||
},
|
||||
child: Container(
|
||||
key: ValueKey<int>(rating),
|
||||
child: IconButton(
|
||||
iconSize: 45.0,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
rating = index + 1;
|
||||
});
|
||||
},
|
||||
color: rating >= (index + 1) ? Color.fromRGBO(255, 186, 0, 1.0) : Colors.grey[400],
|
||||
icon: Icon(rating >= (index + 1) ? Icons.star : Icons.star)),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 12),
|
||||
|
||||
// Note text field
|
||||
Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 24.r,
|
||||
hasShadow: false,
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
child: TextField(
|
||||
maxLines: 4,
|
||||
decoration: InputDecoration.collapsed(
|
||||
hintText: LocaleKeys.notes.tr(context: context),
|
||||
hintStyle: TextStyle(fontSize: 16.f, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.64, height: 23 / 16)),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
notes = value;
|
||||
});
|
||||
},
|
||||
))),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
// Bottom action buttons pinned to bottom
|
||||
SafeArea(
|
||||
top: false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
text: LocaleKeys.later.tr(context: context),
|
||||
backgroundColor: Color(0xffFEE9EA),
|
||||
borderColor: Color(0xffFEE9EA),
|
||||
textColor: Color(0xffED1C2B),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
text: LocaleKeys.submit.tr(context: context),
|
||||
onPressed: () async {
|
||||
// Set up clinic rating and show clinic rating view
|
||||
// appointmentRatingViewModel!.setTitle(LocaleKeys.rateDoctor.tr(context: context),);
|
||||
// appointmentRatingViewModel!.setSubTitle(LocaleKeys.howWasYourLastVisitWithDoctor.tr(context: context),);
|
||||
// appointmentRatingViewModel!.setClinicOrDoctor(true);
|
||||
|
||||
LoaderBottomSheet.showLoader();
|
||||
await myAppointmentsViewModel.submitDoctorRating(docRate: rating, docNote: notes, patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel);
|
||||
// await appointmentRatingViewModel!.submitClinicRating(clinicRate: rating, clinicNote: note);
|
||||
LoaderBottomSheet.hideLoader();
|
||||
Navigator.pop(context);
|
||||
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/core/app_assets.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/appointment_details_resp_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
|
||||
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
class BuildDoctorRowAppointmentRating extends StatelessWidget {
|
||||
final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
|
||||
|
||||
BuildDoctorRowAppointmentRating({super.key, required this.patientAppointmentHistoryResponseModel});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Image.network(
|
||||
patientAppointmentHistoryResponseModel.doctorImageURL!,
|
||||
width: 63.h,
|
||||
height: 63.h,
|
||||
fit: BoxFit.cover,
|
||||
).circle(100),
|
||||
SizedBox(width: 16.h),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
patientAppointmentHistoryResponseModel.doctorNameObj!.toString().toText16(isBold: true, maxlines: 1),
|
||||
SizedBox(height: 8.h),
|
||||
Wrap(
|
||||
direction: Axis.horizontal,
|
||||
spacing: 3.h,
|
||||
runSpacing: 4.h,
|
||||
children: [
|
||||
AppCustomChipWidget(
|
||||
labelText: patientAppointmentHistoryResponseModel.projectName.toString(),
|
||||
),
|
||||
AppCustomChipWidget(
|
||||
labelText: patientAppointmentHistoryResponseModel.clinicName.toString(),
|
||||
),
|
||||
Directionality(
|
||||
textDirection: ui.TextDirection.ltr,
|
||||
child: AppCustomChipWidget(
|
||||
labelPadding: EdgeInsetsDirectional.only(start: -8.w, end: 6.w),
|
||||
icon: AppAssets.ic_date_filter,
|
||||
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false),
|
||||
isEnglishOnly: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||