172 lines
4.7 KiB
Markdown
172 lines
4.7 KiB
Markdown
# Upload Inline Panel Swap Implementation Plan
|
|
|
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
|
|
**Goal:** Reorder the embedded sections inside the upload card so subtitle defaults render above the upload dropzone while preserving current upload, mode, language, and trim behavior.
|
|
|
|
**Architecture:** Keep the existing three-card top row and embedded subtitle-defaults approach. Add a focused regression test that locks the internal order of the upload card, then minimally reorder the JSX in `src/components/UploadScreen.tsx` and keep existing interaction tests green.
|
|
|
|
**Tech Stack:** React 19, TypeScript, Tailwind CSS v4 utilities, Vitest, React Testing Library
|
|
|
|
---
|
|
|
|
### Task 1: Lock the new internal order with a failing test
|
|
|
|
**Files:**
|
|
- Modify: `src/components/UploadScreen.test.tsx`
|
|
- Reference: `src/components/UploadScreen.tsx`
|
|
|
|
**Step 1: Write the failing test**
|
|
|
|
Add a structure test that checks the subtitle defaults panel appears before the upload surface inside the upload card:
|
|
|
|
```tsx
|
|
it('renders subtitle defaults before the upload surface inside the upload card', () => {
|
|
renderUploadScreen();
|
|
|
|
const uploadCard = screen.getByTestId('upload-dropzone-card');
|
|
const subtitlePanel = screen.getByTestId('upload-subtitle-defaults-panel');
|
|
const uploadSurface = screen.getByTestId('upload-dropzone-surface');
|
|
|
|
expect(uploadCard).toContainElement(subtitlePanel);
|
|
expect(uploadCard).toContainElement(uploadSurface);
|
|
expect(
|
|
subtitlePanel.compareDocumentPosition(uploadSurface) & Node.DOCUMENT_POSITION_FOLLOWING,
|
|
).toBeTruthy();
|
|
});
|
|
```
|
|
|
|
**Step 2: Run test to verify it fails**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx
|
|
```
|
|
|
|
Expected: FAIL because the upload surface currently renders before the subtitle defaults panel and does not yet expose the new marker.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
Add the missing test id for the upload surface and reorder the upload-card sections.
|
|
|
|
**Step 4: Run test to verify it passes**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx
|
|
```
|
|
|
|
Expected: PASS for the new order assertion.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git add src/components/UploadScreen.tsx src/components/UploadScreen.test.tsx
|
|
git commit -m "test: lock upload card panel order"
|
|
```
|
|
|
|
### Task 2: Reorder the upload card sections
|
|
|
|
**Files:**
|
|
- Modify: `src/components/UploadScreen.tsx`
|
|
- Modify: `src/components/UploadScreen.test.tsx`
|
|
|
|
**Step 1: Write the failing test**
|
|
|
|
If needed, add one more focused regression test to protect the upload input location:
|
|
|
|
```tsx
|
|
it('keeps the upload interaction inside the lower upload section after the swap', () => {
|
|
renderUploadScreen();
|
|
|
|
expect(screen.getByTestId('upload-dropzone-surface')).toContainElement(
|
|
screen.getByLabelText(/upload video file/i),
|
|
);
|
|
});
|
|
```
|
|
|
|
**Step 2: Run test to verify it fails**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx
|
|
```
|
|
|
|
Expected: FAIL until the new structure is in place.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
Refactor `src/components/UploadScreen.tsx` to:
|
|
|
|
- move the embedded subtitle defaults block above the upload dropzone block
|
|
- keep the heading and description at the top of the card
|
|
- keep support text and the mode chip associated with the upload section
|
|
- preserve all existing handlers and controls
|
|
|
|
**Step 4: Run test to verify it passes**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx
|
|
```
|
|
|
|
Expected: PASS for the structure tests and existing interaction tests.
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git add src/components/UploadScreen.tsx src/components/UploadScreen.test.tsx
|
|
git commit -m "feat: swap upload card panel order"
|
|
```
|
|
|
|
### Task 3: Full verification
|
|
|
|
**Files:**
|
|
- Modify: `src/components/UploadScreen.tsx`
|
|
- Modify: `src/components/UploadScreen.test.tsx`
|
|
|
|
**Step 1: Write the failing test**
|
|
|
|
If a regression appears during final polish, add the smallest possible test first.
|
|
|
|
**Step 2: Run test to verify it fails**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
node ./node_modules/vitest/vitest.mjs run src/components/UploadScreen.test.tsx src/App.test.tsx
|
|
```
|
|
|
|
Expected: FAIL only if a real regression remains.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
Apply only the final layout tweaks needed to restore parity.
|
|
|
|
**Step 4: Run test to verify it passes**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
npm.cmd test
|
|
npm.cmd run lint
|
|
npm.cmd run build
|
|
```
|
|
|
|
Expected:
|
|
|
|
- all tests PASS
|
|
- lint PASS
|
|
- build PASS
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git add src/components/UploadScreen.tsx src/components/UploadScreen.test.tsx docs/plans/2026-03-21-upload-inline-panel-swap-design.md docs/plans/2026-03-21-upload-inline-panel-swap.md
|
|
git commit -m "test: verify swapped upload card layout"
|
|
```
|