diff --git a/src/components/MainSiteArticleHeader/MainSiteByline.tsx b/src/components/MainSiteArticleHeader/MainSiteByline.tsx new file mode 100644 index 00000000..1179e011 --- /dev/null +++ b/src/components/MainSiteArticleHeader/MainSiteByline.tsx @@ -0,0 +1,132 @@ +// support for multiple authors +import * as React from 'react' +import { css } from 'react-emotion' +import { MainSiteArticleHeaderProps, BylineInfo } from './index' +import dbLogo from './db-logo.png' +import { + headlineFont, + boldFont, + dailyBruinBlue, + subInfoFontSize, + smallInfoFontSize, + darkGray, +} from '../../globals/mainsiteGlobalStyles' + +export default function MainSiteByline(props: MainSiteArticleHeaderProps) { + const rawDate = new Date(props.date) + const renderedDate = rawDate.toLocaleDateString('default', { + day: 'numeric', + month: 'long', + year: 'numeric', + }) + // first check if there's only one author with a profile photo + if (props.bylineInfo.length === 1) { + const photoURL = props.bylineInfo[0].authorPhotoURL + ? props.bylineInfo[0].authorPhotoURL + : dbLogo + return ( +
+ +
+
+ By{' '} + + {props.bylineInfo[0].authorName} + +
+
+ {renderedDate} +
+
+
+ ) + } else { + const renderedByline = props.bylineInfo.map( + (element: BylineInfo, index: number) => { + let delimiter = index ? ', ' : '' + if (index === props.bylineInfo.length - 1) { + delimiter = ' and ' + } + return ( + + {delimiter} + + {element.authorName} + + + ) + } + ) + return ( +
+ By {renderedByline} +
+ {renderedDate} +
+
+ ) + } +} diff --git a/src/components/MainSiteArticleHeader/MainSiteHeadline.tsx b/src/components/MainSiteArticleHeader/MainSiteHeadline.tsx new file mode 100644 index 00000000..646b99a1 --- /dev/null +++ b/src/components/MainSiteArticleHeader/MainSiteHeadline.tsx @@ -0,0 +1,52 @@ +import * as React from 'react' +import { css } from 'react-emotion' +import { MainSiteArticleHeaderProps } from './index' + +import { + headlineFont, + headlineFontSize, + boldFont, + topBarFont, + dailyBruinBlue, + smallInfoFontSize, +} from '../../globals/mainsiteGlobalStyles' + +export default function MainSiteHeadline(props: MainSiteArticleHeaderProps) { + return ( +
+
+ + {props.articleCategory} + +
+
+ {props.headlineText} +
+
+ ) +} diff --git a/src/components/MainSiteArticleHeader/db-logo.png b/src/components/MainSiteArticleHeader/db-logo.png new file mode 100644 index 00000000..69de711b Binary files /dev/null and b/src/components/MainSiteArticleHeader/db-logo.png differ diff --git a/src/components/MainSiteArticleHeader/index.mdx b/src/components/MainSiteArticleHeader/index.mdx new file mode 100644 index 00000000..9c06c86c --- /dev/null +++ b/src/components/MainSiteArticleHeader/index.mdx @@ -0,0 +1,72 @@ +--- +name: Main Site Article Header +route: /main-site-article-header +--- + +import { Playground, Props } from 'docz' +import MainSiteArticleHeader from '.' +import { css } from 'react-emotion' + +# Main Site Article Header + +This header goes at the top of all main site articles. Below you'll find a diagram that relates enum to the appearance of the layout. + +TODO: add that image + + + +## One author + + + + + + +## Multiple authors + + + + diff --git a/src/components/MainSiteArticleHeader/index.tsx b/src/components/MainSiteArticleHeader/index.tsx new file mode 100644 index 00000000..772347b7 --- /dev/null +++ b/src/components/MainSiteArticleHeader/index.tsx @@ -0,0 +1,120 @@ +import * as React from 'react' +import { css } from 'react-emotion' +import MainSiteByline from './MainSiteByline' +import MainSiteHeadline from './MainSiteHeadline' + +import { + bodyFont, + dailyBruinBlue, + smallInfoFontSize, +} from '../../globals/mainsiteGlobalStyles' + +export enum MainSiteArticleHeaderLayoutType { + Standard, + VerticalPhoto, + WidePhoto, + ExtraWidePhoto, +} + +export interface BylineInfo { + /** Author that contributed to the article */ + authorName: string + /** Link to their profile image URL - optional */ + authorPhotoURL?: string + /** URL to their profile page on the main site */ + authorProfileURL: string +} + +export interface CreditInfo { + /** staff name */ + imageCredit: string + /** staff position */ + imagePosition: string + /** profile link */ + imageCreditProfileURL: string +} + +export interface MainSiteArticleHeaderProps { + /** text of the headline */ + headlineText: string + /** category that the headline is in */ + articleCategory: string + /** URL of the category page that the article is in */ + categoryURL: string + /** URL of the main photo that should be displayed */ + featuredPhotoURL?: string + /** caption for the featured photo */ + featuredPhotoCaption?: string + /** credit info for the photo */ + featuredPhotoCredit?: CreditInfo + /** info that should be displayed in the byline box */ + bylineInfo: BylineInfo[] + /** date that the article was published */ + date: string +} + +class MainSiteArticleHeader extends React.Component< + MainSiteArticleHeaderProps +> { + public render() { + let featuredPhoto + // check to see if there's a featured photo for this story + if (this.props.featuredPhotoURL) { + featuredPhoto = ( +
+ +
+ {this.props.featuredPhotoCaption}{' '} + + ({this.props.featuredPhotoCredit.imageCredit}/ + {this.props.featuredPhotoCredit.imagePosition}) + +
+
+ ) + } + return ( +
+ + {featuredPhoto} + +
+ ) + } +} + +export default MainSiteArticleHeader diff --git a/src/globals/mainsiteGlobalStyles.tsx b/src/globals/mainsiteGlobalStyles.tsx index 38235cad..0522823d 100644 --- a/src/globals/mainsiteGlobalStyles.tsx +++ b/src/globals/mainsiteGlobalStyles.tsx @@ -22,6 +22,8 @@ export const gray = 'rgb(197, 197, 197)' export const lightGray = 'rgb(242, 242, 242)' export const black = '#000' export const white = '#fff' +export const darkGray = 'rgb(100, 100, 100)' +export const dailyBruinBlue = '#0080C6' export const headlineFont = 'Arimo' export const storyListFont = 'Lora' export const bodyFont = 'PT Serif' @@ -30,6 +32,9 @@ export const boldFont = 700 export const topBarFont = 'Source Sans Pro' export const cardInnerPadding = '11px 14px 15px' export const cardShadow = '0px 2px 4px 0px rgba(0,0,0,0.2)' +export const headlineFontSize = '2em' +export const subInfoFontSize = '1em' +export const smallInfoFontSize = '0.8em' /** CSS breakpoints */ export const mediaMobileBreakpoint = '@media (max-width: 600px)'