feat: enhance AttachmentPreviewDialog integration; add icon variant and improve file display in material cards

This commit is contained in:
Yoga Pangestu 2026-09-04 11:51:27 +07:00
parent 19397d3b5b
commit facf7ab177
3 changed files with 68 additions and 59 deletions

View File

@ -1,11 +1,17 @@
import { Paperclip } from 'lucide-react';
import { Eye, Paperclip } from 'lucide-react';
import { useState } from 'react';
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip';
import { cn } from '@/lib/utils';
const IMAGE_EXTENSIONS = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
@ -19,12 +25,14 @@ type AttachmentPreviewDialogProps = {
fileUrl: string;
fileName: string;
className?: string;
variant?: 'link' | 'icon';
};
export function AttachmentPreviewDialog({
fileUrl,
fileName,
className,
variant = 'link',
}: AttachmentPreviewDialogProps) {
const [open, setOpen] = useState(false);
const extension = fileExtension(fileName);
@ -34,17 +42,34 @@ export function AttachmentPreviewDialog({
return (
<>
<button
type="button"
onClick={() => setOpen(true)}
className={cn(
'inline-flex items-center gap-1 text-primary underline underline-offset-4 hover:text-primary/80',
className,
)}
>
<Paperclip className="h-3.5 w-3.5 shrink-0" />
<span className="truncate">{fileName}</span>
</button>
{variant === 'icon' ? (
<Tooltip>
<TooltipTrigger asChild>
<Button
type="button"
variant="ghost"
size="icon"
className={className}
onClick={() => setOpen(true)}
>
<Eye className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="top">Lihat</TooltipContent>
</Tooltip>
) : (
<button
type="button"
onClick={() => setOpen(true)}
className={cn(
'inline-flex items-center gap-1 text-primary underline underline-offset-4 hover:text-primary/80',
className,
)}
>
<Paperclip className="h-3.5 w-3.5 shrink-0" />
<span className="truncate">{fileName}</span>
</button>
)}
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent

View File

@ -27,7 +27,14 @@ export function createMaterialCard(params: CreateCardParams) {
</Badge>
)}
</div>
{(canUpdate || canDelete) && (
<div className="flex items-center">
{material.file_url && material.file_name && (
<AttachmentPreviewDialog
fileUrl={material.file_url}
fileName={material.file_name}
variant="icon"
/>
)}
<RowActions
actions={[
{
@ -46,7 +53,7 @@ export function createMaterialCard(params: CreateCardParams) {
},
]}
/>
)}
</div>
</div>
<div>
@ -63,18 +70,6 @@ export function createMaterialCard(params: CreateCardParams) {
? `${courseClass.course?.code ?? ''} ${courseClass.course?.name ?? ''}`
: '-'}
</p>
{material.files.length > 0 && (
<div className="flex flex-col gap-1">
{material.files.map((file) => (
<AttachmentPreviewDialog
key={file.id}
fileUrl={file.url}
fileName={file.name}
/>
))}
</div>
)}
</div>
);
};

View File

@ -64,38 +64,27 @@ export function createMaterialColumns(
return `${courseClass.course?.code ?? ''} ${courseClass.course?.name ?? ''}`;
},
},
{
accessorKey: 'file_name',
header: () => <span>File</span>,
cell: ({ row }) => {
const material = row.original;
if (!material.file_url || !material.file_name) {
return <span className="text-muted-foreground">-</span>;
}
return (
<AttachmentPreviewDialog
fileUrl={material.file_url}
fileName={material.file_name}
/>
);
},
},
];
if (canUpdate || canDelete) {
columns.push({
id: 'actions',
header: () => <span className="block text-center">Aksi</span>,
meta: {
className: 'w-[100px] text-center',
headerClassName: 'w-[100px] text-center',
},
cell: ({ row }) => {
const material = row.original;
columns.push({
id: 'actions',
header: () => <span className="block text-center">Aksi</span>,
meta: {
className: 'w-[130px] text-center',
headerClassName: 'w-[130px] text-center',
},
cell: ({ row }) => {
const material = row.original;
return (
return (
<div className="flex items-center justify-center">
{material.file_url && material.file_name && (
<AttachmentPreviewDialog
fileUrl={material.file_url}
fileName={material.file_name}
variant="icon"
/>
)}
<RowActions
actions={[
{
@ -114,10 +103,10 @@ export function createMaterialColumns(
},
]}
/>
);
},
});
}
</div>
);
},
});
return columns;
}