Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FW-2923, FW-5063 join #184

Merged
merged 42 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
848694a
FW-5090 success message for story privacy update
gmcauliffe Oct 23, 2023
c64eb7a
Add Join request service
gmcauliffe Oct 23, 2023
1e1ca69
Add Join request service
gmcauliffe Oct 23, 2023
fe7becc
Add to index
gmcauliffe Oct 23, 2023
836e040
Merge branch 'FW-2923-join-button' of https://github.com/First-People…
gmcauliffe Oct 23, 2023
407a5a8
Initial set-up of dataHooks for join requests
gmcauliffe Oct 23, 2023
f527ab2
Merge branch 'main' into FW-2923-join-button
gmcauliffe Oct 24, 2023
2b14ad1
Rename useJoinRequests
gmcauliffe Oct 24, 2023
a697715
Merge branch 'main' into FW-2923-join-button
gmcauliffe Oct 24, 2023
a93c95d
Fix id typos
gmcauliffe Oct 25, 2023
e38ffab
AudioButton - skip any undefined values
gmcauliffe Oct 25, 2023
1588329
Merge branch 'main' into FW-2923-join-button
gmcauliffe Oct 31, 2023
de63518
Add join reason constants
gmcauliffe Oct 31, 2023
2654e07
Update hook API params and to return mutation
gmcauliffe Oct 31, 2023
9853cd0
Join button with modal form component
gmcauliffe Oct 31, 2023
e8f6feb
Styling
gmcauliffe Nov 1, 2023
c4ec061
Styling
gmcauliffe Nov 1, 2023
11406d6
Allow for setting error message, conditional rendering of join link
gmcauliffe Nov 1, 2023
7d87335
Allow for passing site and styling
gmcauliffe Nov 2, 2023
589b600
Remove unused util visibilityHelpers
gmcauliffe Nov 2, 2023
2f11937
Remove unused docType param
gmcauliffe Nov 2, 2023
e235e05
Add isMember helper
gmcauliffe Nov 2, 2023
6663435
Separate Join form from Modal and JoinButton
gmcauliffe Nov 2, 2023
b9e91a9
Refactor to pass site object
gmcauliffe Nov 2, 2023
34ebb4d
Add Join to site routes
gmcauliffe Nov 2, 2023
65056cd
Add Join link to Mobile menu
gmcauliffe Nov 2, 2023
03174e9
Fix import
gmcauliffe Nov 2, 2023
49a4a43
Remove Logout option for JoinModalButton
gmcauliffe Nov 2, 2023
fbed490
Add JoinModalButton to Site Navbar
gmcauliffe Nov 2, 2023
103641f
Ensure site menu items aren't lodaed before data received
gmcauliffe Nov 2, 2023
146d059
Merge branch 'main' into FW-2923-join-button
gmcauliffe Nov 2, 2023
4c594ae
Replace inaccurate term parentLanguage with language
gmcauliffe Nov 2, 2023
53934f1
Include membership check for allSites list
gmcauliffe Nov 2, 2023
ba52a23
Pass user to SIte card
gmcauliffe Nov 3, 2023
d1b3524
Add login and join buttons to Private site modal
gmcauliffe Nov 3, 2023
d0ddb16
Submit sitename with form
gmcauliffe Nov 3, 2023
efe742c
Use navigate instead of window
gmcauliffe Nov 3, 2023
5a575d3
Add close modal callback param
gmcauliffe Nov 3, 2023
f365b2c
Add Join form to Private Site modal
gmcauliffe Nov 3, 2023
6e1f959
Ensure event is passed to login function
gmcauliffe Nov 6, 2023
3389499
Only show join button on site homepage
gmcauliffe Nov 6, 2023
b385728
Provide closeModalCallback for JoinModalButton
gmcauliffe Nov 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const parentLanguageColors = {
export const languageColors = {
dtd: 'rgb(255,112,255)',
hei: 'rgb(255,128,255)',
kwk: 'rgb(255,176,255)',
Expand Down
1 change: 1 addition & 0 deletions src/common/constants/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './docTypes'
export * from './join'
export * from './media'
export * from './misc'
export * from './notificationTypes'
Expand Down
11 changes: 11 additions & 0 deletions src/common/constants/join.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Join Request Reason Keys for API
export const OTHER = 'OTHER'
export const LANGUAGE_LEARNER = 'LANGUAGE_LEARNER'
export const LANGUAGE_TEACHER = 'LANGUAGE_TEACHER'
export const FLUENT_SPEAKER = 'FLUENT_SPEAKER'
export const LANGUAGE_INTEREST = 'LANGUAGE_INTEREST'
export const HERITAGE = 'HERITAGE'
export const COMMUNITY_MEMBER = 'COMMUNITY_MEMBER'
export const COMMUNITY_STAFF = 'COMMUNITY_STAFF'
export const RECONCILIATION = 'RECONCILIATION'
export const FV_TEAM = 'FV_TEAM'
1 change: 1 addition & 0 deletions src/common/constants/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export const CATEGORIES = 'categories'
export const CHARACTERS = 'characters'
export const CONTACT_US = 'contact-us'
export const DICTIONARY = 'dictionary'
export const JOIN_REQUESTS = 'join-requests'
export const PAGES = 'pages'
export const PARTS_OF_SPEECH = 'parts-of-speech'
export const PEOPLE = 'people'
Expand Down
2 changes: 1 addition & 1 deletion src/common/dataAdaptors/siteAdaptors.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {

export function languagesListAdaptor({ languagesData }) {
return languagesData?.map((language) => ({
language: language?.language,
title: language?.language,
languageCode: language?.languageCode,
sites: sitesListAdaptor({ sitesData: language?.sites }),
}))
Expand Down
151 changes: 151 additions & 0 deletions src/common/dataHooks/useJoinRequests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import {
useInfiniteQuery,
useMutation,
useQueryClient,
} from '@tanstack/react-query'
import { useParams } from 'react-router-dom'

// FPCC
import api from 'services/api'
import { JOIN_REQUESTS, MEMBER } from 'common/constants'
import useMutationWithNotification from 'common/dataHooks/useMutationWithNotification'

export function useJoinRequests() {
const { sitename } = useParams()

const allJoinRequestsResponse = useInfiniteQuery(
[JOIN_REQUESTS, sitename],
({ pageParam = 1 }) =>
api.joinRequests.getJoinRequests({
sitename,
pageParam,
}),
{
// The query will not execute until the sitename exists
enabled: !!sitename,
},
)

return allJoinRequestsResponse
}

export function useJoinRequestCreate(options = {}) {
const queryClient = useQueryClient()

const createJoinRequest = async (formData) => {
const { sitename, reasons, message } = formData

const properties = {
reasons,
reason_note: message,
}
return api.joinRequests.create({
sitename,
properties,
})
}
const _options = {
...options,
mutationFn: createJoinRequest,
onSuccess: (response) => {
queryClient.invalidateQueries({
queryKey: [JOIN_REQUESTS, response?.site?.slug],
})
},
}

const mutation = useMutation(_options)

return mutation
}

// APPROVE
export function useJoinRequestApprove() {
const { sitename } = useParams()

const approveJoinRequest = async (formData) => {
const properties = {
role: formData?.role || MEMBER,
}
return api.joinRequests.approve({
id: formData?.id,
sitename,
properties,
})
}

const mutation = useMutationWithNotification({
mutationFn: approveJoinRequest,
queryKeyToInvalidate: [JOIN_REQUESTS, sitename],
actionWord: 'approved',
type: 'join request',
})

const onSubmit = (formData) => {
mutation.mutate(formData)
}
return { ...mutation, onSubmit }
}

// IGNORE
export function useJoinRequestIgnore() {
const { sitename } = useParams()
const ignoreJoinRequest = async (id) =>
api.joinRequests.ignore({
id,
sitename,
})

const mutation = useMutationWithNotification({
mutationFn: ignoreJoinRequest,
queryKeyToInvalidate: [JOIN_REQUESTS, sitename],
actionWord: 'ignored',
type: 'join request',
})
const onSubmit = (id) => {
mutation.mutate(id)
}
return { ...mutation, onSubmit }
}

// REJECT
export function useJoinRequestReject() {
const { sitename } = useParams()
const rejectJoinRequest = async (id) =>
api.joinRequests.reject({
id,
sitename,
})

const mutation = useMutationWithNotification({
mutationFn: rejectJoinRequest,
queryKeyToInvalidate: [JOIN_REQUESTS, sitename],
actionWord: 'rejected',
type: 'join request',
})
const onSubmit = (id) => {
mutation.mutate(id)
}
return { ...mutation, onSubmit }
}

// DELETE
export function useJoinRequestDelete() {
const { sitename } = useParams()
const deleteJoinRequest = async (id) =>
api.joinRequests.delete({
id,
sitename,
})

const mutation = useMutationWithNotification({
mutationFn: deleteJoinRequest,
queryKeyToInvalidate: [JOIN_REQUESTS, sitename],
actionWord: 'deleted',
type: 'join request',
})
const onSubmit = (id) => {
mutation.mutate(id)
}
return { ...mutation, onSubmit }
}
4 changes: 3 additions & 1 deletion src/common/dataHooks/useMutationWithNotification.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { useNavigate } from 'react-router-dom'

// FPCC
import { ERROR, SUCCESS } from 'common/constants'
Expand All @@ -15,6 +16,7 @@ export default function useMutationWithNotification({
}) {
const queryClient = useQueryClient()
const { setNotification } = useNotification()
const navigate = useNavigate()

const mutation = useMutation({
mutationFn,
Expand All @@ -28,7 +30,7 @@ export default function useMutationWithNotification({
}
if (redirectTo) {
setTimeout(() => {
window.location.href = redirectTo
navigate(redirectTo)
}, 1000)
}
},
Expand Down
7 changes: 7 additions & 0 deletions src/common/utils/membershipHelpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// FPCC
import { atLeastMember } from 'common/constants/roles'

export const isMember = ({ user, sitename }) => {
const userSiteRole = user?.roles?.[sitename] || ''
return userSiteRole.match(atLeastMember)
}
30 changes: 0 additions & 30 deletions src/common/utils/visibilityHelpers.js

This file was deleted.

35 changes: 18 additions & 17 deletions src/components/AudioButton/AudioButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,24 @@ import getIcon from 'common/utils/getIcon'
function AudioButton({ audioArray, iconStyling, hoverTooltip }) {
const { setCurrentAudio } = useAudiobar()

const audioButtons = audioArray?.map((audioObject) => (
<button
type="button"
key={audioObject?.id}
className="print:hidden relative group"
onClick={() => setCurrentAudio(audioObject)}
>
<div className="sr-only">Play audio</div>
{getIcon('Audio', iconStyling)}
{hoverTooltip ? (
<div className="z-10 hidden group-hover:inline-flex absolute -bottom-8 -right-1 w-auto p-1 text-sm bg-fv-charcoal-light text-white text-center rounded-lg whitespace-nowrap">
Play audio
</div>
) : null}
</button>
))
return audioArray?.length > 0 ? audioButtons : ''
return audioArray?.map((audioObject) =>
audioObject?.id ? (
<button
type="button"
key={audioObject?.id}
className="print:hidden relative group"
onClick={() => setCurrentAudio(audioObject)}
>
<div className="sr-only">Play audio</div>
{getIcon('Audio', iconStyling)}
{hoverTooltip ? (
<div className="z-10 hidden group-hover:inline-flex absolute -bottom-8 -right-1 w-auto p-1 text-sm bg-fv-charcoal-light text-white text-center rounded-lg whitespace-nowrap">
Play audio
</div>
) : null}
</button>
) : null,
)
}
// PROPTYPES
const { array, string, bool } = PropTypes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function ConfirmationDialogPresentation({
return (
<Modal.Presentation isOpen={isOpen} closeHandler={closeHandler}>
<div
id="RemoveWidgetModalContent"
data-testid="ConfirmationDialogPresentation"
className="inline-block align-bottom space-y-5 bg-white rounded-lg p-6 lg:p-8 overflow-hidden shadow-xl transform transition-all sm:align-middle sm:max-w-sm sm:w-full"
>
<div className="text-center space-y-2">
Expand Down
3 changes: 1 addition & 2 deletions src/components/DeleteButton/DeleteButtonPresentation.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ function DeleteButtonPresentation({ deleteHandler, label, message, styling }) {
<span>{label}</span>
</button>

{/* Remove Modal */}
<Modal.Presentation
isOpen={deleteModalOpen}
closeHandler={() => setDeleteModalOpen(false)}
>
<div
id="RemoveWidgetModalContent"
data-testid="DeleteModal"
className="inline-block align-bottom space-y-5 bg-white rounded-lg p-6 lg:p-8 overflow-hidden shadow-xl transform transition-all sm:align-middle sm:max-w-sm sm:w-full"
>
<div className="text-center space-y-2">
Expand Down
7 changes: 3 additions & 4 deletions src/components/DictionaryDetail/DictionaryDetailContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import DictionaryDetailPresentationDrawer from 'components/DictionaryDetail/Dict
import DictionaryDetailPresentationKids from 'components/DictionaryDetail/DictionaryDetailPresentationKids'
import Loading from 'components/Loading'

function DictionaryDetailContainer({ docId, docType, isDrawer, kids }) {
function DictionaryDetailContainer({ id, isDrawer, kids }) {
const { actions, entry, isLoading, moreActions, sitename, backHandler } =
DictionaryDetailData({ docId, docType })
DictionaryDetailData({ id })
return (
<Loading.Container isLoading={isLoading}>
{isDrawer && (
Expand Down Expand Up @@ -40,8 +40,7 @@ function DictionaryDetailContainer({ docId, docType, isDrawer, kids }) {
// PROPTYPES
const { bool, string } = PropTypes
DictionaryDetailContainer.propTypes = {
docId: string,
docType: string.isRequired,
id: string,
isDrawer: bool,
kids: bool,
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/DictionaryDetail/DictionaryDetailData.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { useNavigate, useParams } from 'react-router-dom'
// FPCC
import { useDictionaryEntry } from 'common/dataHooks/useDictionaryEntry'

function DictionaryDetailData({ docId }) {
const { id, sitename } = useParams()
function DictionaryDetailData({ id }) {
const { id: paramsId, sitename } = useParams()
const navigate = useNavigate()

const idToSend = docId || id
const idToSend = id || paramsId

const backHandler = () => navigate(-1)

Expand Down
8 changes: 1 addition & 7 deletions src/components/EntryDetail/EntryDetailContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,7 @@ function EntryDetailContainer({ id, type, isDrawer }) {
switch (type) {
case TYPE_PHRASE:
case TYPE_WORD:
return (
<DictionaryDetail.Container
docId={id}
docType={type}
isDrawer={isDrawer}
/>
)
return <DictionaryDetail.Container id={id} isDrawer={isDrawer} />
case TYPE_SONG:
return <Song.Container docId={id} isDrawer={isDrawer} />
case TYPE_STORY:
Expand Down
Loading
Loading