itmpwk.ac.id/resources/js/pages/admin/academic-classes/materials/card.tsx

82 lines
3.2 KiB
TypeScript

import { Pencil, Trash2 } from 'lucide-react';
import { AttachmentPreviewDialog } from '@/components/attachment-preview-dialog';
import { RowActions } from '@/components/row-actions';
import { Badge } from '@/components/ui/badge';
import type { Material } from '@/types/material';
type CreateCardParams = {
handleEdit: (material: Material) => void;
handleDeleteClick: (material: Material) => void;
canUpdate: boolean;
canDelete: boolean;
};
export function createMaterialCard(params: CreateCardParams) {
const { handleEdit, handleDeleteClick, canUpdate, canDelete } = params;
return function MaterialCard(material: Material) {
const courseClass = material.course_class;
return (
<div className="flex flex-col gap-3">
<div className="flex items-start justify-between gap-2">
<div className="flex flex-wrap items-center gap-2">
{material.meeting_number && (
<Badge variant="secondary">
Pertemuan {material.meeting_number}
</Badge>
)}
</div>
{(canUpdate || canDelete) && (
<RowActions
actions={[
{
label: 'Edit',
icon: <Pencil className="h-4 w-4" />,
show: canUpdate,
onClick: () => handleEdit(material),
},
{
label: 'Hapus',
icon: (
<Trash2 className="h-4 w-4 text-destructive" />
),
show: canDelete,
onClick: () => handleDeleteClick(material),
},
]}
/>
)}
</div>
<div>
<p className="font-medium">{material.title}</p>
{material.description && (
<p className="mt-1 line-clamp-2 text-sm text-muted-foreground">
{material.description}
</p>
)}
</div>
<p className="text-sm text-muted-foreground">
{courseClass
? `${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>
);
};
}