academic/src/components/Card.tsx
2025-09-21 22:49:24 +02:00

83 lines
2.4 KiB
TypeScript

import type { CardDownloadType } from '@/types/cards'
import Mdown from './Mdown'
import { useState } from 'react'
interface Props {
title: string
content: string
id?: number
downloads?: Array<CardDownloadType>
}
export default function Card({ title, content, id, downloads }: Props) {
return (
<div className="bg-[#161718] w-xl max-w-4/5 p-5 flex flex-col gap-5 rounded-xl self-center hover:shadow-xl/20 hover:shadow-white transition-shadow mb-5">
<h1 className="text-white text-2xl font-bold" id={id?.toString()}>
<Mdown>{title}</Mdown>
</h1>
<div className=" flex flex-col space-y-1 text-[#9e9b97]">
<Mdown>{content}</Mdown>
</div>
{downloads != null ? (
<details className="text-[#9e9b97]">
<summary>Téléchargments</summary>
<ol className="list-disc list-inside pl-5">
{downloads.map((e, i) => (
<Download e={e} i={i} />
))}
</ol>
</details>
) : null}
</div>
)
}
interface DownloadProps {
e: CardDownloadType
i: number
}
function Download({ e, i }: DownloadProps) {
const [isDownloading, setIsDownloading] = useState(false)
function download(path: URL, fileName = 'file') {
if (isDownloading) {
return
}
setIsDownloading(true)
fetch(path)
.then((response) => response.blob())
.then((blob) => {
const url = window.URL.createObjectURL(new Blob([blob]))
const link = document.createElement('a')
link.href = url
link.download = fileName
document.body.appendChild(link)
link.click()
link.parentNode?.removeChild(link)
setIsDownloading(false)
})
}
return (
<li>
<a
key={i}
className={
isDownloading
? 'text-gray-600 underline cursor-wait'
: 'text-sky-600 underline cursor-pointer'
}
onClick={() => download(e.link, e.filename)}
>
{isDownloading ? '[Téléchargement en cours ...] ' : null}{' '}
{e.title}
</a>
</li>
)
}