diff --git a/src/components/Notifications/index.tsx b/src/components/Notifications/index.tsx index 5366f87..2b2d458 100644 --- a/src/components/Notifications/index.tsx +++ b/src/components/Notifications/index.tsx @@ -1,7 +1,7 @@ import _ from "lodash" import React, { memo, useCallback, useEffect, useRef, useState } from "react" import isNode from "detect-node" -import { useDispatch, useSelector } from "react-redux" +import { shallowEqual, useDispatch, useSelector } from "react-redux" import classnames from "classnames" import { fetchVolunteerNotifsSet } from "../../store/volunteerNotifsSet" import styles from "./styles.module.scss" @@ -9,15 +9,22 @@ import { selectUserJwtToken } from "../../store/auth" import { VolunteerNotifs } from "../../services/volunteers" // import { TeamWishesForm } from ".." import { fetchFor as fetchForTeamWishesForm } from "../VolunteerBoard/TeamWishesForm/TeamWishesForm" +import { AppState } from "../../store" +import Block from "../ui/Content/ContentBlock" -interface Props { - // eslint-disable-next-line react/require-default-props - volunteerNotifs?: VolunteerNotifs -} +let prevNotifs: VolunteerNotifs | undefined -const Notifications = ({ volunteerNotifs }: Props): JSX.Element | null => { +const Notifications = (): JSX.Element | null => { const dispatch = useDispatch() const jwtToken = useSelector(selectUserJwtToken) + const volunteerNotifs = useSelector((state: AppState) => { + const notifs = state.volunteerNotifsSet?.entity + if (notifs) { + prevNotifs = notifs + return notifs + } + return prevNotifs + }, shallowEqual) const hidden = volunteerNotifs?.hiddenNotifs || [] const notifs: JSX.Element[] = [] @@ -36,19 +43,17 @@ const Notifications = ({ volunteerNotifs }: Props): JSX.Element | null => { if (!_.includes(hidden, 1)) { notifs.push(
-
-
-
- Salut {volunteerNotifs?.firstname} ! -
- Ici tu seras notifié(e) des nouvelles importantes et des questions - pour lesquelles il nous faudrait absolument ta réponse. -
- -
+
+ + Salut {volunteerNotifs?.firstname} ! +
+ Ici tu seras notifié(e) des nouvelles importantes et des questions pour + lesquelles il nous faudrait absolument ta réponse. +
+
- -
+
+
) @@ -80,64 +85,62 @@ const Notifications = ({ volunteerNotifs }: Props): JSX.Element | null => { if (!_.includes(hidden, 2)) { notifs.push(
-
-
-
-
- Si les conditions sanitaires te le permettent, souhaites-tu être - bénévole à PeL 2022 ?
- - - - {participation === "peut-etre" ? ( -
- On te le reproposera dans quelques temps. -
- Si tu as besoin d'infos, viens nous en parler sur le - serveur Discord ! Pour le rejoindre,{" "} - - clique ici{" "} - - . -
- ) : null} -
- +
+
+ + Si les conditions sanitaires te le permettent, souhaites-tu être + bénévole à PeL 2022 ?
+ + + + {participation === "peut-etre" ? ( +
+ On te le reproposera dans quelques temps. +
+ Si tu as besoin d'infos, viens nous en parler sur le + serveur Discord ! Pour le rejoindre,{" "} + + clique ici{" "} + + .
-
{participationMessage}
- -
+ ) : null} +
+ +
+
{participationMessage}
+
@@ -155,27 +158,25 @@ const Notifications = ({ volunteerNotifs }: Props): JSX.Element | null => { if (!_.includes(hidden, 3)) { notifs.push(
-
-
-
-
+ +
+ La{" "} + - La{" "} - - gazette de février - {" "} - est disponible !
-
- -
+ gazette de février + {" "} + est disponible !
+
+
- -
+
+
) @@ -381,49 +382,47 @@ Tu n'y es absolument pas obligé(e) ! C'est juste plus pratique. if (notifs.length === 0) { notifs.push(
-
-
-
- -
{notifMessage}
+ +
+
+ + + +
{notifMessage}
+ + Pas besoin de valider, le site mémorise automatiquement si tu changes ta + réponse. +
-
+
) } diff --git a/src/components/Notifications/styles.module.scss b/src/components/Notifications/styles.module.scss index a83d092..2c68b21 100755 --- a/src/components/Notifications/styles.module.scss +++ b/src/components/Notifications/styles.module.scss @@ -6,7 +6,7 @@ } .notificationsContent { - @include page-content-wrapper; + @include inner-content-wrapper; } .pushNotificationsPage { @@ -14,7 +14,7 @@ } .pushNotificationsContent { - @include page-content-wrapper; + @include inner-content-wrapper; } .notifIntro { diff --git a/src/components/VolunteerBoard/Board.tsx b/src/components/VolunteerBoard/Board.tsx index 944d269..faf2a35 100644 --- a/src/components/VolunteerBoard/Board.tsx +++ b/src/components/VolunteerBoard/Board.tsx @@ -6,16 +6,29 @@ import ParticipationDetailsFormModal from "./ParticipationDetailsForm/Participat import TeamWishes from "./TeamWishes/TeamWishes" import TeamWishesFormModal from "./TeamWishesForm/TeamWishesFormModal" import withUserConnected from "../../utils/withUserConnected" +import { fetchVolunteerDayWishesSetIfNeed } from "../../store/volunteerDayWishesSet" +import { fetchVolunteerParticipationDetailsSetIfNeed } from "../../store/volunteerParticipationDetailsSet" +import { fetchTeamListIfNeed } from "../../store/teamList" +import { fetchVolunteerTeamWishesSetIfNeed } from "../../store/volunteerTeamWishesSet" +import ContentTitle from "../ui/Content/ContentTitle" const Board: FC = (): JSX.Element => ( -
+ <> + -
+ ) export default memo(withUserConnected(Board)) + +export const fetchFor = [ + fetchVolunteerDayWishesSetIfNeed, + fetchVolunteerParticipationDetailsSetIfNeed, + fetchTeamListIfNeed, + fetchVolunteerTeamWishesSetIfNeed, +] diff --git a/src/components/VolunteerBoard/TeamWishesForm/TeamWishesForm.tsx b/src/components/VolunteerBoard/TeamWishesForm/TeamWishesForm.tsx index 03c2242..65ea790 100644 --- a/src/components/VolunteerBoard/TeamWishesForm/TeamWishesForm.tsx +++ b/src/components/VolunteerBoard/TeamWishesForm/TeamWishesForm.tsx @@ -65,7 +65,7 @@ const TeamWishesForm: FC = ({ afterSubmit }): JSX.Element | null => { {selection.map((item) => { const team = teams.find((t: any) => t.id === item) if (!team) return null - return
  • {team.name}
  • + return
  • {team.name}
  • })}
    diff --git a/src/components/VolunteerConfirmation/VolunteerConfirmation.tsx b/src/components/VolunteerConfirmation/VolunteerConfirmation.tsx new file mode 100644 index 0000000..4a74a0d --- /dev/null +++ b/src/components/VolunteerConfirmation/VolunteerConfirmation.tsx @@ -0,0 +1,8 @@ +import { FC, memo } from "react" +import styles from "./styles.module.scss" + +const VolunteerConfirmation: FC = (): JSX.Element => ( +
    ✓ Tu es bénévole pour le festival de 2022. Merci !
    +) + +export default memo(VolunteerConfirmation) diff --git a/src/components/VolunteerConfirmation/styles.module.scss b/src/components/VolunteerConfirmation/styles.module.scss new file mode 100755 index 0000000..f0bfad0 --- /dev/null +++ b/src/components/VolunteerConfirmation/styles.module.scss @@ -0,0 +1,7 @@ +@import "../../theme/variables"; + +.root { + margin-bottom: 10px; + text-align: center; + color: $color-green; +} diff --git a/src/components/index.ts b/src/components/index.ts index 5b3c1b9..ba0a18d 100755 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -12,6 +12,7 @@ import VolunteerList from "./VolunteerList" import VolunteerInfo from "./VolunteerInfo" import VolunteerSet from "./VolunteerSet" import WishAdd from "./WishAdd" +import { fetchFor as fetchForBoardForms } from "./VolunteerBoard/Board" export { AnnouncementLink, @@ -28,4 +29,5 @@ export { VolunteerList, VolunteerSet, WishAdd, + fetchForBoardForms, } diff --git a/src/components/ui/Content/ContentBlock.tsx b/src/components/ui/Content/ContentBlock.tsx new file mode 100644 index 0000000..ebd4b32 --- /dev/null +++ b/src/components/ui/Content/ContentBlock.tsx @@ -0,0 +1,21 @@ +import { FC, memo, ReactNode } from "react" +import styles from "./styles.module.scss" +import ContentTitle from "./ContentTitle" + +interface Props { + children: ReactNode + title?: string | null +} + +const ContentBlock: FC = ({ children, title }): JSX.Element => ( +
    + {title && } +
    {children}
    +
    +) + +ContentBlock.defaultProps = { + title: null, +} + +export default memo(ContentBlock) diff --git a/src/components/ui/Content/ContentTitle.tsx b/src/components/ui/Content/ContentTitle.tsx new file mode 100644 index 0000000..10ac7bd --- /dev/null +++ b/src/components/ui/Content/ContentTitle.tsx @@ -0,0 +1,12 @@ +import { FC, memo } from "react" +import styles from "./styles.module.scss" + +interface Props { + title: string +} + +const ContentTitle: FC = ({ title }): JSX.Element => ( +

    {title}

    +) + +export default memo(ContentTitle) diff --git a/src/components/ui/Content/styles.module.scss b/src/components/ui/Content/styles.module.scss new file mode 100755 index 0000000..ddf4df2 --- /dev/null +++ b/src/components/ui/Content/styles.module.scss @@ -0,0 +1,12 @@ +@import "../../../theme/mixins"; + +.title { + margin: 30px 10px 0; + padding: 0; + font-weight: 600; + font-size: 1.1em; +} + +.content { + @include inner-content-wrapper; +} diff --git a/src/components/Page/Page.tsx b/src/components/ui/Page/Page.tsx similarity index 100% rename from src/components/Page/Page.tsx rename to src/components/ui/Page/Page.tsx diff --git a/src/components/Page/styles.module.scss b/src/components/ui/Page/styles.module.scss similarity index 77% rename from src/components/Page/styles.module.scss rename to src/components/ui/Page/styles.module.scss index fd951e3..ac77648 100755 --- a/src/components/Page/styles.module.scss +++ b/src/components/ui/Page/styles.module.scss @@ -1,4 +1,4 @@ -@import "../../theme/mixins"; +@import "../../../theme/mixins"; .pageWrapper { @include page-wrapper-center; diff --git a/src/pages/Board/Board.tsx b/src/pages/Board/Board.tsx index c7d2b41..6bdb341 100644 --- a/src/pages/Board/Board.tsx +++ b/src/pages/Board/Board.tsx @@ -4,7 +4,7 @@ import { useSelector } from "react-redux" import { AppThunk } from "../../store" import { selectUserJwtToken } from "../../store/auth" -import Page from "../../components/Page/Page" +import Page from "../../components/ui/Page/Page" import Board from "../../components/VolunteerBoard/Board" import { fetchVolunteerDayWishesSetIfNeed } from "../../store/volunteerDayWishesSet" import { fetchVolunteerParticipationDetailsSetIfNeed } from "../../store/volunteerParticipationDetailsSet" diff --git a/src/pages/Home/Home.tsx b/src/pages/Home/Home.tsx index 6586af1..e6b796f 100644 --- a/src/pages/Home/Home.tsx +++ b/src/pages/Home/Home.tsx @@ -1,35 +1,33 @@ import { FC, memo } from "react" import { RouteComponentProps, Link } from "react-router-dom" -import { useSelector, shallowEqual } from "react-redux" +import { useSelector } from "react-redux" import { Helmet } from "react-helmet" -import { AppState, AppThunk } from "../../store" -import { LoginForm, Notifications, fetchForTeamWishesForm } from "../../components" +import { AppThunk } from "../../store" +import { LoginForm, Notifications, fetchForBoardForms } from "../../components" import styles from "./styles.module.scss" -import { fetchVolunteerNotifsSetIfNeed } from "../../store/volunteerNotifsSet" -import { VolunteerNotifs } from "../../services/volunteers" +import { fetchVolunteerNotifsSetIfNeed, hasWaitingNotifs } from "../../store/volunteerNotifsSet" import { selectUserJwtToken } from "../../store/auth" +import Board from "../../components/VolunteerBoard/Board" +import Page from "../../components/ui/Page/Page" +import VolunteerConfirmation from "../../components/VolunteerConfirmation/VolunteerConfirmation" export type Props = RouteComponentProps -let prevNotifs: VolunteerNotifs | undefined - const HomePage: FC = (): JSX.Element => { const jwtToken = useSelector(selectUserJwtToken) - - const volunteerNotifs = useSelector((state: AppState) => { - const notifs = state.volunteerNotifsSet?.entity - if (notifs) { - prevNotifs = notifs - return notifs - } - return prevNotifs - }, shallowEqual) + const waitingNotifs = useSelector(hasWaitingNotifs) if (jwtToken === undefined) return

    Loading...

    if (jwtToken) { - return + return ( + + {!waitingNotifs && } + + {!waitingNotifs && } + + ) } return (
    @@ -51,7 +49,7 @@ const HomePage: FC = (): JSX.Element => { // Fetch server-side data here export const loadData = (): AppThunk[] => [ fetchVolunteerNotifsSetIfNeed(), - ...fetchForTeamWishesForm.map((f) => f()), + ...fetchForBoardForms.map((f) => f()), ] export default memo(HomePage) diff --git a/src/pages/Volunteers/Volunteers.tsx b/src/pages/Volunteers/Volunteers.tsx index 3791e7d..eec249a 100644 --- a/src/pages/Volunteers/Volunteers.tsx +++ b/src/pages/Volunteers/Volunteers.tsx @@ -4,7 +4,7 @@ import { useSelector } from "react-redux" import { AppThunk } from "../../store" import { selectUserJwtToken } from "../../store/auth" -import Page from "../../components/Page/Page" +import Page from "../../components/ui/Page/Page" import { fetchVolunteerListIfNeed } from "../../store/volunteerList" export type Props = RouteComponentProps diff --git a/src/store/volunteerNotifsSet.ts b/src/store/volunteerNotifsSet.ts index a34db8c..4200652 100644 --- a/src/store/volunteerNotifsSet.ts +++ b/src/store/volunteerNotifsSet.ts @@ -1,4 +1,5 @@ -import { PayloadAction, createSlice } from "@reduxjs/toolkit" +import { PayloadAction, createSlice, createSelector } from "@reduxjs/toolkit" +import get from "lodash/get" import { StateRequest, toastError, elementFetch } from "./utils" import { VolunteerNotifs } from "../services/volunteers" @@ -57,3 +58,21 @@ export const fetchVolunteerNotifsSetIfNeed = return null } + +export const openedNotifsIds = [1, 2, 3] + +export const selectVolunteerNotifsSetState = (state: AppState): StateVolunteerNotifsSet => + state.volunteerNotifsSet + +export const selectHiddenNotifs = createSelector(selectVolunteerNotifsSetState, (notifState) => + get(notifState, "entity.hiddenNotifs", []) +) + +export const selectWaitingsNotifs = createSelector(selectHiddenNotifs, (hidden) => + openedNotifsIds.filter((id) => !hidden.find((hiddenId: number) => hiddenId === id)) +) + +export const hasWaitingNotifs = createSelector( + selectWaitingsNotifs, + (waiting) => waiting.length > 0 +) diff --git a/src/theme/mixins.scss b/src/theme/mixins.scss index b16fd3c..3fe4d75 100644 --- a/src/theme/mixins.scss +++ b/src/theme/mixins.scss @@ -37,7 +37,7 @@ } @mixin inner-content-wrapper() { - margin: 10px 0; + margin: 5px 0 10px; padding: 10px; border-radius: 5px; background-color: $color-grey-lighter;