From 61126991330cd51afed9570b39b0458f4c785692 Mon Sep 17 00:00:00 2001
From: Song367 <601337784@qq.com>
Date: Sat, 21 Mar 2026 12:39:57 +0800
Subject: [PATCH] docs: add upload workbench redesign plan
---
.../2026-03-21-upload-workbench-redesign.md | 336 ++++++++++++++++++
1 file changed, 336 insertions(+)
create mode 100644 docs/plans/2026-03-21-upload-workbench-redesign.md
diff --git a/docs/plans/2026-03-21-upload-workbench-redesign.md b/docs/plans/2026-03-21-upload-workbench-redesign.md
new file mode 100644
index 0000000..bec3384
--- /dev/null
+++ b/docs/plans/2026-03-21-upload-workbench-redesign.md
@@ -0,0 +1,336 @@
+# 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
+
+```
+
+**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"
+```