diff --git a/frontend/src/components/ContactPoint/ContactPointCard.tsx b/frontend/src/components/ContactPoint/ContactPointCard.tsx deleted file mode 100644 index fe44a4749..000000000 --- a/frontend/src/components/ContactPoint/ContactPointCard.tsx +++ /dev/null @@ -1,164 +0,0 @@ -import { Col, Icon, Row, Text } from '../_dsfr'; -import { ContactPoint, DraftContactPoint } from '@zerologementvacant/models'; -import { mailto, pluralize } from '../../utils/stringUtils'; -import { useLocalityList } from '../../hooks/useLocalityList'; -import _ from 'lodash'; -import Tag from '@codegouvfr/react-dsfr/Tag'; -import Card from '@codegouvfr/react-dsfr/Card'; -import AppLink from '../_app/AppLink/AppLink'; -import ContactPointEditionModal from '../modals/ContactPointEditionModal/ContactPointEditionModal'; -import ConfirmationModal from '../modals/ConfirmationModal/ConfirmationModal'; -import Typography from '@mui/material/Typography'; - -interface Props { - contactPoint: ContactPoint; - onEdit?: (contactPoint: DraftContactPoint | ContactPoint) => Promise; - onRemove?: (contactPointId: string) => Promise; - isPublicDisplay: boolean; -} - -function ContactPointCard({ - contactPoint, - onEdit, - onRemove, - isPublicDisplay -}: Props) { - const { localities, localitiesGeoCodes } = useLocalityList( - contactPoint.establishmentId - ); - return ( - - {!isPublicDisplay && ( - - - - - - - - {onEdit && ( - - )} - {onRemove && ( - onRemove(contactPoint.id)} - openingButtonProps={{ - iconId: 'fr-icon-delete-bin-fill', - priority: 'tertiary no outline', - title: 'Supprimer', - className: 'd-inline-block' - }} - > - - Êtes-vous sûr de vouloir supprimer ce guichet ? - - - )} - - - )} - - {contactPoint.title} - - - } - desc={ -
-
- {contactPoint.phone && ( -
- - Téléphone - - {contactPoint.phone} -
- )} - {contactPoint.opening && ( -
- - Horaires et jours d’ouverture - - - {contactPoint.opening} - -
- )} - {contactPoint.address && ( -
- - Adresse - - - {contactPoint.address} - -
- )} - {!isPublicDisplay && contactPoint.geoCodes && localities?.length && ( -
- - {pluralize(contactPoint.geoCodes.length)('Commune')} - - - {_.isEqual(contactPoint.geoCodes, localitiesGeoCodes) ? ( - Toutes les communes du territoire - ) : ( - <> - {contactPoint.geoCodes.map((geoCode) => ( - - {localities?.find((_) => _.geoCode === geoCode)?.name} - - ))} - - )} - -
- )} - {contactPoint.email && ( -
- - Adresse mail - - - {contactPoint.email} - -
- )} - {contactPoint.notes && ( -
- - Notes - - - {contactPoint.notes} - -
- )} -
- } - >
- ); -} - -export default ContactPointCard; diff --git a/frontend/src/components/ContactPoint/ContactPointPublicPage.tsx b/frontend/src/components/ContactPoint/ContactPointPublicPage.tsx deleted file mode 100644 index a308614de..000000000 --- a/frontend/src/components/ContactPoint/ContactPointPublicPage.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { Col, Container, Icon, Row, Text } from '../_dsfr'; - -import { Establishment, getEstablishmentUrl } from '../../models/Establishment'; -import styles from './contact-point-public-page.module.scss'; -import { useClipboard } from '../../hooks/useClipboard'; -import homepage_thumbnail from '../../assets/images/homepage_thumbnail.png'; -import Button from '@codegouvfr/react-dsfr/Button'; -import AppLink from '../_app/AppLink/AppLink'; -import Typography from '@mui/material/Typography'; - -interface Props { - establishment: Establishment; -} - -function ContactPointPublicPage({ establishment }: Props) { - const link = `${window.location.protocol}//${ - window.location.hostname - }${getEstablishmentUrl(establishment)}`; - - const clipboard = useClipboard(); - - async function copyLink() { - await clipboard.copy(link); - } - - return ( - - - - - - - - Page publique de {establishment.name} - - - Cette page publique sert à communiquer auprès des propriétaires les - informations relatives à la lutte contre la vacance sur votre - territoire. Elle permet aux propriétaires de se renseigner et de - prendre contact avec vous à travers un formulaire. Les réponses à ce - formulaire sont lisibles dans votre boîte de réception ZLV. - - - - {link} - - - - - - S’y rendre - - - - - - - ); -} - -export default ContactPointPublicPage; diff --git a/frontend/src/components/ContactPoint/contact-point-public-page.module.scss b/frontend/src/components/ContactPoint/contact-point-public-page.module.scss deleted file mode 100644 index 150562659..000000000 --- a/frontend/src/components/ContactPoint/contact-point-public-page.module.scss +++ /dev/null @@ -1,27 +0,0 @@ -.container { - padding: 2.5rem 1.5rem; - background-color: white; -} - -.frame { - background-color: #e0e5eA; - border-radius: 1rem; - height: fit-content; - - img { - border-radius: 1rem; - width: 100%; - } -} - -.disabled { - background-color: transparent; - border: 1px solid var(--blue-france-850); - border-radius: 3px; - color: var(--text-disabled-grey); - margin: 0 1rem 0 0; - padding: 0.5rem 1rem; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} diff --git a/frontend/src/components/modals/ContactPointEditionModal/ContactPointEditionModal.tsx b/frontend/src/components/modals/ContactPointEditionModal/ContactPointEditionModal.tsx deleted file mode 100644 index b57bf94be..000000000 --- a/frontend/src/components/modals/ContactPointEditionModal/ContactPointEditionModal.tsx +++ /dev/null @@ -1,257 +0,0 @@ -import { ChangeEvent, useMemo, useState } from 'react'; -import { Col, Container, Row, SearchableSelect } from '../../_dsfr'; - -import * as yup from 'yup'; -import { ContactPoint, DraftContactPoint } from '@zerologementvacant/models'; -import { emailValidator, useForm } from '../../../hooks/useForm'; -import { useLocalityList } from '../../../hooks/useLocalityList'; -import _ from 'lodash'; -import AppTextInput from '../../_app/AppTextInput/AppTextInput'; -import { createModal } from '@codegouvfr/react-dsfr/Modal'; -import Tag from '@codegouvfr/react-dsfr/Tag'; -import AppCheckbox from '../../_app/AppCheckbox/AppCheckbox'; -import Button from '@codegouvfr/react-dsfr/Button'; - -interface Props { - establishmentId: string; - contactPoint?: ContactPoint; - onSubmit: (contactPoint: DraftContactPoint | ContactPoint) => Promise; -} - -const ContactPointEditionModal = ({ - establishmentId, - contactPoint, - onSubmit, -}: Props) => { - const modal = useMemo( - () => - createModal({ - id: `contact-point-edition-modal-${contactPoint?.id}`, - isOpenedByDefault: false, - }), - [contactPoint], - ); - - const { localitiesOptions, localities, localitiesGeoCodes } = - useLocalityList(establishmentId); - const [title, setTitle] = useState(contactPoint?.title ?? ''); - const [opening, setOpening] = useState(contactPoint?.opening ?? undefined); - const [address, setAddress] = useState(contactPoint?.address ?? undefined); - const [geoCodes, setGeoCodes] = useState( - contactPoint?.geoCodes ?? localitiesGeoCodes, - ); - const [email, setEmail] = useState(contactPoint?.email ?? undefined); - const [phone, setPhone] = useState(contactPoint?.phone ?? undefined); - const [notes, setNotes] = useState(contactPoint?.notes ?? undefined); - - const filteredLocalityOptions = localitiesOptions.filter( - (option) => !geoCodes.includes(option.value), - ); - - const shape = { - title: yup.string().required('Veuillez saisir le titre du guichet'), - opening: yup.string(), - address: yup.string(), - geoCodes: yup - .array() - .of(yup.string()) - .ensure() - .min(1, 'Veuillez sélectionner au moins une commune'), - email: emailValidator.nullable().optional(), - phone: yup.string(), - notes: yup.string(), - }; - type FormShape = typeof shape; - - const form = useForm(yup.object().shape(shape), { - title, - opening, - address, - geoCodes, - email, - phone, - notes, - }); - - const submitContactPointForm = async () => { - await form.validate(async () => { - await onSubmit({ - ...(contactPoint?.id ? { id: contactPoint.id } : {}), - establishmentId, - title: title!, - opening, - address, - geoCodes, - email, - phone, - notes, - }); - modal.close(); - }); - }; - - const isGlobal = _.isEqual(geoCodes, localitiesGeoCodes); - - return ( - <> - {contactPoint ? ( - - )} - - - {contactPoint?.id - ? 'Modifier le guichet contact' - : 'Ajouter un guichet contact'} - - } - buttons={[ - { - children: 'Annuler', - priority: 'secondary', - }, - { - children: 'Enregistrer', - onClick: submitContactPointForm, - doClosesModal: false, - }, - ]} - style={{ textAlign: 'initial' }} - > - -
- - - - value={title} - onChange={(e) => setTitle(e.target.value)} - inputForm={form} - inputKey="title" - label="Titre du guichet (obligatoire)" - required - /> - - - - - - textArea - value={opening} - onChange={(e) => setOpening(e.target.value)} - inputForm={form} - inputKey="opening" - label="Horaires et jours d’ouverture" - rows={2} - /> - - - - - - textArea - value={address} - onChange={(e) => setAddress(e.target.value)} - inputForm={form} - inputKey="address" - label="Adresse postale" - rows={3} - /> - - - - - ) => - setGeoCodes(e.target.checked ? localitiesGeoCodes : []) - } - checked={isGlobal} - label="Ce guichet concerne l'ensemble des communes de votre territoire." - hintText="Décochez cette case si vous voulez sélectionner seulement une ou plusieurs communes" - /> - - - {!isGlobal && ( - - - { - if (value) { - setGeoCodes([...geoCodes, value]); - } - }} - /> - {geoCodes.map((geoCode) => ( - - setGeoCodes(geoCodes.filter((v) => v !== geoCode)) - } - iconId="fr-icon-close-line" - > - {localities?.find((_) => _.geoCode === geoCode)?.name} - - ))} - {form.messageType('geoCodes') === 'error' && ( -

{form.message('geoCodes')}

- )} - -
- )} - - - - value={phone} - onChange={(e) => setPhone(e.target.value)} - inputForm={form} - inputKey="phone" - label="Téléphone" - /> - - - - - - value={email} - type="email" - onChange={(e) => setEmail(e.target.value)} - inputForm={form} - inputKey="email" - label="Adresse email" - /> - - - - - - textArea - value={notes} - onChange={(e) => setNotes(e.target.value)} - label="Notes" - inputForm={form} - inputKey="notes" - rows={3} - /> - - -
-
-
- - ); -}; - -export default ContactPointEditionModal; diff --git a/frontend/src/views/Establishment/EstablishmentContactPoints.tsx b/frontend/src/views/Establishment/EstablishmentContactPoints.tsx deleted file mode 100644 index 24b33fd7d..000000000 --- a/frontend/src/views/Establishment/EstablishmentContactPoints.tsx +++ /dev/null @@ -1,181 +0,0 @@ -import { useMemo, useState } from 'react'; -import { Col, Row } from '../../components/_dsfr'; -import { ContactPoint, DraftContactPoint } from '@zerologementvacant/models'; -import { useMatomo } from '@jonkoops/matomo-tracker-react'; -import ContactPointEditionModal from '../../components/modals/ContactPointEditionModal/ContactPointEditionModal'; -import { - TrackEventActions, - TrackEventCategories -} from '../../models/TrackEvent'; -import ContactPointCard from '../../components/ContactPoint/ContactPointCard'; -import AppHelp from '../../components/_app/AppHelp/AppHelp'; -import AppSearchBar from '../../components/_app/AppSearchBar/AppSearchBar'; -import { useSettings } from '../../hooks/useSettings'; -import { - useCreateContactPointMutation, - useFindContactPointsQuery, - useRemoveContactPointMutation, - useUpdateContactPointMutation -} from '../../services/contact-point.service'; -import { Alert } from '@codegouvfr/react-dsfr/Alert'; -import ToggleSwitch from '@codegouvfr/react-dsfr/ToggleSwitch'; -import Typography from '@mui/material/Typography'; - -interface Props { - establishmentId: string; -} - -const EstablishmentContactPoints = ({ establishmentId }: Props) => { - const { trackEvent } = useMatomo(); - - const { data: contactPoints } = useFindContactPointsQuery({ - establishmentId, - publicOnly: false - }); - - const [ - updateContactPoint, - { - isSuccess: isUpdateSuccess, - originalArgs: updateArgs, - isError: isUpdateError - } - ] = useUpdateContactPointMutation(); - const [ - createContactPoint, - { isSuccess: isCreateSuccess, isError: isCreateError } - ] = useCreateContactPointMutation(); - const [ - deleteContactPoint, - { isSuccess: isDeleteSuccess, isError: isDeleteError } - ] = useRemoveContactPointMutation(); - - const { settings, togglePublishContactPoints } = useSettings(establishmentId); - - const [query, setQuery] = useState(); - - function search(query: string): void { - setQuery(query); - } - - async function searchAsync(query: string): Promise { - search(query); - } - - const points = useMemo( - () => - query - ? contactPoints?.filter((cp) => cp.title.search(query) !== -1) - : contactPoints, - [query, contactPoints] - ); - - const onSubmitEditingContactPoint = async ( - contactPoint: DraftContactPoint | ContactPoint - ) => { - const isDraft = !('id' in contactPoint); - trackEvent({ - category: TrackEventCategories.ContactPoints, - action: isDraft - ? TrackEventActions.ContactPoints.Create - : TrackEventActions.ContactPoints.Update - }); - if (isDraft) { - await createContactPoint(contactPoint); - } else { - await updateContactPoint(contactPoint as ContactPoint); - } - }; - - const onSubmitRemovingContactPoint = async (contactPointId: string) => { - trackEvent({ - category: TrackEventCategories.ContactPoints, - action: TrackEventActions.ContactPoints.Delete - }); - await deleteContactPoint(contactPointId); - }; - - return ( - <> - - - - Vos guichets contacts ({contactPoints?.length}) - - {settings && ( - - )} -
-
- -
- -
- -
- {isCreateSuccess && ( - - )} - {isUpdateSuccess && ( - - )} - {isDeleteSuccess && ( - - )} - {(isCreateError || isUpdateError || isDeleteError) && ( - - )} - - Renseignez vos guichets contact ici. Ce sont les points de contact qui - seront affichés sur votre page publique. - - - {points?.map((contactPoint) => ( - - - - ))} - - - ); -}; - -export default EstablishmentContactPoints; diff --git a/frontend/src/views/Establishment/EstablishmentLocalityTaxes.tsx b/frontend/src/views/Establishment/EstablishmentLocalityTaxes.tsx deleted file mode 100644 index 07e720951..000000000 --- a/frontend/src/views/Establishment/EstablishmentLocalityTaxes.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import { useEffect, useState } from 'react'; - -import { Col, Row, Text } from '../../components/_dsfr'; -import { useMatomo } from '@jonkoops/matomo-tracker-react'; -import LocalityTaxCard from '../../components/LocalityTaxesCard/LocalityTaxesCard'; -import { useLocalityList } from '../../hooks/useLocalityList'; - -import { Locality, TaxKinds, TaxKindsLabels } from '../../models/Locality'; - -import { - TrackEventActions, - TrackEventCategories -} from '../../models/TrackEvent'; -import AppHelp from '../../components/_app/AppHelp/AppHelp'; -import { useUpdateLocalityTaxMutation } from '../../services/locality.service'; -import { Alert } from '@codegouvfr/react-dsfr/Alert'; -import Tag from '@codegouvfr/react-dsfr/Tag'; -import Typography from '@mui/material/Typography'; - -interface Props { - establishmentId: string; -} - -const EstablishmentLocalityTaxes = ({ establishmentId }: Props) => { - const { trackEvent } = useMatomo(); - - const [ - updateLocalityTax, - { isSuccess: isUpdateSuccess, isError: isUpdateError } - ] = useUpdateLocalityTaxMutation(); - - const { localities, filterCount } = useLocalityList(establishmentId); - - const [hasTLVFilter, setHasTLVFilter] = useState(true); - const [hasTHLVFilter, setHasTHLVFilter] = useState(true); - const [hasNoTaxFilter, setHasNoTaxFilter] = useState(true); - const [filteredLocalities, setFilteredLocalities] = useState< - Locality[] | undefined - >(localities); - - useEffect( - () => { - setFilteredLocalities( - localities?.filter( - (locality) => - (hasTLVFilter && locality.taxKind === TaxKinds.TLV) || - (hasTHLVFilter && locality.taxKind === TaxKinds.THLV) || - (hasNoTaxFilter && locality.taxKind === TaxKinds.None) - ) - ); - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [localities, hasTLVFilter, hasTHLVFilter, hasNoTaxFilter] - ); - - const onSubmitEditingLocalityTax = ( - geoCode: string, - taxKind: TaxKinds, - taxRate?: number - ) => { - trackEvent({ - category: TrackEventCategories.LocalityTaxes, - action: TrackEventActions.LocalityTaxes.Update - }); - updateLocalityTax({ - geoCode, - taxKind, - taxRate - }); - }; - - return ( - <> - - Taxes sur les logements vacants - - - Informations publiées par défaut - - {isUpdateSuccess && ( - - )} - {isUpdateError && ( - - )} -
- setHasTLVFilter(!hasTLVFilter) - }} - > - {TaxKindsLabels[TaxKinds.TLV]} ( - {filterCount((l) => l.taxKind === TaxKinds.TLV)}) - - setHasTHLVFilter(!hasTHLVFilter) - }} - > - {TaxKindsLabels[TaxKinds.THLV]} ( - {filterCount((l) => l.taxKind === TaxKinds.THLV)}) - - setHasNoTaxFilter(!hasNoTaxFilter) - }} - > - {TaxKindsLabels[TaxKinds.None]} ( - {filterCount((l) => l.taxKind === TaxKinds.None)}) - -
- {filteredLocalities && !filteredLocalities.length ? ( - Aucune commune - ) : ( - - {filteredLocalities?.map((locality) => ( - - - - ))} - - )} - - ); -}; - -export default EstablishmentLocalityTaxes; diff --git a/frontend/src/views/Establishment/EstablishmentView.tsx b/frontend/src/views/Establishment/EstablishmentView.tsx deleted file mode 100644 index 0c972fbf4..000000000 --- a/frontend/src/views/Establishment/EstablishmentView.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { Container, Text } from '../../components/_dsfr'; -import EstablishmentContactPoints from './EstablishmentContactPoints'; -import { useDocumentTitle } from '../../hooks/useDocumentTitle'; -import EstablishmentLocalityTaxes from './EstablishmentLocalityTaxes'; -import { useAppSelector } from '../../hooks/useStore'; -import ContactPointPublicPage from '../../components/ContactPoint/ContactPointPublicPage'; -import MainContainer from '../../components/MainContainer/MainContainer'; -import Tabs from '@codegouvfr/react-dsfr/Tabs'; -import Typography from '@mui/material/Typography'; - -const EstablishmentView = () => { - useDocumentTitle('Informations publiques'); - const establishment = useAppSelector( - (state) => state.authentication.authUser?.establishment - ); - - if (!establishment) { - return <>; - } - - return ( - - - - Remplissez les détails de votre territoire ici pour informer le - public. Cela aidera à diriger les propriétaires vers vos contacts - locaux et à partager des informations sur la vacance. Les informations - fournies ici seront publiées sur votre page publique, alors - assurez-vous qu’elles soient précises et claires. - - - ) - }, - { - label: 'Taxes sur les logements vacants', - content: ( - - ) - } - ]} - > - - - - Votre page publique - - - - - ); -}; - -export default EstablishmentView;