A complete frontend-only web application for churches to generate seating arrangements and mass reading schedules automatically — with fairness, flexibility, and easy manual editing.
- Overview
- Tech Stack
- Project Structure
- Getting Started
- Module 1 — Refectory Seating
- Module 2 — Mass Reading
- Import / Export
- Data Persistence
- Keyboard Shortcuts
- File Format Reference
Arrangement Manager contains two independent modules:
| Module | Purpose |
|---|---|
| Refectory Seating | Assigns community members to tables, grouped strictly by gender, with overflow handling |
| Mass Reading | Generates fair rotating reading schedules for liturgical celebrations |
Both modules support:
- Manual member entry
- JSON and Excel import
- Excel and PDF export
- Shuffle button
- Undo / Redo (50-step history)
- Manual editing via searchable dropdowns
- 14-day, 30-day, or custom duration
| Layer | Technology |
|---|---|
| Framework | React 18 + TypeScript |
| Build tool | Vite 5 |
| UI library | Material UI v6 |
| Routing | React Router v6 |
| State management | Zustand 5 (localStorage persistence) |
| Form validation | React Hook Form + Zod |
| Animations | Framer Motion |
| Excel | xlsx (SheetJS) |
| jsPDF + jspdf-autotable | |
| Dropdowns | React Select |
| Notifications | React Toastify |
src/
├── components/
│ ├── common/ # Shared UI atoms
│ │ ├── ConfirmDialog.tsx
│ │ ├── EmptyState.tsx
│ │ ├── LoadingSkeleton.tsx
│ │ ├── PageHeader.tsx
│ │ ├── SearchableSelect.tsx
│ │ └── StatCard.tsx
│ └── layout/
│ └── AppShell.tsx # Sidebar + topbar shell
├── pages/
│ ├── Dashboard.tsx
│ ├── ImportExport.tsx
│ ├── Settings.tsx
│ ├── seating/
│ │ ├── SeatingPage.tsx
│ │ └── components/
│ │ ├── ArrangementView.tsx
│ │ ├── CreateLayoutDialog.tsx
│ │ ├── MemberManager.tsx
│ │ └── TableCard.tsx
│ └── reading/
│ ├── ReadingPage.tsx
│ └── components/
│ ├── CreateScheduleDialog.tsx
│ ├── ReadingMemberManager.tsx
│ └── ScheduleView.tsx
├── store/
│ ├── seatingStore.ts # Zustand store — Module 1
│ ├── readingStore.ts # Zustand store — Module 2
│ └── settingsStore.ts # App-wide settings
├── theme/
│ └── muiTheme.ts # MUI theme (purple palette)
├── types/
│ └── index.ts # All TypeScript interfaces
├── utils/
│ ├── exportUtils.ts # Excel + PDF export/import helpers
│ ├── helpers.ts # UUID, dates, shuffle utilities
│ ├── readingAlgorithm.ts
│ └── seatingAlgorithm.ts
├── styles/
│ └── global.css
├── App.tsx
└── main.tsx
- Node.js 18+
- npm 9+
cd arrangement-manager
npm install
npm run devOpen http://localhost:5173 in your browser.
npm run build
npm run preview- Go to Refectory Seating in the sidebar
- Click New Layout
- Configure:
- Layout title
- Number of tables
- Chairs per table
- Members per table
- Duration (14 days / 30 days / custom)
- Starting gender (Male / Female / Random)
- Manual: Type name, select gender, press Add or Enter
- JSON import:
[{ "name": "James", "gender": "Male" }] - Excel import: Columns
name,gender
Click Generate — the algorithm will:
- Split members into Male and Female pools
- Shuffle each pool randomly
- Fill tables one gender at a time (no mixed-gender tables)
- Create a Table 0 (Overflow) if members exceed total chair count
- Set expiry date based on the configured duration
- Only one gender per table — no exceptions
- The configured starting gender fills tables first; the other gender follows
- If 80 chairs exist for 83 members → 3 overflow members go to Table 0
- After the duration expires, use Shuffle to reshuffle
Each seat row has a searchable dropdown listing all eligible members. Selecting a member in a new seat automatically clears them from their previous seat — no duplicate assignments.
| Action | Button |
|---|---|
| Re-randomise arrangement | Shuffle (⟳) |
| Undo last change | Undo (↩) — 50 steps |
| Redo undone change | Redo (↪) |
- Go to Mass Reading in the sidebar
- Click New Schedule
- Configure title, start date, and duration
- No gender required
- Manual entry, JSON (
[{ "name": "…" }]), or Excel (namecolumn)
Click Generate — the algorithm will:
- Build three circular rotation queues (one per role)
- Assign First Reading and Responsorial Psalm every day
- Assign Second Reading only on Sundays — left blank on weekdays
- Ensure everyone receives at least one assignment before repetition
- Prevent the same member from holding two roles on the same day
The schedule grid shows every day as a row. Each role column has a searchable dropdown for reassignment.
| Module | Excel | |
|---|---|---|
| Seating arrangement | ✓ | ✓ |
| Reading schedule | ✓ | ✓ |
| Module | Excel | JSON |
|---|---|---|
| Seating members | ✓ | ✓ |
| Reading members | ✓ | ✓ |
Use the Import / Export page for bulk operations across any saved layout or schedule.
All data is stored in browser localStorage — no backend, no server, no authentication.
| localStorage key | Contents |
|---|---|
am-seating |
All seating layouts + members + arrangements |
am-reading |
All reading schedules + members + days |
am-settings |
Application settings |
Note: Clearing browser data will erase all arrangements. Export to Excel/PDF for a permanent record.
| name | gender |
|---|---|
| James | Male |
| Monica | Female |
| name |
|---|
| James |
| Monica |
[
{ "name": "James", "gender": "Male" },
{ "name": "Monica", "gender": "Female" }
][
{ "name": "James" },
{ "name": "Monica" }
]| Shortcut | Action |
|---|---|
Enter in name field |
Add member |
| Dropdown search | Type to filter members |
Arrangement Manager v1.0 — Frontend only, no backend required.