import React, { useEffect, useState } from "react"; import { Helmet } from "react-helmet-async"; import Joyride, { EVENTS } from "react-joyride"; import ReactPlayer from "react-player/lazy"; import useWindowSize from "@rooks/use-window-size"; import { closeDiscussion, endProgramPoint, openDiscussion, renameProgramPoint, } from "actions/program"; import { DropdownMenu, DropdownMenuItem } from "components/dropdown-menu"; import ErrorMessage from "components/ErrorMessage"; import { AlreadyFinished, BreakInProgress, NotYetStarted, } from "components/home"; import ModalConfirm from "components/modals/ModalConfirm"; import { Beacon, steps } from "components/onboarding"; import ProgramEntryEditModal from "components/program/ProgramEntryEditModal"; import AddAnnouncementForm from "containers/AddAnnouncementForm"; import AddPostForm from "containers/AddPostForm"; import AnnouncementsContainer from "containers/AnnoucementsContainer"; import GlobalStats from "containers/GlobalStats"; import JitsiInviteCard from "containers/JitsiInviteCard"; import PostFilters from "containers/PostFilters"; import PostsContainer from "containers/PostsContainer"; import { useActionConfirm } from "hooks"; import { AuthStore, GlobalInfoStore, ProgramStore } from "stores"; import "./Home.css"; const tourLSKey = "cf2021__tour"; const Home = () => { const { currentId, items: programEntries, scheduleIds, } = ProgramStore.useState(); const { isAuthenticated, user } = AuthStore.useState(); const { streamUrl } = GlobalInfoStore.useState(); const programEntry = currentId ? programEntries[currentId] : null; const [showProgramEditModal, setShowProgramEditModal] = useState(false); const [runJoyRide, setRunJoyride] = useState(false); const { innerWidth } = useWindowSize(); const isLg = innerWidth >= 1024; const [ showCloseDiscussion, setShowCloseDiscussion, onCloseDiscussionConfirm, onCloseDiscussionCancel, ] = useActionConfirm(closeDiscussion, programEntry); const [ showOpenDiscussion, setShowOpenDiscussion, onOpenDiscussionConfirm, onOpenDiscussionCancel, ] = useActionConfirm(openDiscussion, programEntry); const [ showEndProgramPoint, setShowEndProgramPoint, onEndProgramPointConfirm, onEndProgramPointCancel, ] = useActionConfirm(endProgramPoint, programEntry); useEffect(() => { if (isLg && !localStorage.getItem(tourLSKey)) { setRunJoyride(true); } }, [isLg, setRunJoyride]); const onEditProgramConfirm = async (newTitle) => { await renameProgramPoint.run({ programEntry, newTitle }); setShowProgramEditModal(false); }; const onEditProgramCancel = () => { setShowProgramEditModal(false); }; const handleJoyrideCallback = ({ action, index, status, type }) => { if (type === EVENTS.TOUR_END) { localStorage.setItem(tourLSKey, "COMPLETED"); } }; const firstProgramEntry = scheduleIds.length ? programEntries[scheduleIds[0]] : null; const lastProgramEntry = scheduleIds.length ? programEntries[scheduleIds[0]] : null; if ( !programEntry && (!firstProgramEntry || new Date() < firstProgramEntry.expectedStartAt) ) { return ( <NotYetStarted startAt={ firstProgramEntry ? firstProgramEntry.expectedStartAt : undefined } /> ); } if ( !programEntry && lastProgramEntry && new Date() > lastProgramEntry.expectedStartAt ) { return <AlreadyFinished />; } if (!programEntry) { return <BreakInProgress />; } const displayActions = isAuthenticated && user.role === "chairman"; return ( <> <Helmet> <title>Přímý přenos | CF 2021 | Pirátská strana</title> <meta name="description" content="Přímý přenos a diskuse z on-line zasedání Celostátního fóra České pirátské strany, 9. 1. 2021." /> <meta property="og:title" content="Přímý přenos | CF 2021 | Pirátská strana" /> <meta property="og:description" content="Přímý přenos a diskuse z on-line zasedání Celostátního fóra České pirátské strany, 9. 1. 2021." /> </Helmet> <Joyride beaconComponent={Beacon} continuous={true} locale={{ back: "Zpět", close: "Zavřít", last: "Poslední", next: "Další", skip: "Přeskočit intro", }} run={runJoyRide} showProgress={true} showSkipButton={true} scrollToFirstStep={true} callback={handleJoyrideCallback} steps={steps} styles={{ options: { arrowColor: "#fff", backgroundColor: "#fff", overlayColor: "rgba(255, 255, 255, 0.75)", primaryColor: "#000", textColor: "#000", textAlign: "left", outline: "none", zIndex: 1000, borderRadius: 0, }, tooltip: { borderRadius: 0, }, tooltipContent: { textAlign: "left", }, buttonClose: { borderRadius: 0, fontSize: "0.875rem", }, buttonNext: { borderRadius: 0, padding: ".75em 2em", fontSize: "0.875rem", }, buttonBack: { color: "#4c4c4c", fontSize: "0.875rem", }, buttonSkip: { color: "#4c4c4c", fontSize: "0.875rem", }, }} /> <article className="container container--wide py-8 lg:py-24 cf2021 bg-white"> <div className="cf2021__title flex justify-between"> <h1 className="head-alt-base lg:head-alt-lg"> Bod č. {programEntry.number}: {programEntry.title} </h1> {displayActions && ( <DropdownMenu right triggerSize="lg" className="pl-4 pt-1 lg:pt-5"> <DropdownMenuItem onClick={() => setShowProgramEditModal(true)} icon="ico--pencil" title="Přejmenovat bod programu" titleSize="base" iconSize="base" /> {programEntry.discussionOpened && ( <DropdownMenuItem onClick={() => setShowCloseDiscussion(true)} icon="ico--bubbles" title="Ukončit rozpravu" titleSize="base" iconSize="base" /> )} {!programEntry.discussionOpened && ( <DropdownMenuItem onClick={() => setShowOpenDiscussion(true)} icon="ico--bubbles" title="Otevřít rozpravu" titleSize="base" iconSize="base" /> )} <DropdownMenuItem onClick={() => setShowEndProgramPoint(true)} icon="ico--switch" title="Ukončit bod programu" titleSize="base" iconSize="base" /> </DropdownMenu> )} </div> <section className="cf2021__video"> <div className="container-padding--zero md:container-padding--auto"> {streamUrl && ( <div className="iframe-container joyride-player"> <ReactPlayer url={streamUrl} title="Video stream" controls={true} playing={true} muted={true} width="100%" height="" /> </div> )} {!streamUrl && ( <p> Server neposlal informaci o aktuálním streamu. Vyčkejte na aktualizaci. </p> )} <GlobalStats /> </div> </section> <section className="cf2021__notifications space-y-8"> <JitsiInviteCard /> <div className="lg:card lg:elevation-10 joyride-announcements"> <AnnouncementsContainer className="container-padding--zero lg:container-padding--auto" /> {isAuthenticated && user.role === "chairman" && ( <AddAnnouncementForm className="lg:card__body pt-4 lg:py-6" /> )} </div> </section> <section className="cf2021__posts joyride-posts"> <div className="flex flex-col xl:flex-row xl:justify-between xl:items-center mb-4"> <h2 className="head-heavy-xs md:head-heavy-sm whitespace-no-wrap"> <span>Příspěvky v rozpravě</span> {!programEntry.discussionOpened && ( <i className="ico--lock text-black ml-2 opacity-50 hover:opacity-100 transition duration-500 text-xl" title="Rozprava je uzavřena" /> )} </h2> <PostFilters /> </div> <PostsContainer className="container-padding--zero lg:container-padding--auto" showAddPostCta={programEntry.discussionOpened} /> {!programEntry.discussionOpened && (!isAuthenticated || (isAuthenticated && !user.isBanned)) && ( <p className="leading-normal"> Rozprava je uzavřena - příspěvky teď nelze přidávat. </p> )} {programEntry.discussionOpened && isAuthenticated && !user.isBanned && <AddPostForm className="my-8 space-y-4" />} {programEntry.discussionOpened && isAuthenticated && user.isBanned && ( <ErrorMessage className="mt-8"> Jejda! Nemůžeš přidávat příspěvky, protože máš ban. Vyčkej než ti ho předsedající odebere. </ErrorMessage> )} </section> </article> <ProgramEntryEditModal isOpen={showProgramEditModal} onConfirm={onEditProgramConfirm} onCancel={onEditProgramCancel} programEntry={programEntry} /> <ModalConfirm isOpen={showCloseDiscussion} onConfirm={onCloseDiscussionConfirm} onCancel={onCloseDiscussionCancel} title="Ukončit rozpravu?" yesActionLabel="Ukončit" > Opravdu chcete ukončit rozpravu? </ModalConfirm> <ModalConfirm isOpen={showOpenDiscussion} onConfirm={onOpenDiscussionConfirm} onCancel={onOpenDiscussionCancel} title="Otevřít rozpravu?" yesActionLabel="Otevřít" > Opravdu chcete otevřít rozpravu k tomuto bodu programu? </ModalConfirm> <ModalConfirm isOpen={showEndProgramPoint} onConfirm={onEndProgramPointConfirm} onCancel={onEndProgramPointCancel} title="Ukončit bod programu?" yesActionLabel="Ukončit bod programu" > Bod programu <strong>bude ukončen</strong>. Opravdu to chcete? </ModalConfirm> </> ); }; export default Home;