You know what really gets me fired up? Healthcare apps that treat patients like data entry machines. I've watched too many people - friends, family members dealing with chronic pain - get completely overwhelmed by apps that demand everything upfront with zero consideration for what they're actually going through.
That's why I'm so passionate about what we're building with Pain Tracker. We're not just collecting pain scores; we're creating a safe space for people who've been let down by the medical system before.
The Foundation: Making Empathy the Default
Here's the thing that took me way too long to figure out - you can't just bolt empathy onto an existing app. It has to be baked into the foundation. So we built this trauma-informed provider that wraps our entire app, kind of like a warm blanket that adapts to what each person needs.
// This is where the magic happens - our trauma-informed context
export function TraumaInformedProvider({ children }: { children: ReactNode }) {
const [preferences, setPreferences] = useState(() => {
// We check secure storage first - nobody's trauma preferences should be sitting in plain text
const secure = secureStorage.get('trauma-informed-preferences', { encrypt: true });
if (secure) return { ...defaultPreferences, ...secure };
// Gentle migration from the old way we used to store this stuff
const legacy = localStorage.getItem('trauma-informed-preferences');
if (legacy) {
const parsed = JSON.parse(legacy);
secureStorage.set('trauma-informed-preferences', parsed, { encrypt: true });
return { ...defaultPreferences, ...parsed };
}
return defaultPreferences;
});
// This is huge - letting people control their own experience
const updatePreferences = (updates: Partial<TraumaInformedPreferences>) => {
const newPreferences = { ...preferences, ...updates };
setPreferences(newPreferences);
secureStorage.set('trauma-informed-preferences', newPreferences, { encrypt: true });
};
// CSS custom properties let us theme everything consistently
useEffect(() => {
const root = document.documentElement;
root.style.setProperty('--ti-font-size', getFontSizeValue(preferences.fontSize));
root.style.setProperty('--ti-touch-size', getTouchSizeValue(preferences.touchTargetSize));
document.body.classList.toggle('ti-simplified', preferences.simplifiedMode);
}, [preferences]);
return (
<TraumaInformedContext.Provider value={{ preferences, updatePreferences }}>
{children}
</TraumaInformedContext.Provider>
);
}
What I love about this approach is that we default to the gentlest settings possible. Larger text, bigger touch targets, simplified language - and then people can opt into more clinical terminology when they're ready. Because here's what I learned from talking to chronic pain patients: agency matters more than anything else. They've had enough experiences where choices were taken away from them.
Breaking Down Overwhelm, One Step at a Time
The 7-step pain assessment was honestly born out of frustration. I watched my mom struggle with fibromyalgia for years, and every doctor's form was this overwhelming wall of questions. So we broke it down into digestible pieces, with clear escape routes for when brain fog hits hard.
// Our step structure - designed around real human limits, not clinical efficiency
const steps = [
{ title: "How You're Feeling Right Now", level: 'essential', content: <PainLevelSection ... /> },
{ title: 'Daily Activities & Function', level: 'helpful', content: <FunctionalImpactSection ... /> },
{ title: 'Medications & Treatments', level: 'helpful', content: <MedicationSection ... /> },
{ title: 'Quality of Life Impact', level: 'helpful', content: <QualityOfLifeSection ... /> },
{ title: 'Work & Daily Life', level: 'advanced', content: <WorkImpactSection ... /> },
{ title: 'Additional Notes', level: 'advanced', content: <NotesSection ... /> },
{ title: 'Summary & Next Steps', level: 'advanced', content: <SummaryStep ... /> },
];
// Auto-save because losing progress is devastating when you're already in pain
useEffect(() => {
if (preferences.autoSave) {
const timer = setTimeout(() => {
secureStorage.set('pain-tracker-draft', formData, { encrypt: true });
}, 2000);
return () => clearTimeout(timer);
}
}, [formData, preferences.autoSave]);
That auto-save feature? Game changer. We learned the hard way that when someone's dealing with pain and they lose 20 minutes of careful data entry because their phone crashed... that's not just an inconvenience. That's trust broken, possibly for good.
Words Matter More Than You Think
This might sound dramatic, but I think microcopy can be the difference between someone getting help and giving up entirely. We've obsessed over every single piece of text in the app.
// These transformations might seem small, but they're everything
const languageTransformations = {
clinical: {
'pain level': "how you're feeling",
symptoms: "what you're experiencing",
compliance: 'your choices',
'failed treatment': "treatment that didn't work for you",
},
empowering: {
'you failed to': "this approach didn't work",
'you should': 'you might consider',
'you must': 'it could be helpful to',
},
};
const languagePreferences = [
{
id: 'gentle-nurturing',
label: 'Gentle & Nurturing',
description: 'Soft, comforting language that provides emotional safety',
example: '"Take your time. There\'s no rush, and whatever you\'re feeling is valid."',
category: 'tone',
},
];
See that switch from "you failed to" to "this approach didn't work"? That's intentional. Chronic pain patients have heard enough blame. Our job is to validate their experience, not add to the shame spiral.
Watching Out for Crisis Moments
This part keeps me up at night sometimes - in a good way. We built this quiet monitoring system that watches for signs someone might be struggling, without being invasive about it.
// Crisis detection that respects privacy while staying alert
const DEFAULT_CONFIG = {
enabled: true,
painThreshold: 7,
stressThreshold: 0.7,
autoActivateEmergencyMode: true
};
const calculateCognitiveLoad = useCallback(() => {
const recentErrors = errorEvents.current.filter(time => Date.now() - time.getTime() < 60000).length;
const recentHelp = helpRequests.current.filter(time => Date.now() - time.getTime() < 60000).length;
return Math.min(1, recentErrors * 0.2 + recentHelp * 0.3 + behaviorMetrics.current.timeSpentOnPage * 0.1);
}, []);
// When signals cross thresholds, we adapt gently
if (
autoActivate &&
(stress >= fullConfig.stressThreshold || pain >= fullConfig.painThreshold || cognitiveLoad >= fullConfig.cognitiveLoadThreshold)
) {
updatePreferences({ enableCrisisDetection: true });
setCrisisState({ ...crisisState, isInCrisis: true, severity: 'emergency', triggers });
}
Everything stays local - no data leaves the device without explicit consent. But when someone's pain scores spike or they're clicking for help repeatedly, we quietly shift into a more supportive mode. Crisis resources appear, the interface simplifies, the language gets even gentler.
Healthcare-Grade Reliability
The technical stuff matters too, especially when someone's in crisis and needs their data to sync immediately. We built this emergency sync system that cuts through normal queues when it really counts.
// Emergency sync - because some moments can't wait
async emergencySync(data: QueuePayload, endpoint: string): Promise<boolean> {
if (!this.isOnline) {
await this.queueForSync(endpoint, 'POST', data, 'high');
return false;
}
try {
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${secureStorage.get<string>('auth-token', { encrypt: true }) || ''}`,
},
body: JSON.stringify(data),
});
if (response.ok) return true;
await this.queueForSync(endpoint, 'POST', data, 'high');
return false;
} catch (error) {
await this.queueForSync(endpoint, 'POST', data, 'high');
return false;
}
}
I've spent countless hours making sure this works reliably. Because imagine being in severe pain, finally getting the courage to reach out for help through the app, and then... nothing happens because of some sync failure. That's not acceptable.
Why This Actually Matters
Look, I'll be honest - building this way is harder. It would be so much easier to just copy what everyone else does, slap together a standard health form, and call it done. But I keep thinking about all the people who've been failed by healthcare technology before.
We're seeing incredible results though. People stick around longer, they share more honest data, and most importantly - they feel heard. When you default to gentleness and give people real control over their experience, beautiful things happen.
If you're building anything for people dealing with chronic conditions, I'm begging you - start with empathy, not efficiency. Give people a way out of every interaction. Assume they're having a rough day and design accordingly.
And if you want to contribute to what we're doing with Pain Tracker, we'd love to have you. Bring your empathy into the codebase - we need more of that in healthcare tech.
Top comments (0)