Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ dist-ssr
*.njsproj
*.sln
*.sw?
.claude
71 changes: 71 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# binding-sim-edu — Claude Code Guidelines

An educational web app for exploring molecular binding simulations, built for the Allen Institute for Cell Science. Runs interactive binding simulations via the Simularium viewer, guides students through experiments, and displays analysis results (concentration plots, equilibrium graphs).

---

## Quick Reference

```
binding-sim-edu/
├── CLAUDE.md <- this file
├── CONTEXT_ORGANIZATION.md <- context/state architecture docs
├── src/
│ ├── components/ <- UI components
│ ├── hooks/ <- React hooks (incl. useSimulationContext.ts)
│ ├── simulation/ <- simulation engine logic
│ ├── constants/ <- app constants
│ ├── content/ <- module content / copy
│ ├── types/ <- shared TypeScript types
│ └── utils/ <- pure utility functions
└── .claude/skills/ <- Claude Code skills
```

---

## State Architecture

Context is split into three providers — see `CONTEXT_ORGANIZATION.md` for full details:

- **SimulariumUiContext** — page, module, section, viewport type, quiz, progression, completed modules
- **SimulariumSimulationContext** — playback, controller, trajectory, concentrations, agents, handlers
- **SimulariumAnalysisContext** — recorded concentrations, analysis reset

Always import via the typed hooks, not `useContext` directly:
```tsx
import { useSimulariumUi, useSimulariumSimulation, useSimulariumAnalysis } from "../hooks/useSimulationContext";
```

---

## Build Commands

| What | Command |
| ---------- | ------------------- |
| Dev server | `bun run dev` |
| Build | `bun run build` |
| Lint | `bun run lint` |
| Type check | `bunx tsc --noEmit` |

---

## Code Standards

### General
- Prefer editing existing files over creating new ones
- No speculative abstractions — build for what's needed now
- No commented-out code
- No `console.log` / debug prints left in production code
- Destructured keys in alphabetical order (imports, params, props)

### TypeScript / React
- All public APIs must have explicit types
- Prefer `interface` over `type` for object shapes
- No `any` — use `unknown` + narrowing if type is genuinely unknown
- Components own their props types — don't scatter them into shared types files
- Custom hooks for shared stateful logic, plain functions for shared pure logic
- Co-locate component, styles, and tests in the same directory

### Import order
External libs → internal aliases → relative imports, each group alphabetical.

80 changes: 80 additions & 0 deletions docs/CONTEXT_ORGANIZATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Context Organization
Comment thread
meganrm marked this conversation as resolved.

The app context has been organized into three separate contexts for better separation of concerns and easier state management.

## Contexts

### SimulariumUiContext
Contains UI-related state:
- `page`, `setPage` - Current page number
- `module`, `setModule` - Current module
- `progressionElement` - Current progression element for hints
- `quizQuestion` - Current quiz question
- `section` - Current section
- `viewportType`, `setViewportType` - Lab vs Simulation view
- `completedModules`, `addCompletedModule` - Track module completion
- `resetAllState()` - Reset all application state
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Odd that this lives in a specific branch if it resets them all but I guess it has to go somewhere


### SimulariumSimulationContext
Contains simulation-related state:
- `isPlaying`, `setIsPlaying` - Playback state
- `simulariumController` - Viewer controller
- `trajectoryName` - Current trajectory
- `timeFactor`, `timeUnit` - Time settings
- `viewportSize`, `setViewportSize` - Viewer dimensions
- `productName`, `adjustableAgentName` - Agent info
- `currentProductionConcentration`, `fixedAgentStartingConcentration`, `maxConcentration` - Concentration values
- `getAgentColor()` - Color mapping
- `handleMixAgents()`, `handleStartExperiment()`, `handleTimeChange()`, `handleTrajectoryChange()` - Handlers

### SimulariumAnalysisContext
Contains analysis and recorded data:
- `recordedConcentrations` - User-recorded concentration values
- `resetAnalysisState()` - Clear recorded data without resetting UI

## Usage

### Using the Hooks

Import the hooks instead of using `useContext` directly:

```tsx
import {
useSimulariumUi,
useSimulariumSimulation,
useSimulariumAnalysis,
} from "../hooks/useSimulationContext";

const MyComponent = () => {
const { page, setPage } = useSimulariumUi();
const { isPlaying, setIsPlaying } = useSimulariumSimulation();
const { recordedConcentrations } = useSimulariumAnalysis();

// Use the values...
};
```

### Using the Reset Button

A `ResetButton` component is available for resetting state:

```tsx
import ResetButton from "../shared/ResetButton";

// Reset all state (UI + simulation + analysis)
<ResetButton resetAll />

// Reset only analysis data
<ResetButton />

// Custom label
<ResetButton resetAll>Start Over</ResetButton>
```

## Benefits

1. **Clearer separation of concerns** - UI, simulation, and analysis state are separate
2. **Easier to reset** - Individual contexts can be reset without affecting others
3. **Better performance** - Components only re-render when their specific context changes
4. **Type safety** - Each context has its own strongly-typed interface
5. **Cleaner imports** - Use hooks instead of context + useContext everywhere
Loading
Loading