Skip to content

Commit

Permalink
Place campaign listing history (#79)
Browse files Browse the repository at this point in the history
* History on campaigns

* Require selected campaign

* Fix import
  • Loading branch information
Lucieo authored Feb 22, 2024
1 parent 0ae6c04 commit af54f3a
Show file tree
Hide file tree
Showing 26 changed files with 340 additions and 210 deletions.
5 changes: 1 addition & 4 deletions back/api/application/controllers/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ module.exports = {
return strapi
.query("application")
.find(
{
...query,
_sort: "disponibility.start:desc",
},
query,
populate
)
.then((res) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"name": "Apache 2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0.html"
},
"x-generation-date": "02/22/2024 1:55:11 PM"
"x-generation-date": "02/22/2024 6:38:10 PM"
},
"x-strapi-config": {
"path": "/documentation",
Expand Down
16 changes: 9 additions & 7 deletions web/components/Account/AccountMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ const getApplicationsItems = ({
],
})

const getPlaceItems = (isCampaignMode) => ({
title: isCampaignMode ? 'solidarity' : 'dashboard',
const getPlaceItems = (hasCampaigns) => ({
title: hasCampaigns ? 'solidarity' : 'dashboard',
items: [
{
icon: <Home />,
Expand Down Expand Up @@ -132,7 +132,7 @@ const AccountMenu = ({ user }: { user: UsersPermissionsUser }) => {
const isComplete = useUserIsComplete(user)
const { data: notifs } = useMyNotifications()

const { currentCampaign, isCampaignPlace } = useCampaignContext()
const { currentCampaign, allPlaceCampaigns } = useCampaignContext()
const applicationItems = useMemo(
() =>
getApplicationsItems({
Expand All @@ -145,13 +145,16 @@ const AccountMenu = ({ user }: { user: UsersPermissionsUser }) => {
[currentCampaign, user?.type],
)

const placeItems = useMemo(() => getPlaceItems(isCampaignPlace), [
isCampaignPlace,
const placeItems = useMemo(() => getPlaceItems(allPlaceCampaigns?.length), [
allPlaceCampaigns?.length,
])
const companyItems = useMemo(
() => getCompanyItems(Boolean(currentCampaign)),
[currentCampaign],
)
const displayApplications =
(user?.type === 'place' && allPlaceCampaigns?.length) ||
(user?.type === 'company' && currentCampaign)

const displayMenu = ({ title, items, translationParams = {} }) => {
const isDisactivated = !isComplete && title === 'dashboard'
Expand Down Expand Up @@ -241,8 +244,7 @@ const AccountMenu = ({ user }: { user: UsersPermissionsUser }) => {
{user?.confirmed &&
user?.accepted &&
displayMenu(user?.type === 'company' ? companyItems : placeItems)}
{((user?.type === 'place' && isCampaignPlace) || currentCampaign) &&
displayMenu(applicationItems)}
{displayApplications && displayMenu(applicationItems)}
{displayMenu(accountItems)}
</VStack>
</Box>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import useCampaignContext from '~components/Campaign/useCampaignContext'
import { useMyApplications } from '~hooks/useMyApplications'
import ApplicationPlaceList from '~components/Account/Application/Place/ApplicationPlaceList'
import InfoPlaceApplications from '~components/Account/Info/InfoPlaceApplications'
import Loading from '~components/Loading'
import { useCurrentUser } from '~hooks/useCurrentUser'
import { useEffect } from 'react'
import { useRouter } from 'next/router'

const ApplicationPlaceData = ({ searchParams }) => {
const ApplicationPlaceFetcher = ({ searchParams }) => {
const { data: user } = useCurrentUser()
const { currentCampaign } = useCampaignContext()

const { query } = useRouter()
const {
data: applications,
isLoading,
refetch,
isFetching,
} = useMyApplications({
campaignId: currentCampaign?.id,
searchParams,
name: ['myApplications', searchParams.disponibility_eq as string],
campaignId: query.campaign as string,
searchParams: { ...searchParams, _sort: 'company.structureName:asc' },
options: {
enabled:
Boolean(searchParams?.disponibility_eq) &&
Expand All @@ -40,4 +40,4 @@ const ApplicationPlaceData = ({ searchParams }) => {
)
}

export default ApplicationPlaceData
export default ApplicationPlaceFetcher
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Chevron from 'public/assets/img/chevron-down.svg'
import Cell from '~components/Account/Booking/Cell'
import useCampaignContext from '~components/Campaign/useCampaignContext'
import ApplicationPlaceListItem from '~components/Account/Application/Place/ApplicationPlaceListItem'
import ApplicationPlaceHelper from '~components/Account/Application/Place/SelectionHelpers/ApplicationPlaceHelper'
import ApplicationPlaceHelper from '~components/Account/Application/Place/ApplicationsHelpers/ApplicationPlaceHelper'

interface Props {
applications: Application[]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,24 @@
import React, { Fragment } from 'react'
import { Application } from '~typings/api'
import { Text, Button, IconButton, ButtonGroup, HStack } from '@chakra-ui/react'
import { Text, Button, IconButton, HStack } from '@chakra-ui/react'
import { useTranslation } from 'next-i18next'
import Cell from '~components/Account/Booking/Cell'
import { client } from '~api/client-api'
import useToast from '~hooks/useToast'
import { useQueryClient } from 'react-query'
import Link from '~components/Link'
import useCampaignContext from '~components/Campaign/useCampaignContext'
import DownloadApplication from 'public/assets/img/downloadApplication.svg'
import { useRouter } from 'next/router'

interface Props {
application: Application
}

const ApplicationPlaceListItem = ({ application }: Props) => {
const { currentCampaign } = useCampaignContext()
const { errorToast, successToast } = useToast()
const { allPlaceCampaigns } = useCampaignContext()
const { query } = useRouter()
const selectedCampaign = allPlaceCampaigns?.find(
(c) => c.id.toString() === query.campaign.toString(),
)
const { t } = useTranslation('application')
const queryClient = useQueryClient()

const onDelete = async () => {
try {
await client.applications.applicationsDelete(application.id)
successToast(t('company.delete_success'))
queryClient.refetchQueries(['myApplications'])
} catch (e) {
errorToast(t('company.delete_error'))
}
}

return (
<Fragment key={application?.id}>
Expand All @@ -55,8 +45,9 @@ const ApplicationPlaceListItem = ({ application }: Props) => {
{application?.creation_title}
</Text>
</Cell>
{currentCampaign?.mode === 'preselections' && (
<Cell>

<Cell>
{['preselections', 'closed']?.includes(selectedCampaign?.mode) ? (
<HStack spacing={2}>
<IconButton
px={2}
Expand All @@ -70,6 +61,7 @@ const ApplicationPlaceListItem = ({ application }: Props) => {
aria-label="dowload"
borderColor="rgba(98,103,130, 0.6)"
icon={<DownloadApplication />}
isDisabled={selectedCampaign?.mode === 'closed'}
/>
<Button
px={2}
Expand All @@ -81,12 +73,15 @@ const ApplicationPlaceListItem = ({ application }: Props) => {
borderRadius="sm"
fontSize="md"
borderColor="rgba(98,103,130, 0.6)"
isDisabled={selectedCampaign?.mode === 'closed'}
>
{t('place.table.buttons.details')}
</Button>
</HStack>
</Cell>
)}
) : (
''
)}
</Cell>
</Fragment>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,50 @@
import { useTranslation } from 'next-i18next'
import useCampaignContext from '~components/Campaign/useCampaignContext'
import MissingSelections from '~components/Account/Application/Place/SelectionHelpers/MissingSelections'
import ConfirmSelections from '~components/Account/Application/Place/SelectionHelpers/ConfirmSelections'
import ValidatedSelections from '~components/Account/Application/Place/SelectionHelpers/ValidatedSelections'
import MissingSelections from '~components/Account/Application/Place/ApplicationsHelpers/MissingSelections'
import ConfirmSelections from '~components/Account/Application/Place/ApplicationsHelpers/ConfirmSelections'
import ValidatedSelections from '~components/Account/Application/Place/ApplicationsHelpers/ValidatedSelections'
import { Application } from '~typings/api'
import { useRouter } from 'next/router'
import ClosedCampaign from '~components/Account/Application/Place/ApplicationsHelpers/ClosedCampaign'

const ApplicationPlaceHelper = ({
applications,
}: {
applications: Application[]
}) => {
const { t } = useTranslation('application')
const { currentCampaign } = useCampaignContext()
const { allPlaceCampaigns } = useCampaignContext()
const preselections = applications?.filter(
(application) => application?.status === 'preselected',
).length

const { query } = useRouter()
const selectedCampaign = allPlaceCampaigns?.find(
(c) => c.id.toString() === query.campaign.toString(),
)
const missingPreselections =
currentCampaign?.preselections_max - preselections
selectedCampaign?.preselections_max - preselections

const validatedApplications = applications?.filter(
(application) => application?.status === 'confirmed',
).length

if (currentCampaign?.mode === 'preselections' && validatedApplications > 0) {
if (selectedCampaign?.mode === 'preselections' && validatedApplications > 0) {
return <ValidatedSelections />
}
if (currentCampaign?.mode === 'preselections' && missingPreselections > 0) {
if (selectedCampaign?.mode === 'preselections' && missingPreselections > 0) {
return <MissingSelections missingPreselections={missingPreselections} />
}

if (currentCampaign?.mode === 'preselections' && missingPreselections === 0) {
if (
selectedCampaign?.mode === 'preselections' &&
missingPreselections === 0
) {
return <ConfirmSelections preselections={preselections} />
}

if (selectedCampaign?.mode === 'closed') {
return <ClosedCampaign />
}

return null
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Box, HStack, Text } from '@chakra-ui/react'
import PreselectionsValidated from 'public/assets/img/preselectionsValidated.svg'
import { useTranslation } from 'next-i18next'

const ClosedCampaign = () => {
const { t } = useTranslation('application')

return (
<Box paddingY={2}>
<HStack backgroundColor="gray.50" borderRadius="4px" p={4}>
<PreselectionsValidated />
<Text as="span" color="gray.700" pl={1}>
{t('place.helper.closed_campaign')}
</Text>
</HStack>
</Box>
)
}

export default ClosedCampaign
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Box, Button, HStack, Stack, Text } from '@chakra-ui/react'
import { format } from '~utils/date'
import PreselectionsWarning from 'public/assets/img/preselectionsWarning.svg'
import { useTranslation } from 'next-i18next'

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { HStack, Text } from '@chakra-ui/react'
import { useTranslation } from 'next-i18next'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import CampaignSelectorField from '~components/Account/Application/Place/CampaignSelector/CampaignSelectorField'
import useCampaignContext from '~components/Campaign/useCampaignContext'
import { ROUTE_ACCOUNT_APPLICATIONS } from '~constants'

const CampaignSelector = ({ children }) => {
const router = useRouter()
const { campaign } = router.query
const { allPlaceCampaigns } = useCampaignContext()
const { t } = useTranslation('application')

// If no campaign defined in url select last one
useEffect(() => {
if (!campaign && allPlaceCampaigns) {
router.push(
`${ROUTE_ACCOUNT_APPLICATIONS}?campaign=${allPlaceCampaigns?.[0]?.id}`,
)
}
}, [allPlaceCampaigns])

const selectedCampaign = allPlaceCampaigns?.find(
(c) => c.id?.toString() === campaign?.toString(),
)

if (!selectedCampaign) return null

return (
<>
<HStack pt={{ base: 4, md: 8 }} pb={4}>
<Text
textStyle="accountTitle"
pl={4}
fontSize="24px"
fontWeight="400"
fontFamily="mabry"
>
{t('place.title')}
</Text>
<CampaignSelectorField />
</HStack>
{selectedCampaign && children}
</>
)
}

export default CampaignSelector
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Select, Text } from '@chakra-ui/react'
import { useTranslation } from 'next-i18next'
import { useRouter } from 'next/router'
import useCampaignContext from '~components/Campaign/useCampaignContext'

const CampaignSelectorField = () => {
const { t } = useTranslation('application')
const router = useRouter()
const { allPlaceCampaigns, isLoadingAllPlaceCampaigns } = useCampaignContext()
if (isLoadingAllPlaceCampaigns || !allPlaceCampaigns) {
return null
}

if (allPlaceCampaigns.length === 1) {
return (
<Text
backgroundColor="blue.100"
color="blue.500"
p={2}
borderRadius="18px"
paddingX={4}
>
{t('place.title_single_tag', { title: allPlaceCampaigns[0]?.title })}
</Text>
)
}
return (
<Select
width="auto"
borderRadius="18px"
backgroundColor="blue.100"
color="blue.500"
borderColor="transparent"
value={router.query.campaign}
onChange={(e) => {
router.push({
pathname: router.pathname,
query: { campaign: e.target.value },
})
}}
>
{allPlaceCampaigns.map((campaign) => (
<option key={campaign.id} value={campaign.id}>
{campaign.title}
</option>
))}
</Select>
)
}

export default CampaignSelectorField
Loading

0 comments on commit af54f3a

Please sign in to comment.