Skip to content

Commit

Permalink
Merge pull request #166 from taylrj/add-podcast-section
Browse files Browse the repository at this point in the history
feat(index-page): add podcast box section
  • Loading branch information
taylrj authored Jan 19, 2021
2 parents 69d8879 + b0ac4be commit 97eb707
Show file tree
Hide file tree
Showing 8 changed files with 278 additions and 18 deletions.
1 change: 1 addition & 0 deletions packages/index-page/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"dependencies": {
"@twreporter/core": "^1.2.1",
"@twreporter/react-components": "^8.3.8",
"lodash": "^4.0.0",
"prop-types": "^15.0.0",
"react": "^16.3.0",
Expand Down
154 changes: 154 additions & 0 deletions packages/index-page/src/components/podcast-box-section.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { finalMedia } from '../utils/style-utils'
import { sourceHanSansTC as fontWeight } from '@twreporter/core/lib/constants/font-weight'
import ArrowIcon from '../static/icon-podcast-arrow-white.svg'
import PodcastLandingPageLinkWithUtm from '@twreporter/react-components/lib/podcast-link-with-utm'
import React from 'react'
import app from '../constants/app'
import styled from 'styled-components'

const mockup = {
defaultWidth: 320,
contentWidth: 238,
}

const mobileContentWidthPct = (mockup.contentWidth / mockup.defaultWidth) * 100

const Container = styled.div`
background-image: url(${app.assetsPath}/PodcastBox_Desktop.jpg);
background-size: contain;
padding-top: 30px;
padding-bottom: 30px;
${finalMedia.mobile`
background-image: url(${app.assetsPath}/PodcastBox_Mobile.jpg);
padding-top: 40px;
padding-bottom: 60px;
`}
${finalMedia.tablet`
background-image: url(${app.assetsPath}/PodcastBox_Tablet.jpg);
`}
${finalMedia.overDesktop`
background-image: url(${app.assetsPath}/PodcastBox_DesktopHD.jpg);
`}
`

const ContentContainer = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
max-width: 1024px;
margin: 0 auto;
padding: 0 100px;
color: #000;
/* ff-tisa-web-prop is for english text */
font-family: ff-tisa-web-pro, source-han-sans-traditional, sans-serif;
h3{
margin: 0;
font-size: 32px;
font-weight: ${fontWeight.bold};
line-height: 1.63;
}
p{
margin-top: 10px;
font-size: 14px;
line-height: 1.57;
text-align: left;
}
${finalMedia.overDesktop`
max-width: 1440px;
padding: 0 219px;
`}
${finalMedia.tablet`
position: relative;
padding: 0 110px;
p{
margin-top: 17px;
}
`}
${finalMedia.mobile`
max-width: ${mobileContentWidthPct}%;
display: block;
text-align: center;
padding: 0;
h3{
font-size: 24px;
line-height: 2.17;
}
p{
margin-top: 0;
}
`}
`

const ListenButton = styled.div`
a {
width: 116px;
height: 40px;
border-radius: 20px;
background: #a67a44;
border: none;
color: #ffffff;
font-size: 16px;
cursor: pointer;
display: table;
${finalMedia.tablet`
position: absolute;
right: 110px;
top: 9px;
`}
${finalMedia.mobile`
margin: 40px auto 0 auto;
`}
span {
display: table-cell;
vertical-align: middle;
text-align: center;
font-weight: ${fontWeight.bold};
}
}
`

const TextColumn = styled.div`
${finalMedia.desktop`
max-width: 608px;
`}
`

const Icon = styled.div`
display: inline-block;
margin-left: 8.6px;
width: 7px;
height: 12px;
`

const listenNow = (
<span>
立即收聽
<Icon>
<ArrowIcon />
</Icon>
</span>
)

class PodcastBoxSection extends React.PureComponent {
render() {
return (
<Container>
<ContentContainer>
<TextColumn>
<h3>聽Podcast,感受真實</h3>
<p>
報導者Podcast節目,透過記者、事件當事人的第一手告白,和來自現場的收音紀錄,帶你走進新聞幕後、故事現場,感受更完整的真實。
</p>
</TextColumn>
<ListenButton>
<PodcastLandingPageLinkWithUtm utmMedium="index">
{listenNow}
</PodcastLandingPageLinkWithUtm>
</ListenButton>
</ContentContainer>
</Container>
)
}
}

export default PodcastBoxSection
1 change: 1 addition & 0 deletions packages/index-page/src/constants/app.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export default {
url: 'https://twreporter.org',
assetsPath: 'https://www.twreporter.org/images/index-page',
domain: '',
expirationDays: 0,
title: '',
Expand Down
4 changes: 3 additions & 1 deletion packages/index-page/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import LatestSection from './components/latest-section'
import LatestTopicSection from './components/latest-topic'
import NewsLetterSection from './components/news-letter-section'
import PhotographySection from './components/photography-section'
import PodcastBoxSection from './components/podcast-box-section'
import ReporterIntro from './components/reporter-intro'
import ReviewsSection from './components/reviews'
import ScrollFadein from './components/animations/scroll-fadein'
Expand All @@ -18,10 +19,11 @@ export default {
DonationBoxSection,
EditorPicks,
InforgraphicSection,
LatestTopicSection,
LatestSection,
LatestTopicSection,
NewsLetterSection,
PhotographySection,
PodcastBoxSection,
ReporterIntro,
ReviewsSection,
ScrollFadein,
Expand Down
24 changes: 24 additions & 0 deletions packages/index-page/src/static/icon-podcast-arrow-white.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 18 additions & 17 deletions packages/react-components/src/donation-link-with-utm.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/* eslint node/no-deprecated-api: "warn" */
import PropTypes from 'prop-types'
import React from 'react'
import url from 'url'
import externalLinks from '@twreporter/core/lib/constants/external-links'
import linkWithParams from './utils/link-with-params'

export default class DonationLinkWithUtm extends React.PureComponent {
static propTypes = {
Expand All @@ -23,27 +22,29 @@ export default class DonationLinkWithUtm extends React.PureComponent {
})
}

getLinkWithSearchParams(originalUrl) {
const { utmSource, utmMedium, utmCampaign } = this.props
try {
const params = {
utm_source: utmSource || window.location.host,
utm_medium: utmMedium,
utm_campaign: utmCampaign || window.location.pathname,
}
return linkWithParams(originalUrl, params)
} catch (e) {
console.warn('Can not get donation url with utm param', e)
return originalUrl
}
}

render() {
const { className, children, utmMedium } = this.props
const { className, children } = this.props
const { isClient } = this.state
let donationURL = externalLinks.donation

if (isClient) {
// client side rendering
try {
const utmSource = this.props.utmSource || window.location.host
const utmCampaign = this.props.utmCampaign || window.location.pathname
const parseQueryString = true
const urlObj = url.parse(donationURL, parseQueryString)

urlObj.query.utm_source = utmSource
urlObj.query.utm_medium = utmMedium
urlObj.query.utm_campaign = utmCampaign

donationURL = url.format(urlObj)
} catch (e) {
console.warn('Can not get donation url with utm param', e)
}
donationURL = this.getLinkWithSearchParams(donationURL)
}

return (
Expand Down
61 changes: 61 additions & 0 deletions packages/react-components/src/podcast-link-with-utm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import PropTypes from 'prop-types'
import React from 'react'
import linkWithParams from './utils/link-with-params'

// TODO(taylrj): update to the topic landing page link
const podcastTopicLandingPageLink = 'https://www.twreporter.org/a/podcast-list'

class PodcastLandingPageLinkWithUtm extends React.PureComponent {
static propTypes = {
children: PropTypes.node,
utmMedium: PropTypes.string,
utmSource: PropTypes.string,
utmCampaign: PropTypes.string,
}

state = {
isClient: false,
}

componentDidMount() {
this.setState({
isClient: true,
})
}

getLinkWithSearchParams(originalUrl) {
const { utmSource, utmMedium, utmCampaign } = this.props
try {
const params = {
utm_source: utmSource || window.location.host,
utm_medium: utmMedium,
utm_campaign: utmCampaign,
}
return linkWithParams(originalUrl, params)
} catch (e) {
console.warn('Can not get podcast landing page url with utm param', e)
return originalUrl
}
}

render() {
const { children } = this.props
const { isClient } = this.state
let podcastLandingPageURL = podcastTopicLandingPageLink

if (isClient) {
// client side rendering
podcastLandingPageURL = this.getLinkWithSearchParams(
podcastLandingPageURL
)
}

return (
<a href={podcastLandingPageURL} target="_blank" rel="noopener noreferrer">
{children}
</a>
)
}
}

export default PodcastLandingPageLinkWithUtm
16 changes: 16 additions & 0 deletions packages/react-components/src/utils/link-with-params.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import url from 'url'

/**
* @param { string } originalUrl - The original url
* @param { Object } params - search params to be set
* @return { string } originalUrl with search params
*/
export default function linkWithParams(originalUrl, params) {
const urlObj = new URL(originalUrl)
for (let key in params) {
if (params[key]) {
urlObj.searchParams.set(key, params[key])
}
}
return url.format(urlObj)
}

0 comments on commit 97eb707

Please sign in to comment.