Make empty/loading/error copy lawyer-friendly
From the PR description
Summary
Sweeps the frontend for generic empty, loading, and error strings and replaces them with action-oriented, lawyer-friendly copy that names the next step. Frontend-only; no backend changes.
Empty states
| Where | Before | After |
|---|---|---|
AppSidebar.tsx chats list |
"No chats yet" | "No chats yet. Ask Gary a question to start one." |
ProjectExplorer.tsx |
"No documents in this project." | "No documents in this project yet. Upload a PDF or Word document to start asking questions about it." |
FileDirectory.tsx default |
"No documents yet" | "No documents yet. Upload a PDF or Word document to get started." |
FileDirectory.tsx folder |
"Empty" | "No documents in this folder yet." |
AddDocumentsModal.tsx |
"No matches found" / "No documents yet" | "Nothing matched that search. Try a document title." / "No documents yet. Upload a PDF or Word document to start." |
AddProjectDocsModal.tsx |
"No matches found" / "No documents in this project" | similar action-oriented copy |
AddNewTRModal.tsx (project picker) |
"No projects found" | "No projects yet. Create one for each client, case, or matter." |
AddNewTRModal.tsx (docs) |
"No ready documents in this project" / "No documents yet" | upload-led copy |
AssistantWorkflowModal.tsx |
"No matches found" / "No assistant workflows found" | "Nothing matched that search." / "No drafting workflows yet." |
DisplayWorkflowModal.tsx (project picker) |
"No projects found" | "No projects yet." |
DisplayWorkflowModal.tsx (columns) |
"No columns defined" | "No columns yet. Add one to tell Gary what to extract from each document." |
DisplayWorkflowModal.tsx (docs) |
"No matches found" / "No documents yet" | upload-led copy |
ProjectPicker.tsx |
"No matches found" / "No projects yet" | "Nothing matched that search. Try a client name or project title." / "No projects yet. Create one for each client, case, or matter." |
ProjectsOverview.tsx (main) |
title "Projects" / generic blurb / "+ Create New" | title "No projects yet" / "Create a project for each client, case, or matter..." / "+ Create Project" |
tabular-reviews/page.tsx (main) |
title "Tabular Reviews" / "Extract data from documents into tables using AI." / "+ Create New" / "No reviews found" | title "No reviews yet" / lawyer-friendly description / "+ Create Review" / "Nothing matched that search or filter." |
WorkflowList.tsx (all 3 tabs) |
"Custom Workflows" / "Hidden Workflows" / "Workflows" plus generic blurbs | "No custom workflows yet" / "No hidden workflows" / "No workflows yet" with practitioner-style descriptions |
TRChatPanel.tsx chat list |
"No previous chats." / "No matches." | "No earlier chats yet." / "Nothing matched that search." |
ProjectPage.tsx drop zone |
"Drop PDF or DOCX files here" | "Drop a PDF or Word document here, or click to upload." |
NewProjectModal.tsx directory |
"No existing documents" | "No documents yet. Upload a PDF or Word document below to add one." |
Loading states
DocumentCard.tsx: "Processing..." → "Reading the document..."AddDocumentsModal.tsx,AddProjectDocsModal.tsx,AddNewTRModal.tsxupload buttons: "Uploading..." → "Uploading your document..."login/page.tsx: "Logging in..." → "Logging in..."signup/page.tsx: "Creating account..." → "Creating your account..."; "Redirecting you to the home page..." → "Taking you to Gary..."
Error states
error.tsx: now acceptsresetfrom Next, shows a Try Again primary CTA plus a Return Home secondary CTA. Body copy: "Gary hit an unexpected problem. Try again, or return home."global-error.tsx: Back button → Try Again wired toreset(). Body copy mirrors the above.not-found.tsx: CTA renamed Go home → Return Home, body softened.DocumentCard.tsx: "Upload failed" → "Upload failed - try again"TRChatPanel.tsxstreaming error: "An error occurred. Please try again." → "Something went wrong. Try asking again."NewProjectModal.tsx: "Failed to create project" → "Could not create the project. Try again."NewWorkflowModal.tsx: "Failed to update/create workflow" → "Could not save/create the workflow. Try again."useFetchSingleDoc.ts: "Failed to load document." → "Could not load the document. Try again."login/page.tsx: "An error occurred during login" → "Could not sign in. Check your email and password and try again."signup/page.tsx: "An error occurred during signup" → "Could not create your account. Try again."account/page.tsxalerts: "Failed to delete account / update display name / update organisation" → "Could not delete your account / save your display name / save your organisation. Try again."account/models/page.tsx:Failed to save ${label}.→Could not save your ${label}. Try again.
console.error lines and thrown internal errors (e.g. throw new Error("HTTP ..."), hook misuse messages) are unchanged - the developer view stays technical.
Technical surfaces remaining (reported, not changed)
Per the brief - "If not easy, leave them and report where they are":
/account/models- the page literally exposes Anthropic / Google API key inputs. Title "API Keys" and labels "Anthropic (Claude) API Key" / "Google (Gemini) API Key" remain. This is the existing settings/advanced area; renaming "API key" away would be misleading and would require renaming the sidebar/account tab too.ApiKeyMissingModal.tsx- title "API key required" and body "You haven't added a {provider} API key yet..." remain. The modal redirects to/account/models. Same reasoning.ModelTogglestill surfaces model names ("Claude Opus 4.7", "Gemini 3.1 Pro") insideChatViewand in/account/models. PR #6 already hid it from the home empty state.AppSidebarnav still labels "Tabular Review" and "Workflows" - feature names; left as-is to avoid renaming routes.text-search-widget.tsx"No results" - inline text-find-in-document message; left as-is, feels right in that micro-context.EmailPillInput.tsx"Could not verify email. Try again." - already lawyer-friendly.- Reasoning-block phrases ("Thinking...", "Pondering...", "Analyzing...", "Reasoning...") are kept; they're already approachable.
Files changed
Frontend only - 25 files, +93/-79. Zero backend files touched (git diff main..HEAD -- backend/ is empty). License unchanged.
Build / lint / tests
npm run lint- 107 problems vs. 108 onmain(one fewer; baseline issues all predate this PR; no new errors or warnings introduced in the changed files).npx tsc --noEmit- clean.npm run build- samefonts.googleapis.comsandbox network failure onmainand on this branch; not a code issue. Cloudflare Workers Builds will run a real build on the PR.- No test scripts in either
package.json.
Test plan
- Workers Build for this PR succeeds.
- Sign out and visit
/loginwith bad credentials - friendlier error appears. - Brand new account with no projects -
/projectsshows "No projects yet" with the new description and "+ Create Project" CTA. - Empty
/tabular-reviewsshows "No reviews yet" with the lawyer description and "+ Create Review". - On
/assistant, sidebar history shows "No chats yet. Ask Gary a question to start one." - Upload a small PDF - DocumentCard shows "Reading the document..." while it's processing.
- Open a project with no documents - drop zone says "Drop a PDF or Word document here, or click to upload."
- Visit a non-existent path like
/foo- not-found page shows "Return Home". - Trigger a render error - error boundary shows the new copy with Try Again + Return Home.
https://claude.ai/code/session_019pRkhcGDRKQWHjzAnV5yCL
Generated by Claude Code
Our analysis
Sweep frontend copy to lawyer-friendly empty, loading, and error states — read the full analysis →
Think the analysis missed something the PR description covers?
Commits in this PR (1)
| SHA | Subject | Author | Date | |
|---|---|---|---|---|
da89931b | Make empty/loading/error copy lawyer-friendly | Claude | 2026-05-07 | ↗ GitHub |
commit bodySweeps the frontend for generic empty, loading, and error strings
and replaces them with action-oriented, lawyer-friendly copy that
explains what to do next. Adds a Try Again CTA to the global error
boundary so users aren't stuck on a dead page.
Highlights:
- Empty states (sidebar, file directory, modals, list pages, project
detail) now name the next step (upload, create, ask, search by
client/title) instead of just stating the absence.
- "Processing..." on a freshly uploaded doc → "Reading the document..."
Upload buttons → "Uploading your document..."
- error.tsx and global-error.tsx now expose Next's reset() handler
via a Try Again button; copy says Gary hit a problem and offers a
return-home link.
- not-found.tsx CTA renamed Go home → Return Home.
- Login/signup error messages and progress labels rewritten
("Could not sign in. Check your email and password and try again.").
- Account/models alerts ("Failed to save X.") rewritten ("Could not
save your X. Try again.").
- Tabular review streaming error: "An error occurred. Please try
again." → "Something went wrong. Try asking again."
No backend changes, no behavior changes, no removed functionality.
Console/log/internal error details are unchanged.
https://claude.ai/code/session_019pRkhcGDRKQWHjzAnV5yCL
| ||||
Capture this PR into my fork
Download a Markdown prompt that tells Claude how to port every
commit in this PR into your working tree. Run it via
claude -p < capture-pull-7.md from
inside the repo you want the changes in.