add notification

This commit is contained in:
2025-11-27 20:41:29 -03:00
parent ab7e4ea38b
commit 2467798855
19 changed files with 560 additions and 80 deletions

View File

@@ -3,10 +3,10 @@
import {
BookCopyIcon,
CalendarClockIcon,
DollarSign,
DollarSignIcon,
FileBadgeIcon,
GraduationCap,
LayoutDashboard,
LayoutDashboardIcon,
ShieldUserIcon,
UploadIcon,
UsersIcon
@@ -26,12 +26,12 @@ const data = {
{
title: 'Visão geral',
url: '/main',
icon: LayoutDashboard
icon: LayoutDashboardIcon
},
{
title: 'Histórico de compras',
url: '/orders',
icon: DollarSign
icon: DollarSignIcon
}
],
navUser: [

View File

@@ -0,0 +1,27 @@
import { BellIcon } from 'lucide-react'
import {
Popover,
PopoverContent,
PopoverTrigger
} from '@repo/ui/components/ui/popover'
import { Button } from '@repo/ui/components/ui/button'
export function Notification() {
return (
<Popover>
<PopoverTrigger asChild>
<Button
variant="link"
size="icon"
className="cursor-pointer text-muted-foreground"
>
<BellIcon className="size-4 text-muted-foreground" />
</Button>
</PopoverTrigger>
<PopoverContent align="end" className="w-80">
<>Notificações</>
</PopoverContent>
</Popover>
)
}

View File

@@ -26,7 +26,6 @@ import {
AlertDialogTitle,
AlertDialogTrigger
} from '@repo/ui/components/ui/alert-dialog'
import { Button } from '@repo/ui/components/ui/button'
import {
DropdownMenu,
@@ -58,24 +57,24 @@ export const columns: ColumnDef<Enrollment>[] = [
}
]
async function getEnrollment(id: string) {
const r = await fetch(`/~/api/enrollments/${id}`, {
method: 'GET'
})
await new Promise((r) => setTimeout(r, 150))
return (await r.json()) as {
cancel_policy?: any
lock?: { hash: string }
}
}
function ActionMenu({ row }: { row: any }) {
const [open, { set: setOpen }] = useToggle(false)
const cert = row.original?.cert
const { data, loading, run, refresh } = useRequest(getEnrollment, {
manual: true
})
const { data, loading, runAsync, refresh } = useRequest(
async () => {
const r = await fetch(`/~/api/enrollments/${row.id}`, {
method: 'GET'
})
return (await r.json()) as {
cancel_policy?: any
lock?: { hash: string }
}
},
{
manual: true
}
)
const onSuccess = () => {
refresh()
@@ -90,7 +89,7 @@ function ActionMenu({ row }: { row: any }) {
onOpenChange={(open) => {
setOpen(open)
if (data) return
run(row.id)
runAsync()
}}
>
<DropdownMenuTrigger asChild>
@@ -140,22 +139,27 @@ type ItemProps = ComponentProps<typeof DropdownMenuItem> & {
}
function DownloadItem({ id, onSuccess, ...props }: ItemProps) {
const [loading, { set }] = useToggle(false)
const { runAsync, loading } = useRequest(
async () => {
return await fetch(`/~/api/enrollments/${id}/download`)
},
{
manual: true
}
)
const download = async (e: Event) => {
e.preventDefault()
set(true)
const r = await fetch(`/~/api/enrollments/${id}/download`, {
method: 'GET'
})
if (r.ok) {
const { presigned_url } = (await r.json()) as { presigned_url: string }
try {
const r = await runAsync()
const { presigned_url } = (await r.json()) as {
presigned_url: string
}
window.open(presigned_url, '_blank')
set(false)
onSuccess?.()
}
} catch {}
}
return (
@@ -299,7 +303,7 @@ function CancelItem({
<AlertDialogDescription>
Esta ação não pode ser desfeita. Isso{' '}
<span className="font-bold">
cancelar permanentemente a matrícula
cancela permanentemente a matrícula
</span>{' '}
deste colaborador.
</AlertDialogDescription>

View File

@@ -20,6 +20,7 @@ import { Toaster } from '@repo/ui/components/ui/sonner'
import { request as req } from '@repo/util/request'
import { AppSidebar } from '@/components/app-sidebar'
import { Notification } from '@/components/notification'
export const middleware: Route.MiddlewareFunction[] = [authMiddleware]
@@ -78,6 +79,7 @@ export default function Route({ loaderData }: Route.ComponentProps) {
<ThemedImage className="max-md:hidden" />
<div className="ml-auto flex gap-2.5 items-center">
<Notification />
<ModeToggle />
<NavUser user={user} />
</div>