Spaces:
Sleeping
Sleeping
File size: 3,106 Bytes
bfd3ad3 38de65f bfd3ad3 f46336a 38de65f f46336a 38de65f f46336a 38de65f bfd3ad3 38de65f bfd3ad3 f46336a 38de65f f46336a 38de65f f46336a 38de65f f46336a 38de65f f46336a 38de65f bfd3ad3 f46336a 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 94 95 96 97 98 99 |
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="flex justify-between items-start mb-4">
<div>
<h3 className="text-xl font-semibold">{title}</h3>
{full_name && <p className="text-sm text-neutral-600">{full_name}</p>}
</div>
{link && (
<a
href={link}
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline text-sm"
>
Website →
</a>
)}
</div>
<div className="space-y-2 mb-4">
<div className="flex items-center text-neutral">
<CalendarDays className="h-4 w-4 mr-2" />
<span className="text-sm">{date}</span>
</div>
<div className="flex items-center text-neutral">
<Globe className="h-4 w-4 mr-2" />
<span className="text-sm">{place}</span>
</div>
<div className="flex items-center text-neutral">
<Clock className="h-4 w-4 mr-2" />
<span className="text-sm">
Deadline: {deadline === 'TBD' ? 'TBD' : `${deadline} (${timezone})`}
</span>
{abstract_deadline && (
<span className="text-sm text-red-500 ml-2">
Abstract: {abstract_deadline}
</span>
)}
</div>
<div className="flex items-center">
<AlarmClock className={`h-4 w-4 mr-2 ${getCountdownColor()}`} />
<span className={`text-sm font-medium ${getCountdownColor()}`}>
{daysLeft}
</span>
</div>
</div>
{Array.isArray(tags) && tags.length > 0 && (
<div className="flex flex-wrap gap-2 mb-4">
{tags.map((tag) => (
<span key={tag} className="tag">
<Tag className="h-3 w-3 mr-1" />
{tag}
</span>
))}
</div>
)}
{note && (
<div
className="text-sm text-neutral-600 mt-2"
dangerouslySetInnerHTML={{ __html: note }}
/>
)}
</div>
);
};
export default ConferenceCard;
|