marco.pms.mobileapp/lib/helpers/widgets/team_members_bottom_sheet.dart

214 lines
5.9 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/helpers/widgets/avatar.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/model/directory/contact_bucket_list_model.dart';
import 'package:marco/helpers/utils/base_bottom_sheet.dart';
class TeamMembersBottomSheet {
static void show(
BuildContext context,
ContactBucket bucket,
List<dynamic> members, {
bool canEdit = false,
VoidCallback? onEdit,
}) {
final ownerId = bucket.createdBy.id;
// Ensure owner is listed first
members.sort((a, b) {
if (a.id == ownerId) return -1;
if (b.id == ownerId) return 1;
return 0;
});
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (_) {
return BaseBottomSheet(
title: 'Bucket Details',
onCancel: () => Navigator.pop(context),
onSubmit: () {}, // Not used, but required
showButtons: false,
child: _TeamContent(
bucket: bucket,
members: members,
canEdit: canEdit,
onEdit: onEdit,
ownerId: ownerId,
),
);
},
);
}
}
class _TeamContent extends StatelessWidget {
final ContactBucket bucket;
final List<dynamic> members;
final bool canEdit;
final VoidCallback? onEdit;
final String ownerId;
const _TeamContent({
required this.bucket,
required this.members,
required this.canEdit,
this.onEdit,
required this.ownerId,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
_buildHeader(),
_buildInfo(),
_buildMembersTitle(),
MySpacing.height(8),
SizedBox(
height: 300,
child: _buildMemberList(),
),
],
);
}
Widget _buildHeader() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Row(
children: [
Expanded(
child: MyText.titleMedium(bucket.name, fontWeight: 700),
),
if (canEdit)
IconButton(
onPressed: onEdit,
icon: const Icon(Icons.edit, color: Colors.red),
tooltip: 'Edit Bucket',
),
],
),
);
}
Widget _buildInfo() {
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (bucket.description.isNotEmpty)
Padding(
padding: const EdgeInsets.only(bottom: 6),
child: MyText.bodySmall(
bucket.description,
color: Colors.grey[700],
),
),
Row(
children: [
const Icon(Icons.contacts_outlined, size: 14, color: Colors.grey),
const SizedBox(width: 4),
MyText.labelSmall(
'${bucket.numberOfContacts} contact(s)',
fontWeight: 600,
color: Colors.red,
),
const SizedBox(width: 12),
const Icon(Icons.ios_share_outlined, size: 14, color: Colors.grey),
const SizedBox(width: 4),
MyText.labelSmall(
'Shared with (${members.length})',
fontWeight: 600,
color: Colors.indigo,
),
],
),
MySpacing.height(8),
Row(
children: [
const Icon(Icons.edit_outlined, size: 14, color: Colors.grey),
const SizedBox(width: 4),
MyText.labelSmall(
canEdit ? 'Can be edited by you' : 'You dont have edit access',
fontWeight: 600,
color: canEdit ? Colors.green : Colors.grey,
),
],
),
MySpacing.height(12),
const Divider(thickness: 1),
],
),
);
}
Widget _buildMembersTitle() {
return Align(
alignment: Alignment.centerLeft,
child: MyText.labelLarge('Shared with', fontWeight: 700, color: Colors.black),
);
}
Widget _buildMemberList() {
if (members.isEmpty) {
return Center(
child: MyText.bodySmall(
"No team members found.",
fontWeight: 600,
color: Colors.grey,
),
);
}
return ListView.separated(
itemCount: members.length,
separatorBuilder: (_, __) => const SizedBox(height: 6),
itemBuilder: (context, index) {
final member = members[index];
final firstName = member.firstName ?? '';
final lastName = member.lastName ?? '';
final isOwner = member.id == ownerId;
return ListTile(
dense: true,
contentPadding: EdgeInsets.zero,
leading: Avatar(firstName: firstName, lastName: lastName, size: 32),
title: Row(
children: [
Expanded(
child: MyText.bodyMedium(
'${firstName.isNotEmpty ? firstName : 'Unnamed'} ${lastName.isNotEmpty ? lastName : ''}',
fontWeight: 600,
),
),
if (isOwner)
Container(
margin: const EdgeInsets.only(left: 6),
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: Colors.red.shade50,
borderRadius: BorderRadius.circular(4),
),
child: MyText.labelSmall(
"Owner",
fontWeight: 600,
color: Colors.red,
),
),
],
),
subtitle: MyText.bodySmall(
member.jobRole ?? '',
color: Colors.grey.shade600,
),
);
},
);
}
}