From 0705ba71b7610070940448fa11d7d645a137f457 Mon Sep 17 00:00:00 2001 From: xaralis <filip.varecha@fragaria.cz> Date: Sun, 27 Dec 2020 14:36:09 +0100 Subject: [PATCH] feat: prepare jitsi invite popup card --- src/components/Button.jsx | 5 ++- src/components/Navbar.jsx | 42 +++++++++++-------- src/components/annoucements/Announcement.jsx | 4 +- .../annoucements/AnnouncementEditModal.jsx | 4 +- .../annoucements/AnnouncementList.jsx | 15 ++++++- src/components/modals/ModalConfirm.jsx | 2 +- src/components/posts/PostEditModal.jsx | 2 +- src/components/posts/PostList.jsx | 3 +- .../program/ProgramEntryEditModal.jsx | 2 +- src/containers/AddAnnouncementForm.jsx | 2 +- src/containers/JitsiInviteCard.jsx | 38 +++++++++++++++++ src/containers/PostsContainer.jsx | 3 +- src/pages/Home.jsx | 29 +++++++------ src/stores.js | 1 + typings/cf2021.d.ts | 2 + 15 files changed, 112 insertions(+), 42 deletions(-) create mode 100644 src/containers/JitsiInviteCard.jsx diff --git a/src/components/Button.jsx b/src/components/Button.jsx index b965282..3e7b791 100644 --- a/src/components/Button.jsx +++ b/src/components/Button.jsx @@ -4,6 +4,7 @@ import classNames from "classnames"; const Button = ({ className, + bodyClassName, icon, color = "black", hoverActive = true, @@ -25,9 +26,11 @@ const Button = ({ className ); + const bodyClass = classNames("btn__body", bodyClassName); + const inner = ( <div className="btn__body-wrap"> - <div className="btn__body">{children}</div> + <div className={bodyClass}>{children}</div> {!!icon && ( <div className="btn__icon"> <i className={icon}></i> diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index 9c6298a..4a5fb9c 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -36,23 +36,28 @@ const Navbar = () => { }; const connectionIndicator = ( - <span - className="relative inline-flex h-4 w-4 mr-4" - title={connectionStateCaption} - > + <div className="inline-flex items-center order-first md:order-last md:ml-8 lg:order-first lg:mr-8 lg:ml-0"> <span - className={classNames( - "animate-ping absolute inline-flex h-full w-full rounded-full opacity-75", - indicatorClass - )} - /> - <span - className={classNames( - "inline-flex rounded-full w-4 h-4", - indicatorClass - )} - /> - </span> + className="relative inline-flex h-4 w-4 mr-4" + title={connectionStateCaption} + > + <span + className={classNames( + "animate-ping absolute inline-flex h-full w-full rounded-full opacity-75", + indicatorClass + )} + /> + <span + className={classNames( + "inline-flex rounded-full w-4 h-4", + indicatorClass + )} + /> + </span> + <span className="hidden md:block text-grey-200"> + {connectionStateCaption} + </span> + </div> ); return ( @@ -113,7 +118,10 @@ const Navbar = () => { alt="Avatar" /> </div> - <button onClick={logout}> + <button + onClick={logout} + className="text-grey-200 hover:text-white" + > <i className="ico--log-out"></i> </button> </div> diff --git a/src/components/annoucements/Announcement.jsx b/src/components/annoucements/Announcement.jsx index 0d9f9c1..1cd7e38 100644 --- a/src/components/annoucements/Announcement.jsx +++ b/src/components/annoucements/Announcement.jsx @@ -105,13 +105,13 @@ const Announcement = ({ {showEdit && ( <DropdownMenuItem onClick={onEdit} - icon="ico--edit-pencil" + icon="ico--pencil" title="Upravit" /> )} <DropdownMenuItem onClick={onDelete} - icon="ico--trashcan" + icon="ico--bin" title="Smazat" /> </DropdownMenu> diff --git a/src/components/annoucements/AnnouncementEditModal.jsx b/src/components/annoucements/AnnouncementEditModal.jsx index 795d696..2f66654 100644 --- a/src/components/annoucements/AnnouncementEditModal.jsx +++ b/src/components/annoucements/AnnouncementEditModal.jsx @@ -72,7 +72,7 @@ const AnnouncementEditModal = ({ <div className="flex items-center justify-between mb-4"> <CardHeadline>Upravit oznámení</CardHeadline> <button onClick={onCancel} type="button"> - <i className="ico--close"></i> + <i className="ico--cross"></i> </button> </div> <MarkdownEditor @@ -104,7 +104,7 @@ const AnnouncementEditModal = ({ onChange={(evt) => onLinkInput(evt.target.value)} /> <div className="text-input-addon text-input-addon--l order-first"> - <i className="ico--link1"></i> + <i className="ico--link"></i> </div> </div> {linkValid === false && ( diff --git a/src/components/annoucements/AnnouncementList.jsx b/src/components/annoucements/AnnouncementList.jsx index 7df00e6..3e3ba8d 100644 --- a/src/components/annoucements/AnnouncementList.jsx +++ b/src/components/annoucements/AnnouncementList.jsx @@ -23,10 +23,23 @@ const AnnouncementList = ({ onSeen(announcement); }; + const getClassName = (idx) => { + if (idx === 0) { + return "pt-4 lg:pt-8"; + } + + if (idx === items.length - 1) { + return "pb-4 lg:pb-8"; + } + + return ""; + }; + return ( <div className={classNames("space-y-px", className)}> - {items.map((item) => ( + {items.map((item, idx) => ( <Announcement + className={getClassName(idx)} key={item.id} datetime={item.datetime} type={item.type} diff --git a/src/components/modals/ModalConfirm.jsx b/src/components/modals/ModalConfirm.jsx index 52cf87a..cfe8d26 100644 --- a/src/components/modals/ModalConfirm.jsx +++ b/src/components/modals/ModalConfirm.jsx @@ -30,7 +30,7 @@ const ModalConfirm = ({ <div className="flex items-center justify-between mb-4"> <CardHeadline>{title}</CardHeadline> <button onClick={onCancel} type="button"> - <i className="ico--close"></i> + <i className="ico--cross"></i> </button> </div> <CardBodyText>{children}</CardBodyText> diff --git a/src/components/posts/PostEditModal.jsx b/src/components/posts/PostEditModal.jsx index edbae53..e880b05 100644 --- a/src/components/posts/PostEditModal.jsx +++ b/src/components/posts/PostEditModal.jsx @@ -43,7 +43,7 @@ const PostEditModal = ({ <div className="flex items-center justify-between mb-4"> <CardHeadline>Upravit text příspěvku</CardHeadline> <button onClick={onCancel} type="button"> - <i className="ico--close"></i> + <i className="ico--cross"></i> </button> </div> <MarkdownEditor diff --git a/src/components/posts/PostList.jsx b/src/components/posts/PostList.jsx index 170a958..48caa5b 100644 --- a/src/components/posts/PostList.jsx +++ b/src/components/posts/PostList.jsx @@ -6,6 +6,7 @@ import Post from "./Post"; const PostList = ({ className, items, + showAddPostCta, currentUser, canThumb, dimArchived, @@ -83,7 +84,7 @@ const PostList = ({ onSeen={onPostSeen(item)} /> ))} - {!items.length && ( + {showAddPostCta && !items.length && ( <p className="p-4 lg:p-0 lg:py-3 leading-snug text-sm md:text-base"> Nikdo zatím žádný odpovídající příspěvek do rozpravy nepřidal. Budeš první? diff --git a/src/components/program/ProgramEntryEditModal.jsx b/src/components/program/ProgramEntryEditModal.jsx index 90b5385..37ce3f4 100644 --- a/src/components/program/ProgramEntryEditModal.jsx +++ b/src/components/program/ProgramEntryEditModal.jsx @@ -29,7 +29,7 @@ const ProgramEntryEditModal = ({ <div className="flex items-center justify-between mb-4"> <CardHeadline>Upravit název programového bodu</CardHeadline> <button onClick={onCancel}> - <i className="ico--close"></i> + <i className="ico--cross"></i> </button> </div> <div className="form-field"> diff --git a/src/containers/AddAnnouncementForm.jsx b/src/containers/AddAnnouncementForm.jsx index 3f96457..1413ece 100644 --- a/src/containers/AddAnnouncementForm.jsx +++ b/src/containers/AddAnnouncementForm.jsx @@ -135,7 +135,7 @@ const AddAnnouncementForm = ({ className }) => { onChange={(evt) => onLinkInput(evt.target.value)} /> <div className="text-input-addon text-input-addon--l order-first"> - <i className="ico--link1"></i> + <i className="ico--link"></i> </div> </div> {linkValid === false && ( diff --git a/src/containers/JitsiInviteCard.jsx b/src/containers/JitsiInviteCard.jsx new file mode 100644 index 0000000..5f480dd --- /dev/null +++ b/src/containers/JitsiInviteCard.jsx @@ -0,0 +1,38 @@ +import React from "react"; + +import Button from "components/Button"; +import { Card, CardBody } from "components/cards"; +import { AuthStore } from "stores"; + +const JitsiInviteCard = () => { + const { showJitsiInvitePopup } = AuthStore.useState(); + + if (!showJitsiInvitePopup) { + return null; + } + + return ( + <Card className="lg:card bg-violet-300 relative" elevation={16}> + <i className="ico--jitsi text-9xl mr-2 text-violet-500 absolute right-0 top-0 opacity-25 z-0" /> + <CardBody className="text-white relative z-10"> + <div className="flex items-center justify-between mb-4"> + <h2 className="head-heavy-xs"> + <span>Pozvánka do Jitsi</span> + </h2> + <button type="button"> + <i className="ico--cross"></i> + </button> + </div> + <p className="leading-snug text-sm mb-4"> + Někdo tě pozval do <strong>chráněného Jitsi kanálu</strong>{" "} + celeostátního fóra. Ke kanálu se připojíš kliknutím na tlačítko níže. + </p> + <Button color="violet-500" className="btn--fullwidth"> + Otevřít Jitsi kanál + </Button> + </CardBody> + </Card> + ); +}; + +export default JitsiInviteCard; diff --git a/src/containers/PostsContainer.jsx b/src/containers/PostsContainer.jsx index fdfb515..daf2a39 100644 --- a/src/containers/PostsContainer.jsx +++ b/src/containers/PostsContainer.jsx @@ -22,7 +22,7 @@ import PostList from "components/posts/PostList"; import { useActionState, useItemActionConfirm } from "hooks"; import { AuthStore, PostStore } from "stores"; -const PostsContainer = ({ className }) => { +const PostsContainer = ({ className, showAddPostCta }) => { const [postToEdit, setPostToEdit] = useState(null); const [confirmingEdit, setConfirmingEdit] = useState(false); const [editError, setEditError] = useState(null); @@ -165,6 +165,7 @@ const PostsContainer = ({ className }) => { )} <PostList items={windowItems.slice(sliceStart, sliceEnd)} + showAddPostCta={showAddPostCta} canThumb={isAuthenticated} onLike={like.run} onDislike={dislike.run} diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index 06ebfcf..f6ecd8c 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -17,6 +17,7 @@ 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"; @@ -167,7 +168,7 @@ const Home = () => { > <DropdownMenuItem onClick={() => setShowProgramEditModal(true)} - icon="ico--edit-pencil" + icon="ico--pencil" title="Přejmenovat bod programu" titleSize="base" iconSize="base" @@ -225,12 +226,10 @@ const Home = () => { </div> </section> - <section className="cf2021__notifications"> - <div className="lg:card lg:elevation-10"> - <div className="lg:card__body pb-2 lg:py-6"> - <h2 className="head-heavy-xs md:head-heavy-sm">Oznámení</h2> - </div> + <section className="cf2021__notifications space-y-8"> + <JitsiInviteCard /> + <div className="lg:card lg:elevation-10"> <AnnouncementsContainer className="container-padding--zero lg:container-padding--auto" /> {isAuthenticated && user.role === "chairman" && ( <AddAnnouncementForm className="lg:card__body pt-4 lg:py-6" /> @@ -248,17 +247,21 @@ const Home = () => { title="Rozprava je uzavřena" /> )} - {programEntry.discussionOpened && ( - <i - className="ico--lock-open text-black ml-1 opacity-50 hover:opacity-100 transition duration-500 text-xl" - title="Probíhá rozprava" - /> - )} </h2> <PostFilters /> </div> - <PostsContainer className="container-padding--zero lg:container-padding--auto" /> + <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" />} diff --git a/src/stores.js b/src/stores.js index 38a0dfa..ef639cd 100644 --- a/src/stores.js +++ b/src/stores.js @@ -15,6 +15,7 @@ export const GlobalInfoStore = new Store(globalInfoStoreInitial); /** @type {CF2021.AuthStorePayload} */ const authStoreInitial = { isAuthenticated: false, + showJitsiInvitePopup: false, }; export const AuthStore = new Store(authStoreInitial); diff --git a/typings/cf2021.d.ts b/typings/cf2021.d.ts index 154eab9..4572332 100644 --- a/typings/cf2021.d.ts +++ b/typings/cf2021.d.ts @@ -49,6 +49,8 @@ declare namespace CF2021 { group?: string; secret?: string; }; + showJitsiInvitePopup: boolean; + jitsiInviteToken?: string; } export type AuthStorePayload = -- GitLab