Skip to content

Commit

Permalink
feat: update verbiage and look of advertiser agreement page (#1103)
Browse files Browse the repository at this point in the history
* feat: update verbiage and look of advertiser agreement page

* fix: add info on localization
  • Loading branch information
IanKrieger authored Feb 27, 2024
1 parent 6ceda3d commit 8da2e8e
Show file tree
Hide file tree
Showing 14 changed files with 375 additions and 280 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ module.exports = {
"transform",
"format",
"name",
"padding",
],
},
],
Expand Down
38 changes: 35 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

Brave Ads Manager is a key component of the ads infrastructure. From the ads manager, advertisers are able to define unique ad campaigns and creatives. Additionally, advertisers can review delivery and engagement metrics on their ad campaigns.

### Tech Stack & Philosophy
## Tech Stack & Philosophy

`ads-manager` is built with [TypeScript](https://www.typescriptlang.org/) and [React.js](https://reactjs.org/).

Expand All @@ -17,7 +17,7 @@ Our application bundle is created with [webpack](https://webpack.js.org/) and st

This bundle is then served to users as a static asset by [AWS CloudFront CDN](https://aws.amazon.com/cloudfront/).

### Local Development
## Local Development

- Create a `.env.local` file, or update `.env` file provided
- Set `BACKEND_URL=<>` to the endpoint you wish to pull data from.
Expand All @@ -26,8 +26,40 @@ This bundle is then served to users as a static asset by [AWS CloudFront CDN](ht
We are using HTTPS in developer mode so that cookie based authentication works properly.
You may need to proceed through a certificate warning in order to develop locally.

#### Generating GraphQL Types:
### Generating GraphQL Types:

```
> npm run codegen
```

## Localization
After changing text, o adding new translated text you need to run:
```
❯ npm run extract
```

THe output should look something like:
```
> [email protected] extract
> lingui extract
Catalog statistics for src/locales/{locale}:
┌──────────┬─────────────┬─────────┐
│ Language │ Total count │ Missing │
├──────────┼─────────────┼─────────┤
│ en │ 488 │ 0 │
│ es │ 491 │ 491 │
│ pt │ 491 │ 491 │
└──────────┴─────────────┴─────────┘
(use "npm run extract" to update catalogs with new messages)
```

This extracts all new messages, and gives a brief glimpse of what you have translated so far.
Once translations are complete, they should be added to the `msgstr` portion of their respective language.

To add more locales, edit the `locales` array in `lingui.config.js` and run `npm run extract` again.
Make sure you also update `i18n.ts` with the new locale.


70 changes: 23 additions & 47 deletions src/auth/components/AdvertiserAddress.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Divider, Stack } from "@mui/material";
import { Box, Stack } from "@mui/material";
import { FormikTextField } from "form/FormikHelpers";
import { CountryPicker } from "components/Country/CountryPicker";
import { PropsWithChildren } from "react";
Expand All @@ -17,52 +17,32 @@ export function AdvertiserAddress({ address }: Props) {
}

return (
<Box flexGrow={1}>
<Divider sx={{ mt: 1, mb: 1 }} />
<Box alignSelf="center" width="50%">
{!address?.street1 && (
<StackedFields>
<FormikTextField
required
name="address.street1"
label={_(msg`Street address`)}
autoComplete="address-line1"
margin="dense"
/>

<FormikTextField
name="address.street2"
label={_(msg`Street address line 2`)}
autoComplete="address-line2"
margin="dense"
/>
</StackedFields>
<FormikTextField
required
name="address.street1"
label={_(msg`Street address`)}
autoComplete="address-line1"
margin="dense"
size="small"
fullWidth
/>
)}

{!address?.city && (
<StackedFields>
<FormikTextField
required
name="address.city"
label={_(msg`City`)}
autoComplete="address-level2"
margin="dense"
/>

<FormikTextField
required
name="address.state"
label={_(msg`State / Province`)}
autoComplete="address-level1"
margin="dense"
/>
</StackedFields>
<FormikTextField
required
name="address.city"
label={_(msg`City`)}
autoComplete="address-level2"
margin="dense"
size="small"
/>
)}

{!address?.country && (
<Stack
direction={{ xs: "column", md: "row" }}
spacing={{ xs: 0, md: 1 }}
>
<StackedFields>
<CountryPicker name="address.country" />

<FormikTextField
Expand All @@ -71,18 +51,14 @@ export function AdvertiserAddress({ address }: Props) {
label={_(msg`Zip / Postal Code`)}
autoComplete="postal-code"
margin="dense"
fullWidth
size="small"
/>
</Stack>
</StackedFields>
)}
</Box>
);
}

function StackedFields(props: PropsWithChildren) {
return (
<Stack direction={{ xs: "column", md: "row" }} spacing={{ xs: 0, md: 1 }}>
{props.children}
</Stack>
);
return <Stack direction="column">{props.children}</Stack>;
}
107 changes: 52 additions & 55 deletions src/auth/components/AdvertiserAgreed.tsx
Original file line number Diff line number Diff line change
@@ -1,81 +1,78 @@
import Typography from "@mui/material/Typography";
import { Link, Stack } from "@mui/material";
import { Box, Link, Stack } from "@mui/material";
import { FormikCheckbox } from "form/FormikHelpers";
import { msg, Trans } from "@lingui/macro";
import { useLingui } from "@lingui/react";
import { LearnMoreButton } from "components/Button/LearnMoreButton";

export function AdvertiserAgreed(props: { requiresPaymentAgree: boolean }) {
const { _ } = useLingui();

return (
<>
<Stack mb={2} spacing={0.5}>
<Typography sx={{ fontWeight: 600 }}>
<Trans>Reporting</Trans>
</Typography>
<Typography>
<Trans>
Brave’s products are made to uphold user privacy. By default, the
Brave browser blocks third-party tracking (scripts, tags, pixels,
etc.) including those used by Google Analytics. This means that most
standard website reporting won’t be compatible with Brave Ads. To
ensure advertisers have visibility into performance of campaigns,
we’ve detailed other effective privacy-first options for measurement
in our{" "}
<Link href="https://brave.com/brave-ads/reporting/" target="_blank">
reporting guide
</Link>
</Trans>
.
</Typography>
<Box alignSelf="center" mt={5}>
<Stack spacing={0.5} direction="row" alignItems="center">
<FormikCheckbox
name="tracking"
label={_(
msg`I understand that Brave Ads will not be compatible with Google Analytics and similar solutions that rely on third-party trackers`,
msg`I understand that first-party analytics are necessary for independent reporting.`,
)}
showErrorMessage={false}
/>
<LearnMoreButton
variant="body2"
helpSection="/campaign-performance/reporting/"
/>
</Stack>
{props.requiresPaymentAgree && (
<Stack mb={2} spacing={0.5}>
<Typography sx={{ fontWeight: 600 }}>
<Trans>Payment</Trans>
</Typography>
<Typography>
<Trans>
To launch a campaign with Brave, you are required to prepay the
full amount you intend to spend. Any remaining funds from your
budget will be credited back to your original payment method upon
request.
</Trans>
</Typography>
<Stack spacing={0.5} direction="row" alignItems="center">
<FormikCheckbox
name="payment"
label={_(
msg`I understand that pre-payment is required to launch my campaigns`,
msg`I understand that payment is required before ad campaigns can be launched.`,
)}
showErrorMessage={false}
/>
<LearnMoreButton
variant="body2"
helpSection="/account-management/billing"
/>
</Stack>
)}

<Stack mb={2} spacing={0.5}>
<Typography sx={{ fontWeight: 600 }}>
<Trans>Terms & Conditions</Trans>
</Typography>
<Typography>
<Trans>
By continuing, you acknowledge and agree to our{" "}
<Link href="https://brave.com/privacy/advertiser" target="_blank">
Privacy Policy
</Link>{" "}
and platform{" "}
<Link href="https://brave.com/brave-ads/terms/" target="_blank">
Terms and Conditions
</Link>
</Trans>
.
</Typography>
<FormikCheckbox name="terms" label={_(msg`I agree`)} />
<Stack spacing={0.5}>
<FormikCheckbox
name="language"
label={_(
msg`I understand that I can only run ad campaigns in English, Spanish, and Portuguese.`,
)}
showErrorMessage={false}
/>
</Stack>

<Stack spacing={0.5}>
<FormikCheckbox
name="terms"
showErrorMessage={false}
label={
<Trans>
I have reviewed and agree to the{" "}
<Link
href="https://brave.com/advertiser-privacy/"
target="_blank"
>
Advertiser Privacy Policy
</Link>{" "}
and platform{" "}
<Link
href="https://basicattentiontoken.org/advertiser-terms-of-service/"
target="_blank"
>
Terms of Service
</Link>{" "}
applicable to Brave Ads.
</Trans>
}
/>
</Stack>
</>
</Box>
);
}
40 changes: 16 additions & 24 deletions src/auth/components/AdvertiserDetailsForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Card, Container, Divider, Skeleton, Stack } from "@mui/material";
import { Box, Card, Container, Skeleton } from "@mui/material";
import Typography from "@mui/material/Typography";
import { useAdvertiser } from "auth/hooks/queries/useAdvertiser";
import { Form, Formik } from "formik";
Expand Down Expand Up @@ -64,7 +64,7 @@ export function AdvertiserDetailsForm() {
variables: {
updateAdvertiserInput: {
id: advertiser.id,
agreed: v.terms && v.tracking && v.payment,
agreed: v.terms && v.tracking && v.payment && v.language,
billingAddress: v.address.id
? undefined
: _.omit(v.address, ["id"]),
Expand All @@ -76,7 +76,7 @@ export function AdvertiserDetailsForm() {
validationSchema={AdvertiserSchema()}
>
<Form>
<Box display="flex" flexDirection="column">
<Box>
{loading && (
<Skeleton
variant="rounded"
Expand All @@ -90,35 +90,27 @@ export function AdvertiserDetailsForm() {
sx={{
p: 3,
mb: 2,
display: "flex",
flexDirection: "column",
}}
>
<Stack spacing={0.5}>
<Typography variant="h4">
<Trans>Welcome to Brave Ads</Trans>,{" "}
<strong>{advertiser.name}</strong>
</Typography>
<Typography variant="subtitle1">
<Trans>
Prior to using the dashboard, please take a moment to
complete your profile and review the following
acknowledgements:
</Trans>
</Typography>
</Stack>
<Typography variant="h4" alignSelf="center" sx={{ mb: 3 }}>
<Trans>Complete your business profile to continue</Trans>
</Typography>

<AdvertiserAddress address={data?.advertiser?.billingAddress} />

<Divider sx={{ mt: 1, mb: 1 }} />

<AdvertiserAgreed requiresPaymentAgree={requiresPaymentAgree} />

<Box alignSelf="center">
<FormikSubmitButton
isCreate={false}
label={msg`Enter Ads Manager`}
sx={{ borderRadius: "10px", mt: 3 }}
/>
</Box>
</Card>
)}
<Box alignSelf="flex-end">
<FormikSubmitButton
isCreate={false}
label={msg`Access dashboard`}
/>
</Box>
</Box>
</Form>
</Formik>
Expand Down
2 changes: 2 additions & 0 deletions src/auth/components/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export type AdvertiserForm = {
tracking: boolean;
payment: boolean;
terms: boolean;
language: boolean;
address: {
id?: string | null;
street1: string;
Expand All @@ -24,6 +25,7 @@ export const initialAdvertiserForm = (
tracking: false,
payment: paymentAgree,
terms: false,
language: false,
address: {
id: maybeAddress?.billingAddress?.id ?? null,
street1: maybeAddress?.billingAddress?.street1 ?? "",
Expand Down
Loading

0 comments on commit 8da2e8e

Please sign in to comment.