Skip to content

Commit

Permalink
Merge pull request #3004 from digitalfabrik/2548-Split-up-web-feedback
Browse files Browse the repository at this point in the history
2548: Split up web feedback at the first level into two smileys again
  • Loading branch information
LeandraH authored Dec 2, 2024
2 parents 8e2e483 + d3d5e13 commit 4b87183
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 49 deletions.
4 changes: 1 addition & 3 deletions web/src/components/CityContentToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,7 @@ const CityContentToolbar = (props: CityContentToolbarProps) => {
id='copy-icon'
/>
</Tooltip>
{hasFeedbackOption && (
<FeedbackToolbarItem route={route} slug={feedbackTarget} isInBottomActionSheet={isInBottomActionSheet} />
)}
{hasFeedbackOption && <FeedbackToolbarItem route={route} slug={feedbackTarget} />}
</Toolbar>
)
}
Expand Down
4 changes: 2 additions & 2 deletions web/src/components/Feedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type FeedbackProps = {
contactMail: string
onCommentChanged: (comment: string) => void
onContactMailChanged: (contactMail: string) => void
onFeedbackChanged: (isPositiveFeedback: boolean | null) => void
onFeedbackChanged?: (isPositiveFeedback: boolean | null) => void
onSubmit: () => void
sendingStatus: SendingStatusType
noResults: boolean | undefined
Expand Down Expand Up @@ -94,7 +94,7 @@ const Feedback = ({
</InputSection>
</>
) : (
<FeedbackButtons isPositive={isPositiveFeedback} onRatingChange={onFeedbackChanged} />
onFeedbackChanged && <FeedbackButtons isPositive={isPositiveFeedback} onRatingChange={onFeedbackChanged} />
)}

<InputSection
Expand Down
5 changes: 4 additions & 1 deletion web/src/components/FeedbackContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ type FeedbackContainerProps = {
noResults?: boolean
slug?: string
onSubmit?: () => void
isPositiveRating: boolean | null
setIsPositiveRating?: (isPositiveFeedback: boolean | null) => void
}

export type SendingStatusType = 'idle' | 'sending' | 'failed' | 'successful'
Expand All @@ -28,8 +30,9 @@ export const FeedbackContainer = ({
slug,
onClose,
onSubmit,
isPositiveRating,
setIsPositiveRating,
}: FeedbackContainerProps): ReactElement => {
const [isPositiveRating, setIsPositiveRating] = useState<boolean | null>(null)
const [comment, setComment] = useState<string>('')
const [contactMail, setContactMail] = useState<string>('')
const [sendingStatus, setSendingStatus] = useState<SendingStatusType>('idle')
Expand Down
27 changes: 22 additions & 5 deletions web/src/components/FeedbackToolbarItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'

import { FeedbackRouteType } from 'shared/api'

import { FeedbackIcon } from '../assets'
import { HappySmileyIcon, SadSmileyIcon } from '../assets'
import useCityContentParams from '../hooks/useCityContentParams'
import { RouteType } from '../routes'
import FeedbackContainer from './FeedbackContainer'
Expand All @@ -13,31 +13,48 @@ import ToolbarItem from './ToolbarItem'
type FeedbackToolbarItemProps = {
route: RouteType
slug?: string
isInBottomActionSheet: boolean
}

const FeedbackToolbarItem = ({ route, slug, isInBottomActionSheet }: FeedbackToolbarItemProps): ReactElement => {
const FeedbackToolbarItem = ({ route, slug }: FeedbackToolbarItemProps): ReactElement => {
const { cityCode, languageCode } = useCityContentParams()
const [isFeedbackOpen, setIsFeedbackOpen] = useState(false)
const [isSubmitted, setIsSubmitted] = useState(false)
const [isPositiveRating, setIsPositiveRating] = useState<boolean | null>(null)
const { t } = useTranslation('feedback')
const title = isSubmitted ? t('thanksHeadline') : t('headline')

return (
<>
{isFeedbackOpen && (
<Modal title={title} closeModal={() => setIsFeedbackOpen(false)} wrapInPortal={isInBottomActionSheet}>
<Modal title={title} closeModal={() => setIsFeedbackOpen(false)} wrapInPortal>
<FeedbackContainer
onClose={() => setIsFeedbackOpen(false)}
onSubmit={() => setIsSubmitted(true)}
routeType={route as FeedbackRouteType}
cityCode={cityCode}
language={languageCode}
slug={slug}
isPositiveRating={isPositiveRating}
setIsPositiveRating={setIsPositiveRating}
/>
</Modal>
)}
<ToolbarItem icon={FeedbackIcon} text={t('feedback')} onClick={() => setIsFeedbackOpen(true)} />
<ToolbarItem
icon={HappySmileyIcon}
text={t('useful')}
onClick={() => {
setIsFeedbackOpen(true)
setIsPositiveRating(true)
}}
/>
<ToolbarItem
icon={SadSmileyIcon}
text={t('notUseful')}
onClick={() => {
setIsFeedbackOpen(true)
setIsPositiveRating(false)
}}
/>
</>
)
}
Expand Down
40 changes: 10 additions & 30 deletions web/src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { ReactNode, useLayoutEffect, useState } from 'react'
import React, { ReactNode } from 'react'
import styled, { css } from 'styled-components'

import dimensions from '../constants/dimensions'
import useWindowDimensions from '../hooks/useWindowDimensions'
import '../styles/Aside.css'
import { MobileBanner } from './MobileBanner'

const additionalToolbarTopSpacing = 32
import Portal from './Portal'

export const RichLayout = styled.div`
position: relative;
Expand Down Expand Up @@ -49,6 +49,7 @@ const Body = styled.div<{ $fullWidth: boolean; $disableScrollingSafari: boolean
background-color: ${props => props.theme.colors.backgroundColor};
word-wrap: break-word;
min-height: 100%;
display: flex;
/* Fix jumping iOS Safari Toolbar by prevent scrolling on body */
Expand Down Expand Up @@ -93,25 +94,6 @@ const Main = styled.main<{ $fullWidth: boolean }>`
}
`

const Aside = styled.aside<{ $languageSelectorHeight: number }>`
top: ${props => props.$languageSelectorHeight + dimensions.headerHeightLarge + additionalToolbarTopSpacing}px;
margin-top: ${props => props.$languageSelectorHeight - dimensions.navigationMenuHeight}px;
display: inline-block;
position: sticky;
width: ${dimensions.toolbarWidth}px;
vertical-align: top;
z-index: 10;
&:empty {
display: none;
}
&:empty + * {
display: block;
max-width: 100%;
}
`

export const LAYOUT_ELEMENT_ID = 'layout'

type LayoutProps = {
Expand All @@ -133,20 +115,18 @@ const Layout = ({
fullWidth = false,
disableScrollingSafari = false,
}: LayoutProps): JSX.Element => {
const { width, viewportSmall } = useWindowDimensions()
const [languageSelectorHeight, setLanguageSelectorHeight] = useState<number>(0)

useLayoutEffect(() => {
const panelHeight = document.getElementById('languageSelector')?.clientHeight
setLanguageSelectorHeight(panelHeight ?? 0)
}, [width])
const { viewportSmall } = useWindowDimensions()

return (
<RichLayout id={LAYOUT_ELEMENT_ID}>
<MobileBanner />
{header}
<Body $fullWidth={fullWidth} $disableScrollingSafari={disableScrollingSafari}>
{!viewportSmall && <Aside $languageSelectorHeight={languageSelectorHeight}>{toolbar}</Aside>}
{!viewportSmall && (
<Portal className='aside' show>
{toolbar}
</Portal>
)}
<Main $fullWidth={fullWidth}>{children}</Main>
</Body>
{viewportSmall && toolbar}
Expand Down
1 change: 1 addition & 0 deletions web/src/components/SearchFeedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const SearchFeedback = ({ cityCode, languageCode, query, noResults }: SearchFeed
routeType={SEARCH_ROUTE}
query={query}
noResults={noResults}
isPositiveRating={null}
/>
</Container>
)
Expand Down
9 changes: 4 additions & 5 deletions web/src/components/__tests__/FeedbackContainer.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,13 @@ describe('FeedbackContainer', () => {
language,
onClose: closeModal,
query,
isPositiveRating: null,
})

it('should display thanks message for modal', async () => {
const { getByRole, findByText } = renderWithTheme(<FeedbackContainer {...buildDefaultProps(CATEGORIES_ROUTE)} />)
const buttonRating = getByRole('button', {
name: 'feedback:useful',
})
fireEvent.click(buttonRating)
const { getByRole, findByText } = renderWithTheme(
<FeedbackContainer {...buildDefaultProps(CATEGORIES_ROUTE)} isPositiveRating />,
)
const button = getByRole('button', {
name: 'feedback:send',
})
Expand Down
5 changes: 2 additions & 3 deletions web/src/components/__tests__/FeedbackToolbarItem.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,17 @@ jest.mock('focus-trap-react', () => ({ children }: { children: ReactElement }) =
describe('FeedbackToolbarItem', () => {
it('should open and update title on submit feedback', async () => {
const { queryByText, findByText, getByText } = renderWithRouterAndTheme(
<FeedbackToolbarItem route={CATEGORIES_ROUTE} slug='my-slug' isInBottomActionSheet={false} />,
<FeedbackToolbarItem route={CATEGORIES_ROUTE} slug='my-slug' />,
)

expect(queryByText('feedback:headline')).toBeFalsy()
expect(queryByText('feedback:thanksHeadline')).toBeFalsy()

fireEvent.click(getByText('feedback:feedback'))
fireEvent.click(getByText('feedback:useful'))

expect(getByText('feedback:headline')).toBeTruthy()
expect(queryByText('feedback:thanksHeadline')).toBeFalsy()

fireEvent.click(getByText('feedback:useful'))
fireEvent.click(getByText('feedback:send'))

expect(await findByText('feedback:thanksMessage')).toBeTruthy()
Expand Down
14 changes: 14 additions & 0 deletions web/src/styles/Aside.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.aside {
position: fixed;
top: 35%;
width: 100px;
left: 1%;

@media (min-width: 1100px) {
left: 10%;
}

&:empty {
display: none;
}
}

0 comments on commit 4b87183

Please sign in to comment.