resolved directory data update issues

This commit is contained in:
Vaibhav Surve 2025-07-17 17:50:13 +05:30
parent 990bf737dc
commit 4908db35ad
4 changed files with 71 additions and 45 deletions

View File

@ -3,6 +3,7 @@ import 'package:marco/helpers/services/api_service.dart';
import 'package:marco/helpers/services/app_logger.dart'; import 'package:marco/helpers/services/app_logger.dart';
import 'package:marco/helpers/widgets/my_snackbar.dart'; import 'package:marco/helpers/widgets/my_snackbar.dart';
import 'package:marco/controller/directory/directory_controller.dart'; import 'package:marco/controller/directory/directory_controller.dart';
import 'package:marco/controller/directory/notes_controller.dart';
class AddCommentController extends GetxController { class AddCommentController extends GetxController {
final String contactId; final String contactId;
@ -39,6 +40,10 @@ class AddCommentController extends GetxController {
final directoryController = Get.find<DirectoryController>(); final directoryController = Get.find<DirectoryController>();
await directoryController.fetchCommentsForContact(contactId); await directoryController.fetchCommentsForContact(contactId);
final notesController = Get.find<NotesController>();
await notesController.fetchNotes(
pageSize: 1000, pageNumber: 1); // Fixed here
Get.back(result: true); Get.back(result: true);
showAppSnackbar( showAppSnackbar(
@ -46,13 +51,6 @@ class AddCommentController extends GetxController {
message: "Your comment has been successfully added.", message: "Your comment has been successfully added.",
type: SnackbarType.success, type: SnackbarType.success,
); );
} else {
logSafe("Comment submission failed", level: LogLevel.error);
showAppSnackbar(
title: "Submission Failed",
message: "Unable to add the comment. Please try again later.",
type: SnackbarType.error,
);
} }
} catch (e) { } catch (e) {
logSafe("Error while submitting comment: $e", level: LogLevel.error); logSafe("Error while submitting comment: $e", level: LogLevel.error);

View File

@ -11,7 +11,8 @@ import 'package:marco/helpers/widgets/my_snackbar.dart';
class EditBucketBottomSheet { class EditBucketBottomSheet {
static void show(BuildContext context, ContactBucket bucket, static void show(BuildContext context, ContactBucket bucket,
List<EmployeeModel> allEmployees) { List<EmployeeModel> allEmployees,
{required String ownerId}) {
final ManageBucketController controller = Get.find(); final ManageBucketController controller = Get.find();
final nameController = TextEditingController(text: bucket.name); final nameController = TextEditingController(text: bucket.name);
@ -192,13 +193,15 @@ class EditBucketBottomSheet {
controlAffinity: controlAffinity:
ListTileControlAffinity.leading, ListTileControlAffinity.leading,
value: selectedIds.contains(emp.id), value: selectedIds.contains(emp.id),
onChanged: (val) { onChanged: emp.id == ownerId
if (val == true) { ? null
selectedIds.add(emp.id); : (val) {
} else { if (val == true) {
selectedIds.remove(emp.id); selectedIds.add(emp.id);
} } else {
}, selectedIds.remove(emp.id);
}
},
title: Text( title: Text(
fullName.isNotEmpty ? fullName : 'Unnamed', fullName.isNotEmpty ? fullName : 'Unnamed',
style: const TextStyle(fontSize: 13), style: const TextStyle(fontSize: 13),

View File

@ -77,18 +77,17 @@ String _convertDeltaToHtml(dynamic delta) {
class _ContactDetailScreenState extends State<ContactDetailScreen> { class _ContactDetailScreenState extends State<ContactDetailScreen> {
late final DirectoryController directoryController; late final DirectoryController directoryController;
late final ProjectController projectController; late final ProjectController projectController;
late ContactModel contact;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
directoryController = Get.find<DirectoryController>(); directoryController = Get.find<DirectoryController>();
projectController = Get.find<ProjectController>(); projectController = Get.find<ProjectController>();
contact = widget.contact;
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
if (!directoryController.contactCommentsMap directoryController.fetchCommentsForContact(contact.id);
.containsKey(widget.contact.id)) {
directoryController.fetchCommentsForContact(widget.contact.id);
}
}); });
} }
@ -133,7 +132,8 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
IconButton( IconButton(
icon: const Icon(Icons.arrow_back_ios_new, icon: const Icon(Icons.arrow_back_ios_new,
color: Colors.black, size: 20), color: Colors.black, size: 20),
onPressed: () => Get.back(), onPressed: () =>
Get.offAllNamed('/dashboard/directory-main-page'),
), ),
MySpacing.width(8), MySpacing.width(8),
Expanded( Expanded(
@ -184,9 +184,9 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
Row( Row(
children: [ children: [
Avatar( Avatar(
firstName: widget.contact.name.split(" ").first, firstName: contact.name.split(" ").first,
lastName: widget.contact.name.split(" ").length > 1 lastName: contact.name.split(" ").length > 1
? widget.contact.name.split(" ").last ? contact.name.split(" ").last
: "", : "",
size: 35, size: 35,
backgroundColor: Colors.indigo, backgroundColor: Colors.indigo,
@ -195,10 +195,10 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
MyText.titleSmall(widget.contact.name, MyText.titleSmall(contact.name,
fontWeight: 600, color: Colors.black), fontWeight: 600, color: Colors.black),
MySpacing.height(2), MySpacing.height(2),
MyText.bodySmall(widget.contact.organization, MyText.bodySmall(contact.organization,
fontWeight: 500, color: Colors.grey[700]), fontWeight: 500, color: Colors.grey[700]),
], ],
), ),
@ -226,24 +226,24 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
} }
Widget _buildDetailsTab() { Widget _buildDetailsTab() {
final email = widget.contact.contactEmails.isNotEmpty final email = contact.contactEmails.isNotEmpty
? widget.contact.contactEmails.first.emailAddress ? contact.contactEmails.first.emailAddress
: "-"; : "-";
final phone = widget.contact.contactPhones.isNotEmpty final phone = contact.contactPhones.isNotEmpty
? widget.contact.contactPhones.first.phoneNumber ? contact.contactPhones.first.phoneNumber
: "-"; : "-";
final tags = widget.contact.tags.map((e) => e.name).join(", "); final tags = contact.tags.map((e) => e.name).join(", ");
final bucketNames = widget.contact.bucketIds final bucketNames = contact.bucketIds
.map((id) => directoryController.contactBuckets .map((id) => directoryController.contactBuckets
.firstWhereOrNull((b) => b.id == id) .firstWhereOrNull((b) => b.id == id)
?.name) ?.name)
.whereType<String>() .whereType<String>()
.join(", "); .join(", ");
final projectNames = widget.contact.projectIds final projectNames = contact.projectIds
?.map((id) => projectController.projects ?.map((id) => projectController.projects
.firstWhereOrNull((p) => p.id == id) .firstWhereOrNull((p) => p.id == id)
?.name) ?.name)
@ -251,7 +251,7 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
.join(", ") ?? .join(", ") ??
"-"; "-";
final category = widget.contact.contactCategory?.name ?? "-"; final category = contact.contactCategory?.name ?? "-";
return Stack( return Stack(
children: [ children: [
@ -270,12 +270,11 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
onTap: () => LauncherUtils.launchPhone(phone), onTap: () => LauncherUtils.launchPhone(phone),
onLongPress: () => LauncherUtils.copyToClipboard(phone, onLongPress: () => LauncherUtils.copyToClipboard(phone,
typeLabel: "Phone")), typeLabel: "Phone")),
_iconInfoRow( _iconInfoRow(Icons.location_on, "Address", contact.address),
Icons.location_on, "Address", widget.contact.address),
]), ]),
_infoCard("Organization", [ _infoCard("Organization", [
_iconInfoRow(Icons.business, "Organization", _iconInfoRow(
widget.contact.organization), Icons.business, "Organization", contact.organization),
_iconInfoRow(Icons.category, "Category", category), _iconInfoRow(Icons.category, "Category", category),
]), ]),
_infoCard("Meta Info", [ _infoCard("Meta Info", [
@ -289,7 +288,7 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
Align( Align(
alignment: Alignment.topLeft, alignment: Alignment.topLeft,
child: MyText.bodyMedium( child: MyText.bodyMedium(
widget.contact.description, contact.description,
color: Colors.grey[800], color: Colors.grey[800],
maxLines: 10, maxLines: 10,
textAlign: TextAlign.left, textAlign: TextAlign.left,
@ -304,12 +303,25 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
right: 20, right: 20,
child: FloatingActionButton.extended( child: FloatingActionButton.extended(
backgroundColor: Colors.red, backgroundColor: Colors.red,
onPressed: () { onPressed: () async {
Get.bottomSheet( final result = await Get.bottomSheet(
AddContactBottomSheet(existingContact: widget.contact), AddContactBottomSheet(existingContact: contact),
isScrollControlled: true, isScrollControlled: true,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
); );
if (result == true) {
await directoryController.fetchContacts();
final updated =
directoryController.allContacts.firstWhereOrNull(
(c) => c.id == contact.id,
);
if (updated != null) {
setState(() {
contact = updated;
});
}
}
}, },
icon: const Icon(Icons.edit, color: Colors.white), icon: const Icon(Icons.edit, color: Colors.white),
label: const Text( label: const Text(
@ -324,7 +336,7 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
Widget _buildCommentsTab(BuildContext context) { Widget _buildCommentsTab(BuildContext context) {
return Obx(() { return Obx(() {
final contactId = widget.contact.id; final contactId = contact.id;
if (!directoryController.contactCommentsMap.containsKey(contactId)) { if (!directoryController.contactCommentsMap.containsKey(contactId)) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
@ -447,8 +459,15 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
final htmlOutput = _convertDeltaToHtml(delta); final htmlOutput = _convertDeltaToHtml(delta);
final updated = final updated =
comment.copyWith(note: htmlOutput); comment.copyWith(note: htmlOutput);
await directoryController await directoryController
.updateComment(updated); .updateComment(updated);
// Re-fetch comments to get updated list
await directoryController
.fetchCommentsForContact(contactId);
// Exit editing mode
directoryController.editingCommentId.value = directoryController.editingCommentId.value =
null; null;
}, },
@ -479,11 +498,16 @@ class _ContactDetailScreenState extends State<ContactDetailScreen> {
right: 20, right: 20,
child: FloatingActionButton.extended( child: FloatingActionButton.extended(
backgroundColor: Colors.red, backgroundColor: Colors.red,
onPressed: () { onPressed: () async {
Get.bottomSheet( final result = await Get.bottomSheet(
AddCommentBottomSheet(contactId: contactId), AddCommentBottomSheet(contactId: contactId),
isScrollControlled: true, isScrollControlled: true,
); );
if (result == true) {
await directoryController
.fetchCommentsForContact(contactId);
}
}, },
icon: const Icon(Icons.add_comment, color: Colors.white), icon: const Icon(Icons.add_comment, color: Colors.white),
label: const Text( label: const Text(

View File

@ -194,7 +194,8 @@ class _ManageBucketsScreenState extends State<ManageBucketsScreen> {
Future.delayed(const Duration(milliseconds: 300), Future.delayed(const Duration(milliseconds: 300),
() { () {
EditBucketBottomSheet.show(context, bucket, EditBucketBottomSheet.show(context, bucket,
manageBucketController.allEmployees); manageBucketController.allEmployees,
ownerId: bucket.createdBy.id);
}); });
}, },
); );