Compare commits
23 Commits
f7027c7ad5
...
89551b9fd7
| Author | SHA1 | Date | |
|---|---|---|---|
| 89551b9fd7 | |||
| 2b9d52b272 | |||
|
|
d82cac35f2 | ||
| 471ce430b0 | |||
|
|
4d3cc94071 | ||
|
|
ab09f01e82 | ||
| 0f72ecf6ad | |||
| 520c9b6e44 | |||
| 42543367a4 | |||
| b1ae31c7dd | |||
| b57523599c | |||
|
|
266fca3bf7 | ||
|
|
f9f34ff304 | ||
|
|
01e27a1c11 | ||
| 66c3b2fb9c | |||
| ec433190c4 | |||
| 240ab136fc | |||
|
|
4809c9a4fb | ||
|
|
3c32c54f45 | ||
|
|
03d9005c1b | ||
|
|
f9e124764f | ||
|
|
8fea8a95e4 | ||
|
|
a1e07ef7e9 |
@ -14,7 +14,7 @@ keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.cosqnet.telemednet"
|
||||
namespace = "com.cosqnet.medoraprovider"
|
||||
compileSdk = flutter.compileSdkVersion
|
||||
ndkVersion = "25.1.8937393"
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.cosqnet.telemednet;
|
||||
package com.cosqnet.medoraprovider;
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity;
|
||||
|
||||
@ -368,7 +368,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.telemednet;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.medoraprovider;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -384,7 +384,7 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.telemednet.RunnerTests;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.medoraprovider.RunnerTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
@ -401,7 +401,7 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.telemednet.RunnerTests;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.medoraprovider.RunnerTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
|
||||
@ -416,7 +416,7 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.telemednet.RunnerTests;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.medoraprovider.RunnerTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
|
||||
@ -547,7 +547,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.telemednet;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.medoraprovider;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
@ -569,7 +569,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.telemednet;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.medoraprovider;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
||||
96
lib/controllers/patient_controller.dart
Normal file
96
lib/controllers/patient_controller.dart
Normal file
@ -0,0 +1,96 @@
|
||||
import 'package:medora/data/models/patient.dart';
|
||||
import '../data/services/patient_registration_service.dart';
|
||||
|
||||
class PatientController {
|
||||
final PatientModel model = PatientModel();
|
||||
Map<String, String> validationErrors = {};
|
||||
|
||||
void clearValidationErrors() {
|
||||
validationErrors.clear();
|
||||
}
|
||||
|
||||
void updateName(String name) {
|
||||
model.name = name;
|
||||
}
|
||||
|
||||
void updatePhoneNumber(String phoneNumber) {
|
||||
model.phoneNumber = phoneNumber;
|
||||
}
|
||||
|
||||
void updateGender(String gender) {
|
||||
model.gender = gender;
|
||||
}
|
||||
|
||||
void updateDateOfBirth(DateTime dateOfBirth) {
|
||||
model.dateOfBirth = dateOfBirth;
|
||||
}
|
||||
|
||||
void updateProfileImage(String imagePath) {
|
||||
model.profileImagePath = imagePath;
|
||||
}
|
||||
|
||||
void updateHouseNo(String houseNo) {
|
||||
model.address.houseNo = houseNo;
|
||||
}
|
||||
|
||||
void updateLine(String line) {
|
||||
model.address.line = line;
|
||||
}
|
||||
|
||||
void updateTown(String town) {
|
||||
model.address.town = town;
|
||||
}
|
||||
|
||||
void updatePincode(String pincode) {
|
||||
model.address.pincode = pincode;
|
||||
}
|
||||
|
||||
void updateCountry(String country) {
|
||||
model.address.country = country;
|
||||
}
|
||||
|
||||
void updateState(String state) {
|
||||
model.address.state = state;
|
||||
}
|
||||
|
||||
void updateCity(String city) {
|
||||
model.address.city = city;
|
||||
}
|
||||
|
||||
void addFamilyMember(FamilyMember member) {
|
||||
model.familyMembers.add(member);
|
||||
}
|
||||
|
||||
void updateFamilyMember(int index, FamilyMember member) {
|
||||
if (index >= 0 && index < model.familyMembers.length) {
|
||||
model.familyMembers[index] = member;
|
||||
}
|
||||
}
|
||||
|
||||
void deleteFamilyMember(int index) {
|
||||
if (index >= 0 && index < model.familyMembers.length) {
|
||||
model.familyMembers.removeAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> savePatientData() async {
|
||||
return await PatientProfileService.savePatientProfile(this);
|
||||
}
|
||||
|
||||
Future<bool> loadPatientData() async {
|
||||
PatientModel? loadedModel = await PatientProfileService.getPatientProfile();
|
||||
if (loadedModel != null) {
|
||||
model.updateFrom(loadedModel);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Future<bool> updatePatientData() async {
|
||||
return await PatientProfileService.updatePatientProfile(model);
|
||||
}
|
||||
|
||||
Future<bool> deletePatientData() async {
|
||||
return await PatientProfileService.deletePatientProfile();
|
||||
}
|
||||
}
|
||||
126
lib/data/models/patient.dart
Normal file
126
lib/data/models/patient.dart
Normal file
@ -0,0 +1,126 @@
|
||||
class PatientModel {
|
||||
String? name;
|
||||
String? phoneNumber;
|
||||
String? gender;
|
||||
DateTime? dateOfBirth;
|
||||
String? profileImagePath;
|
||||
String? profileImageUrl;
|
||||
PatientAddress address;
|
||||
|
||||
List<FamilyMember> familyMembers = [];
|
||||
|
||||
PatientModel() : address = PatientAddress();
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'name': name,
|
||||
'phoneNumber': phoneNumber,
|
||||
'gender': gender,
|
||||
'dateOfBirth': dateOfBirth?.toIso8601String(),
|
||||
'profileImagePath': profileImagePath,
|
||||
'profileImageUrl': profileImageUrl,
|
||||
'address': address.toJson(),
|
||||
'familyMembers': familyMembers.map((member) => member.toJson()).toList(),
|
||||
};
|
||||
}
|
||||
|
||||
PatientModel.fromJson(Map<String, dynamic> json)
|
||||
: address = PatientAddress() {
|
||||
name = json['name'];
|
||||
phoneNumber = json['phoneNumber'];
|
||||
gender = json['gender'];
|
||||
dateOfBirth = json['dateOfBirth'] != null
|
||||
? DateTime.parse(json['dateOfBirth'])
|
||||
: null;
|
||||
profileImagePath = json['profileImagePath'];
|
||||
profileImageUrl = json['profileImageUrl'];
|
||||
if (json['address'] != null) {
|
||||
address =
|
||||
PatientAddress.fromJson(json['address'] as Map<String, dynamic>);
|
||||
}
|
||||
if (json['familyMembers'] != null) {
|
||||
familyMembers = (json['familyMembers'] as List)
|
||||
.map((memberJson) => FamilyMember.fromJson(memberJson))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
void updateFrom(PatientModel other) {
|
||||
name = other.name;
|
||||
phoneNumber = other.phoneNumber;
|
||||
gender = other.gender;
|
||||
dateOfBirth = other.dateOfBirth;
|
||||
profileImagePath = other.profileImagePath;
|
||||
profileImageUrl = other.profileImageUrl;
|
||||
address = other.address;
|
||||
familyMembers = other.familyMembers;
|
||||
}
|
||||
}
|
||||
|
||||
class FamilyMember {
|
||||
String? name;
|
||||
String? relation;
|
||||
String? gender;
|
||||
DateTime? dateOfBirth;
|
||||
|
||||
FamilyMember({this.name, this.relation, this.gender, this.dateOfBirth});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'name': name,
|
||||
'relation': relation,
|
||||
'gender': gender,
|
||||
'dateOfBirth': dateOfBirth?.toIso8601String(),
|
||||
};
|
||||
}
|
||||
|
||||
FamilyMember.fromJson(Map<String, dynamic> json) {
|
||||
name = json['name'];
|
||||
relation = json['relation'];
|
||||
gender = json['gender'];
|
||||
dateOfBirth = json['dateOfBirth'] != null
|
||||
? DateTime.parse(json['dateOfBirth'])
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
class PatientAddress {
|
||||
String? houseNo;
|
||||
String? line;
|
||||
String? town;
|
||||
String? pincode;
|
||||
String? country;
|
||||
String? state;
|
||||
String? city;
|
||||
|
||||
PatientAddress(
|
||||
{this.houseNo,
|
||||
this.line,
|
||||
this.town,
|
||||
this.pincode,
|
||||
this.country,
|
||||
this.state,
|
||||
this.city});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'houseNo': houseNo,
|
||||
'line': line,
|
||||
'town': town,
|
||||
'pincode': pincode,
|
||||
'country': country,
|
||||
'state': state,
|
||||
'city': city,
|
||||
};
|
||||
}
|
||||
|
||||
PatientAddress.fromJson(Map<String, dynamic> json) {
|
||||
houseNo = json['houseNo'];
|
||||
line = json['line'];
|
||||
town = json['town'];
|
||||
pincode = json['pincode'];
|
||||
country = json['country'];
|
||||
state = json['state'];
|
||||
city = json['city'];
|
||||
}
|
||||
}
|
||||
198
lib/data/services/patient_registration_service.dart
Normal file
198
lib/data/services/patient_registration_service.dart
Normal file
@ -0,0 +1,198 @@
|
||||
import 'dart:io';
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:firebase_storage/firebase_storage.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:medora/controllers/patient_controller.dart';
|
||||
import 'package:medora/data/models/patient.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
class PatientProfileService {
|
||||
static final String patientProfileCollectionName =
|
||||
dotenv.env['PATIENT_PROFILE_COLLECTION_NAME']!;
|
||||
static final FirebaseFirestore db = FirebaseFirestore.instance;
|
||||
static final FirebaseStorage storage = FirebaseStorage.instanceFor(
|
||||
bucket: dotenv.env['FIREBASE_STORAGE_BUCKET']!);
|
||||
|
||||
static Future<String?> uploadProfileImage(File imageFile) async {
|
||||
try {
|
||||
final User? user = FirebaseAuth.instance.currentUser;
|
||||
if (user == null) {
|
||||
print('No user logged in');
|
||||
return null;
|
||||
}
|
||||
final String uid = user.uid;
|
||||
final String fileName =
|
||||
'profile_${uid}_${DateTime.now().millisecondsSinceEpoch}${path.extension(imageFile.path)}';
|
||||
final Reference storageRef =
|
||||
storage.ref().child('profile_images/$fileName');
|
||||
final UploadTask uploadTask = storageRef.putFile(
|
||||
imageFile,
|
||||
SettableMetadata(
|
||||
contentType: 'image/${path.extension(imageFile.path).substring(1)}',
|
||||
customMetadata: {
|
||||
'userId': uid,
|
||||
'uploadedAt': DateTime.now().toIso8601String(),
|
||||
},
|
||||
),
|
||||
);
|
||||
final TaskSnapshot snapshot = await uploadTask;
|
||||
final String downloadUrl = await snapshot.ref.getDownloadURL();
|
||||
|
||||
print('Profile image uploaded successfully');
|
||||
return downloadUrl;
|
||||
} catch (e) {
|
||||
print('Error uploading profile image: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> deleteProfileImage(String imageUrl) async {
|
||||
try {
|
||||
final Reference storageRef = storage.refFromURL(imageUrl);
|
||||
await storageRef.delete();
|
||||
print('Profile image deleted successfully');
|
||||
return true;
|
||||
} catch (e) {
|
||||
print('Error deleting profile image: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> savePatientProfile(PatientController controller) async {
|
||||
try {
|
||||
final User? user = FirebaseAuth.instance.currentUser;
|
||||
if (user == null) {
|
||||
print('No user logged in');
|
||||
return false;
|
||||
}
|
||||
|
||||
final String uid = user.uid;
|
||||
final PatientModel patientData = controller.model;
|
||||
String? imageUrl;
|
||||
if (patientData.profileImagePath != null) {
|
||||
final File imageFile = File(patientData.profileImagePath!);
|
||||
imageUrl = await uploadProfileImage(imageFile);
|
||||
if (imageUrl == null) {
|
||||
print('Failed to upload profile image');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
final Map<String, dynamic> patientJson = patientData.toJson();
|
||||
patientJson['createdAt'] = FieldValue.serverTimestamp();
|
||||
patientJson['updatedAt'] = FieldValue.serverTimestamp();
|
||||
patientJson['uid'] = uid;
|
||||
patientJson['profileImageUrl'] = imageUrl;
|
||||
|
||||
await db
|
||||
.collection(patientProfileCollectionName)
|
||||
.doc(uid)
|
||||
.set(patientJson);
|
||||
|
||||
print('Patient profile saved successfully');
|
||||
return true;
|
||||
} catch (e) {
|
||||
print('Error saving patient profile: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> updatePatientProfile(PatientModel patient) async {
|
||||
try {
|
||||
final User? user = FirebaseAuth.instance.currentUser;
|
||||
if (user == null) {
|
||||
print('No user logged in');
|
||||
return false;
|
||||
}
|
||||
|
||||
final String uid = user.uid;
|
||||
String? imageUrl;
|
||||
if (patient.profileImagePath != null) {
|
||||
final DocumentSnapshot oldDoc =
|
||||
await db.collection(patientProfileCollectionName).doc(uid).get();
|
||||
if (oldDoc.exists) {
|
||||
final oldData = oldDoc.data() as Map<String, dynamic>;
|
||||
final String? oldImageUrl = oldData['profileImageUrl'];
|
||||
if (oldImageUrl != null) {
|
||||
await deleteProfileImage(oldImageUrl);
|
||||
}
|
||||
}
|
||||
final File imageFile = File(patient.profileImagePath!);
|
||||
imageUrl = await uploadProfileImage(imageFile);
|
||||
if (imageUrl == null) {
|
||||
print('Failed to upload new profile image');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
final Map<String, dynamic> patientJson = patient.toJson();
|
||||
patientJson['updatedAt'] = FieldValue.serverTimestamp();
|
||||
if (imageUrl != null) {
|
||||
patientJson['profileImageUrl'] = imageUrl;
|
||||
}
|
||||
|
||||
await db
|
||||
.collection(patientProfileCollectionName)
|
||||
.doc(uid)
|
||||
.update(patientJson);
|
||||
|
||||
print('Patient profile updated successfully');
|
||||
return true;
|
||||
} catch (e) {
|
||||
print('Error updating patient profile: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> deletePatientProfile() async {
|
||||
try {
|
||||
final User? user = FirebaseAuth.instance.currentUser;
|
||||
if (user == null) {
|
||||
print('No user logged in');
|
||||
return false;
|
||||
}
|
||||
|
||||
final String uid = user.uid;
|
||||
final DocumentSnapshot doc =
|
||||
await db.collection(patientProfileCollectionName).doc(uid).get();
|
||||
if (doc.exists) {
|
||||
final data = doc.data() as Map<String, dynamic>;
|
||||
final String? imageUrl = data['profileImageUrl'];
|
||||
if (imageUrl != null) {
|
||||
await deleteProfileImage(imageUrl);
|
||||
}
|
||||
}
|
||||
|
||||
await db.collection(patientProfileCollectionName).doc(uid).delete();
|
||||
|
||||
print('Patient profile deleted successfully');
|
||||
return true;
|
||||
} catch (e) {
|
||||
print('Error deleting patient profile: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<PatientModel?> getPatientProfile() async {
|
||||
try {
|
||||
final User? user = FirebaseAuth.instance.currentUser;
|
||||
if (user == null) {
|
||||
print('No user logged in');
|
||||
return null;
|
||||
}
|
||||
final String uid = user.uid;
|
||||
final DocumentSnapshot doc =
|
||||
await db.collection(patientProfileCollectionName).doc(uid).get();
|
||||
if (!doc.exists) {
|
||||
print('No patient profile found for this user');
|
||||
return null;
|
||||
}
|
||||
final data = doc.data() as Map<String, dynamic>;
|
||||
return PatientModel.fromJson(data);
|
||||
} catch (e) {
|
||||
print('Error fetching patient profile: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -85,5 +85,4 @@ class DefaultFirebaseOptions {
|
||||
storageBucket: 'cosq-telemednet-dev.appspot.com',
|
||||
measurementId: 'G-BBV9TFGNN5',
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ project(runner LANGUAGES CXX)
|
||||
set(BINARY_NAME "telemednet")
|
||||
# The unique GTK application identifier for this application. See:
|
||||
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
|
||||
set(APPLICATION_ID "com.cosqnet.telemednet")
|
||||
set(APPLICATION_ID "com.cosqnet.medoraprovider")
|
||||
|
||||
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
||||
# versions of CMake.
|
||||
|
||||
@ -385,7 +385,7 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.telemednet.RunnerTests;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.medoraprovider.RunnerTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/telemednet.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/telemednet";
|
||||
@ -399,7 +399,7 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.telemednet.RunnerTests;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.medoraprovider.RunnerTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/telemednet.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/telemednet";
|
||||
@ -413,7 +413,7 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.telemednet.RunnerTests;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.medoraprovider.RunnerTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/telemednet.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/telemednet";
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
PRODUCT_NAME = telemednet
|
||||
|
||||
// The application's bundle identifier
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.telemednet
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cosqnet.medoraprovider
|
||||
|
||||
// The copyright displayed in application information
|
||||
PRODUCT_COPYRIGHT = Copyright © 2024 com.cosqnet. All rights reserved.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user