mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-15 18:53:06 +00:00
167 lines
5.3 KiB
TypeScript
167 lines
5.3 KiB
TypeScript
'use client'
|
|
|
|
import { usePathname } from 'next/navigation'
|
|
import { useEffect, useRef } from 'react'
|
|
|
|
import { CampaignGlobalSearchBody } from '@/components/campaign/dashboard/CampaignGlobalSearchMount'
|
|
import { CampaignHomeActionStrip } from '@/components/campaign/dashboard/CampaignHomeActionStrip'
|
|
import { useHomeSearch } from '@/components/campaign/dashboard/HomeSearchContext'
|
|
import { HomeSearchExcludeProvider } from '@/components/campaign/dashboard/HomeSearchExcludeContext'
|
|
import { useCampaignQuickActionContext } from '@/components/campaign/shell/CampaignQuickActionContext'
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from '@/components/ui/dialog'
|
|
import { Drawer, DrawerContent, DrawerDescription, DrawerTitle } from '@/components/ui/Drawer'
|
|
import { useIsMobile } from '@/hooks/use-mobile'
|
|
import type { CampaignQuickAction } from '@/lib/campaignQuickActionTypes'
|
|
import { resolveHomeSearchExcludeContext } from '@/lib/homeSearchExcludeCurrentEntity'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
const overlayRetractionClass = (retracted: boolean) =>
|
|
cn(
|
|
'grid min-h-0 transition-[grid-template-rows,opacity] duration-[220ms] ease-out motion-reduce:transition-none',
|
|
retracted
|
|
? 'grid-rows-[0fr] opacity-0 pointer-events-none motion-reduce:opacity-0'
|
|
: 'grid-rows-[1fr] opacity-100 motion-reduce:opacity-100',
|
|
)
|
|
|
|
const OverlayActionsChrome = ({
|
|
actions,
|
|
retracted,
|
|
}: {
|
|
actions: readonly CampaignQuickAction[]
|
|
retracted: boolean
|
|
}) => {
|
|
if (actions.length === 0) return null
|
|
|
|
return (
|
|
<div
|
|
data-slot="quick-actions-chrome"
|
|
data-retracted={retracted || undefined}
|
|
className={overlayRetractionClass(retracted)}
|
|
aria-hidden={retracted || undefined}
|
|
>
|
|
<div className="min-h-0 overflow-hidden">
|
|
<CampaignHomeActionStrip
|
|
variant="grid"
|
|
actions={actions.map((action) => ({
|
|
id: action.id,
|
|
label: action.label,
|
|
icon: action.icon,
|
|
description: action.description,
|
|
href: action.href,
|
|
}))}
|
|
className="w-full"
|
|
/>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const OverlaySearchChrome = ({ className }: { className?: string }) => (
|
|
<div data-slot="quick-actions-search" className={cn('min-w-0 md:pr-10', className)}>
|
|
<CampaignGlobalSearchBody />
|
|
</div>
|
|
)
|
|
|
|
const CampaignQuickActionsOverlayBody = ({
|
|
actions,
|
|
}: {
|
|
actions: readonly CampaignQuickAction[]
|
|
}) => {
|
|
const { uiFocused: focused } = useHomeSearch()
|
|
|
|
return (
|
|
<div className="flex min-h-0 flex-col">
|
|
<div className="order-1 md:order-2">
|
|
<OverlayActionsChrome actions={actions} retracted={focused} />
|
|
</div>
|
|
<OverlaySearchChrome
|
|
className={cn('order-2 min-w-0 md:order-1', focused ? 'mt-0 pt-4' : 'mt-4 md:mt-0 md:mb-4')}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const CampaignQuickActionsOverlayContent = ({
|
|
actions,
|
|
}: {
|
|
actions: readonly CampaignQuickAction[]
|
|
}) => {
|
|
const pathname = usePathname()
|
|
const { context } = useCampaignQuickActionContext()
|
|
const excludeContext = resolveHomeSearchExcludeContext(pathname, context)
|
|
|
|
return (
|
|
<HomeSearchExcludeProvider value={excludeContext}>
|
|
<CampaignQuickActionsOverlayBody actions={actions} />
|
|
</HomeSearchExcludeProvider>
|
|
)
|
|
}
|
|
|
|
export const CampaignQuickActionsOverlay = ({
|
|
open,
|
|
onOpenChange,
|
|
actions,
|
|
}: {
|
|
open: boolean
|
|
onOpenChange: (open: boolean) => void
|
|
actions: readonly CampaignQuickAction[]
|
|
}) => {
|
|
const isMobile = useIsMobile()
|
|
const { clear } = useHomeSearch()
|
|
const titleRef = useRef<HTMLHeadingElement>(null)
|
|
|
|
useEffect(() => {
|
|
if (!open) clear()
|
|
}, [open, clear])
|
|
|
|
if (isMobile) {
|
|
return (
|
|
<Drawer open={open} onOpenChange={onOpenChange} showSwipeHandle>
|
|
<DrawerContent
|
|
id="CampaignQuickActionsOverlay"
|
|
initialFocus={titleRef}
|
|
className="max-h-[85dvh] border-t border-border bg-background text-foreground [--drawer-height:auto]"
|
|
>
|
|
<DrawerTitle ref={titleRef} tabIndex={-1} className="sr-only outline-none">
|
|
Ações rápidas
|
|
</DrawerTitle>
|
|
<DrawerDescription className="sr-only">
|
|
Ações do contexto e busca na campanha
|
|
</DrawerDescription>
|
|
<div className="flex flex-col overflow-y-auto px-4 pb-[max(0.75rem,env(safe-area-inset-bottom))] pt-3">
|
|
<CampaignQuickActionsOverlayContent actions={actions} />
|
|
</div>
|
|
</DrawerContent>
|
|
</Drawer>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent
|
|
id="CampaignQuickActionsOverlay"
|
|
className="flex max-h-[min(85dvh,40rem)] w-[calc(100vw-2rem)] max-w-lg flex-col gap-4 overflow-hidden p-4 sm:p-6"
|
|
onOpenAutoFocus={(event) => {
|
|
event.preventDefault()
|
|
titleRef.current?.focus()
|
|
}}
|
|
>
|
|
<DialogHeader className="sr-only">
|
|
<DialogTitle ref={titleRef} tabIndex={-1} className="outline-none">
|
|
Ações rápidas
|
|
</DialogTitle>
|
|
<DialogDescription>Ações do contexto e busca na campanha</DialogDescription>
|
|
</DialogHeader>
|
|
<div className="flex flex-col overflow-y-auto">
|
|
<CampaignQuickActionsOverlayContent actions={actions} />
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|