Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 119 additions & 81 deletions frontend/src/components/ui/ForumDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Link from 'next/link';
import Loading from '@/components/Loading';
import { StaffMember, Event, ForumEvent } from '@/types';
import { FormattedReviewText, formatReviewText } from '@/utils/textFormatting';
import { useMemo } from 'react';

const ForumDashboard = () => {
const { loading } = useAuth();
Expand All @@ -17,6 +18,7 @@ const ForumDashboard = () => {
const [isEngagePopupOpen, setIsEngagePopupOpen] = useState(false);
const [isEngageLoading, setIsEngageLoading] = useState(false);
const [engageEvents, setEngageEvents] = useState<Event[]>([]);
const [searchTerm, setSearchTerm] = useState<string>('');

// Form state
const [title, setTitle] = useState<string>('');
Expand Down Expand Up @@ -137,6 +139,18 @@ const ForumDashboard = () => {
fetchEngageEvents();
}, [isEngagePopupOpen]);

// Filter Engage events dynamically
const filteredEngageEvents = useMemo(() => {
const term = searchTerm.toLowerCase();
return engageEvents.filter(
(event) =>
event.name.toLowerCase().includes(term) ||
(event.location &&
event.location.toLowerCase().includes(term)) ||
(event.host && event.host.toLowerCase().includes(term))
);
}, [searchTerm, engageEvents]);

const resetForm = () => {
setTitle('');
setDescription('');
Expand Down Expand Up @@ -402,98 +416,119 @@ const ForumDashboard = () => {
Import from Engage
</h2>
<button
onClick={() => setIsEngagePopupOpen(false)}
onClick={() => {
setIsEngagePopupOpen(false);
setSearchTerm('');
}}
className="text-gray-500 hover:text-gray-700 text-2xl leading-none"
>
×
</button>
</div>

<div className="mb-4">
<input
type="text"
placeholder="Search events by name, location, or host"
className="w-full p-3 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-400 transition"
value={searchTerm}
onChange={(e) =>
setSearchTerm(e.target.value)
}
/>
</div>

{/* Popup body */}
{isEngageLoading ? (
<p className="text-gray-500 text-center my-8">
Loading events from Engage...
</p>
) : engageEvents.length > 0 ? (
) : filteredEngageEvents.length > 0 ? (
<ul className="space-y-4">
{engageEvents.map((event: Event, index) => (
<li
key={index}
className="border border-gray-200 rounded-lg p-4 hover:shadow-md transition-shadow bg-gray-50"
>
<h3 className="text-lg font-semibold text-gray-900 mb-1">
{event.name}
</h3>

<p className="text-sm text-gray-600 mb-1">
<strong>Date:</strong>{' '}
{new Date(
event.start
).toLocaleString()}{' '}
→{' '}
{new Date(
event.end
).toLocaleString()}
</p>

<p className="text-sm text-gray-600 mb-1">
<strong>Location:</strong>{' '}
{event.location || 'N/A'}
</p>

<p className="text-sm text-gray-600 mb-1">
<strong>Host:</strong>{' '}
{event.host || 'Unknown'}
</p>

<div className="text-sm text-gray-700 mt-2 line-clamp-3">
<FormattedReviewText
text={event.description}
/>
</div>

<div className="flex justify-between items-center mt-3">
<a
href={event.details_url}
target="_blank"
rel="noopener noreferrer"
className="text-blue-500 hover:underline text-sm"
>
View on Engage ↗
</a>

<button
onClick={() => {
setEngageEventId(
event.details_url
);
setTitle(event.name);
setDescription(
event.description
);
setLocation(
event.location
);

setEventDate(
toDatetimeLocal(
new Date(
event.start
).toISOString()
)
);

setIsEngagePopupOpen(
false
);
}}
className="bg-blue-500 text-white px-3 py-1.5 rounded hover:bg-blue-600 text-sm"
>
Select
</button>
</div>
</li>
))}
{filteredEngageEvents.map(
(event: Event, index) => (
<li
key={index}
className="border border-gray-200 rounded-lg p-4 hover:shadow-md transition-shadow bg-gray-50"
>
<h3 className="text-lg font-semibold text-gray-900 mb-1">
{event.name}
</h3>

<p className="text-sm text-gray-600 mb-1">
<strong>Date:</strong>{' '}
{new Date(
event.start
).toLocaleString()}{' '}
→{' '}
{new Date(
event.end
).toLocaleString()}
</p>

<p className="text-sm text-gray-600 mb-1">
<strong>Location:</strong>{' '}
{event.location || 'N/A'}
</p>

<p className="text-sm text-gray-600 mb-1">
<strong>Host:</strong>{' '}
{event.host || 'Unknown'}
</p>

<div className="text-sm text-gray-700 mt-2 line-clamp-3">
<FormattedReviewText
text={event.description}
/>
</div>

<div className="flex justify-between items-center mt-3">
<a
href={event.details_url}
target="_blank"
rel="noopener noreferrer"
className="text-blue-500 hover:underline text-sm"
>
View on Engage ↗
</a>

<button
onClick={() => {
setEngageEventId(
event.details_url
);
setTitle(
event.name
);
setDescription(
event.description
);
setLocation(
event.location
);

setEventDate(
toDatetimeLocal(
new Date(
event.start
).toISOString()
)
);

setIsEngagePopupOpen(
false
);

setSearchTerm('');
}}
className="bg-blue-500 text-white px-3 py-1.5 rounded hover:bg-blue-600 text-sm"
>
Select
</button>
</div>
</li>
)
)}
</ul>
) : (
<p className="text-gray-500 text-center my-8">
Expand All @@ -503,7 +538,10 @@ const ForumDashboard = () => {

<div className="flex justify-end mt-6">
<button
onClick={() => setIsEngagePopupOpen(false)}
onClick={() => {
setIsEngagePopupOpen(false);
setSearchTerm('');
}}
className="bg-gray-300 text-gray-800 px-4 py-2 rounded hover:bg-gray-400"
>
Close
Expand Down