Spaces:
Running
Running
File size: 3,018 Bytes
bfd3ad3 38de65f bfd3ad3 f46336a 38de65f f46336a 38de65f f46336a 38de65f bfd3ad3 38de65f bfd3ad3 f46336a 38de65f 13083aa f46336a 8728aad f46336a 13083aa f46336a 13083aa f46336a 38de65f 13083aa f46336a 38de65f bfd3ad3 13083aa bfd3ad3 f46336a 38de65f 13083aa 38de65f 13083aa 38de65f 13083aa 38de65f f46336a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
import { CalendarDays, Globe, Tag, Clock, AlarmClock } from "lucide-react";
import { Conference } from "@/types/conference";
import { formatDistanceToNow, parseISO, isValid } from "date-fns";
const ConferenceCard = ({
title,
full_name,
date,
place,
deadline,
timezone,
tags = [],
link,
note,
abstract_deadline,
}: Conference) => {
const deadlineDate = deadline && deadline !== 'TBD' ? parseISO(deadline) : null;
const daysLeft = deadlineDate && isValid(deadlineDate) ? formatDistanceToNow(deadlineDate, { addSuffix: true }) : 'TBD';
// Determine countdown color based on days remaining
const getCountdownColor = () => {
if (!deadlineDate || !isValid(deadlineDate)) return "text-neutral-600";
const daysRemaining = Math.ceil((deadlineDate.getTime() - new Date().getTime()) / (1000 * 60 * 60 * 24));
if (daysRemaining <= 7) return "text-red-600";
if (daysRemaining <= 30) return "text-orange-600";
return "text-green-600";
};
return (
<div className="conference-card">
<div className="mb-3">
{link ? (
<a
href={link}
target="_blank"
rel="noopener noreferrer"
className="hover:underline"
>
<h3 className="text-lg font-semibold text-primary">{title}</h3>
</a>
) : (
<h3 className="text-lg font-semibold">{title}</h3>
)}
{full_name && <p className="text-xs text-neutral-600 truncate">{full_name}</p>}
</div>
<div className="flex flex-col gap-2 mb-3">
<div className="flex items-center text-neutral">
<CalendarDays className="h-4 w-4 mr-2 flex-shrink-0" />
<span className="text-sm truncate">{date}</span>
</div>
<div className="flex items-center text-neutral">
<Globe className="h-4 w-4 mr-2 flex-shrink-0" />
<span className="text-sm truncate">{place}</span>
</div>
<div className="flex items-center text-neutral">
<Clock className="h-4 w-4 mr-2 flex-shrink-0" />
<span className="text-sm truncate">
{deadline === 'TBD' ? 'TBD' : deadline}
</span>
</div>
<div className="flex items-center">
<AlarmClock className={`h-4 w-4 mr-2 flex-shrink-0 ${getCountdownColor()}`} />
<span className={`text-sm font-medium truncate ${getCountdownColor()}`}>
{daysLeft}
</span>
</div>
</div>
{Array.isArray(tags) && tags.length > 0 && (
<div className="flex flex-wrap gap-1 mt-auto">
{tags.map((tag) => (
<span key={tag} className="tag text-xs py-0.5">
<Tag className="h-3 w-3 mr-1" />
{tag}
</span>
))}
</div>
)}
{note && (
<div
className="text-xs text-neutral-600 mt-2"
dangerouslySetInnerHTML={{ __html: note }}
/>
)}
</div>
);
};
export default ConferenceCard;
|