-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ui): admin ui debug menu (#1066)
This PR adds a `Admin UI` menu for controlling and debugging various UI elements. Each button in the menu is a toggle so each element can be turned on and off. This will allow us to work on various UI elements, and debug them more easily. This menu will only be accessible when running the app in `development` mode. This menu can also be used for turning Feature Flags on and off during development to test different states of the app. ![CleanShot 2024-11-14 at 18 12 33](https://github.com/user-attachments/assets/1a50ab1e-0401-41fb-8a2b-19245570ad24) https://www.loom.com/share/f6854a529806458ba062ced1c407c87a?sid=19d95cae-b7f0-4e7a-a005-11322cea9a7f --------- Co-authored-by: Brian Pearce <[email protected]>
- Loading branch information
Showing
11 changed files
with
266 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* eslint-disable i18next/no-literal-string */ | ||
import { MenuWrapper, MenuContent, ToggleButton } from './styles'; | ||
import { useFloating, offset, shift, flip, useClick, useInteractions, useDismiss } from '@floating-ui/react'; | ||
import { useState } from 'react'; | ||
import { ThemeGroup } from './groups/ThemeGroup'; | ||
import { DialogsGroup } from './groups/DialogsGroup'; | ||
import { GreenModalsGroup } from './groups/GreenModalsGroup'; | ||
import { ToastsGroup } from './groups/ToastsGroup'; | ||
import { OtherUIGroup } from './groups/OtherUIGroup'; | ||
import { AnimatePresence } from 'framer-motion'; | ||
|
||
export default function AdminUI() { | ||
const [isOpen, setIsOpen] = useState(false); | ||
|
||
const { refs, floatingStyles, context } = useFloating({ | ||
open: isOpen, | ||
onOpenChange: setIsOpen, | ||
middleware: [offset(10), flip(), shift()], | ||
placement: 'bottom-end', | ||
}); | ||
|
||
const click = useClick(context); | ||
const dismiss = useDismiss(context); | ||
const { getReferenceProps, getFloatingProps } = useInteractions([click, dismiss]); | ||
|
||
return ( | ||
<> | ||
<ToggleButton ref={refs.setReference} {...getReferenceProps()} $isOpen={isOpen}> | ||
Admin UI | ||
</ToggleButton> | ||
<AnimatePresence> | ||
{isOpen && ( | ||
<MenuWrapper ref={refs.setFloating} style={floatingStyles} {...getFloatingProps()}> | ||
<MenuContent | ||
initial={{ opacity: 0, y: 10 }} | ||
animate={{ opacity: 1, y: 0 }} | ||
exit={{ opacity: 0, y: 10 }} | ||
> | ||
<ThemeGroup /> | ||
<DialogsGroup /> | ||
<GreenModalsGroup /> | ||
<ToastsGroup /> | ||
<OtherUIGroup /> | ||
</MenuContent> | ||
</MenuWrapper> | ||
)} | ||
</AnimatePresence> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* eslint-disable i18next/no-literal-string */ | ||
import { Button, ButtonGroup, CategoryLabel } from '../styles'; | ||
import { useUIStore } from '@app/store/useUIStore'; | ||
import { useAppStateStore } from '@app/store/appStateStore'; | ||
|
||
export function DialogsGroup() { | ||
const { setCriticalError, criticalError } = useAppStateStore(); | ||
const { setDialogToShow, dialogToShow, showExternalDependenciesDialog, setShowExternalDependenciesDialog } = | ||
useUIStore(); | ||
|
||
return ( | ||
<> | ||
<CategoryLabel>Dialogs</CategoryLabel> | ||
<ButtonGroup> | ||
<Button | ||
onClick={() => setCriticalError(criticalError ? undefined : 'This is a critical error')} | ||
$isActive={!!criticalError} | ||
> | ||
Critical Error | ||
</Button> | ||
<Button | ||
onClick={() => setDialogToShow(dialogToShow === 'autoUpdate' ? undefined : 'autoUpdate')} | ||
$isActive={dialogToShow === 'autoUpdate'} | ||
> | ||
Auto Update Dialog | ||
</Button> | ||
<Button | ||
onClick={() => setShowExternalDependenciesDialog(!showExternalDependenciesDialog)} | ||
$isActive={showExternalDependenciesDialog} | ||
> | ||
External Dependencies | ||
</Button> | ||
</ButtonGroup> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* eslint-disable i18next/no-literal-string */ | ||
import { Button, ButtonGroup, CategoryLabel } from '../styles'; | ||
import { usePaperWalletStore } from '@app/store/usePaperWalletStore'; | ||
import { useStagedSecurityStore } from '@app/store/useStagedSecurityStore'; | ||
import { useShareRewardStore } from '@app/store/useShareRewardStore'; | ||
|
||
export function GreenModalsGroup() { | ||
const { showModal: showPaperWallet, setShowModal: setShowPaperWallet } = usePaperWalletStore(); | ||
const { showModal: showStagedSecurity, setShowModal: setShowStagedSecurity } = useStagedSecurityStore(); | ||
const { showModal: showShareReward, setShowModal: setShowShareReward } = useShareRewardStore(); | ||
|
||
return ( | ||
<> | ||
<CategoryLabel>Green Modals</CategoryLabel> | ||
<ButtonGroup> | ||
<Button onClick={() => setShowPaperWallet(!showPaperWallet)} $isActive={showPaperWallet}> | ||
Paper Wallet | ||
</Button> | ||
<Button onClick={() => setShowStagedSecurity(!showStagedSecurity)} $isActive={showStagedSecurity}> | ||
Staged Security | ||
</Button> | ||
<Button onClick={() => setShowShareReward(!showShareReward)} $isActive={showShareReward}> | ||
Share Reward | ||
</Button> | ||
</ButtonGroup> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* eslint-disable i18next/no-literal-string */ | ||
import { Button, ButtonGroup, CategoryLabel } from '../styles'; | ||
import { useAppStateStore } from '@app/store/appStateStore'; | ||
|
||
export function OtherUIGroup() { | ||
const { isSettingUp, setIsSettingUp } = useAppStateStore(); | ||
|
||
return ( | ||
<> | ||
<CategoryLabel>Other UI</CategoryLabel> | ||
<ButtonGroup> | ||
<Button onClick={() => setIsSettingUp(!isSettingUp)} $isActive={isSettingUp}> | ||
Startup Screen | ||
</Button> | ||
</ButtonGroup> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* eslint-disable i18next/no-literal-string */ | ||
import { Button, ButtonGroup, CategoryLabel } from '../styles'; | ||
import { useUIStore } from '@app/store/useUIStore'; | ||
|
||
export function ThemeGroup() { | ||
const { setTheme, theme } = useUIStore(); | ||
|
||
return ( | ||
<> | ||
<CategoryLabel>Theme</CategoryLabel> | ||
<ButtonGroup> | ||
<Button onClick={() => setTheme('light')} $isActive={theme === 'light'}> | ||
Light Theme | ||
</Button> | ||
<Button onClick={() => setTheme('dark')} $isActive={theme === 'dark'}> | ||
Dark Theme | ||
</Button> | ||
</ButtonGroup> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import { m } from 'framer-motion'; | ||
import styled, { css } from 'styled-components'; | ||
|
||
export const ToggleButton = styled('button')<{ $isOpen?: boolean }>` | ||
background: #444; | ||
color: white; | ||
padding: 8px 20px; | ||
border-radius: 4px; | ||
cursor: pointer; | ||
position: fixed; | ||
top: 20px; | ||
right: 30px; | ||
z-index: 99999; | ||
pointer-events: all; | ||
font-size: 12px; | ||
opacity: 0; | ||
transition: opacity 0.2s ease; | ||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); | ||
&:hover { | ||
background: #555; | ||
opacity: 1; | ||
} | ||
${({ $isOpen }) => | ||
$isOpen && | ||
css` | ||
background: #555; | ||
opacity: 1; | ||
`} | ||
`; | ||
|
||
export const MenuWrapper = styled(m.div)` | ||
position: fixed; | ||
top: 20px; | ||
right: 30px; | ||
z-index: 99999; | ||
max-width: 350px; | ||
`; | ||
|
||
export const MenuContent = styled(m.div)` | ||
background: rgba(0, 0, 0, 0.8); | ||
padding: 20px; | ||
border-radius: 8px; | ||
display: flex; | ||
flex-direction: column; | ||
gap: 10px; | ||
min-width: 200px; | ||
max-height: calc(100vh - 100px); | ||
overflow-y: auto; | ||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); | ||
`; | ||
|
||
export const Button = styled('button')<{ $isActive?: boolean }>` | ||
background: ${({ $isActive }) => ($isActive ? '#666' : '#444')}; | ||
color: white; | ||
border: 1px solid #666; | ||
padding: 4px 8px; | ||
border-radius: 4px; | ||
cursor: pointer; | ||
pointer-events: all; | ||
font-size: 11px; | ||
transition: background-color 0.2s ease; | ||
&:hover { | ||
background: ${({ $isActive }) => ($isActive ? '#666' : '#555')}; | ||
} | ||
`; | ||
|
||
export const CategoryLabel = styled('div')` | ||
color: #999; | ||
font-size: 11px; | ||
text-transform: uppercase; | ||
padding-bottom: 2px; | ||
border-bottom: 1px solid #666; | ||
`; | ||
|
||
export const ButtonGroup = styled('div')` | ||
display: grid; | ||
grid-template-columns: repeat(2, 1fr); | ||
gap: 6px; | ||
padding-bottom: 10px; | ||
&:last-child { | ||
padding-bottom: 0; | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters