AeThex-Connect/src/frontend/mockup/EventsPanel.jsx

392 lines
12 KiB
JavaScript

import React, { useState } from 'react';
const mockEvents = [
{
id: 1,
title: 'Monthly Community Townhall',
description: 'Join us for our monthly Q&A session with the AeThex team. Ask questions, get updates, and connect with the community.',
type: 'stage',
channel: 'community-stage',
startTime: new Date(Date.now() + 2 * 60 * 60 * 1000), // 2 hours from now
endTime: new Date(Date.now() + 4 * 60 * 60 * 1000),
host: { name: 'Anderson', avatar: 'A', color: '#ff0000' },
interested: 234,
image: null,
recurring: 'monthly',
},
{
id: 2,
title: 'Game Night: Among Us',
description: 'Weekly game night! This week we\'re playing Among Us. Join the voice channel 10 minutes early.',
type: 'voice',
channel: 'gaming-voice',
startTime: new Date(Date.now() + 26 * 60 * 60 * 1000), // Tomorrow
endTime: new Date(Date.now() + 29 * 60 * 60 * 1000),
host: { name: 'Sarah', avatar: 'S', color: '#ffa500' },
interested: 89,
image: null,
recurring: 'weekly',
},
{
id: 3,
title: 'AeThex SDK Workshop',
description: 'Learn how to integrate the AeThex SDK into your projects. Hands-on coding session with live Q&A.',
type: 'external',
location: 'https://workshop.aethex.com',
startTime: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000), // 3 days
endTime: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000 + 2 * 60 * 60 * 1000),
host: { name: 'Trevor', avatar: 'T', color: '#0066ff' },
interested: 456,
image: null,
recurring: null,
},
];
export default function EventsPanel({ onClose, onCreateEvent }) {
const [activeTab, setActiveTab] = useState('upcoming');
const [selectedEvent, setSelectedEvent] = useState(null);
const formatDate = (date) => {
const now = new Date();
const diff = date - now;
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
if (days === 0) {
const hours = Math.floor(diff / (1000 * 60 * 60));
if (hours === 0) {
const minutes = Math.floor(diff / (1000 * 60));
return `In ${minutes} minutes`;
}
return `In ${hours} hours`;
} else if (days === 1) {
return 'Tomorrow';
} else {
return date.toLocaleDateString('en-US', { weekday: 'long', month: 'short', day: 'numeric' });
}
};
const formatTime = (date) => {
return date.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' });
};
const getTypeIcon = (type) => {
switch (type) {
case 'stage': return '📢';
case 'voice': return '🔊';
case 'external': return '🔗';
default: return '📅';
}
};
if (selectedEvent) {
return (
<EventDetail
event={selectedEvent}
onBack={() => setSelectedEvent(null)}
formatDate={formatDate}
formatTime={formatTime}
getTypeIcon={getTypeIcon}
/>
);
}
return (
<div className="events-panel">
<div className="events-header">
<h2>Events</h2>
<div className="events-actions">
<button className="create-event-btn" onClick={onCreateEvent}>
+ Create Event
</button>
<button className="events-close" onClick={onClose}></button>
</div>
</div>
<div className="events-tabs">
<button
className={`events-tab ${activeTab === 'upcoming' ? 'active' : ''}`}
onClick={() => setActiveTab('upcoming')}
>
Upcoming
</button>
<button
className={`events-tab ${activeTab === 'recurring' ? 'active' : ''}`}
onClick={() => setActiveTab('recurring')}
>
Recurring
</button>
<button
className={`events-tab ${activeTab === 'past' ? 'active' : ''}`}
onClick={() => setActiveTab('past')}
>
Past
</button>
</div>
<div className="events-list">
{mockEvents.map(event => (
<div
key={event.id}
className="event-card"
onClick={() => setSelectedEvent(event)}
>
<div className="event-date-badge">
<span className="event-month">
{event.startTime.toLocaleDateString('en-US', { month: 'short' })}
</span>
<span className="event-day">
{event.startTime.getDate()}
</span>
</div>
<div className="event-info">
<div className="event-timing">
<span className="event-time-label">{formatDate(event.startTime)}</span>
<span className="event-time">
{formatTime(event.startTime)} - {formatTime(event.endTime)}
</span>
</div>
<h3 className="event-title">
<span className="event-type-icon">{getTypeIcon(event.type)}</span>
{event.title}
</h3>
<p className="event-description">{event.description}</p>
<div className="event-meta">
<div className="event-host">
<div
className="host-avatar"
style={event.host.color ? { background: event.host.color } : undefined}
>
{event.host.avatar}
</div>
<span>Hosted by {event.host.name}</span>
</div>
<div className="event-interested">
<span className="interested-count"> {event.interested} interested</span>
</div>
</div>
{event.recurring && (
<div className="recurring-badge">
🔄 Repeats {event.recurring}
</div>
)}
</div>
</div>
))}
</div>
{mockEvents.length === 0 && (
<div className="events-empty">
<span className="empty-icon">📅</span>
<h3>No upcoming events</h3>
<p>Create an event to bring your community together!</p>
<button className="create-event-btn" onClick={onCreateEvent}>
Create Event
</button>
</div>
)}
</div>
);
}
function EventDetail({ event, onBack, formatDate, formatTime, getTypeIcon }) {
const [isInterested, setIsInterested] = useState(false);
return (
<div className="event-detail">
<button className="back-btn" onClick={onBack}>
Back to Events
</button>
<div className="event-detail-header">
<div className="event-type-badge">
{getTypeIcon(event.type)} {event.type.charAt(0).toUpperCase() + event.type.slice(1)}
</div>
<h1>{event.title}</h1>
</div>
<div className="event-detail-content">
<div className="detail-section">
<h4>📅 Date & Time</h4>
<p>{formatDate(event.startTime)}</p>
<p className="time-range">
{formatTime(event.startTime)} - {formatTime(event.endTime)}
</p>
{event.recurring && (
<p className="recurring-info">🔄 Repeats {event.recurring}</p>
)}
</div>
<div className="detail-section">
<h4>📍 Location</h4>
{event.type === 'external' ? (
<a href={event.location} className="external-link">
{event.location}
</a>
) : (
<p>#{event.channel}</p>
)}
</div>
<div className="detail-section">
<h4>📝 Description</h4>
<p>{event.description}</p>
</div>
<div className="detail-section">
<h4>👤 Host</h4>
<div className="host-info">
<div
className="host-avatar large"
style={event.host.color ? { background: event.host.color } : undefined}
>
{event.host.avatar}
</div>
<span>{event.host.name}</span>
</div>
</div>
<div className="interested-section">
<span> {event.interested + (isInterested ? 1 : 0)} interested</span>
</div>
</div>
<div className="event-detail-actions">
<button
className={`interested-btn ${isInterested ? 'active' : ''}`}
onClick={() => setIsInterested(!isInterested)}
>
{isInterested ? '⭐ Interested' : '☆ Mark as Interested'}
</button>
<button className="share-event-btn">
📤 Share
</button>
</div>
</div>
);
}
// Event creation modal
export function CreateEventModal({ onSubmit, onClose }) {
const [title, setTitle] = useState('');
const [description, setDescription] = useState('');
const [type, setType] = useState('voice');
const [date, setDate] = useState('');
const [startTime, setStartTime] = useState('');
const [endTime, setEndTime] = useState('');
const handleSubmit = () => {
if (!title.trim() || !date || !startTime) return;
onSubmit?.({
title,
description,
type,
date,
startTime,
endTime,
});
onClose?.();
};
return (
<div className="modal-overlay" onClick={onClose}>
<div className="create-event-modal" onClick={(e) => e.stopPropagation()}>
<div className="modal-header">
<h2>Create Event</h2>
<button className="modal-close" onClick={onClose}></button>
</div>
<div className="modal-content">
<div className="form-group">
<label>Event Type</label>
<div className="event-type-options">
<button
className={`type-option ${type === 'stage' ? 'active' : ''}`}
onClick={() => setType('stage')}
>
📢 Stage
</button>
<button
className={`type-option ${type === 'voice' ? 'active' : ''}`}
onClick={() => setType('voice')}
>
🔊 Voice
</button>
<button
className={`type-option ${type === 'external' ? 'active' : ''}`}
onClick={() => setType('external')}
>
🔗 External
</button>
</div>
</div>
<div className="form-group">
<label>Event Title</label>
<input
type="text"
placeholder="What's your event called?"
value={title}
onChange={(e) => setTitle(e.target.value)}
maxLength={100}
/>
</div>
<div className="form-group">
<label>Description</label>
<textarea
placeholder="Tell people what this event is about..."
value={description}
onChange={(e) => setDescription(e.target.value)}
rows={3}
/>
</div>
<div className="form-row">
<div className="form-group">
<label>Date</label>
<input
type="date"
value={date}
onChange={(e) => setDate(e.target.value)}
/>
</div>
<div className="form-group">
<label>Start Time</label>
<input
type="time"
value={startTime}
onChange={(e) => setStartTime(e.target.value)}
/>
</div>
<div className="form-group">
<label>End Time</label>
<input
type="time"
value={endTime}
onChange={(e) => setEndTime(e.target.value)}
/>
</div>
</div>
</div>
<div className="modal-footer">
<button className="cancel-btn" onClick={onClose}>Cancel</button>
<button
className="submit-btn"
onClick={handleSubmit}
disabled={!title.trim() || !date || !startTime}
>
Create Event
</button>
</div>
</div>
</div>
);
}