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:
parent
1000185841
commit
1b7d343984
@ -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
|
||||
|
56
client/src/components/organisms/ChannelTeaser.module.scss
Normal file
56
client/src/components/organisms/ChannelTeaser.module.scss
Normal 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});
|
||||
}
|
||||
}
|
98
client/src/components/organisms/ChannelTeaser.tsx
Normal file
98
client/src/components/organisms/ChannelTeaser.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
{
|
||||
"title": "Test Channel",
|
||||
"slug": "test-channel",
|
||||
"teaser": "Hello teaser.",
|
||||
"description": "Hello description."
|
||||
}
|
||||
]
|
||||
|
15
client/src/routes/Channels.test.tsx
Normal file
15
client/src/routes/Channels.test.tsx
Normal 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()
|
||||
})
|
||||
})
|
@ -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 (
|
||||
<Route title={channels.title} description={channels.description}>
|
||||
<Content>
|
||||
<ul>
|
||||
<Content wide>
|
||||
{channels.items.map(channel => (
|
||||
<li key={channel.title}>
|
||||
<Link to={`/channels/${channel.slug}`}>
|
||||
{channel.title}
|
||||
</Link>
|
||||
</li>
|
||||
<ChannelTeaser
|
||||
key={channel.title}
|
||||
channel={channel.slug}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</Content>
|
||||
</Route>
|
||||
)
|
||||
|
@ -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;
|
||||
|
@ -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<HomeProps, HomeState> {
|
||||
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<HTMLInputElement>) => {
|
||||
@ -87,7 +41,7 @@ export default class Home extends Component<HomeProps, HomeState> {
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { channelAssets, isLoadingChannel, search } = this.state
|
||||
const { search } = this.state
|
||||
|
||||
return (
|
||||
<Route
|
||||
@ -114,32 +68,7 @@ export default class Home extends Component<HomeProps, HomeState> {
|
||||
</Content>
|
||||
|
||||
<Content wide>
|
||||
<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>
|
||||
|
||||
<ChannelTeaser channel="ai-for-good" />
|
||||
<AssetsLatest />
|
||||
</Content>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user