"use client" import React, { useCallback, useEffect, useMemo, useRef } from "react" import { motion, AnimatePresence } from "framer-motion" import type { icons } from "lucide-react" import { Button } from "@/components/ui/button" import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip" import { cn, getShortcutKeys, isEditableElement } from "@/lib/utils" import { LaIcon } from "@/components/custom/la-icon" import { useAtom } from "jotai" import { parseAsBoolean, useQueryState } from "nuqs" import { useConfirm } from "@omit/react-confirm-dialog" import { useAccount, useCoState } from "@/lib/providers/jazz-provider" import { PersonalLink } from "@/lib/schema" import { ID } from "jazz-tools" import { globalLinkFormExceptionRefsAtom } from "./partials/form/link-form" import { useLinkActions } from "./hooks/use-link-actions" import { useKeydownListener } from "@/hooks/use-keydown-listener" interface ToolbarButtonProps extends React.ComponentPropsWithoutRef { icon: keyof typeof icons onClick?: (e: React.MouseEvent) => void tooltip?: string } const ToolbarButton = React.forwardRef( ({ icon, onClick, tooltip, className, ...props }, ref) => { const button = ( ) if (tooltip) { return ( {button}

{tooltip}

) } return button } ) ToolbarButton.displayName = "ToolbarButton" export const LinkBottomBar: React.FC = () => { const [editId, setEditId] = useQueryState("editId") const [createMode, setCreateMode] = useQueryState("create", parseAsBoolean) const [, setGlobalLinkFormExceptionRefsAtom] = useAtom(globalLinkFormExceptionRefsAtom) const { me } = useAccount({ root: { personalLinks: [] } }) const personalLink = useCoState(PersonalLink, editId as ID) const cancelBtnRef = useRef(null) const confirmBtnRef = useRef(null) const overlayRef = useRef(null) const contentRef = useRef(null) const deleteBtnRef = useRef(null) const editMoreBtnRef = useRef(null) const plusBtnRef = useRef(null) const plusMoreBtnRef = useRef(null) const { deleteLink } = useLinkActions() const confirm = useConfirm() const handleCreateMode = useCallback(() => { setEditId(null) requestAnimationFrame(() => { setCreateMode(prev => !prev) }) }, [setEditId, setCreateMode]) const exceptionRefs = useMemo( () => [ overlayRef, contentRef, deleteBtnRef, editMoreBtnRef, cancelBtnRef, confirmBtnRef, plusBtnRef, plusMoreBtnRef ], [] ) useEffect(() => { setGlobalLinkFormExceptionRefsAtom(exceptionRefs) }, [setGlobalLinkFormExceptionRefsAtom, exceptionRefs]) const handleDelete = async (e: React.MouseEvent) => { if (!personalLink || !me) return const result = await confirm({ title: `Delete "${personalLink.title}"?`, description: "This action cannot be undone.", alertDialogTitle: { className: "text-base" }, alertDialogOverlay: { ref: overlayRef }, alertDialogContent: { ref: contentRef }, cancelButton: { variant: "outline", ref: cancelBtnRef }, confirmButton: { variant: "destructive", ref: confirmBtnRef } }) if (result) { deleteLink(me, personalLink) setEditId(null) } } const handleKeydown = useCallback( (event: KeyboardEvent) => { const isCreateShortcut = event.key === "c" const target = event.target as HTMLElement if (isCreateShortcut && !isEditableElement(target)) { event.preventDefault() handleCreateMode() } }, [handleCreateMode] ) useKeydownListener(handleKeydown) const shortcutText = getShortcutKeys(["c"]) return (
{editId && ( setEditId(null)} aria-label="Go back" /> )} {!editId && ( {createMode && } {!createMode && ( s.symbol).join("")})`} ref={plusBtnRef} aria-label="New link" /> )} )}
) } LinkBottomBar.displayName = "LinkBottomBar" export default LinkBottomBar