Skip to content

Fix emergency button: open support dialog with partner selection, coping activities, meditation suggestion, and journal prompt#51

Merged
JustinhSE merged 2 commits intomainfrom
copilot/fix-emergency-button-functionality
Feb 25, 2026
Merged

Fix emergency button: open support dialog with partner selection, coping activities, meditation suggestion, and journal prompt#51
JustinhSE merged 2 commits intomainfrom
copilot/fix-emergency-button-functionality

Conversation

Copy link
Contributor

Copilot AI commented Feb 25, 2026

The emergency button was silently notifying all accountability partners with no user feedback, no control over who gets notified, and no in-app support resources.

Changes

src/components/PanicButton.tsx

Replaced the fire-and-forget click handler with a modal dialog containing:

  • Coping activities — 10 actionable strategies (breathing, cold water, delay technique, affirmations, etc.) to interrupt cravings immediately
  • Suggested meditation — randomly selects one available (non-coming-soon) audio meditation on each open; links to /meditations
  • Journal prompt — targeted reflection prompt with link to /journal
  • Partner selection — lists accountability partners with checkboxes (all pre-selected); notifies only selected partners; disables after send to prevent duplicates

src/utils/firebase.ts

  • Added optional partnerIds?: string[] to notifyAccountabilityPartners() — filters notification targets when provided, falls back to all partners (backward-compatible)
  • Fixed pre-existing syntax error in updateCalendarDay (missing return false + closing brace) that was breaking the production build
// Before: notified everyone, no filter
notifyAccountabilityPartners(uid, 'emergency', message)

// After: notifies only selected partners
notifyAccountabilityPartners(uid, 'emergency', message, selectedPartnerIds)

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

…ities, meditation suggestion, and journal prompt

Co-authored-by: JustinhSE <84724234+JustinhSE@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix emergency button to enable partner notification and suggestions Fix emergency button: open support dialog with partner selection, coping activities, meditation suggestion, and journal prompt Feb 25, 2026
@JustinhSE JustinhSE requested a review from Copilot February 25, 2026 23:37
@JustinhSE JustinhSE marked this pull request as ready for review February 25, 2026 23:40
@JustinhSE JustinhSE merged commit f17f8d5 into main Feb 25, 2026
4 of 5 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR transforms the emergency button from a silent fire-and-forget notification system into a comprehensive support dialog. When users click the emergency button, they now see a modal with immediate coping strategies (breathing exercises, physical activities, affirmations), a randomly suggested meditation, a journal prompt, and the ability to selectively notify accountability partners. The changes improve user agency and provide in-app resources during moments of crisis.

Changes:

  • Added interactive dialog with coping activities, meditation suggestions, journal prompt, and selective partner notification
  • Enhanced notifyAccountabilityPartners function to support filtering notifications to specific partners
  • Fixed syntax error in updateCalendarDay function (missing return statement and closing brace)

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 7 comments.

File Description
src/components/PanicButton.tsx Replaced simple notification trigger with comprehensive support dialog containing coping strategies, meditation/journal suggestions, and partner selection UI
src/utils/firebase.ts Added optional partnerIds parameter to notifyAccountabilityPartners for selective notification; fixed syntax error in updateCalendarDay
package-lock.json Dependency metadata changes from npm version/configuration differences; no actual version updates

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

const [selectedPartners, setSelectedPartners] = useState<string[]>([]);
const [notifying, setNotifying] = useState(false);
const [notified, setNotified] = useState(false);
const [suggestedMeditation, setSuggestedMeditation] = useState(AVAILABLE_MEDITATIONS[0]);
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initial state for suggestedMeditation uses AVAILABLE_MEDITATIONS[0], but this value is immediately replaced when the dialog opens in handleOpen(). Consider initializing with a lazy function or using null/undefined with proper type handling to avoid unnecessary initial state that will never be used.

Copilot uses AI. Check for mistakes.
Comment on lines +75 to 91
const handleNotify = async () => {
if (!currentUser) return;
setNotifying(true);
try {
await notifyAccountabilityPartners(
currentUser.uid,
'emergency',
'has pressed the emergency button and needs support'
'has pressed the emergency button and needs support',
selectedPartners
);

// Call the provided callback function
setNotified(true);
if (onEmergencyClick) onEmergencyClick();
toast.error('Emergency support triggered!');
} else {
toast.error('You must be logged in to use this feature.');
toast.success('Your selected partners have been notified!');
} finally {
setNotifying(false);
}
};
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The handleNotify function doesn't handle the case where selectedPartners is empty. While the button is disabled when selectedPartners.length === 0 (line 239), defensive programming would check this condition at the start of handleNotify and return early to prevent unnecessary Firebase calls if the button state is somehow bypassed.

Copilot uses AI. Check for mistakes.
toast.error('Emergency support triggered!');
} else {
toast.error('You must be logged in to use this feature.');
toast.success('Your selected partners have been notified!');
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling in handleNotify only uses a finally block to reset the notifying state but doesn't catch errors. If notifyAccountabilityPartners fails, the user sees no error feedback and the notified state remains false, allowing repeated attempts. Add a try-catch block to show an error toast when notification fails.

Suggested change
toast.success('Your selected partners have been notified!');
toast.success('Your selected partners have been notified!');
} catch (error) {
console.error('Failed to notify accountability partners:', error);
toast.error('Failed to notify your accountability partners. Please try again.');

Copilot uses AI. Check for mistakes.
Comment on lines +206 to +224
<label
key={partner.id}
className="flex items-center gap-3 p-2 rounded-md hover:bg-muted/50 cursor-pointer"
>
<Checkbox
checked={selectedPartners.includes(partner.id)}
onCheckedChange={() => togglePartner(partner.id)}
disabled={notified}
/>
<Avatar className="h-7 w-7">
<AvatarFallback className="text-xs">{getInitials(partner)}</AvatarFallback>
</Avatar>
<span className="text-sm">
{partner.firstName} {partner.lastName}
{partner.username && (
<span className="text-muted-foreground ml-1">@{partner.username}</span>
)}
</span>
</label>
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checkbox labels use onClick on the label element but don't have proper ARIA attributes. While clicking the label works due to the htmlFor association, keyboard users navigating with screen readers would benefit from role="checkbox" being explicitly set or ensuring the Checkbox component handles this. Verify that the shadcn/ui Checkbox component properly handles keyboard navigation and screen reader announcements.

Copilot uses AI. Check for mistakes.
<ul className="space-y-1">
{COPING_ACTIVITIES.map((activity, i) => (
<li
key={i}
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The coping activities list uses array index as the key (line 124: key={i}), which is acceptable here since the list is static and never reordered. However, if these activities were to become dynamic or user-customizable in the future, using index as key could cause React rendering issues. Consider using a more stable identifier or the activity text itself as the key for better future-proofing.

Suggested change
key={i}
key={activity}

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +27

const AVAILABLE_MEDITATIONS = [
{ id: '1', title: 'Urge Surfing', description: 'Learn to ride the wave of desire without giving in', duration: 10 },
{ id: '2', title: 'Morning Clarity', description: 'Start your day with purpose and clear intentions', duration: 5 },
{ id: '3', title: 'Body Scan For Relaxation', description: 'Release tension and find deep relaxation', duration: 15 },
{ id: '6', title: 'Before Sleep Relaxation', description: 'Calm your mind and body with this soothing practice', duration: 10 },
];
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meditation list in PanicButton is hardcoded and duplicates data from Meditations.tsx. This creates a maintenance issue where changes to meditation metadata (title, description, duration) in one location won't be reflected in the other. Consider importing MEDITATIONS_DATA from a shared location, or at minimum filtering only non-comingSoon meditations from the main source to ensure consistency.

Suggested change
const AVAILABLE_MEDITATIONS = [
{ id: '1', title: 'Urge Surfing', description: 'Learn to ride the wave of desire without giving in', duration: 10 },
{ id: '2', title: 'Morning Clarity', description: 'Start your day with purpose and clear intentions', duration: 5 },
{ id: '3', title: 'Body Scan For Relaxation', description: 'Release tension and find deep relaxation', duration: 15 },
{ id: '6', title: 'Before Sleep Relaxation', description: 'Calm your mind and body with this soothing practice', duration: 10 },
];
import { MEDITATIONS_DATA } from './Meditations';
const AVAILABLE_MEDITATIONS = MEDITATIONS_DATA.filter(
(meditation) => !meditation.comingSoon
);

Copilot uses AI. Check for mistakes.
Comment on lines +56 to +67
const handleOpen = () => {
if (!currentUser) {
toast.error('You must be logged in to use this feature.');
return;
}
setSelectedPartners(accountabilityPartners.map((p) => p.id));
setNotified(false);
setSuggestedMeditation(
AVAILABLE_MEDITATIONS[Math.floor(Math.random() * AVAILABLE_MEDITATIONS.length)]
);
setOpen(true);
};
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When no accountability partners exist, the dialog shows coping activities and meditation suggestions but hides the notification button. However, if partners are added while the dialog is open, those partners won't be auto-selected since selectedPartners is only initialized in handleOpen(). Consider adding a useEffect to sync selectedPartners when accountabilityPartners changes, or documenting that users must close and reopen the dialog to notify newly added partners.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants