From 20b1b922d276edeca5f19b9ab57a8cc170e43a18 Mon Sep 17 00:00:00 2001 From: Remy van der Wereld Date: Wed, 15 Jan 2025 14:31:22 +0100 Subject: [PATCH] Add ExpandableContainer component and integrate it into HolidayRentalRegistrations --- .../ExpandableContainer.tsx | 74 ++++ .../components/Timeline/TimelineStyle.tsx | 21 +- .../HolidayRentalRegistrations.tsx | 5 +- .../components/Registration.tsx | 29 +- .../components/hooks/useValues.tsx | 20 +- .../HolidayRentalRegistrations.stories.tsx | 3 +- .../holidayRentalRegistrationsData.ts | 380 ++++++++++-------- 7 files changed, 326 insertions(+), 206 deletions(-) create mode 100644 src/components/Data/ExpandableContainer/ExpandableContainer.tsx diff --git a/src/components/Data/ExpandableContainer/ExpandableContainer.tsx b/src/components/Data/ExpandableContainer/ExpandableContainer.tsx new file mode 100644 index 00000000..8dd0ee76 --- /dev/null +++ b/src/components/Data/ExpandableContainer/ExpandableContainer.tsx @@ -0,0 +1,74 @@ +import React, { ReactNode, useState } from "react" +import styled from "styled-components" +import { Button, Icon } from "@amsterdam/asc-ui" +import { ExpandMore } from "../../Icons" + +export type StyleProps = { + isOpen?: boolean +} & React.AnchorHTMLAttributes & + React.HTMLAttributes; + +export const StyledExpandableButton = styled(Button)` + position: relative; + width: 100%; + height: initial; + background-color: transparent; + padding: 12px 0; + font-size: 18px; + &:hover, + &:focus { + background-color: transparent; + } + span { + span { + transform: rotate(${ ({ isOpen }) => (isOpen ? "180deg" : "0deg") }); + transition: transform 0.3s ease; + } + } +` + +export const StyledExpandableContent = styled.div` + transition: opacity 0.3s ease-in-out, max-height 0.3s ease-in-out; + opacity: ${ ({ isOpen }) => (isOpen ? 1 : 0) }; + max-height: ${ ({ isOpen }) => (isOpen ? "1000px" : "0") }; + overflow: hidden; + position: relative; +` + +const StyledDiv = styled.div` + margin-bottom: 12px; +` + +type Props = { + title: string + children: ReactNode + defaultOpen?: boolean +} + +const ExpandableContainer: React.FC = ({ title, children, defaultOpen = false }) => { + const [open, setOpen] = useState(defaultOpen) + + const onClick = () => { + setOpen(!open) + } + + return ( + + } + onClick={onClick} + > + { title } + + + { children } + + + ) +} + +export default ExpandableContainer \ No newline at end of file diff --git a/src/components/EventsTimeline/components/Timeline/TimelineStyle.tsx b/src/components/EventsTimeline/components/Timeline/TimelineStyle.tsx index 00934b02..429a43e1 100644 --- a/src/components/EventsTimeline/components/Timeline/TimelineStyle.tsx +++ b/src/components/EventsTimeline/components/Timeline/TimelineStyle.tsx @@ -1,6 +1,5 @@ import styled, { css } from "styled-components" import { themeColor, themeSpacing, breakpoint, Icon, Button } from "@amsterdam/asc-ui" -import { IconStyle } from "@amsterdam/asc-ui/lib/components/Icon" export type Props = { isOpen?: boolean @@ -106,11 +105,12 @@ const NestedContainer = styled.div` ` const TimelineContent = styled.div` - transition: border-color 0.1s ease-in-out; - border: none; - padding: ${ themeSpacing(4) } 0; + transition: opacity 0.3s ease-in-out, max-height 0.5s ease-in-out; + opacity: ${ ({ isOpen }) => (isOpen ? 1 : 0) }; + max-height: ${ ({ isOpen }) => (isOpen ? "1000px" : "0") }; /* Adjust 500px based on your content */ + overflow: hidden; + padding: ${ ({ isOpen }) => (isOpen ? "16px 0" : "0") }; position: relative; - display: ${ ({ isOpen }) => !isOpen && "none" }; ` const TimelineButtonContent = styled.span` @@ -137,12 +137,11 @@ const TimelineButton = styled(Button)` border: 0; } } - // TODO This doesn't seem to do anything - ${ IconStyle } { - align-self: flex-start; - transform: rotate(${ ({ isOpen }) => (isOpen ? "180deg" : "0deg") }); - transition: transform 0.3s ease; - width: 14px; + span { + span { + transform: rotate(${ ({ isOpen }) => (isOpen ? "180deg" : "0deg") }); + transition: transform 0.3s ease; + } } ` diff --git a/src/components/HolidayRentalRegistrations/HolidayRentalRegistrations.tsx b/src/components/HolidayRentalRegistrations/HolidayRentalRegistrations.tsx index 6490eed6..cc2710ca 100644 --- a/src/components/HolidayRentalRegistrations/HolidayRentalRegistrations.tsx +++ b/src/components/HolidayRentalRegistrations/HolidayRentalRegistrations.tsx @@ -9,6 +9,7 @@ type Props = { horizontalBordered?: boolean loading?: boolean loadingRows?: number + defaultOpen?: boolean } /** @@ -19,7 +20,8 @@ const HolidayRentalRegistrations: React.FC = ({ data, horizontalBordered = true, loading = false, - loadingRows + loadingRows, + defaultOpen }) => { if (loading) { return loadingRows ? : @@ -35,6 +37,7 @@ const HolidayRentalRegistrations: React.FC = ({ key={registration.registrationNumber} registration={registration} horizontalBordered={horizontalBordered} + defaultOpen={defaultOpen} /> ))} diff --git a/src/components/HolidayRentalRegistrations/components/Registration.tsx b/src/components/HolidayRentalRegistrations/components/Registration.tsx index b6b8013f..457045fd 100644 --- a/src/components/HolidayRentalRegistrations/components/Registration.tsx +++ b/src/components/HolidayRentalRegistrations/components/Registration.tsx @@ -1,29 +1,28 @@ import React from "react" -import styled from "styled-components" -import DefinitionList from "../../Data/DefinitionList/DefinitionList" +import DefinitionList from "../../Data/DefinitionList/DefinitionList" +import ExpandableContainer from "../../Data/ExpandableContainer/ExpandableContainer" import useValues from "./hooks/useValues" import type { HolidayRentalRegistration } from "../types" type Props = { registration: HolidayRentalRegistration horizontalBordered?: boolean + defaultOpen?: boolean } -const StyledDiv = styled.div` - margin-top: 12px; -` +const Registration: React.FC = ({ registration, horizontalBordered, defaultOpen }) => { + const values = useValues(registration) -const Registration: React.FC = ({ registration, horizontalBordered }) => { - const values = useValues(registration) return ( - - - + + + ) } diff --git a/src/components/HolidayRentalRegistrations/components/hooks/useValues.tsx b/src/components/HolidayRentalRegistrations/components/hooks/useValues.tsx index 6f37fc64..fe6f9fd1 100644 --- a/src/components/HolidayRentalRegistrations/components/hooks/useValues.tsx +++ b/src/components/HolidayRentalRegistrations/components/hooks/useValues.tsx @@ -2,9 +2,10 @@ import React from "react" import type { HolidayRentalRegistration } from "../../types" import DateDisplay from "../../../DateDisplay/DateDisplay" -const formatRequester = (requester: HolidayRentalRegistration["requester"]) => { - const { personalDetails } = requester - const name = `${ personalDetails?.firstName ?? "" } ${ personalDetails?.lastNamePrefix ? `${ personalDetails?.lastNamePrefix } ` : "" }${ personalDetails?.lastName ?? "" }` +const formatPersonName = (personalDetails: Record) => { + if (!personalDetails) return "" + const { firstName, lastNamePrefix, lastName } = personalDetails + const name = `${ firstName ?? "" } ${ lastNamePrefix ? `${ lastNamePrefix } ` : "" }${ lastName ?? "" }` return name } @@ -13,18 +14,21 @@ export default (registration: HolidayRentalRegistration) => { requester, agreementDate, createdAt, - requestForBedAndBreakfast + requestForBedAndBreakfast, + rentalHouse: { owner } } = registration - const requesterName = formatRequester(requester) - - const values = { - "Aanvrager": requesterName, + const values: Record = { + "Aanvrager": formatPersonName(requester?.personalDetails), "E-mail": requester?.email, "Aangemaakt": , "Overeenkomst": , "B&B verzoek": requestForBedAndBreakfast ? "Ja" : "Nee" } + if (owner?.personalDetails) { + values["Aangevraagd voor"] = formatPersonName(owner?.personalDetails) + } + return values } diff --git a/src/stories/HolidayRentalRegistrations.stories.tsx b/src/stories/HolidayRentalRegistrations.stories.tsx index e47dec2f..1b320423 100644 --- a/src/stories/HolidayRentalRegistrations.stories.tsx +++ b/src/stories/HolidayRentalRegistrations.stories.tsx @@ -15,6 +15,7 @@ export const Default: Story = { args: { data: holidayRentalRegistrationsData, horizontalBordered: true, - loading: false + loading: false, + defaultOpen: true } } diff --git a/src/stories/mockedData/holidayRentalRegistrationsData.ts b/src/stories/mockedData/holidayRentalRegistrationsData.ts index 801428b9..8c9a59d8 100644 --- a/src/stories/mockedData/holidayRentalRegistrationsData.ts +++ b/src/stories/mockedData/holidayRentalRegistrationsData.ts @@ -1,176 +1,216 @@ import { HolidayRentalRegistration } from "../../components/HolidayRentalRegistrations/types" const holidayRentalRegistrationsData: HolidayRentalRegistration[] = [ - { - "registrationNumber": "0363 98C3 E248 CBC3 E906", - "requester": { - "personType": "LegalEntity", - "email": "luke@skywalker.org", - "bsn": null, - "personalDetails": { - "firstName": "Luke", - "lastNamePrefix": null, - "lastName": "Skywalker" - } - }, - "rentalHouse": { - "street": "Amstel", - "houseNumber": "1", - "houseLetter": null, - "houseNumberExtension": null, - "postalCode": "1011PN", - "city": "Amsterdam", - "shortName": "Amstel", - "adresseerbaarObjectIdentificatie": "0363010012143319", - "nummeraanduidingIdentificatie": "0363200012145295", - "openbareRuimteIdentificatie": "0363300000002701", - "woonplaatsIdentificatie": "3594", - "pandIdentificaties": [ - "0363100012186092" - ], - "owner": null - }, - "requestForOther": false, - "requestForBedAndBreakfast": true, - "createdAt": "2021-07-13T13:49:11.3915875Z", - "agreementDate": "2021-07-13T13:49:11.3915875Z" - }, - { - "registrationNumber": "0363 A376 B039 B516 8EED", - "requester": { - "personType": "NaturalPerson", - "email": "leia@organa.org", - "bsn": null, - "personalDetails": { - "firstName": "Leia", - "lastNamePrefix": null, - "lastName": "Organa" - } - }, - "rentalHouse": { - "street": "Amstel", - "houseNumber": "1", - "houseLetter": null, - "houseNumberExtension": null, - "postalCode": "1011PN", - "city": "Amsterdam", - "shortName": "Amstel", - "adresseerbaarObjectIdentificatie": "0363010012143319", - "nummeraanduidingIdentificatie": "0363200012145295", - "openbareRuimteIdentificatie": "0363300000002701", - "woonplaatsIdentificatie": "3594", - "pandIdentificaties": [ - "0363100012186092" - ], - "owner": null - }, - "requestForOther": false, - "requestForBedAndBreakfast": false, - "createdAt": "2022-08-24T09:20:46.4590698Z", - "agreementDate": "2022-08-24T09:20:46.4590698Z" - }, - { - "registrationNumber": "0363 3BF1 1D4A 06A8 1DBC", - "requester": { - "personType": "NaturalPerson", - "email": "obi-wan@kenobi.org", - "bsn": null, - "personalDetails": { - "firstName": "Obi-Wan", - "lastNamePrefix": null, - "lastName": "Kenobi" - } - }, - "rentalHouse": { - "street": "Amstel", - "houseNumber": "1", - "houseLetter": null, - "houseNumberExtension": null, - "postalCode": "1011PN", - "city": "Amsterdam", - "shortName": "Amstel", - "adresseerbaarObjectIdentificatie": "0363010012143319", - "nummeraanduidingIdentificatie": "0363200012145295", - "openbareRuimteIdentificatie": "0363300000002701", - "woonplaatsIdentificatie": "3594", - "pandIdentificaties": [ - "0363100012186092" - ], - "owner": null - }, - "requestForOther": false, - "requestForBedAndBreakfast": true, - "createdAt": "2022-09-15T09:23:01.324015Z", - "agreementDate": "2022-09-15T09:23:01.324015Z" - }, - { - "registrationNumber": "0363 D848 E18E ABDB 9AFF", - "requester": { - "personType": "NaturalPerson", - "email": "chewbacca@starwars.org", - "bsn": null, - "personalDetails": { - "firstName": "Chewbacca", - "lastNamePrefix": "from", - "lastName": "Kashyyyk" - } - }, - "rentalHouse": { - "street": "Amstel", - "houseNumber": "1", - "houseLetter": null, - "houseNumberExtension": null, - "postalCode": "1011PN", - "city": "Amsterdam", - "shortName": "Amstel", - "adresseerbaarObjectIdentificatie": "0363010012143319", - "nummeraanduidingIdentificatie": "0363200012145295", - "openbareRuimteIdentificatie": "0363300000002701", - "woonplaatsIdentificatie": "3594", - "pandIdentificaties": [ - "0363100012186092" - ], - "owner": null - }, - "requestForOther": false, - "requestForBedAndBreakfast": true, - "createdAt": "2022-11-23T13:40:06.3829529Z", - "agreementDate": "2022-11-23T13:40:06.3829529Z" - }, - { - "registrationNumber": "0363 4E71 131F A46A 3D9B", - "requester": { - "personType": "EuropeanCitizen", - "email": "r2-d2@starwars.org", - "bsn": null, - "personalDetails": { - "firstName": "R2-D2", - "lastNamePrefix": null, - "lastName": null - } - }, - "rentalHouse": { - "street": "Amstel", - "houseNumber": "1", - "houseLetter": null, - "houseNumberExtension": null, - "postalCode": "1011PN", - "city": "Amsterdam", - "shortName": "Amstel", - "adresseerbaarObjectIdentificatie": "0363010012143319", - "nummeraanduidingIdentificatie": "0363200012145295", - "openbareRuimteIdentificatie": "0363300000002701", - "woonplaatsIdentificatie": "3594", - "pandIdentificaties": [ - "0363100012186092" - ], - "owner": null - }, - "requestForOther": false, - "requestForBedAndBreakfast": true, - "createdAt": "2024-11-28T10:43:23.0953603Z", - "agreementDate": "2024-11-28T10:43:23.0953603Z" - } + { + "registrationNumber": "0363 98C3 E248 CBC3 E200", + "requester": { + "personType": "NaturalPerson", + "email": "darth.sidious@starwars.org", + "bsn": null, + "personalDetails": { + "firstName": "Darth", + "lastNamePrefix": null, + "lastName": "Sidious" + } + }, + "rentalHouse": { + "street": "Amstel", + "houseNumber": "1", + "houseLetter": null, + "houseNumberExtension": null, + "postalCode": "1011PN", + "city": "Amsterdam", + "shortName": "Amstel", + "adresseerbaarObjectIdentificatie": "0363010012143319", + "nummeraanduidingIdentificatie": "0363200012145295", + "openbareRuimteIdentificatie": "0363300000002701", + "woonplaatsIdentificatie": "3594", + "pandIdentificaties": [ + "0363100012186092" + ], + "owner": { + "personalDetails": { + "firstName": "Boba", + "lastNamePrefix": "is", + "lastName": "Fett" + } + } + }, + "requestForOther": true, + "requestForBedAndBreakfast": true, + "createdAt": "2024-11-20T11:25:13.2947715Z", + "agreementDate": "2024-11-20T11:25:13.2947715Z" + }, + { + "registrationNumber": "0363 98C3 E248 CBC3 E906", + "requester": { + "personType": "LegalEntity", + "email": "luke@skywalker.org", + "bsn": null, + "personalDetails": { + "firstName": "Luke", + "lastNamePrefix": null, + "lastName": "Skywalker" + } + }, + "rentalHouse": { + "street": "Amstel", + "houseNumber": "1", + "houseLetter": null, + "houseNumberExtension": null, + "postalCode": "1011PN", + "city": "Amsterdam", + "shortName": "Amstel", + "adresseerbaarObjectIdentificatie": "0363010012143319", + "nummeraanduidingIdentificatie": "0363200012145295", + "openbareRuimteIdentificatie": "0363300000002701", + "woonplaatsIdentificatie": "3594", + "pandIdentificaties": [ + "0363100012186092" + ], + "owner": null + }, + "requestForOther": false, + "requestForBedAndBreakfast": true, + "createdAt": "2021-07-13T13:49:11.3915875Z", + "agreementDate": "2021-07-13T13:49:11.3915875Z" + }, + { + "registrationNumber": "0363 A376 B039 B516 8EED", + "requester": { + "personType": "NaturalPerson", + "email": "leia@organa.org", + "bsn": null, + "personalDetails": { + "firstName": "Leia", + "lastNamePrefix": null, + "lastName": "Organa" + } + }, + "rentalHouse": { + "street": "Amstel", + "houseNumber": "1", + "houseLetter": null, + "houseNumberExtension": null, + "postalCode": "1011PN", + "city": "Amsterdam", + "shortName": "Amstel", + "adresseerbaarObjectIdentificatie": "0363010012143319", + "nummeraanduidingIdentificatie": "0363200012145295", + "openbareRuimteIdentificatie": "0363300000002701", + "woonplaatsIdentificatie": "3594", + "pandIdentificaties": [ + "0363100012186092" + ], + "owner": null + }, + "requestForOther": false, + "requestForBedAndBreakfast": false, + "createdAt": "2022-08-24T09:20:46.4590698Z", + "agreementDate": "2022-08-24T09:20:46.4590698Z" + }, + { + "registrationNumber": "0363 3BF1 1D4A 06A8 1DBC", + "requester": { + "personType": "NaturalPerson", + "email": "obi-wan@kenobi.org", + "bsn": null, + "personalDetails": { + "firstName": "Obi-Wan", + "lastNamePrefix": null, + "lastName": "Kenobi" + } + }, + "rentalHouse": { + "street": "Amstel", + "houseNumber": "1", + "houseLetter": null, + "houseNumberExtension": null, + "postalCode": "1011PN", + "city": "Amsterdam", + "shortName": "Amstel", + "adresseerbaarObjectIdentificatie": "0363010012143319", + "nummeraanduidingIdentificatie": "0363200012145295", + "openbareRuimteIdentificatie": "0363300000002701", + "woonplaatsIdentificatie": "3594", + "pandIdentificaties": [ + "0363100012186092" + ], + "owner": null + }, + "requestForOther": false, + "requestForBedAndBreakfast": true, + "createdAt": "2022-09-15T09:23:01.324015Z", + "agreementDate": "2022-09-15T09:23:01.324015Z" + }, + { + "registrationNumber": "0363 D848 E18E ABDB 9AFF", + "requester": { + "personType": "NaturalPerson", + "email": "chewbacca@starwars.org", + "bsn": null, + "personalDetails": { + "firstName": "Chewbacca", + "lastNamePrefix": "from", + "lastName": "Kashyyyk" + } + }, + "rentalHouse": { + "street": "Amstel", + "houseNumber": "1", + "houseLetter": null, + "houseNumberExtension": null, + "postalCode": "1011PN", + "city": "Amsterdam", + "shortName": "Amstel", + "adresseerbaarObjectIdentificatie": "0363010012143319", + "nummeraanduidingIdentificatie": "0363200012145295", + "openbareRuimteIdentificatie": "0363300000002701", + "woonplaatsIdentificatie": "3594", + "pandIdentificaties": [ + "0363100012186092" + ], + "owner": null + }, + "requestForOther": false, + "requestForBedAndBreakfast": true, + "createdAt": "2022-11-23T13:40:06.3829529Z", + "agreementDate": "2022-11-23T13:40:06.3829529Z" + }, + { + "registrationNumber": "0363 4E71 131F A46A 3D9B", + "requester": { + "personType": "EuropeanCitizen", + "email": "r2-d2@starwars.org", + "bsn": null, + "personalDetails": { + "firstName": "R2-D2", + "lastNamePrefix": null, + "lastName": null + } + }, + "rentalHouse": { + "street": "Amstel", + "houseNumber": "1", + "houseLetter": null, + "houseNumberExtension": null, + "postalCode": "1011PN", + "city": "Amsterdam", + "shortName": "Amstel", + "adresseerbaarObjectIdentificatie": "0363010012143319", + "nummeraanduidingIdentificatie": "0363200012145295", + "openbareRuimteIdentificatie": "0363300000002701", + "woonplaatsIdentificatie": "3594", + "pandIdentificaties": [ + "0363100012186092" + ], + "owner": null + }, + "requestForOther": false, + "requestForBedAndBreakfast": true, + "createdAt": "2024-11-28T10:43:23.0953603Z", + "agreementDate": "2024-11-28T10:43:23.0953603Z" + } ] export default holidayRentalRegistrationsData