diff --git a/web/components/Account/Application/Place/ApplicationPlaceList.tsx b/web/components/Account/Application/Place/ApplicationPlaceList.tsx index 1b3708c..6a98430 100644 --- a/web/components/Account/Application/Place/ApplicationPlaceList.tsx +++ b/web/components/Account/Application/Place/ApplicationPlaceList.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useMemo, useState } from 'react' import { Flex, Text, @@ -9,13 +9,14 @@ import { useDisclosure, } from '@chakra-ui/react' import { useTranslation } from 'next-i18next' -import { Application, Applications } from '~typings/api' +import { Application } from '~typings/api' import Chevron from 'public/assets/img/chevron-down.svg' import Cell from '~components/Account/Booking/Cell' import ApplicationPlaceHelper from '~components/Account/Application/Place/ApplicationsHelpers/ApplicationPlaceHelper' import ApplicationPlaceListItem from '~components/Account/Application/Place/ApplicationPlaceListItem' import useSelectedCampaign from '~hooks/useSelectedCampaign' import ApplicationDetailDrawer from '~components/Account/Application/Place/DetailDrawer/ApplicationDetailDrawer' +import { useRouter } from 'next/router' interface Props { applications: Application[] @@ -31,8 +32,10 @@ const ApplicationPlaceList = ({ applications = [] }: Props) => { const [isDesc, setDesc] = useState(true) const [selectedApplication, onApplicationSelect] = useState() const { isOpen, onOpen, onClose } = useDisclosure() + const { query } = useRouter() const { selectedCampaign } = useSelectedCampaign() + useEffect(() => { setList(applications) setDesc(true) @@ -43,6 +46,23 @@ const ApplicationPlaceList = ({ applications = [] }: Props) => { setList(list.reverse()) } + const preselectedApplications = applications?.filter( + (application) => application?.status === 'preselected', + ) + + const filteredList = useMemo( + () => + list.filter((application) => { + return ( + !query.search?.length || + `${application?.company?.structureName} (${application.company.firstname} ${application.company.lastname})` + .toLowerCase() + ?.includes((query.search as string)?.toLowerCase()) + ) + }), + [list, query.search], + ) + return ( @@ -85,7 +105,7 @@ const ApplicationPlaceList = ({ applications = [] }: Props) => { )} - {list.map((application) => ( + {filteredList.map((application) => ( { isOpen={isOpen} onClose={onClose} application={selectedApplication} + canPreselect={ + preselectedApplications?.length < + selectedCampaign?.preselections_max && + selectedCampaign?.mode === 'preselections' + } /> ) diff --git a/web/components/Account/Application/Place/ApplicationsSearch.tsx b/web/components/Account/Application/Place/ApplicationsSearch.tsx new file mode 100644 index 0000000..3975334 --- /dev/null +++ b/web/components/Account/Application/Place/ApplicationsSearch.tsx @@ -0,0 +1,38 @@ +import { Box, Input, InputGroup, InputRightElement } from '@chakra-ui/react' +import { useTranslation } from 'next-i18next' +import { useRouter } from 'next/router' +import SearchIcon from '~public/assets/icons/SearchIcon' + +const ApplicationsSearch = () => { + const { t } = useTranslation('application') + const router = useRouter() + + const handleSearch = (value) => { + router.push( + { + pathname: router.pathname, + query: { ...router.query, search: value }, + }, + undefined, + { shallow: true }, + ) + } + + return ( + + + handleSearch(e.target.value)} + width="auto" + p={2} + /> + + + + + + ) +} + +export default ApplicationsSearch diff --git a/web/components/Account/Application/Place/DetailDrawer/ApplicationDetailDrawer.tsx b/web/components/Account/Application/Place/DetailDrawer/ApplicationDetailDrawer.tsx index 9d2e531..b3e7022 100644 --- a/web/components/Account/Application/Place/DetailDrawer/ApplicationDetailDrawer.tsx +++ b/web/components/Account/Application/Place/DetailDrawer/ApplicationDetailDrawer.tsx @@ -21,10 +21,12 @@ const ApplicationDetailDrawer = ({ isOpen, onClose, application, + canPreselect, }: { isOpen: boolean onClose: () => void application: Application + canPreselect: boolean }) => { const { t } = useTranslation('application') const { id } = application ?? {} @@ -52,7 +54,10 @@ const ApplicationDetailDrawer = ({ - + diff --git a/web/components/Account/Application/Place/DetailDrawer/ApplicationPreselectButton.tsx b/web/components/Account/Application/Place/DetailDrawer/ApplicationPreselectButton.tsx index d8fda42..2a55f63 100644 --- a/web/components/Account/Application/Place/DetailDrawer/ApplicationPreselectButton.tsx +++ b/web/components/Account/Application/Place/DetailDrawer/ApplicationPreselectButton.tsx @@ -9,14 +9,14 @@ import { useRouter } from 'next/router' import RemoveIcon from '~public/assets/icons/RemoveIcon' import Link from '~components/Link' import { ROUTE_CONTACT } from '~constants' -import useSelectedCampaign from '~hooks/useSelectedCampaign' const ApplicationPreselectButton = ({ application, + canPreselect, }: { application: Application + canPreselect: boolean }) => { - const { selectedCampaign } = useSelectedCampaign() const { t } = useTranslation('application') const { errorToast, successToast } = useToast() const queryClient = useQueryClient() @@ -48,7 +48,7 @@ const ApplicationPreselectButton = ({ } return ( - + - + diff --git a/web/components/Account/Application/Place/DisponibilitiesSelector/DisponibilitiesSelector.tsx b/web/components/Account/Application/Place/DisponibilitiesSelector/DisponibilitiesSelector.tsx index a7aafb6..dc4dd3e 100644 --- a/web/components/Account/Application/Place/DisponibilitiesSelector/DisponibilitiesSelector.tsx +++ b/web/components/Account/Application/Place/DisponibilitiesSelector/DisponibilitiesSelector.tsx @@ -3,6 +3,7 @@ import { useTranslation } from 'next-i18next' import { useRouter } from 'next/router' import { useEffect, useState } from 'react' import ApplicationPlaceFetcher from '~components/Account/Application/Place/ApplicationPlaceFetcher' +import ApplicationsSearch from '~components/Account/Application/Place/ApplicationsSearch' import ApplicationSelector from '~components/Account/Application/Place/DisponibilitiesSelector/DisponibilitiesSelectorFields' import { useMyApplications } from '~hooks/useMyApplications' import { useMyPlaces } from '~hooks/useMyPlaces' @@ -56,7 +57,7 @@ const DisponibilitiesSelector = () => { return ( <> {Boolean(places?.length) && !isLoading && !isFetching && ( - + ({ ...p, @@ -66,6 +67,7 @@ const DisponibilitiesSelector = () => { }))} hasConfirmedSelection={hasConfirmedSelection} /> + )} diff --git a/web/public/assets/icons/SearchIcon.tsx b/web/public/assets/icons/SearchIcon.tsx new file mode 100644 index 0000000..3469d7f --- /dev/null +++ b/web/public/assets/icons/SearchIcon.tsx @@ -0,0 +1,31 @@ +const SearchIcon = ({ stroke = '#626782' }) => ( + + + + + + + + + + + +) + +export default SearchIcon diff --git a/web/public/locales/fr/application.json b/web/public/locales/fr/application.json index 2befa89..646929b 100644 --- a/web/public/locales/fr/application.json +++ b/web/public/locales/fr/application.json @@ -42,6 +42,7 @@ "details": "Détails" } }, + "search": "Recherche", "helper": { "preselection_start": "Établissez votre présélection avant le {{date}}.", "missing_preselections": "{{num}} manquantes.",