// DEPLOY_CONFIG: {"triggers": [{"name": "remind_review_card_if_stale", "on": "collection.update", "collection": "cards", "actions": [{"type": "email", "to": "{{owner_email}}", "subject": "Reminder to review your card", "body": "This is a reminder to review your card because it has not been updated in 6 months."}]}]} import { useEffect, useMemo, useState } from 'react'; import { useAuth } from '@deplixo/sdk'; import { useCollection } from '@deplixo/sdk'; import { MedicalInfo } from './components/MedicalInfo.jsx'; import { EmergencyContacts } from './components/EmergencyContacts.jsx'; import { InsuranceInfo } from './components/InsuranceInfo.jsx'; import { CardView } from './components/CardView.jsx'; function App() { const { user, loading: authLoading, login, logout } = useAuth(); const { items: ownerCards, loading: cardLoading, add, update } = useCollection('emergency-card', { personal: true }); const { items: shareAccessItems, loading: shareLoading, add: addShareAccess, update: updateShareAccess, remove: removeShareAccess } = useCollection('emergency-card-share', { personal: true }); const [activeTab, setActiveTab] = useState('card'); const [shareName, setShareName] = useState(''); const [shareEmail, setShareEmail] = useState(''); const [shareRole, setShareRole] = useState('viewer'); const [shareNote, setShareNote] = useState(''); const [shareMessage, setShareMessage] = useState(''); const [shareError, setShareError] = useState(''); const tabs = [ { id: 'card', label: '🪪 Card', icon: '🪪' }, { id: 'medical', label: '🩺 Medical', icon: '🩺' }, { id: 'contacts', label: '📞 Contacts', icon: '📞' }, { id: 'insurance', label: '🏥 Insurance', icon: '🏥' }, ]; const ownerCard = useMemo(() => { if (!user) return null; return ownerCards?.find(card => card.ownerId === user.id) || null; }, [ownerCards, user]); const sharedAccess = useMemo(() => { if (!user) return []; return (shareAccessItems || []) .filter(item => item.ownerId === user.id) .sort((a, b) => new Date(b.createdAt || 0) - new Date(a.createdAt || 0)); }, [shareAccessItems, user]); useEffect(() => { if (user && activeTab === 'card' && !ownerCard && !cardLoading) { const seedCard = { ownerId: user.id, ownerName: user.name, ownerEmail: user.email, ownerAvatar: user.avatar, }; add(seedCard); } }, [add, activeTab, cardLoading, ownerCard, user]); const handleSignIn = async () => { if (login) { await login('google'); } }; const handleCreateShare = async (e) => { e.preventDefault(); setShareMessage(''); setShareError(''); if (!user || !ownerCard) { setShareError('Create your emergency card first before sharing it.'); return; } if (!shareEmail.trim()) { setShareError('Recipient email is required.'); return; } const inviteToken = `card_${Math.random().toString(36).slice(2, 10)}_${Date.now().toString(36)}`; const sharePayload = { ownerId: user.id, cardId: ownerCard.id || null, recipientName: shareName.trim(), recipientEmail: shareEmail.trim().toLowerCase(), role: shareRole, note: shareNote.trim(), status: 'pending', inviteToken, inviteLink: `${window.location.origin}${window.location.pathname}#share=${inviteToken}`, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; await addShareAccess(sharePayload); setShareName(''); setShareEmail(''); setShareRole('viewer'); setShareNote(''); setShareMessage('Invite created. Share the link or email it to your recipient.'); }; const handleSendInvite = async (shareItem) => { setShareMessage(''); setShareError(''); const updated = { ...shareItem, status: 'sent', updatedAt: new Date().toISOString(), }; await updateShareAccess(shareItem.id, updated); setShareMessage(`Invite marked as sent to ${shareItem.recipientEmail}.`); }; const handleCopyLink = async (link) => { try { await navigator.clipboard.writeText(link); setShareMessage('Share link copied to clipboard.'); setShareError(''); } catch { setShareError('Could not copy the link. Please copy it manually.'); } }; const handleRevoke = async (shareItem) => { setShareMessage(''); setShareError(''); await removeShareAccess(shareItem.id); setShareMessage(`Access revoked for ${shareItem.recipientEmail}.`); }; const handleToggleAccess = async (shareItem) => { setShareMessage(''); setShareError(''); const nextStatus = shareItem.status === 'revoked' ? 'sent' : 'revoked'; await updateShareAccess(shareItem.id, { ...shareItem, status: nextStatus, updatedAt: new Date().toISOString(), }); setShareMessage(nextStatus === 'revoked' ? 'Access paused.' : 'Access restored.'); }; if (authLoading) return
Signing in...
; if (!user) { return (
🆘

Emergency Card

Sign in with Google to securely access your private emergency card.

); } return (
🆘

Emergency Card

Your personal medical & emergency info

{activeTab === 'card' && (

Share access

{sharedAccess.length} shared

Invite a doctor, caregiver, or travel companion to view your emergency card. You can copy a private link or manage access anytime.

setShareName(e.target.value)} placeholder="Dr. Nguyen or Alex" />
setShareEmail(e.target.value)} placeholder="name@example.com" required />
setShareNote(e.target.value)} placeholder="Trip dates, appointment context, etc." />
{shareMessage &&
{shareMessage}
} {shareError &&
{shareError}
}

Shared access

{sharedAccess.length === 0 ? (
🔒

No shared access yet

Create an invite above to share your card with someone you trust.

) : (
{sharedAccess.map((item) => (
{item.recipientName || item.recipientEmail} {item.status}
{item.recipientEmail} {item.role} {item.note ? {item.note} : null}
{item.inviteLink}
))}
)}
)} {activeTab === 'medical' && } {activeTab === 'contacts' && } {activeTab === 'insurance' && }
); } export default App; ReactDOM.createRoot(document.getElementById('root')).render();