# Upload Workbench Redesign Implementation Plan > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** Rebuild the upload page into a responsive workbench layout that keeps the settings panel fully accessible while preserving the current upload, trim, subtitle-default, and TTS selection behavior. **Architecture:** Keep the existing upload-page workflow and state model, but replace the rigid centered flex layout with a top-aligned page shell and responsive grid. Most of the work lives in `src/components/UploadScreen.tsx`, with a smaller shell adjustment in `src/App.tsx` and assertion updates in the upload-page tests. The implementation should stay behavior-compatible and lean on CSS/Tailwind layout changes instead of introducing new product state. **Tech Stack:** React 19, TypeScript, Vite, Tailwind CSS v4 utilities, Lucide React icons, Vitest, React Testing Library --- ### Task 1: Lock the redesigned upload-page structure with failing tests **Files:** - Modify: `src/App.test.tsx` - Modify: `src/components/UploadScreen.test.tsx` - Reference: `src/App.tsx` - Reference: `src/components/UploadScreen.tsx` **Step 1: Write the failing test** Add assertions that describe the redesigned shell and card structure before implementation: ```tsx it('shows the upload workbench header and keeps the language switcher visible', () => { render(); expect(screen.getByText('Video Translate')).toBeInTheDocument(); expect( screen.getByText('Upload a source video, tune subtitle defaults, and choose dubbing settings before generation.'), ).toBeInTheDocument(); expect(screen.getByLabelText('switch-ui-language-zh')).toBeInTheDocument(); expect(screen.getByLabelText('switch-ui-language-en')).toBeInTheDocument(); }); it('renders upload, mode, subtitle defaults, and language cards inside the responsive workbench', () => { renderUploadScreen(); expect(screen.getByTestId('upload-workbench')).toBeInTheDocument(); expect(screen.getByTestId('upload-dropzone-card')).toBeInTheDocument(); expect(screen.getByTestId('upload-settings-column')).toBeInTheDocument(); expect(screen.getByRole('heading', { name: 'Mode & Workflow' })).toBeInTheDocument(); expect(screen.getByRole('heading', { name: 'Subtitle Defaults' })).toBeInTheDocument(); expect(screen.getByRole('heading', { name: 'Language & Dubbing' })).toBeInTheDocument(); }); ``` **Step 2: Run test to verify it fails** Run: ```bash node ./node_modules/vitest/vitest.mjs run src/App.test.tsx src/components/UploadScreen.test.tsx ``` Expected: FAIL because the new header copy, section headings, and test ids do not exist yet. **Step 3: Write minimal implementation** Do not redesign everything yet. Add only the smallest missing semantic hooks and copy needed to satisfy the new tests: - app-shell heading and intro copy in `src/App.tsx` - stable `data-testid` markers and section headings in `src/components/UploadScreen.tsx` Use copy aligned with the approved design: ```tsx

Video Translate

{m.upload.workbenchTitle}

{m.upload.workbenchDescription}

``` **Step 4: Run test to verify it passes** Run: ```bash node ./node_modules/vitest/vitest.mjs run src/App.test.tsx src/components/UploadScreen.test.tsx ``` Expected: PASS for the new structure assertions, with no unrelated failures in those files. **Step 5: Commit** ```bash git add src/App.test.tsx src/components/UploadScreen.test.tsx src/App.tsx src/components/UploadScreen.tsx src/i18n.tsx git commit -m "test: lock upload workbench shell structure" ``` ### Task 2: Rebuild the page shell and header layout **Files:** - Modify: `src/App.tsx` - Modify: `src/i18n.tsx` - Test: `src/App.test.tsx` **Step 1: Write the failing test** Extend the app test to assert the header content is grouped into a page shell and remains bilingual: ```tsx expect(screen.getByRole('banner')).toBeInTheDocument(); expect(screen.getByRole('heading', { name: 'Upload & prepare' })).toBeInTheDocument(); expect(screen.getByText('Keep subtitle defaults visible and avoid clipped settings panels.')).toBeInTheDocument(); ``` **Step 2: Run test to verify it fails** Run: ```bash node ./node_modules/vitest/vitest.mjs run src/App.test.tsx ``` Expected: FAIL because the new banner structure and localized hero text are not present yet. **Step 3: Write minimal implementation** Update `src/App.tsx` and `src/i18n.tsx` to: - wrap the upload page in a proper shell with `min-h-screen` - add a responsive header above the view content - move the language switcher into the header - add localized upload-page title and description strings for both Chinese and English Implementation sketch: ```tsx

{m.app.productName}

{m.upload.workbenchTitle}

{m.upload.workbenchDescription}

{languageSwitcher}
{currentView === 'upload' ? : }
``` **Step 4: Run test to verify it passes** Run: ```bash node ./node_modules/vitest/vitest.mjs run src/App.test.tsx ``` Expected: PASS, showing the new header shell in the upload view and preserving the language toggle behavior. **Step 5: Commit** ```bash git add src/App.tsx src/i18n.tsx src/App.test.tsx git commit -m "feat: add upload page workbench shell" ``` ### Task 3: Replace the rigid upload-page flex layout with a responsive workbench grid **Files:** - Modify: `src/components/UploadScreen.tsx` - Modify: `src/components/UploadScreen.test.tsx` - Modify: `src/index.css` - Reference: `src/types.ts` **Step 1: Write the failing test** Add tests that lock in the redesigned composition while preserving behavior: ```tsx it('keeps subtitle preview behavior after the layout redesign', () => { renderUploadScreen(); fireEvent.change(screen.getByLabelText(/subtitle initial size/i), { target: { value: '32' }, }); expect(screen.getByTestId('upload-subtitle-preview')).toHaveStyle({ fontSize: '32px' }); expect(screen.getByRole('button', { name: 'Generate Translated Video' })).toBeDisabled(); }); it('keeps the upload interaction wired through the redesigned dropzone card', () => { renderUploadScreen(); expect(screen.getByTestId('upload-dropzone-card')).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 because the current layout does not expose the new workbench structure markers and updated headings yet. **Step 3: Write minimal implementation** Refactor `src/components/UploadScreen.tsx` to: - replace the outer `flex ... h-screen items-center` shell with a responsive grid container - use a wide primary upload card plus a flexible sidebar column - remove the fixed `w-[400px]` sidebar - add `min-w-0` to shrinkable containers - convert the settings area into three distinct cards: - mode and workflow - subtitle defaults - language and dubbing - reduce the preview height and tighten card spacing - keep the language list internally scrollable - keep the primary generation button prominent at the bottom of the settings flow Representative JSX shape: ```tsx
...
``` If a small amount of shared CSS improves consistency, keep it narrowly scoped in `src/index.css`: ```css .app-surface { background: rgba(255, 255, 255, 0.86); backdrop-filter: blur(14px); } ``` **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 upload-screen interaction tests, including subtitle-preview updates and upload confirmation behavior. **Step 5: Commit** ```bash git add src/components/UploadScreen.tsx src/components/UploadScreen.test.tsx src/index.css src/i18n.tsx git commit -m "feat: redesign upload page workbench layout" ``` ### Task 4: Full verification and cleanup **Files:** - Modify: `src/App.tsx` - Modify: `src/components/UploadScreen.tsx` - Modify: `src/i18n.tsx` - Modify: `src/index.css` - Test: `src/App.test.tsx` - Test: `src/components/UploadScreen.test.tsx` **Step 1: Write the failing test** Add one final regression assertion for the bilingual header text to ensure the redesigned shell still switches languages correctly: ```tsx fireEvent.click(screen.getByLabelText('switch-ui-language-en')); expect(screen.getByRole('heading', { name: 'Upload & prepare' })).toBeInTheDocument(); expect(screen.getByText('Upload a source video, tune subtitle defaults, and choose dubbing settings before generation.')).toBeInTheDocument(); ``` **Step 2: Run test to verify it fails** Run: ```bash node ./node_modules/vitest/vitest.mjs run src/App.test.tsx ``` Expected: FAIL until the new localized header copy is fully wired. **Step 3: Write minimal implementation** Complete any remaining polish needed to satisfy the regression coverage: - finalize localized header and section labels - ensure the upload page stays visually coherent in both locales - remove unused classes or stale layout wrappers from the old design **Step 4: Run test to verify it passes** Run: ```bash node ./node_modules/vitest/vitest.mjs run src/App.test.tsx src/components/UploadScreen.test.tsx npm run lint npm run build ``` Expected: - targeted tests PASS - typecheck PASS - production build PASS **Step 5: Commit** ```bash git add src/App.tsx src/components/UploadScreen.tsx src/i18n.tsx src/index.css src/App.test.tsx src/components/UploadScreen.test.tsx git commit -m "test: verify upload workbench redesign" ```