# 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