EventBuzz_Website/src/components/SessionQuestionsCard.tsx

184 lines
5.8 KiB
TypeScript

import { useCallback, useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { useSessionQuestionsRtdb } from "../hooks/useSessionQuestionsRtdb";
import { AudienceQuestionCard, type AudienceQuestionItem } from "./AudienceQuestionCard";
import { AskQuestionModal } from "./AskQuestionModal";
type QuestionItem = AudienceQuestionItem & { _id?: string };
const sample: QuestionItem[] = [
{
author: "Ashok Kuwal",
text: "Role of GINA Guidelines for Iniang and Monitoring Asthma Treatment?",
up: 2,
down: 3,
},
{
author: "Ashok Kuwal",
text: "Role of GINA Guidelines for Iniang and Monitoring Asthma Treatment?",
up: 2,
down: 3,
},
{
author: "Ashok Kuwal",
text: "Role of GINA Guidelines for Iniang and Monitoring Asthma Treatment?",
up: 2,
down: 3,
},
];
type SessionQuestionsCardProps = {
title?: string;
showQuestionNav?: boolean;
eventId?: string;
sessionId?: string;
};
export function SessionQuestionsCard({
title = "Session Questions",
showQuestionNav = false,
eventId,
sessionId,
}: SessionQuestionsCardProps) {
const live = Boolean(eventId?.trim() && sessionId?.trim());
const eid = eventId?.trim() ?? "";
const sid = sessionId?.trim() ?? "";
const { items: rtdbItems, loading, error } = useSessionQuestionsRtdb(
live ? sid : null,
live ? eid : null,
);
const items: QuestionItem[] = live
? rtdbItems.map((r) => ({
_id: r._id,
author: r.author,
text: r.text,
up: r.up,
down: r.down,
}))
: sample;
const total = items.length;
const [index, setIndex] = useState(0);
const [askModalOpen, setAskModalOpen] = useState(false);
useEffect(() => {
if (index >= total && total > 0) setIndex(0);
else if (total === 0) setIndex(0);
}, [total, index]);
const goNext = useCallback(() => {
if (total <= 0) return;
setIndex((i) => (i + 1) % total);
}, [total]);
const goPrev = useCallback(() => {
if (total <= 0) return;
setIndex((i) => (i - 1 + total) % total);
}, [total]);
useEffect(() => {
if (total <= 1) return;
const id = window.setInterval(goNext, 2000);
return () => window.clearInterval(id);
}, [total, goNext]);
const safeIndex = total > 0 ? Math.min(index, total - 1) : 0;
const current = total > 0 ? items[safeIndex] : null;
const viewAllTo =
live ? `/questions?event_id=${encodeURIComponent(eid)}&session_id=${encodeURIComponent(sid)}` : null;
return (
<section
className="relative z-10 flex w-full max-w-none flex-col gap-4 rounded-lg border border-[rgba(116,112,112,0.2)] bg-whit card-bg py-4 shadow-sm"
data-name="Session Questions"
>
<div className="flex h-8 items-center justify-between gap-2 px-4">
<div className="flex min-w-0 flex-1 items-center gap-2">
<h2 className="truncate text-lg font-semibold tracking-wide text-[#24282f]">
{title}
</h2>
{total > 0 ? (
<span className="shrink-0 rounded bg-[#e5e5ea] px-2 py-0.5 text-[10px] tracking-wide text-[#24282f]">
{safeIndex + 1}/{total}
</span>
) : null}
</div>
{showQuestionNav && total > 1 ? (
<div className="flex shrink-0 gap-1">
<button
type="button"
className="rounded-full bg-[#f2f2f7] p-1"
aria-label="Previous question"
onClick={goPrev}
>
<ChevronLeft className="size-4 text-[#24282f]" />
</button>
<button
type="button"
className="rounded-full bg-[#f2f2f7] p-1"
aria-label="Next question"
onClick={goNext}
>
<ChevronRight className="size-4 text-[#24282f]" />
</button>
</div>
) : null}
</div>
<div className="border-t border-[#f2f2f7]">
{live && loading ? (
<p className="px-4 py-6 text-center text-sm text-[rgba(36,40,47,0.55)]">Loading questions…</p>
) : live && error ? (
<p className="px-4 py-6 text-center text-sm text-red-600">{error}</p>
) : current ? (
<div className="p-0">
<AudienceQuestionCard
key={current._id ?? `${safeIndex}-${current.text.slice(0, 24)}`}
item={current}
variant="embedded"
voteContext={live ? { eventId: eid, sessionId: sid } : undefined}
/>
</div>
) : (
<p className="px-4 py-6 text-center text-sm text-[rgba(36,40,47,0.55)]">No questions yet.</p>
)}
</div>
<div className="flex items-center justify-between gap-3 px-4">
{viewAllTo ? (
<Link
to={viewAllTo}
className="font-inter text-xs font-semibold uppercase tracking-wider text-[#1e72e theme-btn-link"
>
View All
</Link>
) : (
<span className="font-inter text-xs font-semibold uppercase tracking-wider text-[rgba(36,40,47,0.35)]">
View All
</span>
)}
<button
type="button"
onClick={() => live && setAskModalOpen(true)}
disabled={!live}
className="shrink-0 rounded-lg bg-[#ef8d1 bg-[var(--theme-button-color)] px-3 py-2 text-xs font-semibold text-white shadow-[0_2px_4px_rgba(0,0,0,0.1)] transition-all duration-300 ease-in-out hover:bg-[#e0800c] transition hover:bg-[var(--theme-button-color)]/90 disabled:opacity-50"
>
Ask your Question
</button>
</div>
{live ? (
<AskQuestionModal
open={askModalOpen}
onClose={() => setAskModalOpen(false)}
eventId={eid}
sessionId={sid}
idSuffix="-card"
/>
) : null}
</section>
);
}