Skip to content

Commit

Permalink
fix: different news CPM (#883)
Browse files Browse the repository at this point in the history
  • Loading branch information
IanKrieger authored Sep 12, 2023
1 parent c519a65 commit 8169b61
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 11 deletions.
23 changes: 19 additions & 4 deletions src/form/FormikHelpers.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { HTMLInputTypeAttribute, PropsWithChildren, ReactNode } from "react";
import {
ChangeEventHandler,
HTMLInputTypeAttribute,
PropsWithChildren,
ReactNode,
} from "react";
import {
Box,
Button,
Expand Down Expand Up @@ -97,15 +102,24 @@ export const FormikSwitch = (props: FormikSwitchProps) => {
interface FormikRadioGroupProps {
name: string;
row?: boolean;
onChange?: ChangeEventHandler<any>;
}

export const FormikRadioGroup = (
props: PropsWithChildren<FormikRadioGroupProps>,
) => {
const [field] = useField(props);
const [field, meta, helper] = useField(props);
return (
<>
<RadioGroup {...props} {...field} />
<RadioGroup
{...props}
{...field}
value={meta.value}
onChange={(e, nv) => {
helper.setValue(nv);
if (props.onChange) props.onChange(e);
}}
/>
<ErrorMessage name={field.name}>
{(msg: string) => <FormHelperText error>{msg}</FormHelperText>}
</ErrorMessage>
Expand All @@ -119,6 +133,7 @@ interface FormikRadioControlProps {
label?: string;
helperText?: ReactNode;
disabled?: boolean;
onChange?: ChangeEventHandler<any>;
}

export const FormikRadioControl = (props: FormikRadioControlProps) => {
Expand All @@ -131,7 +146,7 @@ export const FormikRadioControl = (props: FormikRadioControlProps) => {
<FormLabel component="legend" color="secondary">
{props.label}
</FormLabel>
<FormikRadioGroup row name={props.name}>
<FormikRadioGroup row name={props.name} onChange={props.onChange}>
{props.options.map((opt) => (
<FormControlLabel
key={opt.value}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,18 @@ import { useAdvertiser } from "auth/hooks/queries/useAdvertiser";
import _ from "lodash";
import { CardContainer } from "components/Card/CardContainer";
import { uiLabelsForBillingType } from "util/billingType";
import { uiTextForCampaignFormat } from "user/library";
import { CampaignFormat } from "graphql/types";

type DefaultPrice = { cpm: number; cpc: number };
const campaignDefaultPrices = new Map<CampaignFormat, DefaultPrice>([
[CampaignFormat.PushNotification, { cpm: 6, cpc: 0.1 }],
[CampaignFormat.NewsDisplayAd, { cpm: 10, cpc: 0.15 }],
]);

export function BudgetField() {
const [, , dailyBudget] = useField<number>("dailyBudget");
const [, , price] = useField<number>("price");
const { isDraft } = useIsEdit();
const { advertiser } = useAdvertiser();
const { values, errors } = useFormikContext<CampaignForm>();
Expand Down Expand Up @@ -69,7 +78,8 @@ export function BudgetField() {

{!advertiser.selfServiceSetPrice ? (
<Typography variant="body2">
Campaigns are priced at a flat rate of{" "}
{uiTextForCampaignFormat(values.format)} campaigns are priced at a
flat rate of{" "}
<strong>
${values.price} {_.upperCase(values.billingType)}
</strong>
Expand All @@ -92,6 +102,13 @@ export function BudgetField() {

<FormikRadioControl
name="billingType"
onChange={(e) => {
const defaultPrice = campaignDefaultPrices.get(values.format);
if (defaultPrice)
price.setValue(
defaultPrice[e.target.value as keyof DefaultPrice],
);
}}
options={[
{
value: "cpm",
Expand All @@ -102,7 +119,9 @@ export function BudgetField() {
label: uiLabelsForBillingType("cpc").longLabel,
},
]}
disabled={!isDraft}
disabled={
!isDraft || values.format === CampaignFormat.NewsDisplayAd
}
/>
</Stack>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { CampaignFormat } from "graphql/types";
import _ from "lodash";
import HelpIcon from "@mui/icons-material/Help";
import { useIsEdit } from "form/FormikHelpers";
import { Billing } from "user/views/adsManager/types";

export function FormatField() {
return (
Expand Down Expand Up @@ -42,13 +43,23 @@ export function FormatField() {

const FormatItemButton = (props: { format: CampaignFormat }) => {
const { isEdit } = useIsEdit();
const [, meta, helper] = useField<CampaignFormat>("format");
const [, meta, format] = useField<CampaignFormat>("format");
const [, , price] = useField<number>("price");
const [, , billing] = useField<Billing>("billingType");

return (
<ListItemButton
disabled={isEdit}
selected={meta.value === props.format}
onClick={() => helper.setValue(props.format)}
onClick={() => {
format.setValue(props.format);
if (props.format === CampaignFormat.NewsDisplayAd) {
price.setValue(10);
billing.setValue("cpm");
} else {
price.setValue(6);
}
}}
sx={{
p: 2,
borderRadius: "16px",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ export function PaymentButton(props: { hasPaymentIntent: boolean }) {
const { isEdit } = useIsEdit();
const paymentText = "Make payment & submit for approval";

console.log();
return (
<FormikSubmitButton
isCreate={!props.hasPaymentIntent || !isEdit}
Expand Down
15 changes: 13 additions & 2 deletions src/validation/CampaignSchema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ import { startOfDay } from "date-fns";
import { twoDaysOut } from "form/DateFieldHelpers";
import { TrailingAsteriskRegex } from "validation/regex";
import { CreativeSchema } from "validation/CreativeSchema";
import { CampaignFormat } from "graphql/types";

export const MIN_PER_DAY = 33;
export const MIN_PER_CAMPAIGN = 100;

export const CampaignSchema = object().shape({
name: string().label("Campaign Name").required(),
format: string()
.label("Campaign Format")
.oneOf([CampaignFormat.NewsDisplayAd, CampaignFormat.PushNotification])
.required(),
budget: number()
.label("Lifetime Budget")
.required()
Expand Down Expand Up @@ -59,10 +64,16 @@ export const CampaignSchema = object().shape({
then: (schema) =>
schema.moreThan(0.09, "CPC price must be .10 or higher"),
})
.when("billingType", {
is: (b: string) => b === "cpm",
.when(["billingType", "format"], {
is: (b: string, f: CampaignFormat) =>
b === "cpm" && f === CampaignFormat.PushNotification,
then: (schema) => schema.moreThan(5, "CPM price must be 6 or higher"),
})
.when(["billingType", "format"], {
is: (b: string, f: CampaignFormat) =>
b === "cpm" && f === CampaignFormat.NewsDisplayAd,
then: (schema) => schema.moreThan(9, "CPM price must be 10 or higher"),
})
.required("Price is a required field"),
billingType: string()
.label("Pricing Type")
Expand Down

0 comments on commit 8169b61

Please sign in to comment.