diff --git a/apps/admin-ui/src/component/ShowTOS.tsx b/apps/admin-ui/src/component/ShowTOS.tsx index ab31919a7..805eee168 100644 --- a/apps/admin-ui/src/component/ShowTOS.tsx +++ b/apps/admin-ui/src/component/ShowTOS.tsx @@ -3,6 +3,7 @@ import styled from "styled-components"; import { useTranslation } from "react-i18next"; import { useGenericTerms } from "common/src/hooks/useGenericTerms"; import { Maybe, type TermsOfUseNode } from "@gql/gql-types"; +import { Sanitize } from "common/src/components/Sanitize"; // NOTE This is partial duplicate from ui/application/Preview.tsx // see if we can combine them (and other Terms later with parameters) @@ -22,12 +23,22 @@ const Terms = styled.div` } `; -const TOSElement = ({ title, text }: { title: string; text: string }) => ( - -

{title}

-

{text}

-
-); +function TOSElement({ + title, + text, + isHtml, +}: { + title: string; + text: string; + isHtml?: boolean; +}) { + return ( + +

{title}

+ {isHtml ? :

{text}

} +
+ ); +} // TODO use a fragment type TOSNode = Pick; @@ -77,6 +88,7 @@ const ShowTOS = ({ reservationUnit }: { reservationUnit: Node }) => { ); diff --git a/apps/ui/components/application/ApprovedReservations.tsx b/apps/ui/components/application/ApprovedReservations.tsx index f239af87d..756d98997 100644 --- a/apps/ui/components/application/ApprovedReservations.tsx +++ b/apps/ui/components/application/ApprovedReservations.tsx @@ -41,7 +41,7 @@ import { import React, { useState } from "react"; import { useTranslation } from "next-i18next"; import styled from "styled-components"; -import Sanitize from "../common/Sanitize"; +import { Sanitize } from "common/src/components/Sanitize"; import { LinkLikeButton } from "common/styles/buttonCss"; import { type TFunction } from "i18next"; import { convertWeekday } from "common/src/conversion"; diff --git a/apps/ui/components/application/NotesWhenApplying.tsx b/apps/ui/components/application/NotesWhenApplying.tsx index c3841bdc5..333a3050c 100644 --- a/apps/ui/components/application/NotesWhenApplying.tsx +++ b/apps/ui/components/application/NotesWhenApplying.tsx @@ -3,7 +3,7 @@ import { useTranslation } from "next-i18next"; import styled from "styled-components"; import { getTranslationSafe } from "common/src/common/util"; import { getLocalizationLang } from "common/src/helpers"; -import Sanitize from "@/components/common/Sanitize"; +import { Sanitize } from "common/src/components/Sanitize"; import { H4 } from "common"; const NotesBox = styled.div` diff --git a/apps/ui/components/application/ViewApplication.tsx b/apps/ui/components/application/ViewApplication.tsx index f8ad2c381..6d6ff3f7a 100644 --- a/apps/ui/components/application/ViewApplication.tsx +++ b/apps/ui/components/application/ViewApplication.tsx @@ -17,7 +17,7 @@ import { TermsAccordion as Accordion, } from "./styled"; import { ApplicationEventList } from "./ApplicationEventList"; -import Sanitize from "../common/Sanitize"; +import { Sanitize } from "common/src/components/Sanitize"; type Node = NonNullable; export function ViewApplication({ diff --git a/apps/ui/components/common/InfoDialog.tsx b/apps/ui/components/common/InfoDialog.tsx index 4857420e2..55a7b35b9 100644 --- a/apps/ui/components/common/InfoDialog.tsx +++ b/apps/ui/components/common/InfoDialog.tsx @@ -2,7 +2,7 @@ import { Dialog, IconInfoCircleFill } from "hds-react"; import React from "react"; import { useTranslation } from "next-i18next"; import { BlackButton } from "../../styles/util"; -import Sanitize from "./Sanitize"; +import { Sanitize } from "common/src/components/Sanitize"; type Props = { id: string; diff --git a/apps/ui/components/reservation/AcceptTerms.tsx b/apps/ui/components/reservation/AcceptTerms.tsx index 6b248fb39..0da35a934 100644 --- a/apps/ui/components/reservation/AcceptTerms.tsx +++ b/apps/ui/components/reservation/AcceptTerms.tsx @@ -2,7 +2,7 @@ import React from "react"; import TermsBox from "common/src/termsbox/TermsBox"; import { useTranslation } from "next-i18next"; import { getTranslation } from "@/modules/util"; -import Sanitize from "../common/Sanitize"; +import { Sanitize } from "common/src/components/Sanitize"; import { type ReservationUnitPageQuery } from "@/gql/gql-types"; type ReservationUnitNodeT = NonNullable< diff --git a/apps/ui/components/reservation/EditStep0.tsx b/apps/ui/components/reservation/EditStep0.tsx index f4da136ef..378978735 100644 --- a/apps/ui/components/reservation/EditStep0.tsx +++ b/apps/ui/components/reservation/EditStep0.tsx @@ -34,7 +34,7 @@ import { ReservationTimePicker } from "./ReservationTimePicker"; import { QuickReservation } from "../reservation-unit/QuickReservation"; import { getNextAvailableTime } from "../reservation-unit/utils"; import { ReservationInfoCard } from "./ReservationInfoCard"; -import Sanitize from "@/components/common/Sanitize"; +import { Sanitize } from "common/src/components/Sanitize"; import { type RoundPeriod } from "@/modules/reservable"; import { PinkBox as PinkBoxBase } from "./styles"; import { H4 } from "common"; diff --git a/apps/ui/components/reservation/ReservationCancellation.tsx b/apps/ui/components/reservation/ReservationCancellation.tsx index e15c30c53..cb2572a7f 100644 --- a/apps/ui/components/reservation/ReservationCancellation.tsx +++ b/apps/ui/components/reservation/ReservationCancellation.tsx @@ -10,7 +10,7 @@ import { type ReservationCancelReasonsQuery, } from "@gql/gql-types"; import { IconButton } from "common/src/components"; -import Sanitize from "../common/Sanitize"; +import { Sanitize } from "common/src/components/Sanitize"; import { getTranslation } from "@/modules/util"; import { ReservationInfoCard } from "./ReservationInfoCard"; import { signOut } from "common/src/browserHelpers"; diff --git a/apps/ui/package.json b/apps/ui/package.json index 81cb92313..500afeb1f 100644 --- a/apps/ui/package.json +++ b/apps/ui/package.json @@ -42,7 +42,6 @@ "react-hook-form": "^7.52.1", "react-transition-group": "^4.4.5", "react-use": "^17.5.1", - "sanitize-html": "^2.13.0", "sass": "^1.81.0", "styled-components": "5.3.11", "tsconfig": "workspace:*", @@ -60,7 +59,6 @@ "@types/react": "18.2.7", "@types/react-dom": "18.3.0", "@types/react-transition-group": "^4.4.11", - "@types/sanitize-html": "^2.13.0", "@types/styled-components": "^5.1.29", "@vercel/style-guide": "^6.0.0", "axe-core": "^4.10.0", diff --git a/apps/ui/pages/recurring/[id]/criteria/index.tsx b/apps/ui/pages/recurring/[id]/criteria/index.tsx index 044d40cd7..e9d6c5222 100644 --- a/apps/ui/pages/recurring/[id]/criteria/index.tsx +++ b/apps/ui/pages/recurring/[id]/criteria/index.tsx @@ -10,7 +10,7 @@ import { } from "@gql/gql-types"; import { breakpoints, H1 } from "common"; import { createApolloClient } from "@/modules/apolloClient"; -import Sanitize from "@/components/common/Sanitize"; +import { Sanitize } from "common/src/components/Sanitize"; import { getTranslation } from "@/modules/util"; import BreadcrumbWrapper from "@/components/common/BreadcrumbWrapper"; import { getApplicationRoundName } from "@/modules/applicationRound"; diff --git a/apps/ui/pages/reservation-unit/[...params].tsx b/apps/ui/pages/reservation-unit/[...params].tsx index 628342d84..0f62fe5c3 100644 --- a/apps/ui/pages/reservation-unit/[...params].tsx +++ b/apps/ui/pages/reservation-unit/[...params].tsx @@ -26,7 +26,7 @@ import { import { type Inputs } from "common/src/reservation-form/types"; import { createApolloClient } from "@/modules/apolloClient"; import { getReservationPath, getReservationUnitPath } from "@/modules/urls"; -import Sanitize from "@/components/common/Sanitize"; +import { Sanitize } from "common/src/components/Sanitize"; import { isReservationUnitFreeOfCharge } from "@/modules/reservationUnit"; import { getCheckoutUrl, diff --git a/apps/ui/pages/reservation-unit/[id].tsx b/apps/ui/pages/reservation-unit/[id].tsx index 4ba7faa0f..c3a7eda56 100644 --- a/apps/ui/pages/reservation-unit/[id].tsx +++ b/apps/ui/pages/reservation-unit/[id].tsx @@ -37,7 +37,7 @@ import { } from "common/src/helpers"; import { Head } from "@/components/reservation-unit/Head"; import { AddressSection } from "@/components/reservation-unit/Address"; -import Sanitize from "@/components/common/Sanitize"; +import { Sanitize } from "common/src/components/Sanitize"; import { RelatedUnits, type RelatedNodeT, diff --git a/apps/ui/pages/reservations/[id]/index.tsx b/apps/ui/pages/reservations/[id]/index.tsx index 78fbbae63..e14d26766 100644 --- a/apps/ui/pages/reservations/[id]/index.tsx +++ b/apps/ui/pages/reservations/[id]/index.tsx @@ -26,7 +26,7 @@ import { import Link from "next/link"; import { createApolloClient } from "@/modules/apolloClient"; import { formatDateTimeRange, getTranslation } from "@/modules/util"; -import Sanitize from "@/components/common/Sanitize"; +import { Sanitize } from "common/src/components/Sanitize"; import { AccordionWithState as Accordion } from "@/components/Accordion"; import { getCheckoutUrl, diff --git a/apps/ui/pages/terms/[id].tsx b/apps/ui/pages/terms/[id].tsx index b651ffcfe..aa6b214fe 100644 --- a/apps/ui/pages/terms/[id].tsx +++ b/apps/ui/pages/terms/[id].tsx @@ -11,7 +11,7 @@ import { import { H1 } from "common/src/common/typography"; import { getCommonServerSideProps } from "@/modules/serverUtils"; import { createApolloClient } from "@/modules/apolloClient"; -import Sanitize from "@/components/common/Sanitize"; +import { Sanitize } from "common/src/components/Sanitize"; import { convertLanguageCode, getTranslationSafe, diff --git a/packages/common/package.json b/packages/common/package.json index 5bab7787f..4b54651d7 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -33,6 +33,7 @@ "react-i18next": "^15.1.1", "react-toastify": "^10.0.5", "react-use": "^17.5.1", + "sanitize-html": "^2.13.0", "styled-components": "5.3.11", "tsconfig": "workspace:*", "zod": "^3.23.8" @@ -53,6 +54,7 @@ "@types/react": "^18.2.7", "@types/react-big-calendar": "^1.16.0", "@types/react-dom": "18.3.0", + "@types/sanitize-html": "^2.13.0", "@types/styled-components": "^5.1.29", "@vercel/style-guide": "^6.0.0", "chalk": "^5.3.0", diff --git a/apps/ui/components/common/Sanitize.tsx b/packages/common/src/components/Sanitize.tsx similarity index 92% rename from apps/ui/components/common/Sanitize.tsx rename to packages/common/src/components/Sanitize.tsx index 0d52de4b3..936b22b93 100644 --- a/apps/ui/components/common/Sanitize.tsx +++ b/packages/common/src/components/Sanitize.tsx @@ -11,6 +11,7 @@ const StyledContent = styled.div` p:empty { display: none; } + /* old data has extra line-breaks instead of just using

*/ p br { display: none; @@ -51,7 +52,7 @@ const config = { }, }; -function Sanitize({ html }: Props): JSX.Element | null { +export function Sanitize({ html }: Props): JSX.Element | null { if (!html) { return null; } @@ -64,5 +65,3 @@ function Sanitize({ html }: Props): JSX.Element | null { /> ); } - -export default Sanitize; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e98c05b4f..51775d6c0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -303,9 +303,6 @@ importers: react-use: specifier: ^17.5.1 version: 17.5.1(react-dom@18.3.1(react@18.2.0))(react@18.2.0) - sanitize-html: - specifier: ^2.13.0 - version: 2.13.0 sass: specifier: ^1.81.0 version: 1.81.0 @@ -352,9 +349,6 @@ importers: '@types/react-transition-group': specifier: ^4.4.11 version: 4.4.11 - '@types/sanitize-html': - specifier: ^2.13.0 - version: 2.13.0 '@types/styled-components': specifier: ^5.1.29 version: 5.1.34 @@ -445,6 +439,9 @@ importers: react-use: specifier: ^17.5.1 version: 17.5.1(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + sanitize-html: + specifier: ^2.13.0 + version: 2.13.0 styled-components: specifier: 5.3.11 version: 5.3.11(@babel/core@7.25.2)(react-dom@18.3.1(react@18.2.0))(react-is@18.3.1)(react@18.2.0) @@ -482,6 +479,9 @@ importers: '@types/react-dom': specifier: 18.3.0 version: 18.3.0 + '@types/sanitize-html': + specifier: ^2.13.0 + version: 2.13.0 '@types/styled-components': specifier: ^5.1.29 version: 5.1.34 @@ -7511,12 +7511,12 @@ snapshots: '@babel/code-frame@7.24.7': dependencies: '@babel/highlight': 7.24.7 - picocolors: 1.1.0 + picocolors: 1.1.1 '@babel/code-frame@7.25.7': dependencies: '@babel/highlight': 7.25.7 - picocolors: 1.1.0 + picocolors: 1.1.1 '@babel/code-frame@7.26.2': dependencies: @@ -7701,7 +7701,7 @@ snapshots: '@babel/helper-validator-identifier': 7.24.7 chalk: 2.4.2 js-tokens: 4.0.0 - picocolors: 1.1.0 + picocolors: 1.1.1 '@babel/highlight@7.25.7': dependencies: @@ -10759,7 +10759,7 @@ snapshots: '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) eslint-config-prettier: 9.1.0(eslint@8.57.1) - eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)) + eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.30.0) eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.30.0)(eslint@8.57.1) eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.1) eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) @@ -10794,7 +10794,7 @@ snapshots: '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) eslint-config-prettier: 9.1.0(eslint@8.57.1) - eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)) + eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.30.0) eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.30.0)(eslint@8.57.1) eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.1) eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) @@ -12089,7 +12089,7 @@ snapshots: eslint-define-config@2.1.0: {} - eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)): + eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.30.0): dependencies: eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) @@ -12107,7 +12107,7 @@ snapshots: debug: 4.3.7(supports-color@5.5.0) enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.8.0 is-bun-module: 1.2.1 @@ -12120,7 +12120,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -12148,7 +12148,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -14328,7 +14328,7 @@ snapshots: postcss@8.4.45: dependencies: nanoid: 3.3.7 - picocolors: 1.1.0 + picocolors: 1.1.1 source-map-js: 1.2.1 postgres-array@2.0.0: {} @@ -15287,7 +15287,7 @@ snapshots: css-tree: 2.3.1 css-what: 6.1.0 csso: 5.0.5 - picocolors: 1.1.0 + picocolors: 1.1.1 swap-case@2.0.2: dependencies: