modularized ResearchLive
by introducing reusable components (DreamyCard
, HeroSection
, SectionHeader
, etc.), reducing code duplication and improving maintainability
Signed-off-by: Matthias Puchstein <matthias@puchstein.bayern>
This commit is contained in:
@@ -1,128 +1,49 @@
|
||||
import {getBackgroundStyle, getTextStyle} from '../../styles/StyleUtils';
|
||||
import {FaCalendarAlt, FaClipboardCheck, FaFlask, FaGlobeAmericas, FaUserMd, FaUsers, FaVideo} from 'react-icons/fa';
|
||||
import {FaCalendarAlt, FaClipboardCheck, FaGlobeAmericas} from 'react-icons/fa';
|
||||
import mockResearchLive from '../../data/MockResearchLive';
|
||||
import HeroSection from '../../components/dreamarchive/HeroSection';
|
||||
import SectionHeader from '../../components/dreamarchive/SectionHeader';
|
||||
import DreamyCard from '../../components/dreamarchive/DreamyCard';
|
||||
import StudyCard from '../../components/dreamarchive/StudyCard';
|
||||
import ResearcherInterviewCard from '../../components/dreamarchive/ResearcherInterviewCard';
|
||||
import IconWithBackground from '../../components/dreamarchive/IconWithBackground';
|
||||
|
||||
export default function ResearchLive() {
|
||||
return (<div className="p-4 pt-24 pb-20 max-w-6xl mx-auto relative overflow-hidden">
|
||||
{/* Hero Section */}
|
||||
<div className="text-center mb-12 sm:mb-16 relative z-10">
|
||||
<div className="animate-pulse flex flex-col items-center mb-8 sm:mb-12">
|
||||
<h1 className="text-3xl sm:text-4xl md:text-5xl font-bold mb-4 dream-title">Traumforschung Live</h1>
|
||||
<p className="text-lg sm:text-xl dreamy-text">Aktuelle Studien, Citizen Science und
|
||||
Forscher-Interviews</p>
|
||||
</div>
|
||||
<div
|
||||
className="dream-container floating max-w-3xl mx-auto backdrop-blur-sm bg-white/10 dark:bg-white/5 rounded-3xl p-4 sm:p-6 md:p-8"
|
||||
style={{animationDelay: '0.2s'}}>
|
||||
<div className="flex flex-col sm:flex-row justify-center items-center mb-3 sm:mb-4">
|
||||
<h2 className="dream-title text-xl sm:text-2xl">Sei Teil der Traumforschung</h2>
|
||||
</div>
|
||||
<p className="mb-4 sm:mb-6 md:mb-8 text-sm sm:text-base md:text-lg" style={{color: 'var(--text)'}}>
|
||||
Entdecke laufende Forschungsprojekte, nimm an Studien teil und lerne von führenden
|
||||
Traumforschern aus der ganzen Welt.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<HeroSection
|
||||
title="Traumforschung Live"
|
||||
subtitle="Aktuelle Studien, Citizen Science und Forscher-Interviews"
|
||||
containerTitle="Sei Teil der Traumforschung"
|
||||
description="Entdecke laufende Forschungsprojekte, nimm an Studien teil und lerne von führenden Traumforschern aus der ganzen Welt."
|
||||
/>
|
||||
|
||||
{/* Current Studies */}
|
||||
<div className="mb-12">
|
||||
<h2 className="text-2xl font-bold mb-6 dream-title">Aktuelle Studien</h2>
|
||||
<SectionHeader title="Aktuelle Studien"/>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{mockResearchLive.currentStudies.slice(0, 2).map((study) => (
|
||||
<div key={study.id} className="dreamy-card p-6" style={getBackgroundStyle(study.color)}>
|
||||
<div className="flex items-center mb-4">
|
||||
<div className={`p-3 bg-${study.color}-500/20 rounded-full mr-4`}>
|
||||
<FaFlask className={`text-${study.color}-600 dark:text-${study.color}-400`} size={28}/>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-bold dreamy-text">{study.title}</h3>
|
||||
<p className="text-xs" style={getTextStyle('muted')}>{study.institution}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white/20 dark:bg-black/20 p-4 rounded-lg mb-4">
|
||||
<div className="flex justify-between mb-2">
|
||||
<span className="text-sm font-bold">Status:</span>
|
||||
<span
|
||||
className={`text-sm bg-${study.statusColor}-100 dark:bg-${study.statusColor}-900 text-${study.statusColor}-800 dark:text-${study.statusColor}-200 px-2 py-0.5 rounded-full`}>{study.status}</span>
|
||||
</div>
|
||||
<div className="flex justify-between mb-2">
|
||||
<span className="text-sm font-bold">Teilnehmer:</span>
|
||||
<span
|
||||
className="text-sm">{study.participants.current.toLocaleString()} / {study.participants.target.toLocaleString()}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm font-bold">Enddatum:</span>
|
||||
<span className="text-sm">{study.endDate}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-sm mb-4">
|
||||
{study.description}
|
||||
</p>
|
||||
|
||||
<button
|
||||
className={`w-full py-2 px-4 bg-${study.color}-500 hover:bg-${study.color}-600 text-white rounded-lg transition-colors`}>
|
||||
Teilnehmen
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
<StudyCard key={study.id} study={study}/>))}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mt-6">
|
||||
{mockResearchLive.currentStudies.slice(2, 4).map((study) => (
|
||||
<div key={study.id} className="dreamy-card p-6" style={getBackgroundStyle(study.color)}>
|
||||
<div className="flex items-center mb-4">
|
||||
<div className={`p-3 bg-${study.color}-500/20 rounded-full mr-4`}>
|
||||
<FaFlask className={`text-${study.color}-600 dark:text-${study.color}-400`} size={28}/>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-bold dreamy-text">{study.title}</h3>
|
||||
<p className="text-xs" style={getTextStyle('muted')}>{study.institution}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white/20 dark:bg-black/20 p-4 rounded-lg mb-4">
|
||||
<div className="flex justify-between mb-2">
|
||||
<span className="text-sm font-bold">Status:</span>
|
||||
<span
|
||||
className={`text-sm bg-${study.statusColor}-100 dark:bg-${study.statusColor}-900 text-${study.statusColor}-800 dark:text-${study.statusColor}-200 px-2 py-0.5 rounded-full`}>{study.status}</span>
|
||||
</div>
|
||||
<div className="flex justify-between mb-2">
|
||||
<span className="text-sm font-bold">Teilnehmer:</span>
|
||||
<span
|
||||
className="text-sm">{study.participants.current.toLocaleString()} / {study.participants.target.toLocaleString()}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm font-bold">Enddatum:</span>
|
||||
<span className="text-sm">{study.endDate}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-sm mb-4">
|
||||
{study.description}
|
||||
</p>
|
||||
|
||||
<button
|
||||
className={`w-full py-2 px-4 bg-${study.color}-500 hover:bg-${study.color}-600 text-white rounded-lg transition-colors`}>
|
||||
Teilnehmen
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
<StudyCard key={study.id} study={study}/>))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Citizen Science */}
|
||||
<div className="mb-12">
|
||||
<h2 className="text-2xl font-bold mb-6 dream-title">Citizen Science: Mitmachen bei der
|
||||
Traumforschung</h2>
|
||||
<SectionHeader title="Citizen Science: Mitmachen bei der Traumforschung"/>
|
||||
|
||||
<div className="dreamy-card p-6" style={getBackgroundStyle('violet')}>
|
||||
<DreamyCard color="violet">
|
||||
<div className="flex items-center mb-6">
|
||||
<div className="p-3 bg-violet-500/20 rounded-full mr-4">
|
||||
<FaUsers className="text-violet-600 dark:text-violet-400" size={28}/>
|
||||
</div>
|
||||
<IconWithBackground
|
||||
icon={<FaCalendarAlt/>}
|
||||
color="violet"
|
||||
size={28}
|
||||
className="mr-4"
|
||||
/>
|
||||
<h3 className="text-xl font-bold dreamy-text">Wie du zur Wissenschaft beitragen kannst</h3>
|
||||
</div>
|
||||
|
||||
@@ -144,25 +65,23 @@ export default function ResearchLive() {
|
||||
IconComponent = FaClipboardCheck;
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={project.id} className="bg-white/20 dark:bg-black/20 p-4 rounded-lg">
|
||||
<div className="flex justify-center mb-3">
|
||||
<div className="p-2 bg-violet-500/20 rounded-full">
|
||||
<IconComponent className="text-violet-600 dark:text-violet-400" size={20}/>
|
||||
</div>
|
||||
</div>
|
||||
<h4 className="font-bold mb-2 text-center">{project.title}</h4>
|
||||
<p className="text-sm">
|
||||
{project.description}
|
||||
</p>
|
||||
<div className="mt-3 text-center">
|
||||
<button
|
||||
className="py-1 px-3 bg-violet-500 hover:bg-violet-600 text-white text-xs rounded-lg transition-colors">
|
||||
Beitragen
|
||||
</button>
|
||||
return (<div key={project.id} className="bg-white/20 dark:bg-black/20 p-4 rounded-lg">
|
||||
<div className="flex justify-center mb-3">
|
||||
<div className="p-2 bg-violet-500/20 rounded-full">
|
||||
<IconComponent className="text-violet-600 dark:text-violet-400" size={20}/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
<h4 className="font-bold mb-2 text-center">{project.title}</h4>
|
||||
<p className="text-sm">
|
||||
{project.description}
|
||||
</p>
|
||||
<div className="mt-3 text-center">
|
||||
<button
|
||||
className="py-1 px-3 bg-violet-500 hover:bg-violet-600 text-white text-xs rounded-lg transition-colors">
|
||||
Beitragen
|
||||
</button>
|
||||
</div>
|
||||
</div>);
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -171,97 +90,29 @@ export default function ResearchLive() {
|
||||
hilft Wissenschaftlern, größere und vielfältigere Datensätze zu sammeln, was zu robusteren
|
||||
Forschungsergebnissen führt.
|
||||
</p>
|
||||
</div>
|
||||
</DreamyCard>
|
||||
</div>
|
||||
|
||||
{/* Researcher Interviews */}
|
||||
<div className="mb-12">
|
||||
<h2 className="text-2xl font-bold mb-6 dream-title">Forscher-Interviews</h2>
|
||||
<SectionHeader title="Forscher-Interviews"/>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{mockResearchLive.researcherInterviews.slice(0, 2).map((interview) => (
|
||||
<div key={interview.id} className="dreamy-card p-6" style={getBackgroundStyle(interview.color)}>
|
||||
<div className="flex items-start mb-4">
|
||||
<div className={`p-3 bg-${interview.color}-500/20 rounded-full mr-4 mt-1`}>
|
||||
<FaUserMd className={`text-${interview.color}-600 dark:text-${interview.color}-400`}
|
||||
size={28}/>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-bold dreamy-text">{interview.name}</h3>
|
||||
<p className="text-xs mb-1" style={getTextStyle('muted')}>{interview.institution}</p>
|
||||
<p className="text-sm mb-3">{interview.specialty}</p>
|
||||
|
||||
<div className="relative">
|
||||
<div
|
||||
className="aspect-video bg-gray-200 dark:bg-gray-700 rounded-lg flex items-center justify-center">
|
||||
<FaVideo className="text-gray-400 dark:text-gray-500" size={32}/>
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div
|
||||
className={`w-12 h-12 rounded-full bg-${interview.color}-500/80 flex items-center justify-center cursor-pointer`}>
|
||||
<div
|
||||
className="w-0 h-0 border-t-8 border-b-8 border-l-12 border-transparent border-l-white ml-1"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 className="font-bold mt-3 mb-1">Themen im Interview:</h4>
|
||||
<ul className="list-disc list-inside text-sm space-y-1">
|
||||
{interview.topics.map((topic, index) => (
|
||||
<li key={index}>{topic}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<ResearcherInterviewCard key={interview.id} interview={interview}/>))}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mt-6">
|
||||
{mockResearchLive.researcherInterviews.slice(2, 4).map((interview) => (
|
||||
<div key={interview.id} className="dreamy-card p-6" style={getBackgroundStyle(interview.color)}>
|
||||
<div className="flex items-start mb-4">
|
||||
<div className={`p-3 bg-${interview.color}-500/20 rounded-full mr-4 mt-1`}>
|
||||
<FaUserMd className={`text-${interview.color}-600 dark:text-${interview.color}-400`}
|
||||
size={28}/>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-bold dreamy-text">{interview.name}</h3>
|
||||
<p className="text-xs mb-1" style={getTextStyle('muted')}>{interview.institution}</p>
|
||||
<p className="text-sm mb-3">{interview.specialty}</p>
|
||||
|
||||
<div className="relative">
|
||||
<div
|
||||
className="aspect-video bg-gray-200 dark:bg-gray-700 rounded-lg flex items-center justify-center">
|
||||
<FaVideo className="text-gray-400 dark:text-gray-500" size={32}/>
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div
|
||||
className={`w-12 h-12 rounded-full bg-${interview.color}-500/80 flex items-center justify-center cursor-pointer`}>
|
||||
<div
|
||||
className="w-0 h-0 border-t-8 border-b-8 border-l-12 border-transparent border-l-white ml-1"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 className="font-bold mt-3 mb-1">Themen im Interview:</h4>
|
||||
<ul className="list-disc list-inside text-sm space-y-1">
|
||||
{interview.topics.map((topic, index) => (
|
||||
<li key={index}>{topic}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<ResearcherInterviewCard key={interview.id} interview={interview}/>))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Upcoming Events */}
|
||||
<div className="mb-12">
|
||||
<h2 className="text-2xl font-bold mb-6 dream-title">Kommende Veranstaltungen</h2>
|
||||
<SectionHeader title="Kommende Veranstaltungen"/>
|
||||
|
||||
<div className="dreamy-card p-6" style={getBackgroundStyle('purple')}>
|
||||
<DreamyCard color="purple">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
@@ -279,13 +130,12 @@ export default function ResearchLive() {
|
||||
<td className="p-2">{event.title}</td>
|
||||
<td className="p-2">{event.location}</td>
|
||||
<td className="p-2">
|
||||
<span
|
||||
className={`bg-${event.typeColor}-100 dark:bg-${event.typeColor}-900 text-${event.typeColor}-800 dark:text-${event.typeColor}-200 text-xs px-2 py-0.5 rounded-full`}>
|
||||
{event.type}
|
||||
</span>
|
||||
<span
|
||||
className={`bg-${event.typeColor}-100 dark:bg-${event.typeColor}-900 text-${event.typeColor}-800 dark:text-${event.typeColor}-200 text-xs px-2 py-0.5 rounded-full`}>
|
||||
{event.type}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tr>))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -296,7 +146,7 @@ export default function ResearchLive() {
|
||||
Alle Veranstaltungen anzeigen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</DreamyCard>
|
||||
</div>
|
||||
</div>);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user