feat(directory): refactor contact card layout for improved readability and interaction
This commit is contained in:
parent
e7940941ed
commit
606c5e5971
@ -303,6 +303,7 @@ class DirectoryMainScreen extends StatelessWidget {
|
||||
final firstName = nameParts.first;
|
||||
final lastName = nameParts.length > 1 ? nameParts.last : "";
|
||||
final tags = contact.tags.map((tag) => tag.name).toList();
|
||||
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Get.to(() => ContactDetailScreen(contact: contact));
|
||||
@ -310,63 +311,56 @@ class DirectoryMainScreen extends StatelessWidget {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12.0, vertical: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Leading Icon
|
||||
Avatar(
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
size: 45,
|
||||
),
|
||||
MySpacing.width(12),
|
||||
// Top Row: Avatar, Info, Icons
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Avatar
|
||||
Avatar(
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
size: 35),
|
||||
MySpacing.width(12),
|
||||
|
||||
// Middle Content
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
MyText.titleSmall(
|
||||
contact.name,
|
||||
fontWeight: 600,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
MyText.bodySmall(
|
||||
contact.organization,
|
||||
color: Colors.grey[700],
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
MySpacing.height(6),
|
||||
|
||||
// Launcher Row
|
||||
Column(
|
||||
// Middle: Contact Info (wrap with Flexible instead of Expanded)
|
||||
Flexible(
|
||||
fit: FlexFit.tight,
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
MyText.titleSmall(contact.name,
|
||||
fontWeight: 600,
|
||||
overflow: TextOverflow.ellipsis),
|
||||
MyText.bodySmall(contact.organization,
|
||||
color: Colors.grey[700],
|
||||
overflow: TextOverflow.ellipsis),
|
||||
MySpacing.height(6),
|
||||
|
||||
// Emails
|
||||
...contact.contactEmails.map((e) =>
|
||||
GestureDetector(
|
||||
onTap: () =>
|
||||
LauncherUtils.launchEmail(
|
||||
e.emailAddress),
|
||||
onLongPress: () =>
|
||||
LauncherUtils.copyToClipboard(
|
||||
e.emailAddress,
|
||||
typeLabel: 'Email'),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 4),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 4),
|
||||
child: GestureDetector(
|
||||
onTap: () =>
|
||||
LauncherUtils.launchEmail(
|
||||
e.emailAddress),
|
||||
onLongPress: () =>
|
||||
LauncherUtils.copyToClipboard(
|
||||
e.emailAddress,
|
||||
typeLabel: 'Email'),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.email_outlined,
|
||||
size: 16,
|
||||
color: Colors.indigo),
|
||||
MySpacing.width(4),
|
||||
ConstrainedBox(
|
||||
constraints:
|
||||
const BoxConstraints(
|
||||
maxWidth: 180),
|
||||
Flexible(
|
||||
child: MyText.labelSmall(
|
||||
e.emailAddress,
|
||||
overflow:
|
||||
@ -380,30 +374,29 @@ class DirectoryMainScreen extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
)),
|
||||
|
||||
// Phones
|
||||
...contact.contactPhones.map((p) =>
|
||||
GestureDetector(
|
||||
onTap: () =>
|
||||
LauncherUtils.launchPhone(
|
||||
p.phoneNumber),
|
||||
onLongPress: () =>
|
||||
LauncherUtils.copyToClipboard(
|
||||
p.phoneNumber,
|
||||
typeLabel: 'Phone number'),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 4),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 4),
|
||||
child: GestureDetector(
|
||||
onTap: () =>
|
||||
LauncherUtils.launchPhone(
|
||||
p.phoneNumber),
|
||||
onLongPress: () =>
|
||||
LauncherUtils.copyToClipboard(
|
||||
p.phoneNumber,
|
||||
typeLabel:
|
||||
'Phone number'),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.phone_outlined,
|
||||
size: 16,
|
||||
color: Colors.indigo),
|
||||
MySpacing.width(4),
|
||||
ConstrainedBox(
|
||||
constraints:
|
||||
const BoxConstraints(
|
||||
maxWidth: 160),
|
||||
Flexible(
|
||||
child: MyText.labelSmall(
|
||||
p.phoneNumber,
|
||||
overflow:
|
||||
@ -419,38 +412,62 @@ class DirectoryMainScreen extends StatelessWidget {
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
if (tags.isNotEmpty) ...[
|
||||
MySpacing.height(4),
|
||||
MyText.labelSmall(
|
||||
tags.join(', '),
|
||||
color: Colors.grey[500],
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
// Right: Arrow + WhatsApp
|
||||
MySpacing.width(
|
||||
8), // spacing between content and right column
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
const Icon(Icons.arrow_forward_ios,
|
||||
color: Colors.grey, size: 16),
|
||||
MySpacing.height(12),
|
||||
if (phone != '-')
|
||||
GestureDetector(
|
||||
onTap: () =>
|
||||
LauncherUtils.launchWhatsApp(phone),
|
||||
child: const FaIcon(
|
||||
FontAwesomeIcons.whatsapp,
|
||||
color: Colors.green,
|
||||
size: 20),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
// WhatsApp launcher icon
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.arrow_forward_ios,
|
||||
color: Colors.grey, size: 16),
|
||||
MySpacing.height(12),
|
||||
if (phone != '-')
|
||||
GestureDetector(
|
||||
onTap: () =>
|
||||
LauncherUtils.launchWhatsApp(phone),
|
||||
child: const FaIcon(
|
||||
FontAwesomeIcons.whatsapp,
|
||||
color: Colors.green,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// Bottom Row: Tags as chips aligned to right
|
||||
if (tags.isNotEmpty) ...[
|
||||
MySpacing.height(5),
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 6,
|
||||
alignment: WrapAlignment.end,
|
||||
children: tags
|
||||
.map(
|
||||
(tag) => Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10, vertical: 5),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.indigo.shade50,
|
||||
borderRadius:
|
||||
BorderRadius.circular(8),
|
||||
),
|
||||
child: MyText.labelSmall(
|
||||
tag,
|
||||
fontWeight: 600,
|
||||
color: Colors.indigo,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
|
Loading…
x
Reference in New Issue
Block a user