карточки редизайн
This commit is contained in:
28
src/component/ui/popover.tsx
Normal file
28
src/component/ui/popover.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import { cn } from '@/lib/utils'
|
||||
import * as PopoverPrimitive from '@radix-ui/react-popover'
|
||||
import * as React from 'react'
|
||||
|
||||
const Popover = PopoverPrimitive.Root
|
||||
const PopoverTrigger = PopoverPrimitive.Trigger
|
||||
const PopoverAnchor = PopoverPrimitive.Anchor
|
||||
|
||||
const PopoverContent = React.forwardRef<
|
||||
React.ElementRef<typeof PopoverPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
|
||||
>(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (
|
||||
<PopoverPrimitive.Portal>
|
||||
<PopoverPrimitive.Content
|
||||
ref={ref}
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</PopoverPrimitive.Portal>
|
||||
))
|
||||
PopoverContent.displayName = PopoverPrimitive.Content.displayName
|
||||
|
||||
export { Popover, PopoverAnchor, PopoverContent, PopoverTrigger }
|
||||
@@ -132,6 +132,31 @@ export const DEFAULT_FUNCTIONS: Record<string, ExcelFunction> = {
|
||||
date.setHours(0, 0, 0, 0)
|
||||
return date.getTime()
|
||||
},
|
||||
ДАТАПРОТОКОЛА: (дата: number | Date) => {
|
||||
try {
|
||||
const months = [
|
||||
'',
|
||||
'января', 'февраля', 'марта',
|
||||
'апреля', 'мая', 'июня',
|
||||
'июля', 'августа', 'сентября',
|
||||
'октября', 'ноября', 'декабря',
|
||||
]
|
||||
let dateObj: Date
|
||||
if (typeof дата === 'number') {
|
||||
dateObj = new Date(дата)
|
||||
} else if (дата instanceof Date) {
|
||||
dateObj = дата
|
||||
} else {
|
||||
return 'Неверный формат даты'
|
||||
}
|
||||
const day = dateObj.getDate().toString().padStart(2, '0')
|
||||
const month = months[dateObj.getMonth() + 1]
|
||||
const year = dateObj.getFullYear()
|
||||
return `${day} ${month} ${year}`
|
||||
} catch (e) {
|
||||
return 'Неверный формат даты'
|
||||
}
|
||||
},
|
||||
|
||||
// Отладочная функция
|
||||
ТЕСТ: (значение: any = 'Функция работает!') => {
|
||||
|
||||
@@ -130,7 +130,7 @@ export const TemplatesOverviewPage = () => {
|
||||
<header className="flex items-center gap-2 border-b px-4 py-2">
|
||||
<SidebarTrigger />
|
||||
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||
<h1 className="text-lg font-semibold">Шаблоны</h1>
|
||||
<h1 className="text-lg font-semibold">Карточки протоколов</h1>
|
||||
|
||||
<div className="ml-auto flex items-center gap-2">
|
||||
{selectionMode && (
|
||||
@@ -263,8 +263,8 @@ export const TemplatesOverviewPage = () => {
|
||||
|
||||
<section
|
||||
className={clsx(
|
||||
'grid gap-6',
|
||||
'grid-cols-1 md:grid-cols-2 lg:grid-cols-3'
|
||||
'grid gap-4',
|
||||
'grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5'
|
||||
)}
|
||||
>
|
||||
{filteredTemplates.map(t => (
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import { Button } from '@/component/ui/button'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/component/ui/card'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/component/ui/popover'
|
||||
import { Template } from '@/type/template'
|
||||
import clsx from 'clsx'
|
||||
import { CheckCircle, Circle, FileText, Settings, Wrench } from 'lucide-react'
|
||||
import {
|
||||
Check,
|
||||
FileText,
|
||||
MoreVertical,
|
||||
Pencil,
|
||||
Settings,
|
||||
Wrench,
|
||||
} from 'lucide-react'
|
||||
import React from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
@@ -35,11 +43,13 @@ const TemplateCard: React.FC<TemplateCardProps> = ({
|
||||
: undefined
|
||||
}
|
||||
className={clsx(
|
||||
'relative', // <-- добавьте этот класс!
|
||||
'border-2 ring-4 ring-offset-2',
|
||||
selectionMode && 'hover:cursor-pointer',
|
||||
selectionMode &&
|
||||
isSelected &&
|
||||
'border-2 border-primary ring-4 ring-primary/30 ring-offset-2',
|
||||
'hover:border-2 hover:border-primary'
|
||||
selectionMode && isSelected
|
||||
? 'border-primary ring-primary/30'
|
||||
: 'border-border ring-transparent',
|
||||
'hover:border-primary'
|
||||
)}
|
||||
>
|
||||
{selectionMode && (
|
||||
@@ -58,9 +68,38 @@ const TemplateCard: React.FC<TemplateCardProps> = ({
|
||||
'focus-visible:ring-2 focus-visible:ring-accent'
|
||||
)}
|
||||
>
|
||||
{isSelected ? <CheckCircle size={18} /> : <Circle size={18} />}
|
||||
{isSelected ? <Check size={18} /> : null}
|
||||
</button>
|
||||
)}
|
||||
{/* Popover-меню с действиями, только если не selectionMode */}
|
||||
{!selectionMode && (
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
tabIndex={0}
|
||||
aria-label="Действия"
|
||||
className={clsx(
|
||||
'absolute right-3 top-3 z-10 flex h-7 w-7 items-center justify-center rounded-full border border-border bg-white text-muted-foreground transition-all',
|
||||
'hover:text-accent-foreground',
|
||||
'focus-visible:ring-2 focus-visible:ring-accent'
|
||||
)}
|
||||
>
|
||||
<MoreVertical className="h-4 w-4" />
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="end" className="w-40 p-1">
|
||||
<button
|
||||
type="button"
|
||||
className="flex w-full items-center gap-2 rounded px-2 py-2 text-sm transition-colors hover:bg-accent hover:text-accent-foreground"
|
||||
>
|
||||
<Pencil className="h-4 w-4" />
|
||||
Редактировать
|
||||
</button>
|
||||
{/* Здесь можно добавить другие действия */}
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)}
|
||||
|
||||
<CardHeader className="pb-4">
|
||||
<CardTitle className="text-base font-medium">{template.name}</CardTitle>
|
||||
|
||||
Reference in New Issue
Block a user