Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/pages/campaigns/components/campaignForm/FormProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ export interface NewCampaignValues {
customerChoice: string;
options: number[];
};
ageRequirements?: {
min: number;
max: number;
}[];
targetCap?: string;
checkboxCap?: boolean;
browsersList?: string[];
Expand Down Expand Up @@ -177,6 +181,10 @@ const FormProvider = ({
customerChoice: dossier?.target?.genderQuote || "",
options: dossier?.visibilityCriteria?.gender || [],
},
ageRequirements: dossier?.visibilityCriteria?.ageRanges?.map((r) => ({
min: r.min,
max: r.max,
})) || [{ min: 0, max: 0 }],
cuf: initialCufCriteria,
};

Expand Down Expand Up @@ -249,6 +257,25 @@ const FormProvider = ({
value: yup.array().min(1, "Almeno un elemento è richiesto"),
})
),
ageRequirements: yup.array().of(
yup.object().shape({
min: yup.number().typeError("Min age must be a number").nullable(),
max: yup
.number()
.typeError("Max age must be a number")
.nullable()
.test(
"is-greater-or-equal",
"Max age must be greater than min age",
function (value) {
const { min } = this.parent;
if (min === null || min === "" || value === null || !value)
return true;
return value >= min;
}
),
})
),
});
return (
<Formik
Expand Down Expand Up @@ -326,6 +353,20 @@ const FormProvider = ({
};
})
: [],
ageRanges: values.ageRequirements
? values.ageRequirements
.filter(
(age) =>
age.min !== null &&
age.min !== undefined &&
age.max !== null &&
age.max !== undefined
)
.map((age) => ({
min: Number(age.min),
max: Number(age.max),
}))
: [],
},
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {
Button,
FormLabel,
Input,
Text,
} from "@appquality/appquality-design-system";
import { FieldArray, useFormikContext } from "formik";
import { NewCampaignValues } from "../FormProvider";
import { ReactComponent as DeleteIcon } from "src/assets/trash.svg";
import styled from "styled-components";

const StyledRow = styled.div`
display: flex;
gap: ${({ theme }) => theme.grid.sizes[4]};
align-items: center;
flex-direction: row;
margin-bottom: ${({ theme }) => theme.grid.sizes[3]};
`;

const AgeRequirements = () => {
const { values, setFieldValue } = useFormikContext<NewCampaignValues>();
const ageRanges = values.ageRequirements || [{ min: "", max: "" }];

const handleChange = (index: number, field: "min" | "max", value: string) => {
const num = value === "" ? "" : Number(value);
const updated = [...ageRanges];
updated[index] = { ...updated[index], [field]: num };
setFieldValue("ageRequirements", updated);
};

return (
<FieldArray name="ageRequirements">
{({ remove, push }) => (
<>
{ageRanges.map((age, index) => (
<div key={index}>
<FormLabel label="" htmlFor={`age-${index}-min`} />
<StyledRow>
<Text style={{ fontWeight: "bold" }}>From</Text>
<Input
id={`age-${index}-min`}
type="number"
value={age.min === "" ? "" : String(age.min)}
onChange={(val) => handleChange(index, "min", val)}
placeholder="Min age"
/>
<Text style={{ fontWeight: "bold" }}>to</Text>
<Input
id={`age-${index}-max`}
type="number"
value={age.max === "" ? "" : String(age.max)}
onChange={(val) => handleChange(index, "max", val)}
placeholder="Max age"
/>
<Button size="sm" kind="danger" onClick={() => remove(index)}>
<DeleteIcon />
</Button>
</StyledRow>
</div>
))}
<Button
size="sm"
kind="secondary"
onClick={() => push({ min: "", max: "" })}
>
+ Add age range
</Button>
</>
)}
</FieldArray>
);
};

export default AgeRequirements;
9 changes: 9 additions & 0 deletions src/pages/campaigns/components/campaignForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { styled } from "styled-components";
import { PhaseSelector } from "../PhaseSelector";
import { CampaignFormContext } from "./campaignFormContext";
import FormOverlay from "./feedbackMessages/FormOverlay";
import AgeRequirements from "./fields/AgeRequirements";
import BrowsersMultiselect from "./fields/BrowsersMultiselect";
import CountrySelect from "./fields/CountrySelect";
import CufCriteria from "./fields/CufCriteria";
Expand Down Expand Up @@ -274,12 +275,20 @@ const CampaignFormContent = ({ dossier, isEdit, duplicate }: FormProps) => {
<FieldWrapper>
<CountrySelect />
<LanguageSelect />
</FieldWrapper>
<FieldWrapper>
<div>
<Title size="s" className="aq-mb-2">
Gender
</Title>
<GenderRequirements />
</div>
<div>
<Title size="s" className="aq-mb-2">
Age range
</Title>
<AgeRequirements />
</div>
</FieldWrapper>
<CufCriteria />
<Title size="s" className="aq-mb-2 aq-pt-4">
Expand Down
Loading