update package
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
type AbbrProps = {
|
||||
children: string
|
||||
maxLen?: number
|
||||
}
|
||||
|
||||
export function Abbr({ children, maxLen = 30, ...props }: AbbrProps) {
|
||||
if (children.length <= maxLen) {
|
||||
return <abbr {...props}>{children}</abbr>
|
||||
}
|
||||
|
||||
return (
|
||||
<abbr title={children} {...props}>
|
||||
{children.substring(0, maxLen).concat('...')}
|
||||
</abbr>
|
||||
)
|
||||
}
|
||||
@@ -18,7 +18,8 @@ import {
|
||||
Sidebar,
|
||||
SidebarContent,
|
||||
SidebarFooter,
|
||||
SidebarHeader
|
||||
SidebarHeader,
|
||||
SidebarRail
|
||||
} from '@repo/ui/components/ui/sidebar'
|
||||
|
||||
const data = {
|
||||
@@ -75,13 +76,14 @@ const data = {
|
||||
]
|
||||
}
|
||||
|
||||
export function AppSidebar({ orgs = [] }) {
|
||||
export function AppSidebar() {
|
||||
return (
|
||||
<Sidebar collapsible="icon">
|
||||
<SidebarHeader>
|
||||
<WorkspaceSwitcher />
|
||||
</SidebarHeader>
|
||||
<SidebarContent>
|
||||
<SidebarRail />
|
||||
<NavMain data={data} />
|
||||
</SidebarContent>
|
||||
<SidebarFooter />
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import { type Column } from '@tanstack/react-table'
|
||||
import {
|
||||
ChevronDownIcon,
|
||||
ChevronsUpDownIcon,
|
||||
ChevronUpIcon
|
||||
} from 'lucide-react'
|
||||
|
||||
import { Button } from '@repo/ui/components/ui/button'
|
||||
import { cn } from '@repo/ui/lib/utils'
|
||||
|
||||
interface DataTableColumnHeaderProps<TData, TValue>
|
||||
extends React.HTMLAttributes<HTMLDivElement> {
|
||||
column: Column<TData, TValue>
|
||||
}
|
||||
|
||||
export function DataTableColumnHeader<TData, TValue>({
|
||||
column,
|
||||
className
|
||||
}: DataTableColumnHeaderProps<TData, TValue>) {
|
||||
// @ts-ignore
|
||||
const title = column.columnDef?.meta?.title ?? column.id
|
||||
|
||||
if (!column.getCanSort()) {
|
||||
return <div className={cn(className)}>{title}</div>
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant="link"
|
||||
size="sm"
|
||||
className={cn('-ml-3 cursor-pointer text-inherit h-auto', className)}
|
||||
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
|
||||
>
|
||||
<span>{title}</span>
|
||||
{column.getIsSorted() === 'desc' ? (
|
||||
<ChevronDownIcon />
|
||||
) : column.getIsSorted() === 'asc' ? (
|
||||
<ChevronUpIcon />
|
||||
) : (
|
||||
<ChevronsUpDownIcon />
|
||||
)}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
@@ -1,297 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
useReactTable,
|
||||
type ColumnDef,
|
||||
type ColumnSort,
|
||||
type RowSelectionState,
|
||||
type SortingState,
|
||||
type Table,
|
||||
type VisibilityState
|
||||
} from '@tanstack/react-table'
|
||||
import {
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
type ReactNode
|
||||
} from 'react'
|
||||
import { useSearchParams } from 'react-router'
|
||||
|
||||
import { Card, CardContent } from '@repo/ui/components/ui/card'
|
||||
import {
|
||||
Table as Table_,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow
|
||||
} from '@repo/ui/components/ui/table'
|
||||
import { cn } from '@repo/ui/lib/utils'
|
||||
import { DataTablePagination } from './pagination'
|
||||
|
||||
interface DataTableProps<TData, TValue> {
|
||||
children?: ReactNode
|
||||
columns: ColumnDef<TData, TValue>[]
|
||||
data: TData[]
|
||||
setSelectedRows?: (selectedRows: TData[]) => void
|
||||
pageIndex: number
|
||||
sort: SortingState
|
||||
pageSize: number
|
||||
rowCount: number
|
||||
columnVisibilityInit?: VisibilityState
|
||||
}
|
||||
|
||||
interface TableContextProps<TData> {
|
||||
table: Table<TData>
|
||||
}
|
||||
|
||||
const TableContext = createContext<TableContextProps<any> | null>(null)
|
||||
|
||||
export function useDataTable<TData>() {
|
||||
const ctx = useContext(TableContext)
|
||||
|
||||
if (!ctx) {
|
||||
throw new Error('TableContext is null')
|
||||
}
|
||||
|
||||
return ctx as { table: Table<TData> }
|
||||
}
|
||||
|
||||
export function DataTable<TData, TValue>({
|
||||
data,
|
||||
children,
|
||||
columns,
|
||||
sort,
|
||||
pageIndex,
|
||||
pageSize,
|
||||
rowCount,
|
||||
setSelectedRows,
|
||||
columnVisibilityInit = {}
|
||||
}: DataTableProps<TData, TValue>) {
|
||||
const [dataTable, setDataTable] = useState<TData[]>(data)
|
||||
const [searchParams, setSearchParams] = useSearchParams()
|
||||
const [rowSelection, setRowSelection] = useState<RowSelectionState>({})
|
||||
|
||||
const columnVisibilityInit_ = useMemo<VisibilityState>(() => {
|
||||
const columns = searchParams.get('columns')
|
||||
|
||||
if (columns === null) {
|
||||
return columnVisibilityInit
|
||||
}
|
||||
|
||||
const columnVisibility = columns ? columns.split(',') : []
|
||||
return Object.keys(columnVisibilityInit).reduce<VisibilityState>(
|
||||
(acc, col) => ({
|
||||
...acc,
|
||||
[col]: columnVisibility.includes(col)
|
||||
}),
|
||||
{}
|
||||
)
|
||||
}, [])
|
||||
|
||||
const [columnVisibility, setColumnVisibility_] = useState<VisibilityState>(
|
||||
columnVisibilityInit_
|
||||
)
|
||||
|
||||
const sorting = useMemo(() => {
|
||||
const sortParam = searchParams.get('sort')
|
||||
|
||||
if (!sortParam) {
|
||||
return sort
|
||||
}
|
||||
|
||||
return sortParam.split(',').map((s) => {
|
||||
const [id, dir] = s.split(':')
|
||||
return { id, desc: dir === 'desc' }
|
||||
})
|
||||
}, [searchParams, sort])
|
||||
|
||||
const setPagination = useCallback(
|
||||
(updater: any) => {
|
||||
const newState =
|
||||
typeof updater === 'function'
|
||||
? updater({ pageIndex, pageSize })
|
||||
: updater
|
||||
|
||||
setRowSelection({})
|
||||
setSearchParams((prev) => {
|
||||
prev.set('p', newState?.pageIndex.toString())
|
||||
prev.set('perPage', newState?.pageSize.toString())
|
||||
|
||||
return prev
|
||||
})
|
||||
},
|
||||
[pageIndex, pageSize, setSearchParams]
|
||||
)
|
||||
|
||||
const setSorting = useCallback(
|
||||
(updater: any) => {
|
||||
const newSorting =
|
||||
typeof updater === 'function' ? updater(sorting) : updater
|
||||
|
||||
setSearchParams((prev) => {
|
||||
if (newSorting.length) {
|
||||
const sort = newSorting
|
||||
.map((s: ColumnSort) => `${s.id}:${s.desc ? 'desc' : 'asc'}`)
|
||||
.join(',')
|
||||
prev.set('sort', sort)
|
||||
} else {
|
||||
prev.delete('sort')
|
||||
}
|
||||
|
||||
return prev
|
||||
})
|
||||
},
|
||||
[sorting, setSearchParams]
|
||||
)
|
||||
|
||||
const setColumnVisibility = useCallback(
|
||||
(updater: any) => {
|
||||
const newColumnVisibility =
|
||||
typeof updater === 'function' ? updater(columnVisibility) : updater
|
||||
|
||||
setColumnVisibility_(newColumnVisibility)
|
||||
|
||||
setSearchParams((prev) => {
|
||||
const columns = Object.entries(newColumnVisibility)
|
||||
.filter(([_, visible]) => visible)
|
||||
.map(([col, _]) => col)
|
||||
|
||||
if (columns.length > 0) {
|
||||
prev.set('columns', columns.join(','))
|
||||
} else {
|
||||
prev.set('columns', '')
|
||||
}
|
||||
|
||||
return prev
|
||||
})
|
||||
},
|
||||
[setSearchParams, setColumnVisibility_]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
setDataTable(data)
|
||||
}, [data])
|
||||
|
||||
const getRowId = useCallback((row: any) => row.id, [])
|
||||
const removeRow = useCallback((rowId: string) => {
|
||||
setDataTable((rows) => rows.filter((row: any) => row.id !== rowId))
|
||||
}, [])
|
||||
|
||||
const table = useReactTable({
|
||||
data: dataTable,
|
||||
columns,
|
||||
rowCount,
|
||||
state: {
|
||||
sorting,
|
||||
rowSelection,
|
||||
columnVisibility,
|
||||
pagination: { pageIndex, pageSize }
|
||||
},
|
||||
manualSorting: true,
|
||||
manualPagination: true,
|
||||
enableRowSelection: true,
|
||||
getRowId,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
onRowSelectionChange: setRowSelection,
|
||||
onSortingChange: setSorting,
|
||||
onColumnVisibilityChange: setColumnVisibility,
|
||||
onPaginationChange: setPagination,
|
||||
meta: { removeRow }
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (!setSelectedRows) return
|
||||
|
||||
const selected = table.getSelectedRowModel().flatRows.map((r) => r.original)
|
||||
setSelectedRows(selected)
|
||||
}, [rowSelection, setSelectedRows, table])
|
||||
|
||||
return (
|
||||
<TableContext value={{ table }}>
|
||||
<div className="space-y-2.5 max-md:mb-2">
|
||||
<Card className="relative w-full overflow-auto">
|
||||
<CardContent>
|
||||
{children}
|
||||
|
||||
<Table_ className="table-auto">
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow
|
||||
key={headerGroup.id}
|
||||
className="hover:bg-transparent"
|
||||
>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead
|
||||
key={header.id}
|
||||
className={cn(
|
||||
'p-2.5',
|
||||
// @ts-ignore
|
||||
header.column.columnDef.meta?.className
|
||||
)}
|
||||
>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</TableHead>
|
||||
)
|
||||
})}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
|
||||
<TableBody>
|
||||
{table.getRowModel().rows?.length ? (
|
||||
table.getRowModel().rows.map((row) => (
|
||||
<TableRow
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && 'selected'}
|
||||
className="has-[[data-state=open]]:bg-muted/50"
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<TableCell
|
||||
key={cell.id}
|
||||
className={cn(
|
||||
'p-2.5',
|
||||
// @ts-ignore
|
||||
cell.column.columnDef.meta?.className
|
||||
)}
|
||||
>
|
||||
{flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext()
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={columns.length}
|
||||
className="h-24 text-center"
|
||||
>
|
||||
Nenhum resultado.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table_>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<DataTablePagination table={table} />
|
||||
</div>
|
||||
</TableContext>
|
||||
)
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export { DataTableColumnHeader } from './column-header'
|
||||
export { DataTable } from './data-table'
|
||||
export { DataTableViewOptions } from './view-options'
|
||||
@@ -1,75 +0,0 @@
|
||||
import { type Table } from '@tanstack/react-table'
|
||||
import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'
|
||||
|
||||
import { Button } from '@repo/ui/components/ui/button'
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue
|
||||
} from '@repo/ui/components/ui/select'
|
||||
|
||||
interface DataTablePaginationProps<TData> {
|
||||
table: Table<TData>
|
||||
}
|
||||
|
||||
export function DataTablePagination<TData>({
|
||||
table
|
||||
}: DataTablePaginationProps<TData>) {
|
||||
const { pageIndex, pageSize } = table.getState().pagination
|
||||
const rowCount = table.getRowCount()
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-end gap-3 lg:gap-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<p className="text-sm font-medium hidden lg:block">Itens por página</p>
|
||||
<Select
|
||||
value={String(table.getState().pagination.pageSize)}
|
||||
onValueChange={(value) => {
|
||||
table.setPageSize(Number(value))
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={table.getState().pagination.pageSize} />
|
||||
</SelectTrigger>
|
||||
<SelectContent side="top">
|
||||
{[12, 25, 50, 100].map((pageSize) => (
|
||||
<SelectItem key={pageSize} value={String(pageSize)}>
|
||||
{pageSize}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="text-sm font-medium">
|
||||
{(pageIndex + 1) * pageSize - pageSize + 1}-
|
||||
{Math.min((pageIndex + 1) * pageSize, rowCount)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 *:cursor-pointer">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="size-8"
|
||||
onClick={() => table.previousPage()}
|
||||
disabled={!table.getCanPreviousPage()}
|
||||
>
|
||||
<span className="sr-only">Ir para a página anterior</span>
|
||||
<ChevronLeftIcon />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="size-8"
|
||||
onClick={() => table.nextPage()}
|
||||
disabled={!table.getCanNextPage()}
|
||||
>
|
||||
<span className="sr-only">Ir para a próxima página</span>
|
||||
<ChevronRightIcon />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { Columns2Icon } from 'lucide-react'
|
||||
|
||||
import { Button } from '@repo/ui/components/ui/button'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuCheckboxItem,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuTrigger
|
||||
} from '@repo/ui/components/ui/dropdown-menu'
|
||||
import { cn } from '@repo/ui/lib/utils'
|
||||
import { useDataTable } from './data-table'
|
||||
|
||||
export function DataTableViewOptions<TData>({
|
||||
className
|
||||
}: {
|
||||
className: string
|
||||
}) {
|
||||
const { table } = useDataTable()
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" className={cn('cursor-pointer', className)}>
|
||||
<Columns2Icon /> Colunas
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-44 *:cursor-pointer">
|
||||
{table
|
||||
.getAllColumns()
|
||||
.filter(
|
||||
(column) =>
|
||||
typeof column.accessorFn !== 'undefined' && column.getCanHide()
|
||||
)
|
||||
.map((column) => {
|
||||
// @ts-ignore
|
||||
const title = column.columnDef?.meta?.title ?? column.id
|
||||
|
||||
return (
|
||||
<DropdownMenuCheckboxItem
|
||||
key={column.id}
|
||||
checked={column.getIsVisible()}
|
||||
onSelect={(e) => e.preventDefault()}
|
||||
onCheckedChange={(value) => column.toggleVisibility(!!value)}
|
||||
>
|
||||
{title}
|
||||
</DropdownMenuCheckboxItem>
|
||||
)
|
||||
})}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
)
|
||||
}
|
||||
@@ -44,9 +44,7 @@ export function NavMain({
|
||||
<SidebarGroup>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
<SidebarGroupLabel className="uppercase">
|
||||
Colaboradores
|
||||
</SidebarGroupLabel>
|
||||
<SidebarGroupLabel>Colaboradores</SidebarGroupLabel>
|
||||
{data.navUser.map((props, idx) => (
|
||||
<SidebarMenuItemLink key={idx} {...props} />
|
||||
))}
|
||||
@@ -57,9 +55,7 @@ export function NavMain({
|
||||
<SidebarGroup>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
<SidebarGroupLabel className="uppercase">
|
||||
Gestão de matrículas
|
||||
</SidebarGroupLabel>
|
||||
<SidebarGroupLabel>Gestão de matrículas</SidebarGroupLabel>
|
||||
{data.navEnrollment.map((props, idx) => (
|
||||
<SidebarMenuItemLink key={idx} {...props} />
|
||||
))}
|
||||
@@ -80,7 +76,7 @@ function SidebarMenuItemLink({ title, url, icon: Icon }: NavItem) {
|
||||
return (
|
||||
<SidebarMenuItem key={title} onClick={onToggle}>
|
||||
<NavLink to={`/${orgid}${url}`}>
|
||||
{({ isActive, isPending }) => (
|
||||
{({ isActive }) => (
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
className="data-[active=true]:text-lime-500"
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { EllipsisIcon } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
import { type DateRange } from 'react-day-picker'
|
||||
import { ptBR } from 'react-day-picker/locale'
|
||||
|
||||
import { Badge } from '@repo/ui/components/ui/badge'
|
||||
import { Button } from '@repo/ui/components/ui/button'
|
||||
import { Calendar } from '@repo/ui/components/ui/calendar'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuRadioGroup,
|
||||
DropdownMenuRadioItem,
|
||||
DropdownMenuTrigger
|
||||
} from '@repo/ui/components/ui/dropdown-menu'
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger
|
||||
} from '@repo/ui/components/ui/popover'
|
||||
import { Separator } from '@repo/ui/components/ui/separator'
|
||||
import { cn } from '@repo/ui/lib/utils'
|
||||
|
||||
const formatted = new Intl.DateTimeFormat('pt-BR', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: '2-digit'
|
||||
})
|
||||
|
||||
type FilterProps = {
|
||||
rangeField?: string
|
||||
dateRange?: DateRange
|
||||
}
|
||||
|
||||
type RangeCalendarFilterProps = {
|
||||
title: string
|
||||
icon: React.ComponentType
|
||||
value?: FilterProps
|
||||
options: { value: string; label: string }[]
|
||||
className?: string
|
||||
onChange?: (values: FilterProps | undefined) => void
|
||||
}
|
||||
|
||||
export function RangeCalendarFilter({
|
||||
title,
|
||||
icon: Icon,
|
||||
value = undefined,
|
||||
options = [],
|
||||
className,
|
||||
onChange
|
||||
}: RangeCalendarFilterProps) {
|
||||
const [rangeField, setRangeField] = useState<string | undefined>(
|
||||
value?.rangeField || options?.[0]?.value
|
||||
)
|
||||
const [dateRange, setDateRange] = useState<DateRange | undefined>(
|
||||
value?.dateRange
|
||||
)
|
||||
|
||||
const handleReset = () => {
|
||||
onChange?.(undefined)
|
||||
setRangeField(options?.[0]?.value)
|
||||
setDateRange(undefined)
|
||||
}
|
||||
|
||||
return (
|
||||
<Popover>
|
||||
<div
|
||||
className={cn(
|
||||
'h-9 border rounded-md dark:bg-input/30 border-dashed flex items-center justify-center',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="ghost" size="sm" className="cursor-pointer h-full">
|
||||
<Icon /> {title}
|
||||
{dateRange && (
|
||||
<>
|
||||
<Separator orientation="vertical" className="mx-0.5 h-4" />
|
||||
<div className="gap-1 flex">
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="rounded-sm px-1 font-mono"
|
||||
>
|
||||
{formatted.format(dateRange.from)}
|
||||
</Badge>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="rounded-sm px-1 font-mono"
|
||||
>
|
||||
{formatted.format(dateRange.to)}
|
||||
</Badge>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
|
||||
{dateRange && (
|
||||
<>
|
||||
<Separator orientation="vertical" className="h-4" />
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="sm" className="cursor-pointer">
|
||||
<EllipsisIcon />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-46" align="end">
|
||||
<DropdownMenuRadioGroup
|
||||
value={rangeField}
|
||||
onValueChange={(rangeField) => {
|
||||
setRangeField(rangeField)
|
||||
onChange?.({ rangeField, dateRange })
|
||||
}}
|
||||
className="*:cursor-pointer"
|
||||
>
|
||||
{options.map(({ label, value }, idx) => (
|
||||
<DropdownMenuRadioItem value={value} key={idx}>
|
||||
{label}
|
||||
</DropdownMenuRadioItem>
|
||||
))}
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<PopoverContent className="w-full p-0" align="start">
|
||||
<Calendar
|
||||
mode="range"
|
||||
locale={ptBR}
|
||||
captionLayout="dropdown"
|
||||
defaultMonth={dateRange?.from}
|
||||
selected={dateRange}
|
||||
numberOfMonths={1}
|
||||
startMonth={new Date(2012, 0)}
|
||||
endMonth={new Date(new Date().getFullYear() + 1, 0)}
|
||||
onSelect={(dateRange: DateRange | undefined) => {
|
||||
if (!dateRange) {
|
||||
onChange?.(undefined)
|
||||
return setDateRange(undefined)
|
||||
}
|
||||
|
||||
if (dateRange.from?.getTime() === dateRange.to?.getTime()) {
|
||||
const nextDay = new Date(String(dateRange.from))
|
||||
nextDay.setDate(nextDay.getDate() + 6)
|
||||
dateRange.to = nextDay
|
||||
}
|
||||
|
||||
onChange?.({ rangeField, dateRange })
|
||||
setDateRange(dateRange)
|
||||
}}
|
||||
/>
|
||||
|
||||
{dateRange && (
|
||||
<>
|
||||
<Separator />
|
||||
<div className="p-1">
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="w-full cursor-pointer font-normal"
|
||||
onClick={handleReset}
|
||||
>
|
||||
Limpar
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)
|
||||
}
|
||||
@@ -18,7 +18,6 @@ import {
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
SidebarRail,
|
||||
useSidebar
|
||||
} from '@repo/ui/components/ui/sidebar'
|
||||
import { initials } from '@repo/ui/lib/utils'
|
||||
@@ -153,7 +152,6 @@ export function WorkspaceSwitcher() {
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</SidebarMenuItem>
|
||||
<SidebarRail />
|
||||
</SidebarMenu>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -10,8 +10,7 @@ import { Suspense } from 'react'
|
||||
import { Await, NavLink, useParams, useRevalidator } from 'react-router'
|
||||
import { toast } from 'sonner'
|
||||
|
||||
import { Abbr } from '@/components/abbr'
|
||||
|
||||
import { Abbr } from '@repo/ui/components/abbr'
|
||||
import { Skeleton } from '@repo/ui/components/skeleton'
|
||||
import {
|
||||
AlertDialog,
|
||||
@@ -180,8 +179,11 @@ function RevokeItem({ id }: { id: string }) {
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Tem certeza absoluta?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
Esta ação não pode ser desfeita. Isso revogará permanentemente os
|
||||
privilégios deste gestor.
|
||||
Esta ação não pode ser desfeita. Isso{' '}
|
||||
<span className="font-bold">
|
||||
revogará permanentemente os privilégios
|
||||
</span>{' '}
|
||||
deste gestor.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter className="*:cursor-pointer">
|
||||
|
||||
@@ -12,6 +12,8 @@ import {
|
||||
import type { ComponentProps, MouseEvent } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
|
||||
import { Abbr } from '@repo/ui/components/abbr'
|
||||
import { DataTableColumnHeader } from '@repo/ui/components/data-table'
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
@@ -38,8 +40,6 @@ import { Progress } from '@repo/ui/components/ui/progress'
|
||||
import { Spinner } from '@repo/ui/components/ui/spinner'
|
||||
import { cn, initials } from '@repo/ui/lib/utils'
|
||||
|
||||
import { Abbr } from '@/components/abbr'
|
||||
import { DataTableColumnHeader } from '@/components/data-table/column-header'
|
||||
import { labels, statuses } from './data'
|
||||
|
||||
// This type is used to define the shape of our data.
|
||||
@@ -384,8 +384,11 @@ function RemoveDedupItem({
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Tem certeza absoluta?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
Esta ação não pode ser desfeita. Isso remove a proteção contra
|
||||
duplicação permanentemente desta matrícula.
|
||||
Esta ação não pode ser desfeita. Isso{' '}
|
||||
<span className="font-bold">
|
||||
remove a proteção contra duplicação permanentemente
|
||||
</span>{' '}
|
||||
desta matrícula.
|
||||
</AlertDialogDescription>
|
||||
{daysRemaining && (
|
||||
<AlertDialogDescription>
|
||||
@@ -453,8 +456,11 @@ function CancelItem({
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Tem certeza absoluta?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
Esta ação não pode ser desfeita. Isso cancelar permanentemente a
|
||||
matrícula deste colaborador.
|
||||
Esta ação não pode ser desfeita. Isso{' '}
|
||||
<span className="font-bold">
|
||||
cancelar permanentemente a matrícula
|
||||
</span>{' '}
|
||||
deste colaborador.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter className="*:cursor-pointer">
|
||||
|
||||
@@ -16,10 +16,9 @@ import { Await, Link, Outlet, useParams, useSearchParams } from 'react-router'
|
||||
import type { BookType } from 'xlsx'
|
||||
import * as XLSX from 'xlsx'
|
||||
|
||||
import { DataTable, DataTableViewOptions } from '@/components/data-table'
|
||||
import { RangeCalendarFilter } from '@/components/range-calendar-filter'
|
||||
|
||||
import { DataTable, DataTableViewOptions } from '@repo/ui/components/data-table'
|
||||
import { FacetedFilter } from '@repo/ui/components/faceted-filter'
|
||||
import { RangeCalendarFilter } from '@repo/ui/components/range-calendar-filter'
|
||||
import { SearchForm } from '@repo/ui/components/search-form'
|
||||
import { Skeleton } from '@repo/ui/components/skeleton'
|
||||
import { Button } from '@repo/ui/components/ui/button'
|
||||
@@ -32,6 +31,7 @@ import {
|
||||
} from '@repo/ui/components/ui/dropdown-menu'
|
||||
import { Kbd } from '@repo/ui/components/ui/kbd'
|
||||
import { createSearch } from '@repo/util/meili'
|
||||
|
||||
import { columns, type Enrollment } from './columns'
|
||||
import { headers, sortings, statuses } from './data'
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@ import type { Route } from './+types'
|
||||
import { Suspense } from 'react'
|
||||
import { Await } from 'react-router'
|
||||
|
||||
import { DataTable } from '@/components/data-table'
|
||||
|
||||
import { DataTable } from '@repo/ui/components/data-table'
|
||||
import { Skeleton } from '@repo/ui/components/skeleton'
|
||||
import { createSearch } from '@repo/util/meili'
|
||||
|
||||
import { columns, type Order } from './columns'
|
||||
|
||||
export function meta({}: Route.MetaArgs) {
|
||||
|
||||
@@ -11,8 +11,8 @@ import {
|
||||
import { NavLink, useParams } from 'react-router'
|
||||
import { toast } from 'sonner'
|
||||
|
||||
import { Abbr } from '@/components/abbr'
|
||||
import { useDataTable } from '@/components/data-table/data-table'
|
||||
import { Abbr } from '@repo/ui/components/abbr'
|
||||
import { useDataTable } from '@repo/ui/components/data-table'
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
@@ -183,8 +183,11 @@ function UnlinkItem({ id }: { id: string }) {
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Tem certeza absoluta?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
Esta ação não pode ser desfeita. Isso removerá permanentemente o
|
||||
vínculo deste colaborador.
|
||||
Esta ação não pode ser desfeita. Isso{' '}
|
||||
<span className="font-bold">
|
||||
removerá permanentemente o vínculo
|
||||
</span>{' '}
|
||||
deste colaborador.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter className="*:cursor-pointer">
|
||||
|
||||
@@ -4,9 +4,7 @@ import { PlusIcon } from 'lucide-react'
|
||||
import { Suspense } from 'react'
|
||||
import { Await, Link, useSearchParams } from 'react-router'
|
||||
|
||||
import { DataTable } from '@/components/data-table'
|
||||
import { columns, type User } from './columns'
|
||||
|
||||
import { DataTable } from '@repo/ui/components/data-table'
|
||||
import { SearchForm } from '@repo/ui/components/search-form'
|
||||
import { Skeleton } from '@repo/ui/components/skeleton'
|
||||
import { Button } from '@repo/ui/components/ui/button'
|
||||
@@ -23,6 +21,8 @@ export function meta({}: Route.MetaArgs) {
|
||||
]
|
||||
}
|
||||
|
||||
import { columns, type User } from './columns'
|
||||
|
||||
export async function loader({ params, context, request }: Route.LoaderArgs) {
|
||||
const { searchParams } = new URL(request.url)
|
||||
const { orgid } = params
|
||||
|
||||
@@ -2,8 +2,7 @@ import type { Route } from './+types'
|
||||
|
||||
import { useLoaderData } from 'react-router'
|
||||
|
||||
import { DataTable } from '@/components/data-table'
|
||||
import { columns, type Webhook } from './columns'
|
||||
import { type Webhook } from './columns'
|
||||
|
||||
export function meta({}: Route.MetaArgs) {
|
||||
return [{ title: 'Webhooks' }]
|
||||
@@ -24,8 +23,6 @@ export default function Page() {
|
||||
Adicione webhooks para sua organização.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<DataTable columns={columns} data={data} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export const middleware: Route.MiddlewareFunction[] = [authMiddleware]
|
||||
|
||||
export async function loader({ params, context, request }: Route.ActionArgs) {
|
||||
const user = context.get(userContext)
|
||||
const rawCookie = request.headers.get('cookie')
|
||||
const rawCookie = request.headers.get('cookie') || ''
|
||||
const parsedCookies = cookie.parse(rawCookie)
|
||||
const { sidebar_state } = parsedCookies
|
||||
|
||||
|
||||
Reference in New Issue
Block a user