1
0
mirror of https://github.com/oceanprotocol/commons.git synced 2023-03-15 18:03:00 +01:00

channel teaser component, use on channels page

This commit is contained in:
Matthias Kretschmann 2019-05-23 17:47:13 +02:00
parent 1000185841
commit 1b7d343984
Signed by: m
GPG Key ID: 606EEEF3C479A91F
8 changed files with 184 additions and 138 deletions

View File

@ -6,7 +6,7 @@ import cx from 'classnames'
import styles from './Asset.module.scss' import styles from './Asset.module.scss'
import CategoryImage from '../atoms/CategoryImage' import CategoryImage from '../atoms/CategoryImage'
const AssetLink = ({ const Asset = ({
asset, asset,
list, list,
minimal minimal
@ -55,4 +55,4 @@ const AssetLink = ({
) )
} }
export default AssetLink export default Asset

View File

@ -0,0 +1,56 @@
@import '../../styles/variables';
.channel {
width: 100%;
padding-top: $spacer * 2;
@media (min-width: $break-point--medium) {
display: flex;
}
> div {
&:first-child {
margin-right: $spacer;
margin-bottom: $spacer;
p {
margin-bottom: 0;
}
}
@media (min-width: $break-point--medium) {
flex: 1;
&:first-child {
flex: 0 0 24.5rem;
}
}
}
h3 {
font-size: $font-size-h4;
}
+ .channel {
border-top: 1px solid $brand-grey-lighter;
margin-top: $spacer * 2;
}
}
.channelTitle {
margin-top: $spacer * 2;
}
.channelResults {
display: grid;
grid-template-columns: 1fr;
grid-gap: $spacer;
@media (min-width: $break-point--small) {
grid-template-columns: repeat(2, 1fr);
}
> article {
min-width: calc(18rem + #{$spacer * 2.3});
}
}

View File

@ -0,0 +1,98 @@
import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import { User } from '../../context'
import { Logger } from '@oceanprotocol/squid'
import Spinner from '../atoms/Spinner'
import Asset from '../molecules/Asset'
import styles from './ChannelTeaser.module.scss'
import channels from '../../data/channels.json'
interface ChannelTeaserProps {
channel: string
}
interface ChannelTeaserState {
channelAssets?: any[]
isLoadingChannel?: boolean
}
export default class ChannelTeaser extends Component<
ChannelTeaserProps,
ChannelTeaserState
> {
public static contextType = User
// Get channel content
public channel = channels.items
.filter(({ slug }) => slug === this.props.channel)
.map(channel => channel)[0]
public state = {
channelAssets: [],
isLoadingChannel: true
}
public async componentDidMount() {
this.getChannelAssets()
}
private getChannelAssets = async () => {
const { ocean } = this.context
const searchQuery = {
offset: 4,
page: 1,
query: {
// TODO: replace dummy category
// categories: [this.channel.title],
categories: ['Engineering'],
price: [-1, 1]
},
sort: {
datePublished: 1
}
}
try {
const search = await ocean.aquarius.queryMetadata(searchQuery)
this.setState({
channelAssets: search.results,
isLoadingChannel: false
})
} catch (error) {
Logger.error(error.message)
this.setState({ isLoadingChannel: false })
}
}
public render() {
const { channelAssets, isLoadingChannel } = this.state
const { title, slug, teaser } = this.channel
return (
<div className={styles.channel}>
<div>
<div>
<h2 className={styles.channelTitle}>
<Link to={`/channels/${slug}`}>{title} </Link>
</h2>
<p>{teaser}</p>
</div>
</div>
<div>
{isLoadingChannel ? (
<Spinner message="Loading..." />
) : channelAssets && channelAssets.length ? (
<div className={styles.channelResults}>
{channelAssets.map((asset: any) => (
<Asset key={asset.id} asset={asset} />
))}
</div>
) : (
<div>No data sets found.</div>
)}
</div>
</div>
)
}
}

View File

@ -11,6 +11,7 @@
{ {
"title": "Test Channel", "title": "Test Channel",
"slug": "test-channel", "slug": "test-channel",
"teaser": "Hello teaser.",
"description": "Hello description." "description": "Hello description."
} }
] ]

View File

@ -0,0 +1,15 @@
import React from 'react'
import { BrowserRouter as Router } from 'react-router-dom'
import { render } from 'react-testing-library'
import Channels from './Channels'
describe('Channels', () => {
it('renders without crashing', () => {
const { container } = render(
<Router>
<Channels />
</Router>
)
expect(container.firstChild).toBeInTheDocument()
})
})

View File

@ -2,22 +2,19 @@ import React, { Component } from 'react'
import Route from '../components/templates/Route' import Route from '../components/templates/Route'
import Content from '../components/atoms/Content' import Content from '../components/atoms/Content'
import channels from '../data/channels.json' import channels from '../data/channels.json'
import { Link } from 'react-router-dom' import ChannelTeaser from '../components/organisms/ChannelTeaser'
class Channels extends Component { class Channels extends Component {
public render() { public render() {
return ( return (
<Route title={channels.title} description={channels.description}> <Route title={channels.title} description={channels.description}>
<Content> <Content wide>
<ul> {channels.items.map(channel => (
{channels.items.map(channel => ( <ChannelTeaser
<li key={channel.title}> key={channel.title}
<Link to={`/channels/${channel.slug}`}> channel={channel.slug}
{channel.title} />
</Link> ))}
</li>
))}
</ul>
</Content> </Content>
</Route> </Route>
) )

View File

@ -14,56 +14,6 @@
} }
} }
.channel {
width: 100%;
padding-top: $spacer * 2;
@media (min-width: $break-point--medium) {
display: flex;
}
> div {
&:first-child {
margin-right: $spacer;
margin-bottom: $spacer;
p {
margin-bottom: 0;
}
}
@media (min-width: $break-point--medium) {
flex: 1;
&:first-child {
flex: 0 0 24.5rem;
}
}
}
h3 {
font-size: $font-size-h4;
}
}
.channelTitle {
margin-top: $spacer * 2;
}
.channelResults {
display: grid;
grid-template-columns: 1fr;
grid-gap: $spacer;
@media (min-width: $break-point--small) {
grid-template-columns: repeat(2, 1fr);
}
> article {
min-width: calc(18rem + #{$spacer * 2.3});
}
}
.title { .title {
font-size: $font-size-h3; font-size: $font-size-h3;
margin-top: $spacer * 2; margin-top: $spacer * 2;

View File

@ -1,9 +1,6 @@
import React, { ChangeEvent, Component, FormEvent } from 'react' import React, { ChangeEvent, Component, FormEvent } from 'react'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import { User, Market } from '../context' import { User, Market } from '../context'
import { Logger } from '@oceanprotocol/squid'
import Spinner from '../components/atoms/Spinner'
import Asset from '../components/molecules/Asset'
import CategoryImage from '../components/atoms/CategoryImage' import CategoryImage from '../components/atoms/CategoryImage'
import Button from '../components/atoms/Button' import Button from '../components/atoms/Button'
import Form from '../components/atoms/Form/Form' import Form from '../components/atoms/Form/Form'
@ -14,14 +11,8 @@ import styles from './Home.module.scss'
import meta from '../data/meta.json' import meta from '../data/meta.json'
import { History } from 'history' import { History } from 'history'
import Content from '../components/atoms/Content' import Content from '../components/atoms/Content'
import channels from '../data/channels.json'
import AssetsLatest from '../components/organisms/AssetsLatest' import AssetsLatest from '../components/organisms/AssetsLatest'
import ChannelTeaser from '../components/organisms/ChannelTeaser'
// AI for Good channel
const channel = channels.items
.filter(({ slug }) => slug === 'ai-for-good')
.map(channel => channel)[0]
const { title, slug, teaser } = channel
interface HomeProps { interface HomeProps {
history: History history: History
@ -29,50 +20,13 @@ interface HomeProps {
interface HomeState { interface HomeState {
search?: string search?: string
channelAssets?: any[]
isLoadingChannel?: boolean
} }
export default class Home extends Component<HomeProps, HomeState> { export default class Home extends Component<HomeProps, HomeState> {
public static contextType = User public static contextType = User
public state = { public state = {
search: '', search: ''
channelAssets: [],
isLoadingChannel: true
}
public async componentDidMount() {
this.getChannelAssets()
}
private getChannelAssets = async () => {
const { ocean } = this.context
const searchQuery = {
offset: 4,
page: 1,
query: {
// TODO: remove dummy category
// categories: [title],
categories: ['Engineering'],
price: [-1, 1]
},
sort: {
datePublished: 1
}
}
try {
const search = await ocean.aquarius.queryMetadata(searchQuery)
this.setState({
channelAssets: search.results,
isLoadingChannel: false
})
} catch (error) {
Logger.error(error.message)
this.setState({ isLoadingChannel: false })
}
} }
private inputChange = (event: ChangeEvent<HTMLInputElement>) => { private inputChange = (event: ChangeEvent<HTMLInputElement>) => {
@ -87,7 +41,7 @@ export default class Home extends Component<HomeProps, HomeState> {
} }
public render() { public render() {
const { channelAssets, isLoadingChannel, search } = this.state const { search } = this.state
return ( return (
<Route <Route
@ -114,32 +68,7 @@ export default class Home extends Component<HomeProps, HomeState> {
</Content> </Content>
<Content wide> <Content wide>
<div className={styles.channel}> <ChannelTeaser channel="ai-for-good" />
<div>
<div>
<h2 className={styles.channelTitle}>
<Link to={`/channels/${slug}`}>
{title}
</Link>
</h2>
<p>{teaser}</p>
</div>
</div>
<div>
{isLoadingChannel ? (
<Spinner message="Loading..." />
) : channelAssets && channelAssets.length ? (
<div className={styles.channelResults}>
{channelAssets.map((asset: any) => (
<Asset key={asset.id} asset={asset} />
))}
</div>
) : (
<div>No data sets found.</div>
)}
</div>
</div>
<AssetsLatest /> <AssetsLatest />
</Content> </Content>