---
# System prepended metadata

title: VO UI pre-tasks

---

# VO UI pre-tasks

This fully plans out the prerequisite VO UI tasks that Collin and I can get started on right now: making the editor login-protected and splitting the audio panel into two to lay the foundation for future work without changing any functionality yet.

Coming next: tasks for the rest!

## TASK: Make the editor login-protected

### SUBTASK: Centralize our React Router components (estimate: 0.5 days)
- Create a new `app/routes/` directory
- Move `app/components/AppRoutes.js` -> `app/routes/index.tsx`
- Move `app/components/AccountRouter.js` -> `app/routes/AccountRouter.tsx`
- Move `app/components/ShopRouter.js` -> `app/routes/ShopRouter.tsx`
- Move `app/components/VideosRouter.js` -> `app/routes/VideosRouter.tsx`
- Move `app/components/RootRouter.js` -> `app/routes/RootRouter.tsx`
- Update imports for all of the old components as needed

### SUBTASK: Refactor `EnsureLoggedInContainer` component and wrap the editor's routes with it (estimate: 0.5 days)
- Replace `app/components/EnsureLoggedInContainer.js` with `app/routes/components/EnsureLoggedInRedirect.tsx`
    - `EnsureLoggedInRedirectProps`:
        - children: React.ReactNode
    - `EnsureLoggedInRedirect` component
        - isLoggedIn = useSelectors(selectors.isLoggedIn)
        - useEffect
            - if !isLoggedIn
                - dispatch(loginActionActions.addLoginAction(...)) so we will navigate back to whatever the current url pathname is after the user successfully logs in
                - goToInternalURL(appURLs.login)
        - If isLoggedIn, return children, otherwise return null
- Wrap the route for the editor pages in `app/routes/index.tsx` with `<EnsureLoggedInRedirect>`

### SUBTASK: Update template browser editor links to be login-protected (estimate: 0.5 days)
- Update the `TemplateBrowserVariantListItem` component in `app/components/TemplateBrowserVariantListItem.js`
    - attemptLoginProtectedAction = useAttemptLoginProtectedAction()
    - Change the `<InternalLink>` component -> `<WaymarkButton>`
        - onClick = `attemptLoginProtectedAction(() => goToInternalURL(appURLs.editVariant(...)))`

## TASK: Split the audio control panel in two

### SUBTASK: Update the main editor control panel's buttons to match new styles (estimate: 0.5 days)
- Update `editor/components/EditorMainControlPanel.tsx`
    - Remove `FootageCompositionPanelButton`, `FontPanelButton`, `AudioPanelButton`, and `ColorPanelButton` components
    - Make editor panel keys
        - Convert `editor/constants/Editor.js` to TS and make editor panel keys type safe
            - `export const editorPanelKeys = { ... } as const`
            - `export type EditorPanelKey = typeof editorPanelKeys[keyof typeof editorPanelKeys]`
        - Update imports to reflect the new TS extension
    - Add new `ControlPanelButton` component
        - `ControlPanelButtonProps`
            - panelKey: EditorPanelKey
                - Key for the editor panel which this button should open when clicked
            - icon: React.ReactNode
                - SVG icon to display in the button
            - buttonText: string
                - Text to display under the icon
    - Update `PanelButtons` component
        - panelButtonProps: `Array<ControlPanelButtonProps>` = useMemo()
            - Make an array and push a ControlPanelButtonProps object onto the array for each field that we need to include a button for
        - Return a div which wraps the buttons
            - data-hasoddchildcount = panelButtonProps length is odd
            - Styled with CSS grid
                - grid-template-columns: repeat(2, 1fr)
                - `[data-hasoddchildcount="true"] { grid-template-columns: repeat(3, 1fr) }`
            - `panelButtonProps.map(({ panelKey, icon, buttonText }) => <ControlPanelButton key={panelKey} ... />)`

### SUBTASK: Break EditorAudioControlPanel into MusicControlPanel and VoiceOverControlPanel (estimate: 1-2 days)
- Update `editor/providers/EditorFormDescriptionProvider.js`
    - We need to split the behavior in the `useResetToDefaultConfigurationValue` hook from `getRichAudioField` since it currently touches both the background AND VO tracks at the same time
    - Add 2 new hooks:
        - `useResetBackgroundAudioToDefault`
            - Don't touch auxiliary audio or volume, just reset the backgroundAudio to default
        - `useResetAuxiliaryAudioToDefault`
            - Remove auxiliary audio track and reset volume
- `editor/constants/Editor.ts`
    - Remove "audio", and "restoreRemovedAudio" from `editorPanelKeys`
    - Add "music", "voiceOverUpload", and "restoreRemovedVoiceOver" to `editorPanelKeys`
- `editor/components/panels/Music/`
    - `index.tsx`
        - export default makeEditorControlPanel(MusicPanelHeader, MusicPanelControls);
    - `PanelHeader.tsx`
        - Copy `EditorAudioHeader` from `editor/components/EditorAudioControlPanel.js` file as a starting point
        - `EditorAudioHeader` -> `PanelHeader`
            - Remove everything related to `EditorPanelTabButtons`
            - `useResetBackgroundAudioToDefault`
    - `PanelControls.tsx`
        - Copy `EditorAudioControls` from `editor/components/EditorAudioControlPanel.js` file as a starting point
        - `EditorAudioControls` -> `PanelControls` 
            - Remove everything tab-related
            - Copy the  contents of `EditorBackgroundAudioTab` and inline them in this `PanelControls` component; adjust as needed, but probably doesn't need much more work
 - `editor/components/panels/VoiceOverUpload/`
    -  `index.tsx`
        - export default makeEditorControlPanel(VoiceOverUploadPanelHeader, VoiceOverUploadPanelControls);
    - `PanelHeader.tsx`
        - Copy `EditorAudioHeader` from `editor/components/EditorAudioControlPanel.js` file as a starting point
        - `EditorAudioHeader` -> `PanelHeader`
            - Remove everything related to `EditorPanelTabButtons`
            - `useResetAuxiliaryAudioToDefault`
    - `PanelControls.tsx`
        - Copy `EditorAudioControls` from `editor/components/EditorAudioControlPanel.js` file as a starting point
        - `EditorAudioControls` -> `PanelControls` 
            - Remove everything tab-related
            - Copy the  contents of `EditorVoiceOverAudioTab` and inline them in this `PanelControls` component; adjust as needed
                - Update the `EditorModeButton` at the bottom of the panel
                    - Remove onClick in favor of `targetMode={editorPanelKeys.restoreRemovedVoiceOver}` 
                    - The analytics action on this button is wrong so let's fix that too
- Update `editor/constants/EditorControlPanels.js` to register these new panels for their panel keys
- Update `EditorMainControlPanel.tsx` to remove the old audio panel button in favor of our two new split panels
    - Make sure the VO button is only rendered if the user has VO permissions