Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions src/amo/components/CategoriesHeader/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import React from 'react';
import { connect } from 'react-redux';
import { compose } from 'redux';

import { categoriesFetch } from 'core/actions/categories';
import translate from 'core/i18n/translate';
import { getCategoryColor, visibleAddonType } from 'core/utils';
import Button from 'ui/components/Button';
import Card from 'ui/components/Card';
import type { DispatchFunc } from 'core/types/redux';
import LoadingText from 'ui/components/LoadingText';

import './styles.scss';


type CategoriesHeaderProps = {
addonType: string,
dispatch: DispatchFunc,
categories: Object,
clientApp: string,
error: boolean | null,
loading: boolean,
i18n: Object,
}

export class CategoriesHeaderBase extends React.Component {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure there's a bug on file to merge this with src/amo/components/Categories

componentWillMount() {
const { addonType, clientApp, dispatch } = this.props;
const categories = this.props.categories[addonType] || {};

if (!Object.values(categories).length) {
dispatch(categoriesFetch({ addonType, clientApp }));
}
}

props: CategoriesHeaderProps;

render() {
const { addonType, error, loading, i18n } = this.props;
const categories = this.props.categories[addonType] ?
Object.values(this.props.categories[addonType]) : [];

if (error) {
return (
<Card className="CategoriesHeader">
<p>{i18n.gettext('Failed to load categories.')}</p>
</Card>
);
}

if (!loading && !categories.length) {
return (
<Card className="CategoriesHeader">
<p>{i18n.gettext('No categories found.')}</p>
</Card>
);
}

return (
<Card className="CategoriesHeader" header={i18n.gettext('Categories')}>
{loading ?
<div className="CategoriesHeader-loading">
<span className="CategoriesHeader-loading-info visually-hidden">
{i18n.gettext('Loading categories.')}
</span>
{Array(8).fill(0).map((value, index) => {
return (
<LoadingText
className="CategoriesHeader-loading-text"
key={`CategoriesHeader-loading-text-${index}`}
maxWidth={20}
range={3}
/>
);
})}
</div>
:
<ul className="CategoriesHeader-list">
{categories.map((category, index) => (
<li
className="CategoriesHeader-item"
key={`category-${index}`}
>
<Button
className={`CategoriesHeader-link Button--action
Button--small
CategoriesHeader--category-color-${getCategoryColor(category)}`}
to={`/${visibleAddonType(addonType)}/${category.slug}/`}
>
{category.name}
</Button>
</li>
))}
</ul>
}
</Card>
);
}
}

export function mapStateToProps(state) {
const clientApp = state.api.clientApp;
const categories = state.categories.categories[clientApp];

return {
categories,
clientApp,
error: state.categories.error,
loading: state.categories.loading,
};
}

export default compose(
connect(mapStateToProps),
translate({ withRef: true }),
)(CategoriesHeaderBase);
38 changes: 38 additions & 0 deletions src/amo/components/CategoriesHeader/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@import "~amo/css/inc/vars";
@import "~core/css/inc/mixins";
@import "~ui/css/vars";

.CategoriesHeader .Card-contents {
display: flex;
}

.CategoriesHeader-loadingText {
@include margin-end(5px);
}

.CategoriesHeader-list {
display: block;
list-style: none;
margin: 0 auto;
padding: 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a couple instances of padding: 0 and margin: 0 in this patch. Are all those necessary? It didn't seem like they were necessary for overrides.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're for ul and li items which have default styles. Not sure where we're declaring those but they do exist 😒

}

.CategoriesHeader-item {
@include margin-end(5px);

display: inline-block;
margin: 0 0 5px;
padding: 0;
}

@for $i from 1 through 12 {
.CategoriesHeader--category-color-#{$i} {
background: desaturate(nth($category-colors, $i), 20);
}
}

@for $i from 1 through 10 {
.CategoriesHeader--type-extension.CategoriesHeader--category-color-#{$i} {
background: desaturate(nth($category-colors-extensions, $i), 20);
}
}
58 changes: 0 additions & 58 deletions src/amo/components/LandingPage.scss

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { connect } from 'react-redux';
import { setViewContext } from 'amo/actions/viewContext';
import LandingAddonsCard from 'amo/components/LandingAddonsCard';
import NotFound from 'amo/components/ErrorPage/NotFound';
import CategoriesHeader
from 'amo/components/CategoriesHeader';
import { loadLandingAddons } from 'amo/utils';
import {
ADDON_TYPE_EXTENSION,
Expand All @@ -22,12 +24,17 @@ import {
visibleAddonType as getVisibleAddonType,
} from 'core/utils';
import translate from 'core/i18n/translate';
import Button from 'ui/components/Button/index';
import Button from 'ui/components/Button';
import Icon from 'ui/components/Icon/index';

import './LandingPage.scss';
import './styles.scss';


const ICON_MAP = {
[ADDON_TYPE_EXTENSION]: 'multitasking-octopus',
[ADDON_TYPE_THEME]: 'artistic-unicorn',
};

export class LandingPageBase extends React.Component {
static propTypes = {
apiAddonType: PropTypes.func.isRequired,
Expand Down Expand Up @@ -126,6 +133,18 @@ export class LandingPageBase extends React.Component {
return { addonType, html: contentForTypes[addonType] };
}

icon(addonType) {
return (
<Icon
className={classNames(
'LandingPage-icon',
`LandingPage-icon--${addonType}`,
)}
name={ICON_MAP[addonType]}
/>
);
}

render() {
const {
featuredAddons,
Expand Down Expand Up @@ -159,37 +178,35 @@ export class LandingPageBase extends React.Component {
};
const contentText = {
[ADDON_TYPE_THEME]: i18n.gettext(
"Change your browser's appearance. Choose from thousands of themes to give Firefox the look you want."),
"Change your browser's appearance. Choose from thousands of themes to give Firefox the look you want."),
[ADDON_TYPE_EXTENSION]: i18n.gettext(
'Install powerful tools that make browsing faster and safer, add-ons make your browser yours.'),
'Install powerful tools that make browsing faster and safer, add-ons make your browser yours.'),
};

return (
<div className={classNames('LandingPage', `LandingPage-${addonType}`)}>
<div className={classNames('LandingPage', `LandingPage--${addonType}`)}>
<div className="LandingPage-header">
<div className="LandingPage-header-top">
<Icon name={visibleAddonType} />
<div className="LandingPage-header-text">
<h1 className="LandingPage-heading">
{headingText[addonType]}
</h1>
<p className="LandingPage-heading-content">
{contentText[addonType]}
</p>
</div>
</div>

<div className="LandingPage-header-bottom">
<Button
className="LandingPage-browse-button Button--light"
to={`/${visibleAddonType}/categories/`}
>
<Icon name="browse" className="LandingPage-browse-icon" />
{i18n.gettext('Browse by category')}
</Button>
{this.icon(addonType)}

<div className="LandingPage-header-text">
<h1 className="LandingPage-addonType-name">
{headingText[addonType]}
</h1>
<p className="LandingPage-heading-content">
{contentText[addonType]}
</p>
</div>
</div>

<CategoriesHeader addonType={addonType} />

<Button
className="LandingPage-button Button--light"
to={`/${getVisibleAddonType(addonType)}/categories/`}
>
{i18n.gettext('Explore all categories')}
</Button>

<LandingAddonsCard addons={featuredAddons}
className="FeaturedAddons" header={html.featuredHeader}
footerLink={html.featuredFooterLink}
Expand Down
61 changes: 61 additions & 0 deletions src/amo/components/LandingPage/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
@import "~amo/css/inc/vars";
@import "~core/css/inc/mixins";

.LandingPage {
padding: $padding-page;
}

.LandingPage-icon--persona {
@include margin-end(20px);
}

.LandingPage-header {
align-items: center;
display: flex;
flex-direction: row;
font-size: $font-size-default;
justify-content: center;
margin: $padding-page auto ($padding-page * 2);
max-width: 600px;
}

.LandingPage-button {
display: block;

@include respond-to(medium) {
display: none;
}
}

.LandingPage-icon {
height: 89px;
width: 225px;

@include respond-to(medium) {
height: 178px;
width: 450px;
}
}

.LandingPage-addonType-name {
font-size: $font-size-l;
margin: 0;

@include respond-to(medium) {
font-size: $font-size-xl;
}
}

.LandingPage-heading-content {
font-size: $font-size-s;
margin: 0;
max-width: 480px;
}

.LandingPage .CategoriesHeader {
display: none;

@include respond-to(medium) {
display: block;
}
}
2 changes: 2 additions & 0 deletions src/ui/components/Button/Button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
$background-hover: $light-hover-color,
$color: $type-black
);

text-shadow: none;
}

.Button--action {
Expand Down
Loading