Skip to content
Snippets Groups Projects
Home.jsx 10.21 KiB
import React, { useEffect, useState } from "react";
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 && new Date() < firstProgramEntry.expectedStartAt) {
    return <NotYetStarted startAt={firstProgramEntry.expectedStartAt} />;
  }

  if (!programEntry && new Date() > lastProgramEntry.expectedStartAt) {
    return <AlreadyFinished />;
  }

  if (!programEntry) {
    return <BreakInProgress />;
  }

  const displayActions = isAuthenticated && user.role === "chairman";

  return (
    <>
      <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 &&
            !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;