Skip to content

Commit

Permalink
Merge pull request #1020 from Onlineberatung/fix/agency-radio-select
Browse files Browse the repository at this point in the history
fix: add single agency radio select component
  • Loading branch information
janrembold authored Mar 6, 2024
2 parents b1e08d3 + 5edf387 commit 96f0fc4
Show file tree
Hide file tree
Showing 14 changed files with 430 additions and 567 deletions.
178 changes: 101 additions & 77 deletions cypress/e2e/registration/consultingType.cy.ts

Large diffs are not rendered by default.

195 changes: 102 additions & 93 deletions cypress/e2e/registration/topic.cy.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,16 @@ interface AgencyLanguagesProps {
agencyId: number;
}

export const AgencyLanguages: React.FC<AgencyLanguagesProps> = ({
agencyId
}) => {
export const AgencyLanguages = ({ agencyId }: AgencyLanguagesProps) => {
const { t: translate } = useTranslation();

const { fixed: fixedLanguages } = useContext(LanguagesContext);
const settings = useAppConfig();
const [isAllShown, setIsAllShown] = useState(false);
const [languages, setLanguages] = useState<string[]>([...fixedLanguages]);
const languagesSelection = languages.slice(0, 2);
const difference = languages.length - languagesSelection.length;

useEffect(() => {
// async wrapper
const getLanguagesFromApi = async () => {
const response = await apiAgencyLanguages(
agencyId,
Expand All @@ -46,47 +44,42 @@ export const AgencyLanguages: React.FC<AgencyLanguagesProps> = ({
settings?.multitenancyWithSingleDomainEnabled
]);

const languagesSelection = languages.slice(0, 2);
const difference = languages.length - languagesSelection.length;

const mapLanguages = (isoCode) => (
<span key={isoCode}>
{translate(`languages.${isoCode}`)} ({isoCode.toUpperCase()})
</span>
);

if (languages.length > 0) {
return (
<div className="agencyLanguages">
<p>
{translate('registration.agencySelection.languages.info')}
</p>
{isAllShown || difference < 1 ? (
<div>{languages.map(mapLanguages)}</div>
) : (
<div>
{languagesSelection.map(mapLanguages)}
<span
className="agencyLanguages__more"
onClick={() => {
if (!languages.length) return null;

return (
<div className="agencyLanguages">
<p>{translate('registration.agencySelection.languages.info')}</p>
{isAllShown || difference < 1 ? (
<div>{languages.map(mapLanguages)}</div>
) : (
<div>
{languagesSelection.map(mapLanguages)}
<button
className="agencyLanguages__more"
onClick={(event) => {
event.preventDefault();
setIsAllShown(true);
}}
tabIndex={0}
onKeyUp={(event) => {
event.preventDefault();
if (event.key === 'Enter') {
setIsAllShown(true);
}}
tabIndex={0}
onKeyDown={(event) => {
if (event.key === 'Enter') {
setIsAllShown(true);
}
}}
>
{`+${difference} ${translate(
'registration.agencySelection.languages.more'
)}`}
</span>
</div>
)}
</div>
);
} else {
return <></>;
}
}
}}
>
{`+${difference} ${translate(
'registration.agencySelection.languages.more'
)}`}
</button>
</div>
)}
</div>
);
};
79 changes: 79 additions & 0 deletions src/components/agencyRadioSelect/AgencyRadioSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import './agencyRadioSelect.styles';
import { AgencyDataInterface } from '../../globalState/interfaces';
import { Headline } from '../headline/Headline';
import { RadioButton } from '../radioButton/RadioButton';
import { InfoTooltip } from '../infoTooltip/InfoTooltip';
import { AgencyLanguages } from './AgencyLanguages';
import clsx from 'clsx';

interface AgencyRadioSelectProps {
agency: AgencyDataInterface;
checkedValue: string;
showTooltipAbove?: boolean;
prefix?: string;
onChange?: (agency: AgencyDataInterface) => void;
onKeyDown?: (event: KeyboardEvent) => void;
}

export const AgencyRadioSelect = ({
checkedValue,
onChange,
onKeyDown,
agency,
prefix,
showTooltipAbove = false
}: AgencyRadioSelectProps) => {
const { t } = useTranslation('agencies');
const agencyIdAsString = agency.id.toString();

return (
<div className="agencyRadioSelect__wrapper">
{prefix && (
<Headline semanticLevel="4" styleLevel="5" text={prefix} />
)}
<div
className={clsx('agencyRadioSelect__radioContainer', {
'agencyRadioSelect__radioContainer--withHeadline': !!prefix
})}
>
<RadioButton
name="agencySelection"
handleRadioButton={() => onChange && onChange(agency)}
onKeyDown={(e: KeyboardEvent) => onKeyDown && onKeyDown(e)}
type="smaller"
value={agencyIdAsString}
checked={agencyIdAsString === checkedValue}
inputId={`agency-${agencyIdAsString}`}
>
{t([`agency.${agencyIdAsString}.name`, agency.name])}
</RadioButton>

<InfoTooltip
translation={{
ns: 'agencies',
prefix: 'agency'
}}
info={agency}
showTeamAgencyInfo={agency.teamAgency}
isProfileView={showTooltipAbove}
/>
</div>

<div className="agencyRadioSelect__content">
{agency.agencyLogo && (
<img
className="agencyRadioSelect__logo"
src={agency.agencyLogo}
alt={t([
`agency.${agencyIdAsString}.name`,
agency.name
])}
/>
)}
<AgencyLanguages agencyId={agency.id} />
</div>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ $input-size: 24px;
color: var(--skin-color-primary-contrast-safe, $primary);
text-decoration: underline;
cursor: pointer;
background: none;
border: none;

&:focus {
outline: $focus-outline;
Expand Down
59 changes: 59 additions & 0 deletions src/components/agencyRadioSelect/agencyRadioSelect.styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
$infoIconSize: 16px;

.agencyRadioSelect {
position: relative;
width: 100%;

&__wrapper {
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 12px 0;

.radioButton {
flex-basis: calc(100% - #{$infoIconSize + 1px});
min-height: unset;
padding: 4px 0 4px 4px;

&__label {
font-size: 16px;
padding-left: 16px;
}

&__contentWrapper {
align-items: center;
}
}

&:not(:last-of-type) {
border-bottom: 1px solid $black-10-opacity;
}

& > .headline {
margin-left: $registration-form-margin-left;
}
}

&__radioContainer {
display: flex;

&--withHeadline {
margin-top: 12px;
}
}

&__content {
display: flex;
flex-direction: row;
justify-content: flex-start;
margin-left: 44px;
}

&__logo {
max-width: 60px;
max-height: 60px;
margin-right: 16px;
object-fit: contain;
object-position: center left;
}
}
76 changes: 24 additions & 52 deletions src/components/agencySelection/AgencySelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,19 @@ import { InputField, InputFieldItem } from '../inputField/InputField';
import { VALID_POSTCODE_LENGTH } from './agencySelectionHelpers';
import './agencySelection.styles';
import '../profile/profile.styles';
import { RadioButton } from '../radioButton/RadioButton';
import { Loading } from '../app/Loading';
import { Text, LABEL_TYPES } from '../text/Text';
import { InfoTooltip } from '../infoTooltip/InfoTooltip';
import { PreselectedAgency } from '../../containers/registration/components/PreSelectedAgency/PreselectedAgency';
import { Headline } from '../headline/Headline';
import { parsePlaceholderString } from '../../utils/parsePlaceholderString';
import { Notice } from '../notice/Notice';
import { AgencyLanguages } from './AgencyLanguages';
import {
VALIDITY_INITIAL,
VALIDITY_INVALID,
VALIDITY_VALID
} from '../registration/registrationHelpers';
import { useTranslation } from 'react-i18next';
import { useAppConfig } from '../../hooks/useAppConfig';
import { AgencyRadioSelect } from '../agencyRadioSelect/AgencyRadioSelect';

export interface AgencySelectionProps {
consultingType: ConsultingTypeBasicInterface;
Expand Down Expand Up @@ -307,13 +304,15 @@ export const AgencySelection = (props: AgencySelectionProps) => {
</ul>
</div>
</div>

<InputField
item={postcodeInputItem}
inputHandle={(e) => handlePostcodeInput(e)}
onKeyDown={(e) =>
props.onKeyDown ? props.onKeyDown(e, false) : null
}
></InputField>
/>

{props.agencySelectionNote && (
<div data-cy="registration-agency-selection-note">
<Text
Expand All @@ -324,6 +323,7 @@ export const AgencySelection = (props: AgencySelectionProps) => {
/>
</div>
)}

{validPostcode() && !preselectedAgency && (
<div className="agencySelection__proposedAgencies">
<h3>
Expand All @@ -335,6 +335,7 @@ export const AgencySelection = (props: AgencySelectionProps) => {
'registration.agencySelection.title.end'
)}
</h3>
<div>WTF</div>
{!proposedAgencies ? (
postcodeFallbackLink ? (
<Notice
Expand Down Expand Up @@ -371,50 +372,20 @@ export const AgencySelection = (props: AgencySelectionProps) => {
)
) : (
proposedAgencies?.map(
(agency: AgencyDataInterface, index) => (
<div
key={index}
className="agencySelection__proposedAgency"
>
<div className="agencySelection__proposedAgency__container">
<RadioButton
name="agencySelection"
handleRadioButton={() =>
setSelectedAgency(
agency
)
}
type="smaller"
value={agency.id.toString()}
checked={index === 0}
inputId={agency.id.toString()}
>
{translate(
[
`agency.${agency.id}.name`,
agency.name
],
{ ns: 'agencies' }
)}
</RadioButton>
<InfoTooltip
translation={{
ns: 'agencies',
prefix: 'agency'
}}
info={agency}
showTeamAgencyInfo={
agency.teamAgency
}
isProfileView={
props.isProfileView
}
/>
</div>
<AgencyLanguages
agencyId={agency.id}
/>
</div>
(proposedAgency: AgencyDataInterface) => (
<AgencyRadioSelect
key={`agency-${proposedAgency.id}`}
agency={proposedAgency}
checkedValue={proposedAgencies[0].id.toString()}
showTooltipAbove={
props.isProfileView
}
onChange={() =>
setSelectedAgency(
proposedAgency
)
}
/>
)
)
)}
Expand All @@ -423,10 +394,11 @@ export const AgencySelection = (props: AgencySelectionProps) => {
</>
)}
{showPreselectedAgency && (
<PreselectedAgency
<AgencyRadioSelect
agency={preselectedAgency}
checkedValue={preselectedAgency.id.toString()}
prefix={translate('registration.agency.preselected.prefix')}
agencyData={preselectedAgency}
isProfileView={props.isProfileView}
showTooltipAbove={props.isProfileView}
/>
)}
</div>
Expand Down
Loading

0 comments on commit 96f0fc4

Please sign in to comment.