From 1b7d34398490a14a0fd62db7b28e54dab14acc30 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Thu, 23 May 2019 17:47:13 +0200 Subject: [PATCH] channel teaser component, use on channels page --- client/src/components/molecules/Asset.tsx | 4 +- .../organisms/ChannelTeaser.module.scss | 56 +++++++++++ .../components/organisms/ChannelTeaser.tsx | 98 +++++++++++++++++++ client/src/data/channels.json | 1 + client/src/routes/Channels.test.tsx | 15 +++ client/src/routes/Channels.tsx | 19 ++-- client/src/routes/Home.module.scss | 50 ---------- client/src/routes/Home.tsx | 79 +-------------- 8 files changed, 184 insertions(+), 138 deletions(-) create mode 100644 client/src/components/organisms/ChannelTeaser.module.scss create mode 100644 client/src/components/organisms/ChannelTeaser.tsx create mode 100644 client/src/routes/Channels.test.tsx diff --git a/client/src/components/molecules/Asset.tsx b/client/src/components/molecules/Asset.tsx index a84251d..8c2d903 100644 --- a/client/src/components/molecules/Asset.tsx +++ b/client/src/components/molecules/Asset.tsx @@ -6,7 +6,7 @@ import cx from 'classnames' import styles from './Asset.module.scss' import CategoryImage from '../atoms/CategoryImage' -const AssetLink = ({ +const Asset = ({ asset, list, minimal @@ -55,4 +55,4 @@ const AssetLink = ({ ) } -export default AssetLink +export default Asset diff --git a/client/src/components/organisms/ChannelTeaser.module.scss b/client/src/components/organisms/ChannelTeaser.module.scss new file mode 100644 index 0000000..a8ef892 --- /dev/null +++ b/client/src/components/organisms/ChannelTeaser.module.scss @@ -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}); + } +} diff --git a/client/src/components/organisms/ChannelTeaser.tsx b/client/src/components/organisms/ChannelTeaser.tsx new file mode 100644 index 0000000..8479887 --- /dev/null +++ b/client/src/components/organisms/ChannelTeaser.tsx @@ -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 ( +
+
+
+

+ {title} → +

+

{teaser}

+
+
+
+ {isLoadingChannel ? ( + + ) : channelAssets && channelAssets.length ? ( +
+ {channelAssets.map((asset: any) => ( + + ))} +
+ ) : ( +
No data sets found.
+ )} +
+
+ ) + } +} diff --git a/client/src/data/channels.json b/client/src/data/channels.json index 39f6f9e..4f5b122 100644 --- a/client/src/data/channels.json +++ b/client/src/data/channels.json @@ -11,6 +11,7 @@ { "title": "Test Channel", "slug": "test-channel", + "teaser": "Hello teaser.", "description": "Hello description." } ] diff --git a/client/src/routes/Channels.test.tsx b/client/src/routes/Channels.test.tsx new file mode 100644 index 0000000..4330b45 --- /dev/null +++ b/client/src/routes/Channels.test.tsx @@ -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( + + + + ) + expect(container.firstChild).toBeInTheDocument() + }) +}) diff --git a/client/src/routes/Channels.tsx b/client/src/routes/Channels.tsx index b60d957..7565d20 100644 --- a/client/src/routes/Channels.tsx +++ b/client/src/routes/Channels.tsx @@ -2,22 +2,19 @@ import React, { Component } from 'react' import Route from '../components/templates/Route' import Content from '../components/atoms/Content' import channels from '../data/channels.json' -import { Link } from 'react-router-dom' +import ChannelTeaser from '../components/organisms/ChannelTeaser' class Channels extends Component { public render() { return ( - -
    - {channels.items.map(channel => ( -
  • - - {channel.title} - -
  • - ))} -
+ + {channels.items.map(channel => ( + + ))}
) diff --git a/client/src/routes/Home.module.scss b/client/src/routes/Home.module.scss index 6454896..3dbd40e 100644 --- a/client/src/routes/Home.module.scss +++ b/client/src/routes/Home.module.scss @@ -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 { font-size: $font-size-h3; margin-top: $spacer * 2; diff --git a/client/src/routes/Home.tsx b/client/src/routes/Home.tsx index 36a85da..211edbd 100644 --- a/client/src/routes/Home.tsx +++ b/client/src/routes/Home.tsx @@ -1,9 +1,6 @@ import React, { ChangeEvent, Component, FormEvent } from 'react' import { Link } from 'react-router-dom' 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 Button from '../components/atoms/Button' import Form from '../components/atoms/Form/Form' @@ -14,14 +11,8 @@ import styles from './Home.module.scss' import meta from '../data/meta.json' import { History } from 'history' import Content from '../components/atoms/Content' -import channels from '../data/channels.json' import AssetsLatest from '../components/organisms/AssetsLatest' - -// AI for Good channel -const channel = channels.items - .filter(({ slug }) => slug === 'ai-for-good') - .map(channel => channel)[0] -const { title, slug, teaser } = channel +import ChannelTeaser from '../components/organisms/ChannelTeaser' interface HomeProps { history: History @@ -29,50 +20,13 @@ interface HomeProps { interface HomeState { search?: string - channelAssets?: any[] - isLoadingChannel?: boolean } export default class Home extends Component { public static contextType = User public state = { - 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 }) - } + search: '' } private inputChange = (event: ChangeEvent) => { @@ -87,7 +41,7 @@ export default class Home extends Component { } public render() { - const { channelAssets, isLoadingChannel, search } = this.state + const { search } = this.state return ( { -
-
-
-

- - {title} → - -

-

{teaser}

-
-
-
- {isLoadingChannel ? ( - - ) : channelAssets && channelAssets.length ? ( -
- {channelAssets.map((asset: any) => ( - - ))} -
- ) : ( -
No data sets found.
- )} -
-
- +