Skip to content

ai-partner: home screen card component #1466

@CraigBuckmaster

Description

@CraigBuckmaster

Parent epic: #1446 (Amicus — AI Study Partner v1)
Phase: 4 · Size: S · Depends on: #1465 (daily prompt), #1467 (deep link)

The "Amicus noticed..." card on the home screen. Renders the daily proactive prompt with a tap-to-open action, an "Ask Amicus anything..." input field, and an upgrade CTA for non-premium users.


Files to create

  • app/src/components/AmicusHomeCard.tsx — the card component
  • app/src/components/__tests__/AmicusHomeCard.test.tsx

Files to modify

  • app/src/screens/HomeScreen.tsx — insert <AmicusHomeCard /> in the layout (see placement below)

Placement in HomeScreen

Current HomeScreen layout (per file header):

  1. Greeting row (text + streak)
  2. ContinueReadingHero (full-width image hero)
  3. Verse of the Day
  4. ActivePlanCard compact row (if active plan)
  5. "From your study" image carousel
  6. ProgressRow collapsible

Insert AmicusHomeCard between 4 and 5 (after plan, before carousel). Amicus feels natural alongside the "what to do next" section. Verify placement with Craig at implementation time if it feels off.


Premium path (card content)

Visual

  • Full-width card, radii.lg corners, base.bgElevated background
  • Gold left border (4px, base.gold)
  • Small MessageSquare icon in top-left (gold, 16px)
  • Header (Cinzel): "Amicus noticed..." (semibold, base.gold)
  • Body (EB Garamond, body-size): the prompt_text from daily prompt (ai-partner: daily proactive prompt generation job #1465)
  • Tappable input row at bottom: "Ask Amicus anything..." placeholder in textMuted

Interactions

  • Tap anywhere on the prompt body → navigate to Amicus tab + seed a new thread with seed_query (handed off to ai-partner: deep link into Partner tab with context #1467)
  • Tap the input row → navigate to Amicus tab + open NewThread with empty state (user types in the tab)
  • Long-press the card → dismiss it for today ("Not now" action)

Loading

  • If getDailyPrompt() returns null (first launch, offline with no cache), render a fallback card:
    • Header: "Meet Amicus"
    • Body: "Your scholarly study companion is ready for questions."
    • Tappable input row as above

Non-premium path

Same visual but:

  • Header: "Unlock Amicus"
  • Body: "Your AI study companion, grounded in 72 scholars. Included with Companion+."
  • Bottom CTA button: "See plans →" → navigates to SubscriptionScreen
  • Input row hidden

Hook usage

const { prompt, isLoading } = useDailyPrompt();  // from #1465
const access = useAmicusAccess();                 // from #1460

Conventions to follow

  • Card styling: match existing cards (ActivePlanCard, ContinueReadingHero) for visual consistency
  • Theme tokens only; no hardcoded colors
  • Skeleton/loading treatment: match existing LoadingSkeleton component
  • Strict TS; no any; logger for actions (e.g., "home card tapped")

Acceptance criteria

  • Card renders in correct position in HomeScreen
  • Premium + prompt: renders prompt_text; tap navigates to Amicus tab with seed_query
  • Premium + no prompt (null from ai-partner: daily proactive prompt generation job #1465): renders fallback with "ready for questions" copy
  • Non-premium: renders "Unlock Amicus" variant with Plans CTA
  • Input row navigates to new-thread flow
  • Long-press dismiss for today (persists to user.db with today's date; card hidden until tomorrow)
  • Card respects amicus_enabled preference (hidden when disabled)
  • Component tests cover all three variants + dismiss action
  • No any types; lint clean

Out of scope

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions