Topic page fixes
This commit is contained in:
parent
3c599e2142
commit
9581f21d7b
|
@ -12,6 +12,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
|
||||||
&.top {
|
&.top {
|
||||||
border-bottom: 1px solid #e1e1e1;
|
border-bottom: 1px solid #e1e1e1;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
.modalwrap {
|
.modalwrap {
|
||||||
pointer-events: all;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: rgb(20 20 20 / 70%);
|
background: rgb(20 20 20 / 70%);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
overflow: auto;
|
||||||
|
pointer-events: all;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
.topic__header {
|
.topicHeader {
|
||||||
@include font-size(1.7rem);
|
@include font-size(1.7rem);
|
||||||
|
|
||||||
padding-top: 5.8rem;
|
padding-top: 5.8rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #2638d9;
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
@include font-size(2rem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.topic__actions {
|
.topicActions {
|
||||||
margin-top: 2.8rem;
|
margin-top: 2.8rem;
|
||||||
|
|
||||||
button,
|
button,
|
|
@ -1,10 +1,11 @@
|
||||||
import { createMemo, Show } from 'solid-js'
|
import { createMemo, Show } from 'solid-js'
|
||||||
import type { Topic } from '../../graphql/types.gen'
|
import type { Topic } from '../../graphql/types.gen'
|
||||||
import { FollowingEntity } from '../../graphql/types.gen'
|
import { FollowingEntity } from '../../graphql/types.gen'
|
||||||
import './Full.scss'
|
import styles from './Full.module.scss'
|
||||||
import { useAuthStore } from '../../stores/auth'
|
import { useAuthStore } from '../../stores/auth'
|
||||||
import { follow, unfollow } from '../../stores/zine/common'
|
import { follow, unfollow } from '../../stores/zine/common'
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
|
import { clsx } from 'clsx'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
topic: Topic
|
topic: Topic
|
||||||
|
@ -15,37 +16,35 @@ export const FullTopic = (props: Props) => {
|
||||||
|
|
||||||
const subscribed = createMemo(() => session()?.news?.topics?.includes(props.topic?.slug))
|
const subscribed = createMemo(() => session()?.news?.topics?.includes(props.topic?.slug))
|
||||||
return (
|
return (
|
||||||
<div class="topic-full container">
|
<div class={styles.topicFull}>
|
||||||
<div class="row">
|
<Show when={!!props.topic?.slug}>
|
||||||
<Show when={!!props.topic?.slug}>
|
<div class={clsx(styles.topicHeader, 'col-md-8 offset-md-2')}>
|
||||||
<div class="topic__header col-md-8 offset-md-2">
|
<h1>#{props.topic.title}</h1>
|
||||||
<h1>#{props.topic.title}</h1>
|
<p>{props.topic.body}</p>
|
||||||
<p>{props.topic.body}</p>
|
<div class={clsx(styles.topicActions)}>
|
||||||
<div class="topic__actions">
|
<Show when={!subscribed()}>
|
||||||
<Show when={!subscribed()}>
|
<button
|
||||||
<button
|
onClick={() => follow({ what: FollowingEntity.Topic, slug: props.topic.slug })}
|
||||||
onClick={() => follow({ what: FollowingEntity.Topic, slug: props.topic.slug })}
|
class="button"
|
||||||
class="button"
|
>
|
||||||
>
|
{t('Follow the topic')}
|
||||||
{t('Follow the topic')}
|
</button>
|
||||||
</button>
|
|
||||||
</Show>
|
|
||||||
<Show when={subscribed()}>
|
|
||||||
<button
|
|
||||||
onClick={() => unfollow({ what: FollowingEntity.Topic, slug: props.topic.slug })}
|
|
||||||
class="button"
|
|
||||||
>
|
|
||||||
{t('Unfollow the topic')}
|
|
||||||
</button>
|
|
||||||
</Show>
|
|
||||||
<a href={`/create/${props.topic.slug}`}>{t('Write about the topic')}</a>
|
|
||||||
</div>
|
|
||||||
<Show when={props.topic.pic}>
|
|
||||||
<img src={props.topic.pic} alt={props.topic.title} />
|
|
||||||
</Show>
|
</Show>
|
||||||
|
<Show when={subscribed()}>
|
||||||
|
<button
|
||||||
|
onClick={() => unfollow({ what: FollowingEntity.Topic, slug: props.topic.slug })}
|
||||||
|
class="button"
|
||||||
|
>
|
||||||
|
{t('Unfollow the topic')}
|
||||||
|
</button>
|
||||||
|
</Show>
|
||||||
|
<a href={`/create/${props.topic.slug}`}>{t('Write about the topic')}</a>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
<Show when={props.topic.pic}>
|
||||||
</div>
|
<img src={props.topic.pic} alt={props.topic.title} />
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import { t } from '../../utils/intl'
|
||||||
import { useAuthorsStore } from '../../stores/zine/authors'
|
import { useAuthorsStore } from '../../stores/zine/authors'
|
||||||
import { loadAuthorArticles, useArticlesStore } from '../../stores/zine/articles'
|
import { loadAuthorArticles, useArticlesStore } from '../../stores/zine/articles'
|
||||||
|
|
||||||
import '../../styles/Topic.scss'
|
|
||||||
import { useTopicsStore } from '../../stores/zine/topics'
|
import { useTopicsStore } from '../../stores/zine/topics'
|
||||||
import { useRouter } from '../../stores/router'
|
import { useRouter } from '../../stores/router'
|
||||||
import { Beside } from '../Feed/Beside'
|
import { Beside } from '../Feed/Beside'
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Row3 } from '../Feed/Row3'
|
||||||
import { Row2 } from '../Feed/Row2'
|
import { Row2 } from '../Feed/Row2'
|
||||||
import { Beside } from '../Feed/Beside'
|
import { Beside } from '../Feed/Beside'
|
||||||
import { ArticleCard } from '../Feed/Card'
|
import { ArticleCard } from '../Feed/Card'
|
||||||
import '../../styles/Topic.scss'
|
import styles from '../../styles/Topic.module.scss'
|
||||||
import { FullTopic } from '../Topic/Full'
|
import { FullTopic } from '../Topic/Full'
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
import { useRouter } from '../../stores/router'
|
import { useRouter } from '../../stores/router'
|
||||||
|
@ -13,6 +13,9 @@ import { loadPublishedArticles, useArticlesStore } from '../../stores/zine/artic
|
||||||
import { useAuthorsStore } from '../../stores/zine/authors'
|
import { useAuthorsStore } from '../../stores/zine/authors'
|
||||||
import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll'
|
import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll'
|
||||||
import { splitToPages } from '../../utils/splitToPages'
|
import { splitToPages } from '../../utils/splitToPages'
|
||||||
|
import { clsx } from 'clsx'
|
||||||
|
import Slider from '../Feed/Slider'
|
||||||
|
import { Row1 } from '../Feed/Row1'
|
||||||
|
|
||||||
type TopicsPageSearchParams = {
|
type TopicsPageSearchParams = {
|
||||||
by: 'comments' | '' | 'recent' | 'viewed' | 'rating' | 'commented'
|
by: 'comments' | '' | 'recent' | 'viewed' | 'rating' | 'commented'
|
||||||
|
@ -70,94 +73,111 @@ export const TopicView = (props: TopicProps) => {
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="topic-page container">
|
<div class={styles.topicPage}>
|
||||||
<Show when={topic()}>
|
<Show when={topic()}>
|
||||||
<FullTopic topic={topic()} />
|
<FullTopic topic={topic()} />
|
||||||
<div class="row group__controls">
|
<div class="container">
|
||||||
<div class="col-md-8">
|
<div class={clsx(styles.groupControls, 'row group__controls')}>
|
||||||
<ul class="view-switcher">
|
<div class="col-md-8">
|
||||||
<li classList={{ selected: searchParams().by === 'recent' || !searchParams().by }}>
|
<ul class="view-switcher">
|
||||||
<button type="button" onClick={() => changeSearchParam('by', 'recent')}>
|
<li classList={{ selected: searchParams().by === 'recent' || !searchParams().by }}>
|
||||||
{t('Recent')}
|
<button type="button" onClick={() => changeSearchParam('by', 'recent')}>
|
||||||
</button>
|
{t('Recent')}
|
||||||
</li>
|
</button>
|
||||||
{/*TODO: server sort*/}
|
</li>
|
||||||
{/*<li classList={{ selected: getSearchParams().by === 'rating' }}>*/}
|
{/*TODO: server sort*/}
|
||||||
{/* <button type="button" onClick={() => changeSearchParam('by', 'rating')}>*/}
|
{/*<li classList={{ selected: getSearchParams().by === 'rating' }}>*/}
|
||||||
{/* {t('Popular')}*/}
|
{/* <button type="button" onClick={() => changeSearchParam('by', 'rating')}>*/}
|
||||||
{/* </button>*/}
|
{/* {t('Popular')}*/}
|
||||||
{/*</li>*/}
|
{/* </button>*/}
|
||||||
{/*<li classList={{ selected: getSearchParams().by === 'viewed' }}>*/}
|
{/*</li>*/}
|
||||||
{/* <button type="button" onClick={() => changeSearchParam('by', 'viewed')}>*/}
|
{/*<li classList={{ selected: getSearchParams().by === 'viewed' }}>*/}
|
||||||
{/* {t('Views')}*/}
|
{/* <button type="button" onClick={() => changeSearchParam('by', 'viewed')}>*/}
|
||||||
{/* </button>*/}
|
{/* {t('Views')}*/}
|
||||||
{/*</li>*/}
|
{/* </button>*/}
|
||||||
{/*<li classList={{ selected: getSearchParams().by === 'commented' }}>*/}
|
{/*</li>*/}
|
||||||
{/* <button type="button" onClick={() => changeSearchParam('by', 'commented')}>*/}
|
{/*<li classList={{ selected: getSearchParams().by === 'commented' }}>*/}
|
||||||
{/* {t('Discussing')}*/}
|
{/* <button type="button" onClick={() => changeSearchParam('by', 'commented')}>*/}
|
||||||
{/* </button>*/}
|
{/* {t('Discussing')}*/}
|
||||||
{/*</li>*/}
|
{/* </button>*/}
|
||||||
</ul>
|
{/*</li>*/}
|
||||||
</div>
|
</ul>
|
||||||
<div class="col-md-4">
|
</div>
|
||||||
<div class="mode-switcher">
|
<div class="col-md-4">
|
||||||
{`${t('Show')} `}
|
<div class="mode-switcher">
|
||||||
<span class="mode-switcher__control">{t('All posts')}</span>
|
{`${t('Show')} `}
|
||||||
|
<span class="mode-switcher__control">{t('All posts')}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row floor floor--important">
|
<Row1 article={sortedArticles()[0]} />
|
||||||
<div class="container">
|
<Row2 articles={sortedArticles().slice(1, 3)} />
|
||||||
<div class="row">
|
|
||||||
<h3 class="col-12">{title()}</h3>
|
<Beside
|
||||||
<For each={sortedArticles().slice(0, 6)}>
|
title={t('Topic is supported by')}
|
||||||
{(article) => (
|
values={authorsByTopic()[topic().slug].slice(0, 6)}
|
||||||
<div class="col-md-6">
|
beside={sortedArticles()[4]}
|
||||||
<ArticleCard
|
wrapper={'author'}
|
||||||
article={article}
|
/>
|
||||||
settings={{ isFloorImportant: true, isBigTitle: true }}
|
|
||||||
/>
|
<Show when={searchParams().by === 'recent'}>
|
||||||
</div>
|
<Slider title={title()} articles={sortedArticles().slice(5, 11)} />
|
||||||
)}
|
</Show>
|
||||||
</For>
|
|
||||||
|
<Beside
|
||||||
|
beside={sortedArticles()[12]}
|
||||||
|
title={t('Top viewed')}
|
||||||
|
values={sortedArticles().slice(0, 5)}
|
||||||
|
wrapper={'top-article'}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Show when={searchParams().by !== 'recent'}>
|
||||||
|
<div class={clsx(styles.floorImportant, 'row floor floor--important')}>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<h3 class="col-12">{title()}</h3>
|
||||||
|
<For each={sortedArticles().slice(0, 6)}>
|
||||||
|
{(article) => (
|
||||||
|
<div class="col-md-6">
|
||||||
|
<ArticleCard
|
||||||
|
article={article}
|
||||||
|
settings={{ isFloorImportant: true, isBigTitle: true }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Show>
|
||||||
|
|
||||||
<div class="row">
|
<Show when={sortedArticles().length > 5}>
|
||||||
<Show when={sortedArticles().length > 5}>
|
<Row3 articles={sortedArticles().slice(13, 16)} />
|
||||||
<Beside
|
<Row2 articles={sortedArticles().slice(16, 18)} />
|
||||||
title={t('Topic is supported by')}
|
<Row3 articles={sortedArticles().slice(18, 21)} />
|
||||||
values={authorsByTopic()[topic().slug].slice(0, 7)}
|
<Row3 articles={sortedArticles().slice(21, 24)} />
|
||||||
beside={sortedArticles()[6]}
|
<Row3 articles={sortedArticles().slice(24, 27)} />
|
||||||
wrapper={'author'}
|
</Show>
|
||||||
/>
|
|
||||||
<Row3 articles={sortedArticles().slice(7, 10)} />
|
|
||||||
<Row2 articles={sortedArticles().slice(10, 12)} />
|
|
||||||
<Row3 articles={sortedArticles().slice(12, 15)} />
|
|
||||||
<Row3 articles={sortedArticles().slice(15, 18)} />
|
|
||||||
<Row3 articles={sortedArticles().slice(18, 21)} />
|
|
||||||
</Show>
|
|
||||||
|
|
||||||
<For each={pages()}>
|
<For each={pages()}>
|
||||||
{(page) => (
|
{(page) => (
|
||||||
<>
|
<>
|
||||||
<Row3 articles={page.slice(0, 3)} />
|
<Row3 articles={page.slice(0, 3)} />
|
||||||
<Row3 articles={page.slice(3, 6)} />
|
<Row3 articles={page.slice(3, 6)} />
|
||||||
<Row3 articles={page.slice(6, 9)} />
|
<Row3 articles={page.slice(6, 9)} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
|
|
||||||
<Show when={isLoadMoreButtonVisible()}>
|
<Show when={isLoadMoreButtonVisible()}>
|
||||||
<p class="load-more-container">
|
<p class="load-more-container">
|
||||||
<button class="button" onClick={loadMore}>
|
<button class="button" onClick={loadMore}>
|
||||||
{t('Load more')}
|
{t('Load more')}
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
.topic-page {
|
.topicPage {
|
||||||
.group__controls {
|
.groupControls {
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
margin-bottom: 4rem;
|
margin-bottom: 4rem;
|
||||||
margin-top: 7rem;
|
margin-top: 7rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.floor--important {
|
.floorImportant {
|
||||||
a:hover {
|
a:hover {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
color: #000 !important;
|
color: #000 !important;
|
Loading…
Reference in New Issue
Block a user