diff --git a/src/features/rewards/adRowsDetails/__snapshots__/spec.tsx.snap b/src/features/rewards/adRowsDetails/__snapshots__/spec.tsx.snap new file mode 100644 index 000000000..36bced689 --- /dev/null +++ b/src/features/rewards/adRowsDetails/__snapshots__/spec.tsx.snap @@ -0,0 +1,94 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Ad Rows Details tests basic tests matches the snapshot 1`] = ` +.c4 { + font-family: Muli,sans-serif; + font-size: 14px; + color: #686978; + display: inline-block; +} + +.c1 { + white-space: nowrap; +} + +.c0 { + text-align: left; + padding-top: 15px; +} + +.c5 { + width: 94.5%; + padding-left: 10px; + display: inline-block; +} + +.c6 { + color: #DADCE8; + background-color: #DADCE8; + height: 2px; + border: none; +} + +.c2 { + margin: 0; + background: none; + border: none; + cursor: pointer; + width: 16px; + height: 16px; + color: #9E9FAB; + padding: 1px; + outline: none; + display: inline-block; + text-align: center; +} + +.c3 { + width: 100%; + height: 100%; + fill: currentColor; +} + + + +
+
+
+ +
+
+ +
+
+
+
+
+
+ + +`; diff --git a/src/features/rewards/adRowsDetails/index.tsx b/src/features/rewards/adRowsDetails/index.tsx new file mode 100644 index 000000000..3672aee34 --- /dev/null +++ b/src/features/rewards/adRowsDetails/index.tsx @@ -0,0 +1,96 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' +import { + StyledAdPortionTD, + StyledAdsDateRow, + StyledAdsDetailRow, + StyledCaratIcon, + StyledDateText, + StyledHR, + StyledHRDiv, + StyledInnerStartTD + } from './style' +import { + CaratTriangleDownSIcon, CaratTriangleRightSIcon +} from '../../../components/icons' +import { DetailRow } from '../tableAdsHistory' +import { Row, Cell } from '../../../components/dataTables/table' + +export interface Props { + id?: string + row?: DetailRow + rowIndex?: number + detailRows?: Row[] +} + +interface State { + innerDetailVisible: boolean +} + +export default class AdRowsDetails extends React.PureComponent { + constructor (props: Props) { + super(props) + this.state = { + innerDetailVisible: true + } + } + + setInnerVisible = () => { + this.setState({ + innerDetailVisible: !this.state.innerDetailVisible + }) + } + + render () { + const { row, rowIndex, detailRows } = this.props + return ( + <> + + + + + + { + this.state.innerDetailVisible ? + + : + + } + + + { + row ? row.date : '' + } + + + + + + + + + { + detailRows && this.state.innerDetailVisible ? + detailRows.map((detailRow: Row, j: number) => { + return ( + + { + detailRow.content.map((detailCell: Cell, k: number) => { + return k === 0 ? + + : + {detailCell.content} + }) + } + + ) + }) + : null + } + + ) + } +} diff --git a/src/features/rewards/adRowsDetails/spec.tsx b/src/features/rewards/adRowsDetails/spec.tsx new file mode 100644 index 000000000..60d17cb7d --- /dev/null +++ b/src/features/rewards/adRowsDetails/spec.tsx @@ -0,0 +1,24 @@ +/* global jest, expect, describe, it, afterEach */ +import * as React from 'react' +import { shallow } from 'enzyme' +import { create } from 'react-test-renderer' +import { TestThemeProvider } from '../../../theme' +import AdRowsDetails from './index'; + +describe('Ad Rows Details tests', () => { + const baseComponent = (props?: object) => + + describe('basic tests', () => { + it('matches the snapshot', () => { + const component = baseComponent() + const tree = create(component).toJSON() + expect(tree).toMatchSnapshot() + }) + + it('renders the component', () => { + const wrapper = shallow(baseComponent()) + const assertion = wrapper.find('#adRowsDetails').length + expect(assertion).toBe(1) + }) + }) +}) diff --git a/src/features/rewards/adRowsDetails/style.ts b/src/features/rewards/adRowsDetails/style.ts new file mode 100644 index 000000000..0d4d72796 --- /dev/null +++ b/src/features/rewards/adRowsDetails/style.ts @@ -0,0 +1,70 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License. v. 2.0. If a copy of the MPL was not distributed with this file. + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import styled from 'styled-components' + +export const StyledDateText = styled<{}, 'div'>('div')` + font-family: Muli, sans-serif; + font-size: 14px; + color: #686978; + display: inline-block; +` +export const StyledAdsDateRow = styled<{}, 'div'>('div')` + white-space: nowrap; +` + +export const StyledAdsDetailRow = styled<{}, 'div'>('div')` + text-align: left; + padding-top: 15px; +` + +export const StyledHRDiv = styled<{}, 'div'>('div')` + width: 94.5%; + padding-left: 10px; + display: inline-block; +` + +export const StyledHR = styled<{}, 'hr'>('hr')` + color: #DADCE8; + background-color: #DADCE8; + height: 2px; + border: none; +` + +export const StyledCaratIcon = styled<{}, 'div'>('div')` + margin: 0; + background: none; + border: none; + cursor: pointer; + width: 16px; + height: 16px; + color: #9E9FAB; + padding: 1px; + outline: none; + display: inline-block; + text-align: center; +` + +export const StyledAdPortionTD = styled<{}, 'td'>('td')` + font-family: Muli, sans-serif; + font-size: 14px; + font-weight: 500; + color: #686978; + border-bottom: none; + padding: 5px 0; + text-align: left; + width: 70%; +` + +export const StyledInnerStartTD = styled<{}, 'td'>('td')` + font-family: Muli, sans-serif; + font-size: 14px; + font-weight: 500; + color: #686978; + border-bottom: none; + padding: 12px 0; + text-align: left; + width: 15%; + height: 0%; +` diff --git a/src/features/rewards/categoryLikePicker/__snapshots__/spec.tsx.snap b/src/features/rewards/categoryLikePicker/__snapshots__/spec.tsx.snap new file mode 100644 index 000000000..475de9674 --- /dev/null +++ b/src/features/rewards/categoryLikePicker/__snapshots__/spec.tsx.snap @@ -0,0 +1,82 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Category Like Picker tests basic tests matches the snapshot 1`] = ` +Array [ + .c0 { + display: inline-block; +} + +.c1 { + margin: auto; + border: none; + height: 32px; + width: 32px; + outline: none; + cursor: pointer; + object-fit: cover; +} + +.c2 { + width: 100%; + height: 100%; + fill: currentColor; +} + +
+
+ +
+
, + .c0 { + display: inline-block; +} + +.c1 { + border: none; + height: 31px; + width: 31px; + outline: none; + cursor: pointer; +} + +.c2 { + width: 100%; + height: 100%; + fill: currentColor; +} + +
+
+ +
+
, +] +`; diff --git a/src/features/rewards/categoryLikePicker/index.tsx b/src/features/rewards/categoryLikePicker/index.tsx new file mode 100644 index 000000000..67037f2e5 --- /dev/null +++ b/src/features/rewards/categoryLikePicker/index.tsx @@ -0,0 +1,110 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' +import { + StyledCategoryActionOptinLogo, + StyledCategoryActionOptoutLogo, + StyledCategoryActionOptinButton, + StyledCategoryActionOptoutButton, + StyledCategoryActionOptinFilledButton, + StyledCategoryActionOptoutFilledButton +} from './style' +import { + HeartLIcon, + HeartSIcon, + BlockLIcon, + BlockSIcon +} from '../../../components/icons' + +interface State { + itemSelected: number +} + +export interface Props { + id?: string + optAction: number + onOptIn?: () => void + onOptOut?: () => void +} + +export default class ThumbLikePicker extends React.PureComponent { + constructor (props: Props) { + super(props) + this.state = { + itemSelected: props.optAction + } + } + + onHeartPress = () => { + this.setState({ + itemSelected: this.state.itemSelected === 1 ? 0 : 1 + }) + const fnProp = this.props.onOptIn + if (fnProp) { + fnProp() + } + } + + onBlockPress = () => { + this.setState({ + itemSelected: this.state.itemSelected === 2 ? 0 : 2 + }) + const fnProp = this.props.onOptOut + if (fnProp) { + fnProp() + } + } + + render () { + return ( + this.state.itemSelected === 1 ? + ( + <> + + + + + + + + + + + + ) + : + this.state.itemSelected === 2 ? + ( + <> + + + + + + + + + + + + ) + : + ( + <> + + + + + + + + + + + + ) + ) + } +} diff --git a/src/features/rewards/categoryLikePicker/spec.tsx b/src/features/rewards/categoryLikePicker/spec.tsx new file mode 100644 index 000000000..c0636950b --- /dev/null +++ b/src/features/rewards/categoryLikePicker/spec.tsx @@ -0,0 +1,24 @@ +/* global jest, expect, describe, it, afterEach */ +import * as React from 'react' +import { shallow } from 'enzyme' +import { create } from 'react-test-renderer' +import { TestThemeProvider } from '../../../theme' +import CategoryLikePicker from './index'; + +describe('Category Like Picker tests', () => { + const baseComponent = (props?: object) => + + describe('basic tests', () => { + it('matches the snapshot', () => { + const component = baseComponent() + const tree = create(component).toJSON() + expect(tree).toMatchSnapshot() + }) + + it('renders the component', () => { + const wrapper = shallow(baseComponent()) + const assertion = wrapper.find('#categoryLikePicker').length + expect(assertion).toBe(1) + }) + }) +}) diff --git a/src/features/rewards/categoryLikePicker/style.ts b/src/features/rewards/categoryLikePicker/style.ts new file mode 100644 index 000000000..b5658ca25 --- /dev/null +++ b/src/features/rewards/categoryLikePicker/style.ts @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License. v. 2.0. If a copy of the MPL was not distributed with this file. +* You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import styled from 'styled-components' + +export const StyledCategoryActionOptinLogo = styled<{}, 'div'>('div')` + display: inline-block; +` + +export const StyledCategoryActionOptoutLogo = styled<{}, 'div'>('div')` + display: inline-block; +` + +export const StyledCategoryActionOptinButton = styled<{}, 'div'>('div')` +margin: auto; + border: none; + height: 32px; + width: 32px; + outline: none; + cursor: pointer; + object-fit: cover; +` + +export const StyledCategoryActionOptoutButton = styled<{}, 'div'>('div')` + border: none; + height: 31px; + width: 31px; + outline: none; + cursor: pointer; +` + +export const StyledCategoryActionOptinFilledButton = styled(StyledCategoryActionOptinButton)` + color: red; +` + +export const StyledCategoryActionOptoutFilledButton = styled(StyledCategoryActionOptoutButton)` + color: red; +` diff --git a/src/features/rewards/dropMenu/__snapshots__/spec.tsx.snap b/src/features/rewards/dropMenu/__snapshots__/spec.tsx.snap new file mode 100644 index 000000000..9fb55a4cb --- /dev/null +++ b/src/features/rewards/dropMenu/__snapshots__/spec.tsx.snap @@ -0,0 +1,37 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Drop Menu tests basic tests matches the snapshot 1`] = ` +.c0 { + width: 32px; + height: 32px; + display: inline-block; + padding: 2px; + position: relative; + border: none; + outline: none; +} + +.c1 { + width: 100%; + height: 100%; + fill: currentColor; +} + +
+
+ +
+
+`; diff --git a/src/features/rewards/dropMenu/index.tsx b/src/features/rewards/dropMenu/index.tsx new file mode 100644 index 000000000..85df0febd --- /dev/null +++ b/src/features/rewards/dropMenu/index.tsx @@ -0,0 +1,89 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' +import { + StyledAdMenuDropContent, + StyledAdStatBulletMenuIcon, + StyledAdMenuOptionDropContent, + StyledAdMenuOptionDropContentText +} from './style' +import { MoreVertLIcon } from '../../../components/icons' +import { getLocale } from '../../../helpers' + +interface State { + menuOpen: boolean +} + +export interface Props { + id?: string + likeAction?: number + onMenuSave?: () => void + onMenuFlag?: () => void +} + +export default class DropMenu extends React.PureComponent { + private container: React.RefObject + constructor (props: Props) { + super(props) + this.state = { + menuOpen: false + } + this.container = React.createRef() + } + + componentDidMount () { + document.addEventListener('mousedown', this.handleClickOutside) + } + + componentWillUnmount () { + document.removeEventListener('mousedown', this.handleClickOutside) + } + + handleClickOutside = (event: MouseEvent) => { + if (this.container.current && !this.container.current.contains(event.target as Element)) { + this.setState({ + menuOpen: false + }) + } + } + + showMenu = () => { + this.setState({ + menuOpen: !this.state.menuOpen + }) + } + + render () { + const { onMenuFlag, onMenuSave } = this.props + return ( + +
+ + { + this.state.menuOpen ? + + + + { + getLocale('saveAd') + } + + + + + { + getLocale('markAsInappropriate') + } + + + + : + null + } +
+
+ ) + } +} diff --git a/src/features/rewards/dropMenu/spec.tsx b/src/features/rewards/dropMenu/spec.tsx new file mode 100644 index 000000000..bebf9a6c8 --- /dev/null +++ b/src/features/rewards/dropMenu/spec.tsx @@ -0,0 +1,24 @@ +/* global jest, expect, describe, it, afterEach */ +import * as React from 'react' +import { shallow } from 'enzyme' +import { create } from 'react-test-renderer' +import { TestThemeProvider } from '../../../theme' +import DropMenu from './index'; + +describe('Drop Menu tests', () => { + const baseComponent = (props?: object) => + + describe('basic tests', () => { + it('matches the snapshot', () => { + const component = baseComponent() + const tree = create(component).toJSON() + expect(tree).toMatchSnapshot() + }) + + it('renders the component', () => { + const wrapper = shallow(baseComponent()) + const assertion = wrapper.find('#dropMenu').length + expect(assertion).toBe(1) + }) + }) +}) diff --git a/src/features/rewards/dropMenu/style.ts b/src/features/rewards/dropMenu/style.ts new file mode 100644 index 000000000..a6308a463 --- /dev/null +++ b/src/features/rewards/dropMenu/style.ts @@ -0,0 +1,46 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License. v. 2.0. If a copy of the MPL was not distributed with this file. +* You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import styled from 'styled-components' + +export const StyledAdMenuDropContent = styled<{}, 'div'>('div')` + display: block; + position: absolute; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + z-index: 1; + margin-top: -10px; + background-color: white; + border: 1px solid; + border-color: #DADCE8; + border-radius: 5px; + width: 200px; +` + +export const StyledAdStatBulletMenuIcon = styled<{}, 'div'>('div')` + width: 32px; + height: 32px; + display: inline-block; + padding: 2px; + position: relative; + border: none; + outline: none; +` + +export const StyledAdMenuOptionDropContent = styled<{}, 'div'>('div')` + display: flex; + align-items: center; + height: 35px; + padding-left: 5px; + margin-top: auto; + cursor: pointer; + &:hover { + background-color: #B0DBFF; + } +` + +export const StyledAdMenuOptionDropContentText = styled<{}, 'span'>('span')` + font-size: 16px; + vertical-align: middle; + font-weight: 600; +` diff --git a/src/features/rewards/index.ts b/src/features/rewards/index.ts index 51f1a1705..172975d62 100644 --- a/src/features/rewards/index.ts +++ b/src/features/rewards/index.ts @@ -2,10 +2,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ +import AdRowsDetails from './adRowsDetails' import Alert from './alert' import Amount from './amount' import Box from './box' import BoxAlert from './boxAlert' +import CategoryLikePicker from './categoryLikePicker' import DisabledBox from './disabledBox' import DisabledContent from './disabledContent' import DisabledPanel from './disabledPanel' @@ -25,17 +27,21 @@ import ModalAddFunds from './modalAddFunds' import ModalBackupRestore from './modalBackupRestore' import ModalContribute from './modalContribute' import ModalDonation from './modalDonation' +import ModalShowAdsHistory from './modalShowAdsHistory' import NextContribution from './nextContribution' import PanelWelcome from './panelWelcome' import Profile from './profile' import RestoreSites from './restoreSites' import RewardsButton from './rewardsButton' import SettingsPage from './settingsPage' +import ShowAdsHistory from './showAdsHistory' import SiteBanner from './siteBanner' import Tab from './tab' +import TableAdsHistory from './tableAdsHistory' import TableContribute from './tableContribute' import TableDonation from './tableDonation' import TableTransactions from './tableTransactions' +import ThumbLikePicker from './thumbLikePicker' import Tip from './tip' import ToggleTips from './toggleTips' import Tokens from './tokens' @@ -50,10 +56,12 @@ import WalletWrapper from './walletWrapper' import WelcomePage from './welcomePage' export { + AdRowsDetails, Alert, Amount, Box, BoxAlert, + CategoryLikePicker, DisabledBox, DisabledContent, DisabledPanel, @@ -73,17 +81,21 @@ export { ModalBackupRestore, ModalContribute, ModalDonation, + ModalShowAdsHistory, NextContribution, PanelWelcome, Profile, RestoreSites, RewardsButton, SettingsPage, + ShowAdsHistory, SiteBanner, Tab, + TableAdsHistory, TableContribute, TableDonation, TableTransactions, + ThumbLikePicker, Tip, ToggleTips, Tokens, diff --git a/src/features/rewards/modalShowAdsHistory/__snapshots__/spec.tsx.snap b/src/features/rewards/modalShowAdsHistory/__snapshots__/spec.tsx.snap new file mode 100644 index 000000000..dfbdb962f --- /dev/null +++ b/src/features/rewards/modalShowAdsHistory/__snapshots__/spec.tsx.snap @@ -0,0 +1,183 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ModalShowAdsHistory tests basic tests matches the snapshot 1`] = ` +.c5 { + font-family: Poppins,sans-serif; + padding-top: 10px; + white-space: nowrap; +} + +.c6 { + font-size: 22px; + font-weight: 600; + color: rgb(193,45,124); + margin-bottom: 10px; + line-height: 1.3; +} + +.c7 { + font-size: 30px; + line-height: 1.2; + margin-bottom: 10px; + font-weight: 300; +} + +.c10 { + font-size: 18px; + color: rgb(193,45,124); +} + +.c9 { + line-height: 1.5; +} + +.c11 { + font-size: 18px; + color: rgb(193,45,124); + font-weight: 600; +} + +.c8 { + line-height: 1.5; + width: 100%; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -ms-flex-pack: justify; + justify-content: space-between; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-align-content: baseline; + -ms-flex-line-pack: baseline; + align-content: baseline; +} + +.c0 { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100vh; + background: rgba(12,13,33,0.85); + z-index: 99; + padding: 0 20px; + overflow: hidden; +} + +.c1 { + max-width: 920px; + margin: 52px auto; + background: #fff; + border-radius: 6px; + overflow: hidden; + position: relative; +} + +.c2 { + position: absolute; + top: 20px; + right: 20px; + cursor: pointer; + width: 20px; + height: 20px; + color: #9E9FAB; +} + +.c4 { + padding: 48px 48px; + overflow-y: auto; + max-height: calc(100vh - 100px); +} + +.c3 { + width: 100%; + height: 100%; + fill: currentColor; +} + +.c12 { + -webkit-text-decoration: none; + text-decoration: none; + font-size: 16px; + font-weight: 400; + padding-top: 24px; +} + + +`; diff --git a/src/features/rewards/modalShowAdsHistory/index.tsx b/src/features/rewards/modalShowAdsHistory/index.tsx new file mode 100644 index 000000000..d1820e1f5 --- /dev/null +++ b/src/features/rewards/modalShowAdsHistory/index.tsx @@ -0,0 +1,144 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' +import { + StyledAdsHeaderWrapper, + StyledAdsHistoryTitle, + StyledAdsInfoText, + StyledAdsInfoTextWrapper, + StyledAdsPerHourText, + StyledAdsSaveFiltered, + StyledDisabledLink, + StyledLink, + StyledSeparatorText, + StyledSubTitleText, + StyledText, + StyledWrapper +} from './style' +import Modal from '../../../components/popupModals/modal/index' +import { getLocale } from '../../../helpers' +import TableAdsHistory, { DetailRow } from '../tableAdsHistory/index' + +export interface Props { + rows?: DetailRow[] + onClose?: () => void + id?: string + isMobile?: boolean + adsPerHour?: number + adsPerDay?: number + hasSavedEntries?: boolean + onSavedFilterClick?: () => void + onAllFilterClick?: () => void +} + +interface State { + savedFilterOn: boolean +} + +export default class ModalShowAdsHistory extends React.PureComponent { + constructor (props: Props) { + super(props) + this.state = { + savedFilterOn: false + } + } + + get headers () { + return [ + getLocale('date'), + getLocale('ads'), + getLocale('category') + ] + } + + onSavedFilterClick = () => { + this.setState({ + savedFilterOn: true + }) + const savedFilterFn = this.props.onSavedFilterClick + if (savedFilterFn) { + savedFilterFn() + } + } + + onAllFilterClick = () => { + this.setState({ + savedFilterOn: false + }) + const allFilterFn = this.props.onAllFilterClick + if (allFilterFn) { + allFilterFn() + } + } + + render () { + const { id, onClose, isMobile, adsPerHour, hasSavedEntries, rows } = this.props + + return ( + + + + {getLocale('adsHistoryTitle')} + + + {getLocale('adsHistorySubTitle')} + + + + + {getLocale('adsCurrentlyViewing')} + + + {(adsPerHour || '0') + (adsPerHour !== 1 ? getLocale('adsPerHourPlural') : getLocale('adsPerHourSingular'))} + + + { + rows && hasSavedEntries ? + + + { + this.state.savedFilterOn ? + + { + getLocale('all') + } + : + + { + getLocale('all') + } + + } + + | + + { + !this.state.savedFilterOn ? + + { + getLocale('saved') + } + : + + { + getLocale('saved') + } + + } + + + : null + } + + + + + ) + } +} diff --git a/src/features/rewards/modalShowAdsHistory/spec.tsx b/src/features/rewards/modalShowAdsHistory/spec.tsx new file mode 100644 index 000000000..c44bcac56 --- /dev/null +++ b/src/features/rewards/modalShowAdsHistory/spec.tsx @@ -0,0 +1,24 @@ +/* global jest, expect, describe, it, afterEach */ +import * as React from 'react' +import { shallow } from 'enzyme' +import { create } from 'react-test-renderer' +import ModalShowAdsHistory from './index' +import { TestThemeProvider } from '../../../theme' + +describe('ModalShowAdsHistory tests', () => { + const baseComponent = (props?: object) => + + describe('basic tests', () => { + it('matches the snapshot', () => { + const component = baseComponent() + const tree = create(component).toJSON() + expect(tree).toMatchSnapshot() + }) + + it('renders the component', () => { + const wrapper = shallow(baseComponent()) + const assertion = wrapper.find('#modal').length + expect(assertion).toBe(1) + }) + }) +}) diff --git a/src/features/rewards/modalShowAdsHistory/style.ts b/src/features/rewards/modalShowAdsHistory/style.ts new file mode 100644 index 000000000..eeb34ca95 --- /dev/null +++ b/src/features/rewards/modalShowAdsHistory/style.ts @@ -0,0 +1,99 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this file, +* You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +import styled from 'styled-components' + +export const StyledWrapper = styled<{}, 'div'>('div')` + font-family: Poppins, sans-serif; + padding-top: 10px; + white-space: nowrap; +` + +export const StyledLink = styled<{}, 'a'>('a')` + cursor: pointer; + display: inline-block; + color: #696FDC; + font-size: 16px; + letter-spacing: 0; +` + +export const StyledDisabledLink = styled<{}, 'span'>('span')` + display: inline-block; + color: #CED0DB; + font-size: 16px; + letter-spacing: 0; +` + +export const StyledText = styled<{}, 'span'>('span')` + font-size: 16px; + letter-spacing: 0; + display: inline-block; + color: #C2C4CF; + margin: 0 10px 0; +` + +export const StyledAdsHistoryTitle = styled<{}, 'div'>('div')` + font-size: 22px; + font-weight: 600; + color: rgb(193, 45, 124); + margin-bottom: 10px; + line-height: 1.3; +` + +export const StyledNote = styled<{}, 'div'>('div')` + max-width: 508px; + font-family: Muli,sans-serif; + font-size: 12px; + font-weight: 300; + margin-bottom: 10px; + line-height: 1.5; + color: #686978; +` + +export const StyledSeparatorText = styled<{}, 'span'>('span')` + font-size: 16px; + font-weight: 200; + letter-spacing: 0; + display: inline-block; + color: #C2C4CF +` + +export const StyledSubTitleText = styled<{}, 'div'>('div')` + font-size: 30px; + line-height: 1.2; + margin-bottom: 10px; + font-weight: 300; +` + +export const StyledAdsInfoText = styled<{}, 'span'>('span')` + font-size: 18px; + color: rgb(193, 45, 124); +` + +export const StyledAdsInfoTextWrapper = styled<{}, 'div'>('div')` + line-height: 1.5; +` + +export const StyledAdsPerHourText = styled<{}, 'span'>('span')` + font-size: 18px; + color: rgb(193, 45, 124); + font-weight: 600; +` + +export const StyledAdsHeaderWrapper = styled<{}, 'div'>('div')` + line-height: 1.5; + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + align-content: baseline; +` + +export const StyledAdsSaveFiltered = styled<{}, 'div'>('div')` + text-align: right; + line-height: 1.5; + display: flex; + justify-content: space-between; +` diff --git a/src/features/rewards/showAdsHistory/__snapshots__/spec.tsx.snap b/src/features/rewards/showAdsHistory/__snapshots__/spec.tsx.snap new file mode 100644 index 000000000..9952dd7da --- /dev/null +++ b/src/features/rewards/showAdsHistory/__snapshots__/spec.tsx.snap @@ -0,0 +1,30 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ShowAdsHistory tests basic tests matches the snapshot 1`] = ` +.c0 { + padding-top: 10px; + text-align: right; +} + +.c1 { + cursor: pointer; + display: inline-block; + color: #696FDC; + font-size: 13px; + font-weight: normal; + -webkit-letter-spacing: 0; + -moz-letter-spacing: 0; + -ms-letter-spacing: 0; + letter-spacing: 0; +} + + +`; diff --git a/src/features/rewards/showAdsHistory/index.tsx b/src/features/rewards/showAdsHistory/index.tsx new file mode 100644 index 000000000..a91856148 --- /dev/null +++ b/src/features/rewards/showAdsHistory/index.tsx @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' +import { StyledLink, StyledWrapper } from './style' + +import { getLocale } from '../../../helpers' + +export interface Props { + onAdsHistoryOpen?: () => void +} + +export default class ShowAdsHistory extends React.PureComponent { + render () { + const { onAdsHistoryOpen } = this.props + + return ( + + + {getLocale('openAdsHistory')} + + + ) + } +} diff --git a/src/features/rewards/showAdsHistory/spec.tsx b/src/features/rewards/showAdsHistory/spec.tsx new file mode 100644 index 000000000..b3a5bd31d --- /dev/null +++ b/src/features/rewards/showAdsHistory/spec.tsx @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this file, +* You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +import * as React from 'react' +import { shallow } from 'enzyme' +import { create } from 'react-test-renderer' +import ShowAdsHistory from './index'; +import { TestThemeProvider } from '../../../theme' + +describe('ShowAdsHistory tests', () => { + const baseComponent = (props?: object) => + + describe('basic tests', () => { + it('matches the snapshot', () => { + const component = baseComponent() + const tree = create(component).toJSON() + expect(tree).toMatchSnapshot() + }) + + it('renders the component', () => { + const wrapper = shallow(baseComponent()) + const assertion = wrapper.find('#disabled-panel').length + expect(assertion).toBe(1) + }) + }) +}) diff --git a/src/features/rewards/showAdsHistory/style.ts b/src/features/rewards/showAdsHistory/style.ts new file mode 100644 index 000000000..3ed16522c --- /dev/null +++ b/src/features/rewards/showAdsHistory/style.ts @@ -0,0 +1,20 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this file, +* You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +import styled from 'styled-components' + +export const StyledWrapper = styled<{}, 'div'>('div')` + padding-top: 10px; + text-align: right; +` + +export const StyledLink = styled<{}, 'a'>('a')` + cursor: pointer; + display: inline-block; + color: #696FDC; + font-size: 13px; + font-weight: normal; + letter-spacing: 0; +` diff --git a/src/features/rewards/tableAdsHistory/__snapshots__/spec.tsx.snap b/src/features/rewards/tableAdsHistory/__snapshots__/spec.tsx.snap new file mode 100644 index 000000000..3f9e6c341 --- /dev/null +++ b/src/features/rewards/tableAdsHistory/__snapshots__/spec.tsx.snap @@ -0,0 +1,21 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Amount tests basic tests matches the snapshot 1`] = ` +.c0 { + -webkit-text-decoration: none; + text-decoration: none; + font-size: 16px; + font-weight: 400; + padding-top: 24px; +} + +
+
+ MISSING: noAdsHistory +
+
+`; diff --git a/src/features/rewards/tableAdsHistory/index.tsx b/src/features/rewards/tableAdsHistory/index.tsx new file mode 100644 index 000000000..66a6a927c --- /dev/null +++ b/src/features/rewards/tableAdsHistory/index.tsx @@ -0,0 +1,236 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' +import { + StyledTHFirst, + StyledTHOther, + StyledTHLast, + StyledAdContentDiv, + StyledLogo, + StyledLogoDiv, + StyledAdInfoDiv, + StyledAdBrand, + StyledAdInfo, + StyledAdStatDiv, + StyledAdStat, + StyledAdStatActions, + StyledCategoryContentDiv, + StyledCategoryName, + StyledCategoryActions, + StyledAdLink, + StyledNoAdHistoryDiv, + StyledNoLogoDiv, + StyledTD +} from './style' +import { Row } from '../../../components/dataTables/table' +import { StyledTable } from '../../../components/dataTables/table/style' +import ThumbLikePicker from '../thumbLikePicker' +import CategoryLikePicker from '../categoryLikePicker' +import DropMenu from '../dropMenu' +import AdRowsDetails from '../adRowsDetails' +import { getLocale } from '../../../helpers' + +export interface DetailRow { + [key: string]: any + id: number + date: string + adDetailRows: AdDetailRow[] +} + +interface AdContent { + brand: string + brandInfo: string + brandLogo: string + brandUrl: string + brandDisplayUrl: string + likeAction: number + adAction: 'Viewed' | 'Clicked' | 'Closed' | 'Landed' + savedAd: boolean + flaggedAd: boolean + logoUrl?: string + onThumbUpPress?: () => void + onThumbDownPress?: () => void + onMenuSave?: () => void + onMenuFlag?: () => void +} + +interface CategoryContent { + category: string + optAction: number + onOptInAction?: () => void + onOptOutAction?: () => void +} + +export interface AdDetailRow { + id: number + adContent: AdContent + categoryContent: CategoryContent +} + +export interface Props { + header: string[] + id?: string + testId?: string + children?: React.ReactNode + headerColor?: boolean + rows?: DetailRow[] + allItems?: boolean +} + +export default class TableAdsHistory extends React.PureComponent { + getAdsHistoryTable = (header: string[], rows: DetailRow[]): any => { + return ( + + { + header ? + + + { + this.getHeader(header) + } + + + : null + } + + { + this.getRows(rows) + } + + + ) + } + + getHeader = (header: string[]) => { + if (!header) { + return + } + + return ( + <> + {header[0]} + {header[1]} + {header[2]} + + ) + } + + getRows = (rows: DetailRow[]) => { + return rows.map((row: DetailRow, i: number) => { + const detailRows = this.getDetailRows(row.adDetailRows) + return ( + detailRows && detailRows.length > 0 ? + + : null + ) + }) + } + + getCategoryContent = (content: CategoryContent) => { + return ( + + + {content.category} + + + + + + ) + } + + getAdContent = (content: AdContent) => { + return ( + + + { + content.logoUrl ? + + + + : + + } + + {content.brand} + {content.brandInfo} + {content.brandDisplayUrl} + + + + + {content.adAction} + +
+ + + + + + + ) + } + + getDetailRows = (rows: AdDetailRow[]): Row[] | undefined => { + if (!rows) { + return + } + const filteredRows: AdDetailRow[] = !this.props.allItems ? rows.filter((row: AdDetailRow) => { + return row.adContent && row.adContent.savedAd + }) : rows + return filteredRows.map((row: AdDetailRow, i: number): Row => { + const cell: Row = { + content: [ + { + content: ( + + ) + }, + { + content: ( + this.getAdContent(row.adContent) + ) + }, + { + content: ( + this.getCategoryContent(row.categoryContent) + ) + } + ] + } + return cell + }) + } + + render () { + const { id, testId, header, rows } = this.props + return ( +
+ { + rows ? + this.getAdsHistoryTable(header, rows) + : + + { + getLocale('noAdsHistory') + } + + } +
+ + ) + } +} diff --git a/src/features/rewards/tableAdsHistory/spec.tsx b/src/features/rewards/tableAdsHistory/spec.tsx new file mode 100644 index 000000000..91aa46566 --- /dev/null +++ b/src/features/rewards/tableAdsHistory/spec.tsx @@ -0,0 +1,24 @@ +/* global jest, expect, describe, it, afterEach */ +import * as React from 'react' +import { shallow } from 'enzyme' +import { create } from 'react-test-renderer' +import { TestThemeProvider } from '../../../theme' +import TableAdsHistory from './index'; + +describe('Amount tests', () => { + const baseComponent = (props?: object) => + + describe('basic tests', () => { + it('matches the snapshot', () => { + const component = baseComponent() + const tree = create(component).toJSON() + expect(tree).toMatchSnapshot() + }) + + it('renders the component', () => { + const wrapper = shallow(baseComponent()) + const assertion = wrapper.find('#tableAdsHistory').length + expect(assertion).toBe(1) + }) + }) +}) diff --git a/src/features/rewards/tableAdsHistory/style.ts b/src/features/rewards/tableAdsHistory/style.ts new file mode 100644 index 000000000..a6d5357de --- /dev/null +++ b/src/features/rewards/tableAdsHistory/style.ts @@ -0,0 +1,170 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License. v. 2.0. If a copy of the MPL was not distributed with this file. +* You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import styled from 'styled-components' + +export const StyledTHOther = styled<{}, 'th'>('th')` + text-transform: uppercase; + text-align: left; + font-family: ${p => p.theme.fontFamily.body}; + font-size: 12px; + font-weight: 500; + border-bottom: 2px solid #dedfe4; + border-top: 2px solid #dedfe4; + color: #4B4C5C; + padding: 12px 0; + width: 70%; +` + +export const StyledOuterTD = styled<{}, 'td'>('td')` + width: 100%; +` + +export const StyledTR = styled<{}, 'tr'>('tr')` + text-align: left; +` + +export const StyledTHLast = styled(StyledTHOther)` + text-transform: uppercase; + text-align: left; + font-family: ${p => p.theme.fontFamily.body}; + font-size: 12px; + font-weight: 500; + border-bottom: 2px solid #dedfe4; + border-top: 2px solid #dedfe4; + color: #4B4C5C; + padding: 12px 0; + width: 15%; +` + +export const StyledTHFirst = styled<{}, 'th'>('th')` + text-transform: uppercase; + text-align: left; + font-family: ${p => p.theme.fontFamily.body}; + font-size: 12px; + font-weight: 500; + border-bottom: 2px solid #dedfe4; + border-top: 2px solid #dedfe4; + color: #4B4C5C; + padding: 12px 0; + width: 15%; +` + +export const StyledToggleWrap = styled<{}, 'div'>('div')` + text-align: right; +` + +export const StyledToggle = styled<{}, 'div'>('div')` + font-family: Poppins, sans-serif; + font-size: 13px; + color: #4c54d2; + text-transform: capitalize; + background: none; + border: none; + padding: 0; + cursor: pointer; +` + +export const StyledAdLink = styled<{}, 'a'>('a')` + text-decoration: none; + cursor: pointer; + display: flex; + color: #686978 +` + +export const StyledAdTable = styled<{}, 'table'>('table')` + min-width: 100%; + margin: 24px 0; + padding-top: 15px; +` +export const StyledAdContentDiv = styled<{}, 'div'>('div')` + min-width: 95%; + border: 1px solid; + border-collapse: separate; + border-radius: 5px; + border-color: #DADCE8; + padding: 10px; + display: inline-flex; + align-items: center; + height: 85px; +` + +export const StyledLogo = styled<{}, 'img'>('img') ` + width: 64px; + height: 64px; +` + +// TODO(jsadler): 'display: none' becomes 'display: inline-block' once icons are in place +export const StyledLogoDiv = styled<{}, 'div'>('div')` + display: inline-block; + width: 64px; + height: 64px; + padding: 1px; + padding-right: 10px; +` + +export const StyledNoLogoDiv = styled<{}, 'div'>('div')` + display: none; +` + +export const StyledAdInfoDiv = styled<{}, 'div'>('div')` + padding-left: 20px; + display: inline-block; +` +export const StyledAdInfo = styled<{}, 'div'>('div')` + display: block; + color: #AEB1C2; + padding-bottom: 2px; +` + +export const StyledAdBrand = styled<{}, 'div'>('div')` + font-family: Poppins, sans-serif; + font-weight: 600; + padding-bottom: 2px; +` + +export const StyledAdStatDiv = styled<{}, 'div'>('div')` + margin-left: auto; + height: 100%; + display: flex; + flex-direction: column; + padding-top: 5px; + padding-bottom: 5px; +` + +export const StyledAdStat = styled<{}, 'div'>('div')` + padding-left: 2px; +` + +export const StyledAdStatActions = styled<{}, 'div'>('div')` + margin-top: auto; +` + +export const StyledCategoryContentDiv = styled<{}, 'div'>('div')` + display: flex; + flex-direction: column; + height: 85px; +` + +export const StyledCategoryName = styled<{}, 'div'>('div')` + font-size: 16px; + font-weight: 600; + margin: auto; +` + +export const StyledCategoryActions = styled<{}, 'div'>('div')` + margin: auto; +` + +export const StyledNoAdHistoryDiv = styled<{}, 'div'>('div')` + text-decoration: none; + font-size: 16px; + font-weight: 400; + padding-top: 24px; +` + +export const StyledTD = styled<{}, 'td'>('td')` + width: '15%'; + border: 'none'; +` diff --git a/src/features/rewards/thumbLikePicker/__snapshots__/spec.tsx.snap b/src/features/rewards/thumbLikePicker/__snapshots__/spec.tsx.snap new file mode 100644 index 000000000..576d8de7b --- /dev/null +++ b/src/features/rewards/thumbLikePicker/__snapshots__/spec.tsx.snap @@ -0,0 +1,65 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Amount tests basic tests matches the snapshot 1`] = ` +Array [ + .c0 { + display: inline-block; + width: 32px; + height: 32px; + padding: 4px; + cursor: pointer; +} + +.c1 { + width: 100%; + height: 100%; + fill: currentColor; +} + +
+ +
, + .c0 { + display: inline-block; + width: 32px; + height: 32px; + margin-top: auto; + padding: 4px; + cursor: pointer; +} + +.c1 { + width: 100%; + height: 100%; + fill: currentColor; +} + +
+ +
, +] +`; diff --git a/src/features/rewards/thumbLikePicker/index.tsx b/src/features/rewards/thumbLikePicker/index.tsx new file mode 100644 index 000000000..bacd5f28d --- /dev/null +++ b/src/features/rewards/thumbLikePicker/index.tsx @@ -0,0 +1,95 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import * as React from 'react' +import { + StyledAdStatThumbUpIcon, + StyledAdStatThumbUpFilledIcon, + StyledAdStatThumbDownIcon, + StyledAdStatThumbDownFilledIcon +} from './style' + +import { + ThumbsupLIcon, + ThumbsdownLIcon, + ThumbsupSIcon, + ThumbsdownSIcon +} from '../../../components/icons' + +interface State { + itemSelected: number +} + +export interface Props { + id?: string + likeAction: number + onThumbUpPress?: () => void + onThumbDownPress?: () => void +} + +export default class ThumbLikePicker extends React.PureComponent { + constructor (props: Props) { + super(props) + this.state = { + itemSelected: props.likeAction + } + } + + onThumbUpPress = () => { + this.setState({ + itemSelected: this.state.itemSelected === 1 ? 0 : 1 + }) + const fnProp = this.props.onThumbUpPress + if (fnProp) { + fnProp() + } + } + + onThumbDownPress = () => { + this.setState({ + itemSelected: this.state.itemSelected === 2 ? 0 : 2 + }) + const fnProp = this.props.onThumbDownPress + if (fnProp) { + fnProp() + } + } + + render () { + return ( + <> + { + this.state.itemSelected === 1 ? + <> + + + + + + + + : + this.state.itemSelected === 2 ? + <> + + + + + + + + : + <> + + + + + + + + } + + ) + } +} diff --git a/src/features/rewards/thumbLikePicker/spec.tsx b/src/features/rewards/thumbLikePicker/spec.tsx new file mode 100644 index 000000000..bda21a57b --- /dev/null +++ b/src/features/rewards/thumbLikePicker/spec.tsx @@ -0,0 +1,24 @@ +/* global jest, expect, describe, it, afterEach */ +import * as React from 'react' +import { shallow } from 'enzyme' +import { create } from 'react-test-renderer' +import { TestThemeProvider } from '../../../theme' +import ThumbLikePicker from './index'; + +describe('Amount tests', () => { + const baseComponent = (props?: object) => + + describe('basic tests', () => { + it('matches the snapshot', () => { + const component = baseComponent() + const tree = create(component).toJSON() + expect(tree).toMatchSnapshot() + }) + + it('renders the component', () => { + const wrapper = shallow(baseComponent()) + const assertion = wrapper.find('#thumbLikePicker').length + expect(assertion).toBe(1) + }) + }) +}) diff --git a/src/features/rewards/thumbLikePicker/style.ts b/src/features/rewards/thumbLikePicker/style.ts new file mode 100644 index 000000000..c7130e08f --- /dev/null +++ b/src/features/rewards/thumbLikePicker/style.ts @@ -0,0 +1,30 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License. v. 2.0. If a copy of the MPL was not distributed with this file. +* You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import styled from 'styled-components' + +export const StyledAdStatThumbUpIcon = styled<{}, 'div'>('div')` + display: inline-block; + width: 32px; + height: 32px; + padding: 4px; + cursor: pointer; +` + +export const StyledAdStatThumbUpFilledIcon = styled(StyledAdStatThumbUpIcon)` + color: red; +` + +export const StyledAdStatThumbDownIcon = styled<{}, 'div'>('div')` + display: inline-block; + width: 32px; + height: 32px; + margin-top: auto; + padding: 4px; + cursor: pointer; +` + +export const StyledAdStatThumbDownFilledIcon = styled(StyledAdStatThumbDownIcon)` + color: red; +` diff --git a/stories/assets/img/tesla.jpg b/stories/assets/img/tesla.jpg new file mode 100644 index 000000000..c5da80917 Binary files /dev/null and b/stories/assets/img/tesla.jpg differ diff --git a/stories/assets/locale.ts b/stories/assets/locale.ts index 91b9d6585..93d5233e7 100644 --- a/stories/assets/locale.ts +++ b/stories/assets/locale.ts @@ -13,8 +13,20 @@ const locale: Record = { addFundsQR: 'Show QR Code', addFundsText: 'Be sure to use the address below that matches the type of cryto you own. It will be converted automatically to BAT by Uphold and appear as an increased balance in your Brave Rewards wallet. Please allow up to one hour for your wallet balance to update.', addFundsTitle: 'Send cryptocurrency from your external account to your Brave Rewards wallet.', + ads: 'Ads', + adsCurrentlyViewing: 'You\'re currently receiving a maximum of ', adsEarnings: 'earned from ads', + adsHistoryFilterAll: 'All', + adsHistoryFilterSaved: 'Saved', + adsHistorySubTitle: 'Ads you\'ve received in the past 30 days', + adsHistoryTitle: 'Ads History', adsNotSupported: 'Sorry! Ads are not yet available in your region.', + adsPerDayPlural: ' ads per day', + adsPerDaySingular: ' ad per day', + adsPerHourContinuation: ', total ', + adsPerHourPlural: ' ads per hour', + adsPerHourSingular: ' ad per hour', + all: 'All', allowTip: 'Allow tips on', amount: 'Amount', and: 'and', @@ -42,6 +54,7 @@ const locale: Record = { captchaProveHuman: 'Prove that you are human!', captchaTarget: 'target.', captchaMissedTarget: 'Hmm… Not Quite. Try Again.', + category: 'Category', claim: 'Claim', closeBalance: 'Closing Balance', contribute: 'Contribute', @@ -93,6 +106,7 @@ const locale: Record = { learnMore: 'Learn More', makeMonthly: 'Make this monthly', manageWallet: 'Manage Your Wallet', + markAsInappropriate: 'Mark As Inappropriate', monthApr: 'Apr', monthAug: 'August', monthDec: 'December', @@ -110,6 +124,7 @@ const locale: Record = { newGrant: 'A free token grant is available.', newTokenGrant: 'New Token Grant', noActivity: 'No activities yet…', + noAdsHistory: 'There is currently no Brave Ads history', noGrants: 'Currently no token grant is available.', notEnoughTokens: 'Not enough tokens. Please', noThankYou: 'No, thank you', @@ -118,6 +133,7 @@ const locale: Record = { on: 'on', oneTime: 'One time', oneTimeDonation: 'One-time Tips', + openAdsHistory: 'Show Ads History', openBalance: 'Opening Balance', payment: 'Payment', paymentMonthly: 'Payment made every {{day}}th day in each month.', @@ -176,7 +192,9 @@ const locale: Record = { rewardsRestoreText4: 'Enter your recovery key or', rewardsSummary: 'Rewards Summary', rewardsWhy: 'Why Brave Rewards…', + saveAd: 'Save', saveAsFile: 'Save', + saved: 'Saved', seeAllItems: 'See all {{numItems}} items', seeAllSites: 'See all {{numSites}} sites', sendDonation: 'Send my donation', diff --git a/stories/features/rewards/modal.tsx b/stories/features/rewards/modal.tsx index 053d1a975..f58d7431f 100644 --- a/stories/features/rewards/modal.tsx +++ b/stories/features/rewards/modal.tsx @@ -11,7 +11,8 @@ import { withKnobs, text } from '@storybook/addon-knobs' import { DetailRow as ContributeRow } from '../../../src/features/rewards/tableContribute' import { DetailRow as DonationDetailRow } from '../../../src/features/rewards/tableDonation' import { DetailRow as TransactionsRow } from '../../../src/features/rewards/tableTransactions' -import { ModalContribute, ModalBackupRestore, ModalActivity, ModalDonation } from '../../../src/features/rewards' +import { DetailRow as AdsHistoryRow } from '../../../src/features/rewards/tableAdsHistory' +import { ModalContribute, ModalBackupRestore, ModalActivity, ModalDonation, ModalShowAdsHistory } from '../../../src/features/rewards' import ModalAddFunds, { Address } from '../../../src/features/rewards/modalAddFunds' const bart = require('../../assets/img/bartBaker.jpeg') @@ -20,6 +21,7 @@ const wiki = require('../../assets/img/wiki.jpg') const buzz = require('../../assets/img/buzz.jpg') const guardian = require('../../assets/img/guardian.jpg') const eich = require('../../assets/img/eich.jpg') +const tesla = require('../../assets/img/tesla.jpg') const doNothing = () => { console.log('nothing') @@ -441,3 +443,185 @@ storiesOf('Feature Components/Rewards/Modal', module) /> ) }) + .add('Show Ads History',() => { + const adsPerHour = 2 + const adId: number = 0 + const rowId: number = 0 + const rows: AdsHistoryRow[] = [ + { + id: rowId, + date: '1/30', + adDetailRows: [ + { + id: adId, + adContent: { + brand: 'Pepsi', + brandLogo: '', + brandUrl: 'https://www.pepsi.com', + brandDisplayUrl: 'pepsi.com', + brandInfo: 'Animation & VFX Degree - Degree in Animation |', + adAction: 'Viewed', + likeAction: 1, + onThumbUpPress: doNothing, + onThumbDownPress: doNothing, + onMenuFlag: doNothing, + onMenuSave: doNothing, + savedAd: false, + flaggedAd: false + }, + categoryContent: { + category: 'Entertainment', + optAction: 0, + onOptInAction: doNothing, + onOptOutAction: doNothing + } + }, + { + id: adId + 1, + adContent: { + brand: 'TESLA', + brandLogo: '', + brandUrl: 'https://www.tesla.com', + brandDisplayUrl: 'tesla.com', + brandInfo: 'Animation & VFX Degree - Degree in Animation |', + adAction: 'Clicked', + likeAction: 2, + onThumbUpPress: doNothing, + onThumbDownPress: doNothing, + onMenuFlag: doNothing, + onMenuSave: doNothing, + savedAd: false, + flaggedAd: false, + logoUrl: tesla + }, + categoryContent: { + category: 'Auto', + optAction: 0, + onOptInAction: doNothing, + onOptOutAction: doNothing + } + }, + { + id: adId + 2, + adContent: { + brand: 'Disney', + brandLogo: '', + brandUrl: 'https://www.disney.com', + brandDisplayUrl: 'disney.com', + brandInfo: 'Animation & VFX Degree - Degree in Animation |', + adAction: 'Clicked', + likeAction: 0, + onThumbUpPress: doNothing, + onThumbDownPress: doNothing, + onMenuFlag: doNothing, + onMenuSave: doNothing, + savedAd: false, + flaggedAd: false + }, + categoryContent: { + category: 'Travel', + optAction: 0, + onOptInAction: doNothing, + onOptOutAction: doNothing + } + } + ] + }, + { + id: rowId + 1, + date: '1/29', + adDetailRows: [ + { + id: adId + 3, + adContent: { + brand: 'Puma', + brandLogo: '', + brandUrl: 'https://www.puma.com', + brandDisplayUrl: 'puma.com', + brandInfo: 'Animation & VFX Degree - Degree in Animation |', + adAction: 'Viewed', + likeAction: 0, + onThumbUpPress: doNothing, + onThumbDownPress: doNothing, + onMenuFlag: doNothing, + onMenuSave: doNothing, + savedAd: false, + flaggedAd: false + }, + categoryContent: { + category: 'Sports', + optAction: 0, + onOptInAction: doNothing, + onOptOutAction: doNothing + } + }, + { + id: adId + 4, + adContent: { + brand: 'Expedia.com', + brandLogo: '', + brandUrl: 'https://www.expedia.com', + brandDisplayUrl: 'expedia.com', + brandInfo: 'Animation & VFX Degree - Degree in Animation |', + adAction: 'Viewed', + likeAction: 0, + onThumbUpPress: doNothing, + onThumbDownPress: doNothing, + onMenuFlag: doNothing, + onMenuSave: doNothing, + savedAd: false, + flaggedAd: true + }, + categoryContent: { + category: 'Travel', + optAction: 2, + onOptInAction: doNothing, + onOptOutAction: doNothing + } + }, + { + id: adId + 5, + adContent: { + brand: 'H&M', + brandLogo: '', + brandUrl: 'https://www.hm.com', + brandDisplayUrl: 'hm.com', + brandInfo: 'Animation & VFX Degree - Degree in Animation |', + adAction: 'Closed', + likeAction: 0, + onThumbUpPress: doNothing, + onThumbDownPress: doNothing, + onMenuFlag: doNothing, + onMenuSave: doNothing, + savedAd: false, + flaggedAd: false + }, + categoryContent: { + category: 'Fashion', + optAction: 1, + onOptInAction: doNothing, + onOptOutAction: doNothing + } + } + ] + } + ] + return ( + + ) + }) + .add('Show Empty Ads History',() => { + const adsPerHour = 0 + return ( + + ) + })