GrannyCare — AI-Powered Eldercare Companion

Inspiration

Elderly family members living alone face daily challenges: remembering medications, maintaining social connection, and getting help in emergencies. Existing solutions are either too complex (smartphone apps with tiny buttons) or too impersonal (basic pill reminders). GrannyCare was built to bridge the digital divide for seniors — a single-tap interface that feels familiar, not intimidating.

What it does

  • 1-Click Mood Check-Ins — "Feeling Good / Okay / Not Well" buttons logged to a personal health timeline
  • Medication Schedule & Tracking — View daily meds, mark as taken, see pending vs completed at a glance
  • SOS Emergency Alert — One big red button triggers alerts to family contacts with the user's location and status
  • Elderly Mode — Extra-large text, prominent buttons, simplified layout, pulsing SOS glow for users with visual/motor impairments
  • Health Insights Dashboard — Check-in history, missed medication alerts, adherence stats
  • Responsive Design — Works on phones, tablets, and laptops with fluid layout adaptation

How we built it

Stack: Jaclang 0.15.2, Vite dev server, CL/JSX frontend, in-memory graph database

Architecture: A single file (main.jac) containing:

Layer Components
Nodes UserProfile, MedicationNode, CheckInNode — graph entities with has fields
Walkers 12 walker:pub endpoints — CRUD for profile, medications, check-ins, contacts, SOS
Frontend Single to cl: def:pub app() with boolean-flag conditional view switching ({show_home and <View/>})
Styling CSS injected via document.createElement("style") — Stitch design tokens, single-line string

Views: 3 tab-based screens (Home, Health, Elderly) sharing a bottom navigation bar. State managed via has variables toggled by async def handler functions that call walkers via root spawn.

Challenges we ran into

Jaclang's CL/JSX parser has strict constraints that required workarounds:

  • No variable-assigned JSX — JSX cannot be stored in variables; all views must be inline in a single return statement
  • No if/return branching — Use {boolean_flag and <View/>} pattern instead
  • No else if — Jac uses Python-style elif
  • No Python ternaryx if cond else y doesn't work; use cond and x or y
  • No enumerate() in list comprehensionsfor x in list only, no tuple unpacking
  • style must be an objectstyle={{marginLeft: "8px"}}, not style="margin-left:8px"
  • new Date() syntax — Requires new(Date) which compiles to Reflect.construct(Date, [])
  • CSS must be single-line — Multi-line strings break the parser; inject via DOM API
  • Lambda handlers work in flat JSXonClick={lambda -> None { fn(); }} works in direct return JSX but not when nested in certain conditional patterns

Accomplishments that we're proud of

  • All 3 Stitch-matched screens compile and serve with zero errors
  • 12 pub walkers all respond correctly via the Jac API server
  • Responsive layout adapts from 480px phones to 960px desktop
  • SOS button with pulsing @keyframes sh glow animation
  • Full Material Symbols icon set integrated with font-variation-settings
  • Stitch design tokens faithfully reproduced: #06644a primary, Literata/Nunito Sans/Lora fonts, correct component spacing

What we learned

  • Jac CL/JSX is viable for single-file applications but has sharp edges — test compilation early and often
  • Boolean-flag conditional rendering ({flag and <View/>}) is a robust pattern that works despite parser limitations
  • CSS injection via DOM is the only reliable styling approach since the JSX parser cannot handle <style> tags
  • Reflect.construct vs direct new — Jac's portable constructor system handles this correctly when using new(Target) syntax
  • Cascade errors in the parser make debugging tricky: one syntax error at the top can produce 50+ misleading errors downstream

What's next for GrannyCare

  • Push notifications for missed medications via browser Notification API
  • Real-time clock in Elderly Mode with live setInterval updates
  • Family caregiver dashboard — separate view for family members to monitor check-ins and alerts
  • Voice assistant integration — "Hey GrannyCare, I took my aspirin" using Web Speech API
  • Pill camera refill detection — ML-powered image recognition to detect low pill bottles
  • Offline mode — Service worker caching for areas with unreliable connectivity
  • Multi-language support — Hindi, Tamil, Bengali, and other Indian languages

Built With

  • jac
Share this project:

Updates