implement app menu window

This commit is contained in:
2025-05-31 16:02:00 +01:00
parent 11d4cc19af
commit 1166fd6ade
2 changed files with 57 additions and 22 deletions

View File

@@ -14,6 +14,13 @@ enum DialogKind {
DeleteBookmark = "DeleteBookmark",
EditBookmark = "EditBookmark",
}
enum WindowKind {
None = "None",
TagFilter = "TagFilter",
AppMenu = "AppMenu",
}
interface NoDialogData {
kind: DialogKind.None | DialogKind.AddBookmark
}
@@ -55,11 +62,9 @@ interface BookmarkPageState {
hasDialog: boolean
actionBarContent: ActionBarContent
statusMessage: string
isTagFilterWindowOpen: boolean
activeWindow: WindowKind
openTagFilterWindow: () => void
closeTagFilterWindow: () => void
toggleTagFilterWindow: () => void
setActiveWindow: (window: WindowKind) => void
setActionBarContent: (content: ActionBarContent) => void
handleBookmarkListItemAction: (bookmark: Bookmark, action: BookmarkListItemAction) => void
setActiveDialog: (dialog: DialogData) => void
@@ -75,22 +80,14 @@ const useBookmarkPageStore = create<BookmarkPageState>()((set, get) => ({
dialog: NO_DIALOG,
actionBarContent: { kind: ActionBarContentKind.Normal },
statusMessage: "",
isTagFilterWindowOpen: false,
activeWindow: WindowKind.None,
get hasDialog(): boolean {
return get().dialog.kind !== DialogKind.None
},
toggleTagFilterWindow() {
set({ isTagFilterWindowOpen: !get().isTagFilterWindowOpen })
},
openTagFilterWindow() {
set({ isTagFilterWindowOpen: true })
},
closeTagFilterWindow() {
set({ isTagFilterWindowOpen: false })
setActiveWindow(window: WindowKind) {
set({ activeWindow: window })
},
setActionBarContent(content: ActionBarContent) {
@@ -158,5 +155,5 @@ const useBookmarkPageStore = create<BookmarkPageState>()((set, get) => ({
},
}))
export { LayoutMode, DialogKind, ActionBarContentKind, useBookmarkPageStore }
export { WindowKind, LayoutMode, DialogKind, ActionBarContentKind, useBookmarkPageStore }
export type { BookmarkPageState }

View File

@@ -12,7 +12,7 @@ import { Message, MessageVariant } from "~/components/message.tsx"
import { useDocumentEvent } from "~/hooks/use-document-event.ts"
import { useMnemonics } from "~/hooks/use-mnemonics.ts"
import { BookmarkList } from "./-bookmark-list"
import { ActionBarContentKind, DialogKind, useBookmarkPageStore } from "./-store"
import { ActionBarContentKind, DialogKind, WindowKind, useBookmarkPageStore } from "./-store"
export const Route = createFileRoute("/bookmarks/")({
component: RouteComponent,
@@ -78,7 +78,7 @@ function BookmarkListContainer() {
}
function BookmarkListActionBar({ className }: { className?: string }) {
const isTagFilterWindowOpen = useBookmarkPageStore((state) => state.isTagFilterWindowOpen)
const activeWindow = useBookmarkPageStore((state) => state.activeWindow)
const content = useBookmarkPageStore((state) => state.actionBarContent)
const { refs, floatingStyles } = useFloating({
placement: "top",
@@ -100,7 +100,16 @@ function BookmarkListActionBar({ className }: { className?: string }) {
}
})()}
</ActionBar>
{isTagFilterWindowOpen ? <TagFilterWindow ref={refs.setFloating} style={floatingStyles} /> : null}
{(() => {
switch (activeWindow) {
case WindowKind.TagFilter:
return <TagFilterWindow ref={refs.setFloating} style={floatingStyles} />
case WindowKind.AppMenu:
return <AppMenuWindow ref={refs.setFloating} style={floatingStyles} />
case WindowKind.None:
return null
}
})()}
</>
)
}
@@ -210,15 +219,16 @@ function SearchBar() {
}
function ActionButtons() {
const setActiveWindow = useBookmarkPageStore((state) => state.setActiveWindow)
const activeWindow = useBookmarkPageStore((state) => state.activeWindow)
const setActiveDialog = useBookmarkPageStore((state) => state.setActiveDialog)
const setActionBarContent = useBookmarkPageStore((state) => state.setActionBarContent)
const toggleTagFilterWindow = useBookmarkPageStore((state) => state.toggleTagFilterWindow)
useMnemonics(
{
a: addBookmark,
s: openSearchBar,
t: toggleTagFilterWindow,
t: toggleTagWindow,
},
{ ignore: useCallback(() => useBookmarkPageStore.getState().dialog.kind !== DialogKind.None, []) },
)
@@ -229,6 +239,17 @@ function ActionButtons() {
function openSearchBar() {
setActionBarContent({ kind: ActionBarContentKind.SearchBar })
if (activeWindow !== WindowKind.TagFilter) {
setActiveWindow(WindowKind.None)
}
}
function toggleTagWindow() {
setActiveWindow(activeWindow === WindowKind.TagFilter ? WindowKind.None : WindowKind.TagFilter)
}
function toggleAppMenu() {
setActiveWindow(activeWindow === WindowKind.AppMenu ? WindowKind.None : WindowKind.AppMenu)
}
return (
@@ -239,9 +260,10 @@ function ActionButtons() {
<Button onClick={openSearchBar}>
<span className="underline">S</span>EARCH
</Button>
<Button onClick={toggleTagFilterWindow}>
<Button onClick={toggleTagWindow}>
<span className="underline">T</span>AGS
</Button>
<Button onClick={toggleAppMenu}></Button>
</div>
)
}
@@ -332,6 +354,22 @@ const TagFilterItem = memo(
},
)
function AppMenuWindow({ ref, style }: { ref: React.Ref<HTMLDivElement>; style: React.CSSProperties }) {
return (
<div ref={ref} style={style} className="border w-full md:w-100">
<p className="bg-stone-900 dark:bg-stone-200 text-stone-300 dark:text-stone-800 text-center">MENU</p>
<div className="p-4">
<ul className="space-y-2">
<li>
<LogOutButton />
</li>
{/* Add other menu items here */}
</ul>
</div>
</div>
)
}
function LogOutButton() {
const logOutMutation = useLogOut()
const navigate = useNavigate()