diff --git a/src/components/Asks/AskHosting.tsx b/src/components/Asks/AskHosting.tsx
new file mode 100644
index 0000000..8c21f81
--- /dev/null
+++ b/src/components/Asks/AskHosting.tsx
@@ -0,0 +1,39 @@
+import { get } from "lodash"
+import { useCallback } from "react"
+import { fetchVolunteerAsksSet } from "../../store/volunteerAsksSet"
+import { useAskTools, addAsk, answerLaterOnProfile } from "./utils"
+import ParticipationDetailsForm, {
+ fetchFor as fetchForParticipationDetailsForm,
+} from "../VolunteerBoard/ParticipationDetailsForm/ParticipationDetailsForm"
+import { useUserParticipationDetails } from "../VolunteerBoard/participationDetails.utils"
+
+export function AskParticipationDetails(asks: JSX.Element[], id: number): void {
+ const { dispatch, jwtToken, volunteerAsks } = useAskTools()
+
+ const onSubmit = useCallback((): void => {
+ dispatch(
+ fetchVolunteerAsksSet(jwtToken, 0, {
+ hiddenAsks: [...(volunteerAsks?.hiddenAsks || []), id],
+ })
+ )
+ }, [dispatch, id, jwtToken, volunteerAsks?.hiddenAsks])
+
+ const [participationDetails] = useUserParticipationDetails()
+ const tshirtSize = get(participationDetails, "tshirtSize", "")
+ const food = get(participationDetails, "food", "")
+ const needToShow = !tshirtSize || !food
+
+ addAsk(
+ asks,
+ id,
+ volunteerAsks,
+ false,
+ needToShow,
+
+ {answerLaterOnProfile}
+
+ )
+}
+
+// Fetch server-side data here
+export const fetchFor = [...fetchForParticipationDetailsForm]
diff --git a/src/components/VolunteerBoard/Board.tsx b/src/components/VolunteerBoard/Board.tsx
index 6803e62..79ba71f 100644
--- a/src/components/VolunteerBoard/Board.tsx
+++ b/src/components/VolunteerBoard/Board.tsx
@@ -1,6 +1,8 @@
import { FC, memo } from "react"
import DayWishes from "./DayWishes/DayWishes"
import DayWishesFormModal from "./DayWishesForm/DayWishesFormModal"
+import Hosting from "./Hosting/Hosting"
+import HostingFormModal from "./HostingForm/HostingFormModal"
import ParticipationDetails from "./ParticipationDetails/ParticipationDetails"
import ParticipationDetailsFormModal from "./ParticipationDetailsForm/ParticipationDetailsFormModal"
import TeamWishes from "./TeamWishes/TeamWishes"
@@ -8,6 +10,7 @@ import TeamWishesFormModal from "./TeamWishesForm/TeamWishesFormModal"
import withUserConnected from "../../utils/withUserConnected"
import ContentTitle from "../ui/Content/ContentTitle"
import { fetchFor as fetchForDayWishesForm } from "./DayWishesForm/DayWishesForm"
+import { fetchFor as fetchForHostingForm } from "./HostingForm/HostingForm"
import { fetchFor as fetchForParticipationDetailsForm } from "./ParticipationDetailsForm/ParticipationDetailsForm"
import { fetchFor as fetchForTeamWishesForm } from "./TeamWishesForm/TeamWishesForm"
import VolunteerTeam from "./VolunteerTeam/VolunteerTeam"
@@ -22,6 +25,8 @@ const Board: FC = (): JSX.Element => (
+
+
>
)
@@ -29,6 +34,7 @@ export default memo(withUserConnected(Board))
export const fetchFor = [
...fetchForDayWishesForm,
+ ...fetchForHostingForm,
...fetchForParticipationDetailsForm,
...fetchForTeamWishesForm,
]
diff --git a/src/components/VolunteerBoard/Hosting/Hosting.tsx b/src/components/VolunteerBoard/Hosting/Hosting.tsx
new file mode 100644
index 0000000..b0fb555
--- /dev/null
+++ b/src/components/VolunteerBoard/Hosting/Hosting.tsx
@@ -0,0 +1,61 @@
+import { FC, memo, useCallback } from "react"
+import get from "lodash/get"
+import styles from "./styles.module.scss"
+import { useUserHosting } from "../hosting.utils"
+import useAction from "../../../utils/useAction"
+import { displayModal, MODAL_IDS } from "../../../store/ui"
+
+const Hosting: FC = (): JSX.Element | null => {
+ const [userWishes] = useUserHosting()
+ const needsHosting = get(userWishes, "needsHosting", false)
+ const canHostCount = get(userWishes, "canHostCount", 0)
+ const distanceToFestival = get(userWishes, "distanceToFestival", 0)
+ const comment = get(userWishes, "hostingComment", "")
+ const execDisplayModal = useAction(displayModal)
+ const onEdit = useCallback(() => execDisplayModal(MODAL_IDS.HOSTING), [execDisplayModal])
+
+ return (
+
+
Mon hébergement
+ {!needsHosting && (
+
+ Je n'ai pas besoin d'un hébergement proche du festival
+
+ )}
+ {needsHosting && (
+
+ J'ai besoin d'un hébergement proche du festival
+
+ )}
+ {canHostCount === 0 && distanceToFestival === 0 && (
+
+ Je ne peux héberger personnes de manière utile.
+
+ )}
+ {canHostCount > 0 && (
+
+ Je peux héberger {canHostCount} personnes !
+
+ )}
+ {distanceToFestival > 0 && (
+
+ Je suis à {distanceToFestival} minutes du festival
+
+ )}
+
+ {comment && (
+
+ Mon commentaire :
+ {comment}
+
+ )}
+
+
+ Modifier
+
+
+
+ )
+}
+
+export default memo(Hosting)
diff --git a/src/components/VolunteerBoard/Hosting/styles.module.scss b/src/components/VolunteerBoard/Hosting/styles.module.scss
new file mode 100755
index 0000000..93683a5
--- /dev/null
+++ b/src/components/VolunteerBoard/Hosting/styles.module.scss
@@ -0,0 +1,53 @@
+@import "../../../theme/variables";
+@import "../../../theme/mixins";
+
+.title {
+ padding-bottom: 10px;
+ font-weight: bold;
+}
+
+.hostingLabel {
+ margin-right: 5px;
+ font-style: bold;
+}
+
+.hosting {
+ @include inner-content-wrapper();
+
+ position: relative;
+ padding-right: 90px;
+}
+
+.hostingLabel,
+.commentLine {
+ margin-bottom: 5px;
+ span {
+ display: inline-block;
+ }
+}
+
+.lineEmpty {
+ color: $color-red;
+ font-style: italic;
+}
+
+.commentLineTitle {
+ padding-right: 5px;
+}
+
+.commentLineText {
+ font-style: italic;
+}
+
+.editButton {
+ @include vertical-center();
+
+ position: absolute;
+ right: 20px;
+
+ button {
+ color: $color-green;
+ font-weight: bold;
+ cursor: pointer;
+ }
+}
diff --git a/src/components/VolunteerBoard/HostingForm/HostingForm.tsx b/src/components/VolunteerBoard/HostingForm/HostingForm.tsx
new file mode 100644
index 0000000..57647fd
--- /dev/null
+++ b/src/components/VolunteerBoard/HostingForm/HostingForm.tsx
@@ -0,0 +1,133 @@
+import { FC, memo, ReactNode, useCallback, useEffect, useRef, useState } from "react"
+import classnames from "classnames"
+import get from "lodash/get"
+import set from "lodash/set"
+import styles from "./styles.module.scss"
+import { useUserHosting } from "../hosting.utils"
+import FormButton from "../../Form/FormButton/FormButton"
+import { fetchVolunteerHostingSetIfNeed } from "../../../store/volunteerHostingSet"
+import IgnoreButton from "../../Form/IgnoreButton/IgnoreButton"
+
+type Props = {
+ children?: ReactNode | undefined
+ afterSubmit?: () => void | undefined
+}
+
+const HostingForm: FC = ({ children, afterSubmit }): JSX.Element => {
+ const [needsHosting, setNeedsHosting] = useState(false)
+ const canHostCountRef = useRef(null)
+ const distanceRef = useRef(null)
+ const commentRef = useRef(null)
+ const [userWishes, saveWishes] = useUserHosting()
+
+ const onNeedsHostingChange = (e: React.ChangeEvent) =>
+ setNeedsHosting(e.target.checked)
+
+ useEffect(() => {
+ if (!userWishes) return
+ setNeedsHosting(get(userWishes, "needsHosting", false))
+ set(canHostCountRef, "current.value", `${get(userWishes, "canHostCount", 0)}`)
+ set(distanceRef, "current.value", `${get(userWishes, "distanceToFestival", 0)}`)
+ set(commentRef, "current.value", get(userWishes, "hostingComment", ""))
+ }, [commentRef, userWishes])
+
+ const onChoiceSubmit = useCallback(() => {
+ const canHostCount = +get(canHostCountRef, "current.value", "0")
+ const distanceToFestival = +get(distanceRef, "current.value", "0")
+ const hostingComment = get(commentRef, "current.value", "")
+ saveWishes(needsHosting, canHostCount, distanceToFestival, hostingComment)
+ if (afterSubmit) afterSubmit()
+ }, [needsHosting, commentRef, saveWishes, afterSubmit])
+
+ return (
+
+
Mes jours de présence
+
+
+
+ Cela t'arrangerait-il d'avoir un hébergement proche du festival ?
+
+
+
+
+ {" "}
+ Oui
+
+
+
+ {needsHosting && (
+
+
+ Il nous serait utile de savoir à quelle temps de transport tu te trouves
+ pour privilégier les bénévoles qui viennent de province à ceux qui viennent
+ de l'autre bout de Paris.
+
+
+ )}
+
+
+
+ Combien de bénévoles peux-tu héberger confortablement ?
+
+
+
+
+
+
+
+
+
+ À combien de minutes de transport es-tu du festival ? (En voiture si tu es
+ en voiture, à vélo si tu as des vélos, sinon en transport en commun.)
+
+
+
+
+
+
+
+ Un commentaire, une précision ?
+
+
+
+ Enregistrer
+ {children === undefined && (
+ <>
+ {" "}
+
+ Annuler
+ {" "}
+ >
+ )}
+ {children !== undefined && (
+ <>
+ {" "}
+
+ {children}
+ {" "}
+ >
+ )}
+
+
+ )
+}
+
+HostingForm.defaultProps = {
+ children: undefined,
+ afterSubmit: undefined,
+}
+
+export default memo(HostingForm)
+
+// Fetch server-side data here
+export const fetchFor = [fetchVolunteerHostingSetIfNeed]
diff --git a/src/components/VolunteerBoard/HostingForm/HostingFormModal.tsx b/src/components/VolunteerBoard/HostingForm/HostingFormModal.tsx
new file mode 100644
index 0000000..1f2375a
--- /dev/null
+++ b/src/components/VolunteerBoard/HostingForm/HostingFormModal.tsx
@@ -0,0 +1,18 @@
+import { FC, memo, useCallback } from "react"
+import { hideModal, MODAL_IDS } from "../../../store/ui"
+import Modal from "../../Modal/Modal"
+import useAction from "../../../utils/useAction"
+import HostingForm from "./HostingForm"
+
+const HostingFormModal: FC = (): JSX.Element => {
+ const execHideModal = useAction(hideModal)
+ const afterFormSubmit = useCallback(() => execHideModal(), [execHideModal])
+
+ return (
+
+
+
+ )
+}
+
+export default memo(HostingFormModal)
diff --git a/src/components/VolunteerBoard/HostingForm/styles.module.scss b/src/components/VolunteerBoard/HostingForm/styles.module.scss
new file mode 100755
index 0000000..4115fba
--- /dev/null
+++ b/src/components/VolunteerBoard/HostingForm/styles.module.scss
@@ -0,0 +1,126 @@
+@import "../../../theme/variables";
+@import "../../../theme/mixins";
+
+.title {
+ padding: 15px 0;
+ font-weight: bold;
+ text-align: center;
+}
+
+.inputWrapper {
+ margin: 25px 0;
+
+ @include desktop {
+ display: flex;
+ }
+}
+
+.noBottomMargin {
+ margin-bottom: 0;
+}
+
+.leftCol {
+ flex: 0 0 320px;
+}
+
+.rightCol {
+ width: 100%;
+ text-align: center;
+}
+
+.needsHostingTitle {
+ display: inline-block;
+ width: 320px;
+ margin-bottom: 10px;
+}
+
+.needsHostingLabel {
+ text-align: left;
+ display: inline-block;
+ margin-bottom: 10px;
+ width: 80px;
+}
+
+.canHostCountTitle {
+ display: inline-block;
+ width: 320px;
+ margin-bottom: 10px;
+}
+
+.canHostCountLabel {
+ text-align: left;
+ display: inline-block;
+ margin-bottom: 10px;
+ width: 80px;
+}
+
+.distanceToFestivalTitle {
+ display: inline-block;
+ width: 320px;
+ margin-bottom: 10px;
+}
+
+.distanceToFestivalLabel {
+ text-align: left;
+ display: inline-block;
+ margin-bottom: 10px;
+ width: 80px;
+}
+
+.hostingTitle {
+ display: inline-block;
+ width: 320px;
+ margin-bottom: 10px;
+}
+
+.hostingList {
+ @include clear-ul-style;
+
+ display: inline-block;
+ width: 204px;
+ text-align: center;
+}
+
+.hostingItem {
+ display: inline-block;
+ margin: 3px;
+}
+
+.hostingButton {
+ margin: 0;
+ padding: 7px 2px 6px;
+ border: 0;
+ border-radius: 0;
+ width: 90px;
+ text-align: center;
+ color: $color-grey-dark;
+ background-color: $color-grey-light;
+ cursor: pointer;
+
+ &.active {
+ color: $color-yellow;
+ background-color: $color-black;
+ }
+}
+
+.hostingCommentWrapper {
+ margin: 6px 0 14px;
+
+ label {
+ display: block;
+ padding: 6px 0 2px 4px;
+ }
+ textarea {
+ width: 100%;
+ height: 50px;
+ padding: 5px;
+ border: 1px solid $color-grey-light;
+ background-color: $color-grey-lighter;
+ outline: 0;
+ }
+}
+
+.buttonWrapper {
+ margin-bottom: 10px;
+ text-align: center;
+}
diff --git a/src/components/VolunteerBoard/hosting.utils.ts b/src/components/VolunteerBoard/hosting.utils.ts
new file mode 100644
index 0000000..aea33ad
--- /dev/null
+++ b/src/components/VolunteerBoard/hosting.utils.ts
@@ -0,0 +1,31 @@
+import { shallowEqual, useSelector } from "react-redux"
+import { useCallback } from "react"
+import { selectUserJwtToken } from "../../store/auth"
+import { AppState } from "../../store"
+import { fetchVolunteerHostingSet } from "../../store/volunteerHostingSet"
+import useAction from "../../utils/useAction"
+
+export const useUserHosting = (): [any, any] => {
+ const save = useAction(fetchVolunteerHostingSet)
+ const jwtToken = useSelector(selectUserJwtToken)
+ const userWishes = useSelector(
+ (state: AppState) => state.volunteerHostingSet?.entity,
+ shallowEqual
+ )
+
+ const saveWishes = useCallback(
+ (needsHosting, canHostCount, distanceToFestival, hostingComment) => {
+ if (!userWishes) return
+ save(jwtToken, 0, {
+ id: userWishes.id,
+ needsHosting,
+ canHostCount,
+ distanceToFestival,
+ hostingComment,
+ })
+ },
+ [userWishes, save, jwtToken]
+ )
+
+ return [userWishes, saveWishes]
+}
diff --git a/src/server/gsheets/volunteers.ts b/src/server/gsheets/volunteers.ts
index 6858767..3228fc2 100644
--- a/src/server/gsheets/volunteers.ts
+++ b/src/server/gsheets/volunteers.ts
@@ -11,6 +11,7 @@ import {
VolunteerTeamWishes,
translationVolunteer,
VolunteerDayWishes,
+ VolunteerHosting,
VolunteerParticipationDetails,
VolunteerTeamAssign,
VolunteerKnowledge,
@@ -324,6 +325,43 @@ export const volunteerDayWishesSet = expressAccessor.set(async (list, body, id)
}
})
+export const volunteerHostingSet = expressAccessor.set(async (list, body, id) => {
+ const requestedId = +body[0] || id
+ if (requestedId !== id && requestedId !== 0) {
+ throw Error(`On ne peut acceder qu'à ses propres infos d'hébergement`)
+ }
+ const wishes = body[1] as VolunteerHosting
+ const volunteer: Volunteer | undefined = list.find((v) => v.id === requestedId)
+ if (!volunteer) {
+ throw Error(`Il n'y a aucun bénévole avec cet identifiant ${requestedId}`)
+ }
+ const newVolunteer = cloneDeep(volunteer)
+
+ if (wishes.needsHosting !== undefined) {
+ newVolunteer.needsHosting = wishes.needsHosting
+ }
+ if (wishes.canHostCount !== undefined) {
+ newVolunteer.canHostCount = wishes.canHostCount
+ }
+ if (wishes.distanceToFestival !== undefined) {
+ newVolunteer.distanceToFestival = wishes.distanceToFestival
+ }
+ if (wishes.hostingComment !== undefined) {
+ newVolunteer.hostingComment = wishes.hostingComment
+ }
+
+ return {
+ toDatabase: newVolunteer,
+ toCaller: {
+ id: newVolunteer.id,
+ needsHosting: newVolunteer.needsHosting,
+ canHostCount: newVolunteer.canHostCount,
+ distanceToFestival: newVolunteer.distanceToFestival,
+ hostingComment: newVolunteer.hostingComment,
+ } as VolunteerHosting,
+ }
+})
+
export const volunteerParticipationDetailsSet = expressAccessor.set(async (list, body, id) => {
const requestedId = +body[0] || id
if (requestedId !== id && requestedId !== 0) {
diff --git a/src/server/index.ts b/src/server/index.ts
index e264aeb..b7e050f 100755
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -26,6 +26,7 @@ import {
volunteerAsksSet,
volunteerDayWishesSet,
volunteerForgot,
+ volunteerHostingSet,
volunteerDiscordId,
volunteerLogin,
volunteerPartialAdd,
@@ -111,6 +112,7 @@ app.post(
volunteerParticipationDetailsSet
)
app.post("/VolunteerDayWishesSet", secure as RequestHandler, volunteerDayWishesSet)
+app.post("/VolunteerHostingSet", secure as RequestHandler, volunteerHostingSet)
app.post("/VolunteerTeamWishesSet", secure as RequestHandler, volunteerTeamWishesSet)
app.post("/VolunteerTeamAssignSet", secure as RequestHandler, volunteerTeamAssignSet)
diff --git a/src/services/volunteers.ts b/src/services/volunteers.ts
index 60543f4..6715c5b 100644
--- a/src/services/volunteers.ts
+++ b/src/services/volunteers.ts
@@ -59,6 +59,14 @@ export class Volunteer implements VolunteerPartial {
bof: number[] = []
niet: number[] = []
+
+ needsHosting = false
+
+ canHostCount = 0
+
+ distanceToFestival = 0
+
+ hostingComment = ""
}
export const translationVolunteer: { [k in keyof Volunteer]: string } = {
@@ -92,6 +100,10 @@ export const translationVolunteer: { [k in keyof Volunteer]: string } = {
ok: "OK",
bof: "Bof",
niet: "Niet",
+ needsHosting: "besoinHébergement",
+ canHostCount: "nombreHébergés",
+ distanceToFestival: "distanceAuFestival",
+ hostingComment: "commentaireHébergement",
}
export class VolunteerPartial {
@@ -137,6 +149,10 @@ export const volunteerExample: Volunteer = {
ok: [5, 7, 24, 26, 31, 38, 50, 52, 54, 58],
bof: [9, 12, 16, 27, 34, 35, 36],
niet: [13, 18, 19, 23, 47, 53, 59, 67],
+ needsHosting: false,
+ canHostCount: 0,
+ distanceToFestival: 0,
+ hostingComment: "",
}
export const emailRegexp =
@@ -181,6 +197,14 @@ export interface VolunteerDayWishes {
dayWishesComment: Volunteer["dayWishesComment"]
}
+export interface VolunteerHosting {
+ id: Volunteer["id"]
+ needsHosting: Volunteer["needsHosting"]
+ canHostCount: Volunteer["canHostCount"]
+ distanceToFestival: Volunteer["distanceToFestival"]
+ hostingComment: Volunteer["hostingComment"]
+}
+
export interface VolunteerParticipationDetails {
id: Volunteer["id"]
tshirtSize: Volunteer["tshirtSize"]
diff --git a/src/services/volunteersAccessors.ts b/src/services/volunteersAccessors.ts
index dea12eb..dbb1efe 100644
--- a/src/services/volunteersAccessors.ts
+++ b/src/services/volunteersAccessors.ts
@@ -3,6 +3,7 @@ import {
elementName,
Volunteer,
VolunteerDayWishes,
+ VolunteerHosting,
VolunteerAsks,
VolunteerParticipationDetails,
VolunteerTeamWishes,
@@ -38,6 +39,9 @@ export const volunteerTeamWishesSet =
export const volunteerDayWishesSet =
serviceAccessors.securedCustomPost<[number, Partial]>("DayWishesSet")
+export const volunteerHostingSet =
+ serviceAccessors.securedCustomPost<[number, Partial]>("HostingSet")
+
export const volunteerParticipationDetailsSet =
serviceAccessors.securedCustomPost<[number, Partial]>(
"ParticipationDetailsSet"
diff --git a/src/store/rootReducer.ts b/src/store/rootReducer.ts
index b05d40c..0bc15d4 100644
--- a/src/store/rootReducer.ts
+++ b/src/store/rootReducer.ts
@@ -16,6 +16,7 @@ import volunteerAsksSet from "./volunteerAsksSet"
import volunteerDayWishesSet from "./volunteerDayWishesSet"
import volunteerDiscordId from "./volunteerDiscordId"
import volunteerForgot from "./volunteerForgot"
+import volunteerHostingSet from "./volunteerHostingSet"
import volunteerList from "./volunteerList"
import volunteerLogin from "./volunteerLogin"
import volunteerKnowledgeSet from "./volunteerKnowledgeSet"
@@ -44,6 +45,7 @@ export default (history: History) => ({
volunteerDayWishesSet,
volunteerDiscordId,
volunteerForgot,
+ volunteerHostingSet,
volunteerList,
volunteerLogin,
volunteerKnowledgeSet,
diff --git a/src/store/ui.ts b/src/store/ui.ts
index 3148b24..f97b6fa 100644
--- a/src/store/ui.ts
+++ b/src/store/ui.ts
@@ -28,6 +28,7 @@ export const selectActiveModalId = createSelector(selectUiData, (ui) => ui.modal
export const MODAL_IDS = {
DAYWISHES: "DAYWISHES",
+ HOSTING: "HOSTING",
PARTICIPATIONDETAILS: "PARTICIPATIONDETAILS",
TEAMWISHES: "TEAMWISHES",
}
diff --git a/src/store/volunteerHostingSet.ts b/src/store/volunteerHostingSet.ts
new file mode 100644
index 0000000..1cc7b32
--- /dev/null
+++ b/src/store/volunteerHostingSet.ts
@@ -0,0 +1,60 @@
+import { PayloadAction, createSlice } from "@reduxjs/toolkit"
+
+import { StateRequest, toastError, elementFetch } from "./utils"
+import { VolunteerHosting } from "../services/volunteers"
+import { AppThunk, AppState } from "."
+import { volunteerHostingSet } from "../services/volunteersAccessors"
+
+type StateVolunteerHostingSet = { entity?: VolunteerHosting } & StateRequest
+
+export const initialState: StateVolunteerHostingSet = {
+ readyStatus: "idle",
+}
+
+const volunteerHostingSetSlice = createSlice({
+ name: "volunteerHostingSet",
+ initialState,
+ reducers: {
+ getRequesting: (_) => ({
+ readyStatus: "request",
+ }),
+ getSuccess: (_, { payload }: PayloadAction) => ({
+ readyStatus: "success",
+ entity: payload,
+ }),
+ getFailure: (_, { payload }: PayloadAction) => ({
+ readyStatus: "failure",
+ error: payload,
+ }),
+ },
+})
+
+export default volunteerHostingSetSlice.reducer
+export const { getRequesting, getSuccess, getFailure } = volunteerHostingSetSlice.actions
+
+export const fetchVolunteerHostingSet = elementFetch(
+ volunteerHostingSet,
+ getRequesting,
+ getSuccess,
+ getFailure,
+ (error: Error) =>
+ toastError(`Erreur lors du chargement des choix de jours de présence: ${error.message}`)
+)
+
+const shouldFetchVolunteerHostingSet = (state: AppState, id: number) =>
+ state.volunteerHostingSet?.readyStatus !== "success" ||
+ (state.volunteerHostingSet?.entity && state.volunteerHostingSet?.entity?.id !== id)
+
+export const fetchVolunteerHostingSetIfNeed =
+ (id = 0, wishes: Partial = {}): AppThunk =>
+ (dispatch, getState) => {
+ let jwt = ""
+
+ if (!id) {
+ ;({ jwt, id } = getState().auth)
+ }
+ if (shouldFetchVolunteerHostingSet(getState(), id))
+ return dispatch(fetchVolunteerHostingSet(jwt, id, wishes))
+
+ return null
+ }