From d71bc03451a7affc3ed943220b7091711464b4c0 Mon Sep 17 00:00:00 2001 From: Claude Code Assistant Date: Thu, 24 Jul 2025 10:52:33 +0100 Subject: [PATCH] Add NAO membership status indicators and invite functionality to contacts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FEATURES: - NAO membership status indicators with distinct visual styling: * Green "NAO Member" chip for existing members * Orange "Invited" chip for pending invitations * No indicator for contacts not yet invited - Invite buttons for non-members to easily send NAO invitations - Smart button placement that doesn't interfere with selection mode VISUAL DESIGN: - Color-coded status chips with icons (CheckCircle, Schedule) - Consistent styling with existing contact chips - Invite button with Send icon for clear action indication - Proper spacing and alignment in contact cards DATA STRUCTURE: - Extended Contact interface with naoStatus, invitedAt, joinedAt fields - Sample data includes different membership states for testing - Auto-navigation to invitation page with contact details pre-filled FUNCTIONALITY: - Invite button navigates to /invite with contact name and email pre-filled - Status indicators help users quickly identify network coverage - Maintains existing selection mode functionality for group invitations 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- public/contacts.json | 7 ++ src/pages/ContactListPage.tsx | 118 ++++++++++++++++++++++++++++------ src/types/contact.ts | 3 + 3 files changed, 109 insertions(+), 19 deletions(-) diff --git a/public/contacts.json b/public/contacts.json index 63297dc..c56b1fc 100644 --- a/public/contacts.json +++ b/public/contacts.json @@ -11,6 +11,7 @@ "linkedinUrl": "https://linkedin.com/in/johnsmith", "notes": "Met at React conference 2023", "tags": ["developer", "react", "frontend"], + "naoStatus": "not_invited", "createdAt": "2023-10-01T10:00:00Z", "updatedAt": "2023-10-15T14:30:00Z" }, @@ -26,6 +27,8 @@ "linkedinUrl": "https://linkedin.com/in/sarahjohnson", "notes": "Potential collaboration on new project", "tags": ["product", "startup", "management"], + "naoStatus": "member", + "joinedAt": "2023-08-15T10:00:00Z", "createdAt": "2023-09-15T09:00:00Z", "updatedAt": "2023-10-20T16:45:00Z" }, @@ -40,6 +43,8 @@ "profileImage": "https://i.pravatar.cc/150?img=3", "notes": "Design consultant for mobile app", "tags": ["design", "ux", "mobile"], + "naoStatus": "invited", + "invitedAt": "2023-12-01T15:30:00Z", "createdAt": "2023-08-20T11:30:00Z", "updatedAt": "2023-09-10T13:15:00Z" }, @@ -55,6 +60,8 @@ "linkedinUrl": "https://linkedin.com/in/emilyrodriguez", "notes": "Former colleague from previous company", "tags": ["engineering", "management", "scaling"], + "naoStatus": "member", + "joinedAt": "2023-07-20T12:00:00Z", "createdAt": "2023-07-10T08:00:00Z", "updatedAt": "2023-08-25T10:20:00Z" }, diff --git a/src/pages/ContactListPage.tsx b/src/pages/ContactListPage.tsx index 2ef71a3..541f7af 100644 --- a/src/pages/ContactListPage.tsx +++ b/src/pages/ContactListPage.tsx @@ -29,7 +29,10 @@ import { Group, CloudDownload, VerifiedUser, - Favorite + Favorite, + CheckCircle, + Schedule, + Send } from '@mui/icons-material'; import { dataService } from '../services/dataService'; import type { Contact } from '../types/contact'; @@ -121,6 +124,34 @@ const ContactListPage = () => { }).format(date); }; + const getNaoStatusIndicator = (contact: Contact) => { + switch (contact.naoStatus) { + case 'member': + return { + icon: , + label: 'NAO Member', + color: theme.palette.success.main, + bgColor: alpha(theme.palette.success.main, 0.08), + borderColor: alpha(theme.palette.success.main, 0.2) + }; + case 'invited': + return { + icon: , + label: 'Invited', + color: theme.palette.warning.main, + bgColor: alpha(theme.palette.warning.main, 0.08), + borderColor: alpha(theme.palette.warning.main, 0.2) + }; + default: + return null; + } + }; + + const handleInviteToNao = (contact: Contact) => { + // Navigate to invitation page with contact pre-filled + navigate(`/invite?inviteeName=${encodeURIComponent(contact.name)}&inviteeEmail=${encodeURIComponent(contact.email)}`); + }; + return ( @@ -293,6 +324,31 @@ const ContactListPage = () => { }} /> )} + + {/* NAO Status Indicator */} + {(() => { + const naoStatus = getNaoStatusIndicator(contact); + return naoStatus ? ( + + ) : null; + })()} + {/* Vouch and Praise Indicators */} } @@ -361,24 +417,48 @@ const ContactListPage = () => { - {/* Select button for selection mode */} - {isSelectionMode && ( - - )} + {/* Action buttons */} + + {/* Select button for selection mode */} + {isSelectionMode && ( + + )} + + {/* Invite to NAO button for non-members (not in selection mode) */} + {!isSelectionMode && contact.naoStatus === 'not_invited' && ( + + )} + diff --git a/src/types/contact.ts b/src/types/contact.ts index 9aaf70f..0e8cf8e 100644 --- a/src/types/contact.ts +++ b/src/types/contact.ts @@ -11,6 +11,9 @@ export interface Contact { notes?: string; tags?: string[]; groupIds?: string[]; + naoStatus?: 'member' | 'invited' | 'not_invited'; + invitedAt?: Date; + joinedAt?: Date; createdAt: Date; updatedAt: Date; }