Fixed topics page style

This commit is contained in:
kvakazyambra 2022-11-09 22:02:12 +03:00
parent 6da1ff8b8d
commit c9958adadc
6 changed files with 111 additions and 67 deletions

View File

@ -9,10 +9,6 @@
.topicDetailsItem { .topicDetailsItem {
margin-bottom: 1.2rem; margin-bottom: 1.2rem;
@include media-breakpoint-up(md) {
margin-bottom: 3.2rem;
}
} }
} }
} }
@ -33,9 +29,9 @@
.topicTitle { .topicTitle {
font-weight: bold; font-weight: bold;
@include font-size(1.7rem); @include font-size(2.2rem);
margin-bottom: 0.8rem; margin-bottom: 1.2rem;
} }
.topicAvatar { .topicAvatar {
@ -56,10 +52,10 @@
} }
.topicDescription { .topicDescription {
@include font-size(1.5rem); @include font-size(1.6rem);
color: #696969; color: #696969;
margin: 0 0 0.8rem; margin: 0 0 1.6rem;
&.compact { &.compact {
font-size: medium; font-size: medium;
@ -85,6 +81,7 @@
} }
.topicDetailsItem { .topicDetailsItem {
@include font-size(1.5rem);
margin-right: 1.6rem; margin-right: 1.6rem;
white-space: nowrap; white-space: nowrap;
@ -104,3 +101,9 @@
float: right; float: right;
} }
} }
.controlContainer {
@include media-breakpoint-up(md) {
text-align: right;
}
}

View File

@ -8,6 +8,7 @@ import { locale } from '../../stores/ui'
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 { getLogger } from '../../utils/logger' import { getLogger } from '../../utils/logger'
import { clsx } from 'clsx'
const log = getLogger('TopicCard') const log = getLogger('TopicCard')
@ -49,11 +50,11 @@ export const TopicCard = (props: TopicProps) => {
[styles.topicInRow]: props.isTopicInRow [styles.topicInRow]: props.isTopicInRow
}} }}
> >
<div classList={{ 'col-md-7': !props.compact && !props.subscribeButtonBottom }}> <div classList={{ 'col-md-9 col-lg-7': !props.compact && !props.subscribeButtonBottom }}>
<Show when={props.topic.title}> <Show when={props.topic.title}>
<div class={styles.topicTitle}> <h3 class={styles.topicTitle}>
<a href={`/topic/${props.topic.slug}`}>{capitalize(props.topic.title || '')}</a> <a href={`/topic/${props.topic.slug}`}>{capitalize(props.topic.title || '')}</a>
</div> </h3>
</Show> </Show>
<Show when={props.topic.pic}> <Show when={props.topic.pic}>
<div class={styles.topicAvatar}> <div class={styles.topicAvatar}>
@ -65,7 +66,7 @@ export const TopicCard = (props: TopicProps) => {
<Show when={!props.compact && props.topic?.body}> <Show when={!props.compact && props.topic?.body}>
<div <div
class={styles.topicDescription} class={clsx(styles.topicDescription, 'text-truncate')}
classList={{ 'topic-description--short': props.shortDescription }} classList={{ 'topic-description--short': props.shortDescription }}
> >
{props.topic.body} {props.topic.body}
@ -75,7 +76,7 @@ export const TopicCard = (props: TopicProps) => {
<Show when={props.topic?.stat}> <Show when={props.topic?.stat}>
<div class={styles.topicDetails}> <div class={styles.topicDetails}>
<Show when={!props.compact}> <Show when={!props.compact}>
<span class={styles.topicDetailsTtem} classList={{ compact: props.compact }}> <span class={styles.topicDetailsItem} classList={{ compact: props.compact }}>
{props.topic.stat?.shouts + {props.topic.stat?.shouts +
' ' + ' ' +
t('post') + t('post') +
@ -84,7 +85,7 @@ export const TopicCard = (props: TopicProps) => {
locale() === 'ru' ? ['ов', '', 'а'] : ['s', '', 's'] locale() === 'ru' ? ['ов', '', 'а'] : ['s', '', 's']
)} )}
</span> </span>
<span class={styles.topicDetailsTtem} classList={{ compact: props.compact }}> <span class={styles.topicDetailsItem} classList={{ compact: props.compact }}>
{props.topic.stat?.authors + {props.topic.stat?.authors +
' ' + ' ' +
t('author') + t('author') +
@ -127,21 +128,24 @@ export const TopicCard = (props: TopicProps) => {
</div> </div>
</Show> </Show>
</div> </div>
<div classList={{ 'col-md-3': !props.compact && !props.subscribeButtonBottom }}> <div
class={styles.controlContainer}
classList={{ 'col-md-3': !props.compact && !props.subscribeButtonBottom }}
>
<Show <Show
when={subscribed()} when={subscribed()}
fallback={ fallback={
<button onClick={() => subscribe(true)} class="button--light button--subscribe-topic"> <button onClick={() => subscribe(true)} class="button--light button--subscribe-topic">
<Show when={props.iconButton}>+</Show> <Show when={props.iconButton}>+</Show>
<Show when={!props.iconButton}>+&nbsp;{t('Follow')}</Show> <Show when={!props.iconButton}>{t('Follow')}</Show>
</button> </button>
} }
> >
<button onClick={() => subscribe(false)} class="button--light button--subscribe-topic"> <button onClick={() => subscribe(false)} class="button--light button--subscribe-topic">
<Show when={props.iconButton}>-</Show> <Show when={props.iconButton}>-</Show>
<Show when={!props.iconButton}>-&nbsp;{t('Unfollow')}</Show> <Show when={!props.iconButton}>{t('Unfollow')}</Show>
</button> </button>
</Show> </Show>
</div> </div>

View File

@ -6,7 +6,8 @@ import { t } from '../../utils/intl'
import { useAuthorsStore, setAuthorsSort } from '../../stores/zine/authors' import { useAuthorsStore, setAuthorsSort } from '../../stores/zine/authors'
import { handleClientRouteLinkClick, useRouter } from '../../stores/router' import { handleClientRouteLinkClick, useRouter } from '../../stores/router'
import { useAuthStore } from '../../stores/auth' import { useAuthStore } from '../../stores/auth'
import '../../styles/AllTopics.scss' import styles from '../../styles/AllTopics.module.scss'
import { clsx } from 'clsx'
type AllAuthorsPageSearchParams = { type AllAuthorsPageSearchParams = {
by: '' | 'name' | 'shouts' | 'rating' by: '' | 'name' | 'shouts' | 'rating'
@ -56,19 +57,19 @@ export const AllAuthorsView = (props: Props) => {
// log.debug(getSearchParams()) // log.debug(getSearchParams())
return ( return (
<div class="all-topics-page"> <div class={styles.allTopicsPage}>
<Show when={sortedAuthors().length > 0}> <Show when={sortedAuthors().length > 0}>
<div class="wide-container"> <div class="wide-container">
<div class="shift-content"> <div class="shift-content">
<div class="row"> <div class="row">
<div class="col-md-9 page-header"> <div class={clsx(styles.pageHeader, 'col-lg-9')}>
<h1>{t('Authors')}</h1> <h1>{t('Authors')}</h1>
<p>{t('Subscribe who you like to tune your personal feed')}</p> <p>{t('Subscribe who you like to tune your personal feed')}</p>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<ul class="view-switcher"> <ul class={clsx(styles.viewSwitcher, 'view-switcher')}>
<li classList={{ selected: searchParams().by === 'shouts' }}> <li classList={{ selected: searchParams().by === 'shouts' }}>
<a href="/authors?by=shouts" onClick={handleClientRouteLinkClick}> <a href="/authors?by=shouts" onClick={handleClientRouteLinkClick}>
{t('By shouts')} {t('By shouts')}
@ -111,13 +112,13 @@ export const AllAuthorsView = (props: Props) => {
> >
<For each={sortedKeys()}> <For each={sortedKeys()}>
{(letter) => ( {(letter) => (
<div class="group"> <div class={clsx(styles.group, 'group')}>
<h2>{letter}</h2> <h2>{letter}</h2>
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<For each={byLetter()[letter]}> <For each={byLetter()[letter]}>
{(author: Author) => ( {(author: Author) => (
<div class="topic col-sm-6 col-md-3"> <div class={clsx(styles.topic, 'topic col-sm-6 col-md-3')}>
<div class="topic-title"> <div class="topic-title">
<a href={`/author/${author.slug}`}>{author.name}</a> <a href={`/author/${author.slug}`}>{author.name}</a>
</div> </div>

View File

@ -6,7 +6,9 @@ import { setTopicsSort, useTopicsStore } from '../../stores/zine/topics'
import { handleClientRouteLinkClick, useRouter } from '../../stores/router' import { handleClientRouteLinkClick, useRouter } from '../../stores/router'
import { TopicCard } from '../Topic/Card' import { TopicCard } from '../Topic/Card'
import { useAuthStore } from '../../stores/auth' import { useAuthStore } from '../../stores/auth'
import '../../styles/AllTopics.scss' import styles from '../../styles/AllTopics.module.scss'
import cardStyles from '../Topic/Card.module.scss'
import { clsx } from 'clsx'
type AllTopicsPageSearchParams = { type AllTopicsPageSearchParams = {
by: 'shouts' | 'authors' | 'title' | '' by: 'shouts' | 'authors' | 'title' | ''
@ -52,54 +54,58 @@ export const AllTopicsView = (props: AllTopicsViewProps) => {
const subscribed = (s) => Boolean(session()?.news?.topics && session()?.news?.topics?.includes(s || '')) const subscribed = (s) => Boolean(session()?.news?.topics && session()?.news?.topics?.includes(s || ''))
return ( return (
<div class="all-topics-page"> <div class={styles.allTopicsPage}>
<Show when={sortedTopics().length > 0}> <Show when={sortedTopics().length > 0}>
<div class="wide-container"> <div class="wide-container">
<div class="shift-content"> <div class="shift-content">
<div class="row"> <div class="row">
<div class="col-md-9 page-header"> <div class={clsx(styles.pageHeader, 'col-lg-9')}>
<h1>{t('Topics')}</h1> <h1>{t('Topics')}</h1>
<p>{t('Subscribe what you like to tune your personal feed')}</p> <div class="col-lg-10">
<p>{t('Subscribe what you like to tune your personal feed')}</p>
</div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<ul class="view-switcher"> <div class="row">
<li classList={{ selected: searchParams().by === 'shouts' || !searchParams().by }}> <ul class={clsx(styles.viewSwitcher, 'view-switcher col-lg-10')}>
<a href="/topics?by=shouts" onClick={handleClientRouteLinkClick}> <li classList={{ selected: searchParams().by === 'shouts' || !searchParams().by }}>
{t('By shouts')} <a href="/topics?by=shouts" onClick={handleClientRouteLinkClick}>
</a> {t('By shouts')}
</li> </a>
<li classList={{ selected: searchParams().by === 'authors' }}> </li>
<a href="/topics?by=authors" onClick={handleClientRouteLinkClick}> <li classList={{ selected: searchParams().by === 'authors' }}>
{t('By authors')} <a href="/topics?by=authors" onClick={handleClientRouteLinkClick}>
</a> {t('By authors')}
</li> </a>
<li classList={{ selected: searchParams().by === 'title' }}> </li>
<a <li classList={{ selected: searchParams().by === 'title' }}>
href="/topics?by=title" <a
onClick={(ev) => { href="/topics?by=title"
// just an example onClick={(ev) => {
ev.preventDefault() // just an example
changeSearchParam('by', 'title') ev.preventDefault()
}} changeSearchParam('by', 'title')
> }}
{t('By alphabet')} >
</a> {t('By alphabet')}
</li> </a>
<li class="view-switcher__search"> </li>
<a href="/topic/search"> <li class="view-switcher__search">
<Icon name="search" /> <a href="/topic/search">
{t('Search topic')} <Icon name="search" />
</a> {t('Search topic')}
</li> </a>
</ul> </li>
</ul>
</div>
<Show <Show
when={searchParams().by === 'title'} when={searchParams().by === 'title'}
fallback={() => ( fallback={() => (
<div class="stats"> <div class={cardStyles.stats}>
<For each={sortedTopics()}> <For each={sortedTopics()}>
{(topic) => ( {(topic) => (
<TopicCard topic={topic} compact={false} subscribed={subscribed(topic.slug)} /> <TopicCard topic={topic} compact={false} subscribed={subscribed(topic.slug)} />
@ -110,13 +116,13 @@ export const AllTopicsView = (props: AllTopicsViewProps) => {
> >
<For each={sortedKeys()}> <For each={sortedKeys()}>
{(letter) => ( {(letter) => (
<div class="group"> <div class={clsx(styles.group, 'group')}>
<h2>{letter}</h2> <h2>{letter}</h2>
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<For each={byLetter()[letter]}> <For each={byLetter()[letter]}>
{(topic) => ( {(topic) => (
<div class="topic col-sm-6 col-md-3"> <div class={clsx(styles.topic, 'topic col-sm-6 col-md-3')}>
<div class="topic-title"> <div class="topic-title">
<a href={`/topic/${topic.slug}`}>{topic.title}</a> <a href={`/topic/${topic.slug}`}>{topic.title}</a>
</div> </div>

View File

@ -1,5 +1,5 @@
.all-topics-page { .allTopicsPage {
.page-header, .pageHeader,
.group h2 { .group h2 {
@include media-breakpoint-down(sm) { @include media-breakpoint-down(sm) {
margin-left: 1.3rem; margin-left: 1.3rem;
@ -38,3 +38,9 @@
width: auto; width: auto;
} }
} }
.viewSwitcher {
@include media-breakpoint-down(sm) {
margin: 0 2.6rem;
}
}

View File

@ -404,12 +404,14 @@ figcaption {
} }
.view-switcher { .view-switcher {
@include font-size(2.2rem); @include font-size(1.7rem);
display: flex;
flex-wrap: wrap;
font-weight: bold; font-weight: bold;
list-style: none; list-style: none;
margin: 0; margin: 2.4rem 0 0;
padding: 0; //padding: 0;
.all-topics-page & { .all-topics-page & {
@include media-breakpoint-down(sm) { @include media-breakpoint-down(sm) {
@ -420,7 +422,11 @@ figcaption {
li { li {
display: inline-block; display: inline-block;
margin-right: 1em; margin-right: 1em;
margin-bottom: 0.5em; margin-bottom: 0.6em;
&:last-child {
margin-right: 0;
}
} }
button { button {
@ -436,6 +442,11 @@ figcaption {
a { a {
border-bottom: 2px solid #fff; border-bottom: 2px solid #fff;
color: rgba(0, 0, 0, 0.5);
&:hover {
color: #fff;
}
} }
.selected { .selected {
@ -458,7 +469,12 @@ figcaption {
} }
.view-switcher__search { .view-switcher__search {
margin-left: 2em; text-align: right;
@include media-breakpoint-up(sm) {
flex: 1;
margin-left: 2em;
}
.icon { .icon {
display: inline-block; display: inline-block;
@ -685,3 +701,11 @@ details {
} }
} }
} }
.text-truncate {
display: -webkit-box !important;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
white-space: normal;
}