Compare commits
No commits in common. "2d6ad73e1b96eed721696da6dc3ca4ccf7a0c74d" and "63784ed5f2b169a0dfac76ba3c76c96dc1c95593" have entirely different histories.
2d6ad73e1b
...
63784ed5f2
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,4 +4,4 @@ dist/
|
|||||||
coverage/
|
coverage/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.log
|
*.log
|
||||||
.worktrees/
|
|
||||||
|
|||||||
@ -1,244 +0,0 @@
|
|||||||
# Upload Workbench Redesign Design
|
|
||||||
|
|
||||||
**Goal:** Redesign the upload page so the right-side controls are always accessible, the layout adapts cleanly across viewport widths, and the page feels like a coherent product workbench instead of a squeezed form.
|
|
||||||
|
|
||||||
## Context
|
|
||||||
|
|
||||||
The current upload page uses a fixed two-column flex layout inside a constrained `max-w-6xl` shell. The left upload area grows aggressively while the right settings column is locked to `w-[400px]`. Combined with `h-screen`, centered alignment, and large outer padding, the layout runs out of horizontal space quickly and the right column becomes partially or fully clipped on narrower desktop windows.
|
|
||||||
|
|
||||||
Functionally, the page already collects the right information:
|
|
||||||
|
|
||||||
- upload source video
|
|
||||||
- choose work mode
|
|
||||||
- define initial subtitle defaults
|
|
||||||
- choose TTS language
|
|
||||||
|
|
||||||
The redesign should preserve that workflow. This is a front-end layout and presentation change, not a product-flow rewrite.
|
|
||||||
|
|
||||||
## User-Approved Direction
|
|
||||||
|
|
||||||
The approved direction is:
|
|
||||||
|
|
||||||
- keep a desktop-friendly left/right split layout
|
|
||||||
- automatically stack into a top/bottom layout on narrower viewports
|
|
||||||
- preserve the current page flow and controls
|
|
||||||
- make the upload area the primary focal point
|
|
||||||
- keep settings visible, grouped, and readable without horizontal clipping
|
|
||||||
|
|
||||||
## Approaches Considered
|
|
||||||
|
|
||||||
### Option A: Responsive dual-column workbench
|
|
||||||
|
|
||||||
Keep the existing information architecture, but replace the rigid flex layout with a responsive grid that shifts from dual-column to single-column when space is limited.
|
|
||||||
|
|
||||||
**Pros**
|
|
||||||
|
|
||||||
- Solves the clipping problem directly
|
|
||||||
- Preserves current user workflow
|
|
||||||
- Requires changes mostly in the upload page shell and card structure
|
|
||||||
- Keeps settings visible without hiding them behind extra clicks
|
|
||||||
|
|
||||||
**Cons**
|
|
||||||
|
|
||||||
- Requires reworking spacing, hierarchy, and card composition
|
|
||||||
|
|
||||||
### Option B: Settings drawer
|
|
||||||
|
|
||||||
Collapse the right-side controls into a slide-over drawer triggered by a button.
|
|
||||||
|
|
||||||
**Pros**
|
|
||||||
|
|
||||||
- Eliminates horizontal overflow entirely
|
|
||||||
- Can simplify the initial page appearance
|
|
||||||
|
|
||||||
**Cons**
|
|
||||||
|
|
||||||
- Reduces discoverability of settings
|
|
||||||
- Adds an extra interaction before upload
|
|
||||||
- Makes subtitle default preview less immediately useful
|
|
||||||
|
|
||||||
### Option C: Multi-step wizard
|
|
||||||
|
|
||||||
Split upload and settings into separate steps.
|
|
||||||
|
|
||||||
**Pros**
|
|
||||||
|
|
||||||
- Very clear progressive flow
|
|
||||||
- Maximum focus per step
|
|
||||||
|
|
||||||
**Cons**
|
|
||||||
|
|
||||||
- Changes the product flow more than requested
|
|
||||||
- Adds more navigation state
|
|
||||||
- Unnecessary for the current page complexity
|
|
||||||
|
|
||||||
### Recommendation
|
|
||||||
|
|
||||||
Use **Option A**. It fixes the visibility problem without changing the product's mental model.
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
### Page Shell
|
|
||||||
|
|
||||||
Replace the current `h-screen` centered flex shell with a top-aligned `min-h-screen` workbench container. The page should use:
|
|
||||||
|
|
||||||
- a lightweight header area with page title, support copy, and language switcher
|
|
||||||
- a responsive content grid for the upload page body
|
|
||||||
- natural document scrolling instead of forcing the full screen height
|
|
||||||
|
|
||||||
This removes the clipping pressure caused by vertical centering and fixed-height layout assumptions.
|
|
||||||
|
|
||||||
### Responsive Grid
|
|
||||||
|
|
||||||
The main upload page body should use a grid with these rules:
|
|
||||||
|
|
||||||
- large desktop: two columns with a wide primary upload column and a narrower settings column
|
|
||||||
- medium desktop: still two columns, but with reduced gap and a flexible sidebar width
|
|
||||||
- tablet and below: a single-column stack with the upload card first and the settings cards below
|
|
||||||
|
|
||||||
Implementation should avoid fixed-width overflow by:
|
|
||||||
|
|
||||||
- using `minmax(...)` for the sidebar column instead of a hard-coded width
|
|
||||||
- adding `min-w-0` to grid children so nested content can shrink safely
|
|
||||||
- limiting card internals rather than the full page height
|
|
||||||
|
|
||||||
### Visual Hierarchy
|
|
||||||
|
|
||||||
The page should read as a workbench with one primary action and three supporting settings groups:
|
|
||||||
|
|
||||||
1. Upload area
|
|
||||||
2. Mode selection
|
|
||||||
3. Subtitle defaults
|
|
||||||
4. Language and dubbing settings
|
|
||||||
|
|
||||||
The upload card becomes the visual anchor of the page. The settings column becomes a structured sidebar of related control cards rather than a tall wall of similar white panels.
|
|
||||||
|
|
||||||
### Header
|
|
||||||
|
|
||||||
Move the language switcher into a clear page header that also introduces the page. The header should include:
|
|
||||||
|
|
||||||
- a concise title
|
|
||||||
- one sentence explaining the workflow
|
|
||||||
- the existing bilingual switcher aligned to the right on larger screens and wrapping naturally on smaller screens
|
|
||||||
|
|
||||||
This removes the current disconnected top-right floating control feeling.
|
|
||||||
|
|
||||||
## Layout Composition
|
|
||||||
|
|
||||||
### Upload Card
|
|
||||||
|
|
||||||
The upload card should be the largest surface in the page. It contains:
|
|
||||||
|
|
||||||
- a strong heading and short instruction copy
|
|
||||||
- the drag-and-drop / click target
|
|
||||||
- supported format text
|
|
||||||
- optional contextual mode summary
|
|
||||||
|
|
||||||
The invisible file input should still power the interaction, but the visible button and dropzone should feel like one unified action surface.
|
|
||||||
|
|
||||||
### Mode Card
|
|
||||||
|
|
||||||
Keep the two work modes, but restyle them as a cleaner segmented card section:
|
|
||||||
|
|
||||||
- each option uses consistent spacing and iconography
|
|
||||||
- selected state is obvious through background, border, and copy contrast
|
|
||||||
- the section remains compact enough for narrower widths
|
|
||||||
|
|
||||||
### Subtitle Defaults Card
|
|
||||||
|
|
||||||
Preserve the existing subtitle preview and sliders, but make the card more compact and better balanced:
|
|
||||||
|
|
||||||
- preview area becomes shorter vertically
|
|
||||||
- reset action remains in the header
|
|
||||||
- control spacing is tightened
|
|
||||||
- the preview remains visually useful without dominating the sidebar
|
|
||||||
|
|
||||||
### Language and Dubbing Card
|
|
||||||
|
|
||||||
Keep subtitle language and TTS language selection in one grouped card. The card should:
|
|
||||||
|
|
||||||
- present subtitle language as read-only contextual information
|
|
||||||
- keep the alphabet/popular tabs compact
|
|
||||||
- constrain the language list with internal scrolling
|
|
||||||
- pin the primary action button near the bottom of the card flow
|
|
||||||
|
|
||||||
On desktop, the settings column should use `sticky` behavior so the user can keep context while scrolling the page.
|
|
||||||
|
|
||||||
## Responsive Behavior
|
|
||||||
|
|
||||||
### Large Desktop
|
|
||||||
|
|
||||||
- two-column layout
|
|
||||||
- upload card and settings sidebar visible simultaneously
|
|
||||||
- settings sidebar can remain sticky
|
|
||||||
|
|
||||||
### Medium Desktop
|
|
||||||
|
|
||||||
- still two columns
|
|
||||||
- reduced outer padding and inter-column gap
|
|
||||||
- sidebar width narrows within safe limits
|
|
||||||
|
|
||||||
### Narrow Desktop / Tablet
|
|
||||||
|
|
||||||
- single-column stack
|
|
||||||
- upload card first
|
|
||||||
- settings cards follow underneath
|
|
||||||
- sticky behavior disabled
|
|
||||||
|
|
||||||
### Mobile-Like Widths
|
|
||||||
|
|
||||||
Although the current use case is desktop-heavy, the layout should remain readable:
|
|
||||||
|
|
||||||
- all cards become full-width
|
|
||||||
- header content wraps cleanly
|
|
||||||
- button actions span full width where helpful
|
|
||||||
- no content should overflow horizontally
|
|
||||||
|
|
||||||
## Interaction Details
|
|
||||||
|
|
||||||
### Primary Action Clarity
|
|
||||||
|
|
||||||
There should be one clearly dominant action:
|
|
||||||
|
|
||||||
- before a file is selected, the upload surface is primary
|
|
||||||
- after a file is prepared, the final "Generate Translated Video" action remains the strongest button in the settings flow
|
|
||||||
|
|
||||||
The redesign should reduce the feeling of multiple competing calls to action.
|
|
||||||
|
|
||||||
### Scroll Ownership
|
|
||||||
|
|
||||||
The full page should scroll naturally. Only the TTS language list should own an internal scroll region. The page should avoid nested full-height scroll containers competing with each other.
|
|
||||||
|
|
||||||
### Behavior Preservation
|
|
||||||
|
|
||||||
The redesign must not change:
|
|
||||||
|
|
||||||
- the `onUpload(...)` contract
|
|
||||||
- subtitle default values or payload structure
|
|
||||||
- selected TTS language mapping
|
|
||||||
- trim modal flow
|
|
||||||
|
|
||||||
## Testing Strategy
|
|
||||||
|
|
||||||
Add or update tests to cover:
|
|
||||||
|
|
||||||
- the upload page structure still renders all core controls after the redesign
|
|
||||||
- the language switcher remains available from the upload page shell
|
|
||||||
- subtitle preview still reflects size and bottom-offset changes
|
|
||||||
- upload confirmation still forwards the same payload values
|
|
||||||
|
|
||||||
Because responsive behavior is mostly CSS-driven, automated tests should focus on stable structural markers and interaction continuity. Final visual validation should also include a manual browser check across multiple viewport widths.
|
|
||||||
|
|
||||||
## Out of Scope
|
|
||||||
|
|
||||||
This redesign does not include:
|
|
||||||
|
|
||||||
- changing the upload-to-editor workflow
|
|
||||||
- adding new subtitle styling options
|
|
||||||
- changing supported languages
|
|
||||||
- redesigning the editor screen
|
|
||||||
- altering backend request contracts
|
|
||||||
|
|
||||||
## Rollout Notes
|
|
||||||
|
|
||||||
This work should remain contained to the upload experience and its tests. The main success criterion is simple: at the viewport width shown in the reported issue, the right-side controls must remain fully accessible without horizontal clipping, while the overall page looks more intentional and usable.
|
|
||||||
@ -1,336 +0,0 @@
|
|||||||
# 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(<App />);
|
|
||||||
|
|
||||||
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
|
|
||||||
<section aria-label="upload-page-intro">
|
|
||||||
<p>Video Translate</p>
|
|
||||||
<h1>{m.upload.workbenchTitle}</h1>
|
|
||||||
<p>{m.upload.workbenchDescription}</p>
|
|
||||||
</section>
|
|
||||||
```
|
|
||||||
|
|
||||||
**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
|
|
||||||
<div className="min-h-screen bg-[...gradient...] text-slate-900">
|
|
||||||
<div className="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
|
|
||||||
<header className="mb-8 flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
|
|
||||||
<div className="space-y-3">
|
|
||||||
<p className="...">{m.app.productName}</p>
|
|
||||||
<h1 className="...">{m.upload.workbenchTitle}</h1>
|
|
||||||
<p className="...">{m.upload.workbenchDescription}</p>
|
|
||||||
</div>
|
|
||||||
{languageSwitcher}
|
|
||||||
</header>
|
|
||||||
{currentView === 'upload' ? <UploadScreen ... /> : <EditorScreen ... />}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
**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
|
|
||||||
<section
|
|
||||||
data-testid="upload-workbench"
|
|
||||||
className="grid gap-6 xl:grid-cols-[minmax(0,1.65fr)_minmax(320px,420px)]"
|
|
||||||
>
|
|
||||||
<div data-testid="upload-dropzone-card" className="min-w-0 ...">
|
|
||||||
...
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<aside data-testid="upload-settings-column" className="min-w-0 space-y-5 xl:sticky xl:top-6">
|
|
||||||
<section className="...">
|
|
||||||
<h2>{m.upload.modeWorkflowTitle}</h2>
|
|
||||||
...
|
|
||||||
</section>
|
|
||||||
<section className="...">
|
|
||||||
<h2>{m.upload.subtitleDefaults}</h2>
|
|
||||||
...
|
|
||||||
</section>
|
|
||||||
<section className="...">
|
|
||||||
<h2>{m.upload.languageDubbingTitle}</h2>
|
|
||||||
...
|
|
||||||
</section>
|
|
||||||
</aside>
|
|
||||||
</section>
|
|
||||||
```
|
|
||||||
|
|
||||||
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"
|
|
||||||
```
|
|
||||||
Loading…
x
Reference in New Issue
Block a user