From dc6dda4745ca9bcba751a9560f99d6e1270d9703 Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Sun, 8 Jan 2023 18:45:33 +0400 Subject: [PATCH] Profile (#81) - Show profile tabs (comments and about) - Save profile fields Co-authored-by: ilya-bkv --- .../Article/RatingControl.module.scss | 3 +- src/components/Author/Card.module.scss | 38 ++++- src/components/Author/Card.tsx | 4 +- src/components/Author/Full.scss | 15 +- src/components/Author/Full.tsx | 2 +- src/components/Author/Userpic.module.scss | 6 +- src/components/Views/Author.module.scss | 55 +++++++ src/components/Views/Author.tsx | 143 +++++++++++++----- .../_shared/Popup/Popup.module.scss | 31 ++-- src/locales/ru.json | 1 + src/utils/apiClient.ts | 14 +- 11 files changed, 249 insertions(+), 63 deletions(-) create mode 100644 src/components/Views/Author.module.scss diff --git a/src/components/Article/RatingControl.module.scss b/src/components/Article/RatingControl.module.scss index 68001845..1d871050 100644 --- a/src/components/Article/RatingControl.module.scss +++ b/src/components/Article/RatingControl.module.scss @@ -16,8 +16,7 @@ justify-content: center; height: 0.9em; line-height: 0; - @include font-size(3.6rem); - + font-size: 1.6em; padding: 0; width: 0.9em; diff --git a/src/components/Author/Card.module.scss b/src/components/Author/Card.module.scss index 19df71b5..e8f9062a 100644 --- a/src/components/Author/Card.module.scss +++ b/src/components/Author/Card.module.scss @@ -54,6 +54,10 @@ padding: 0 0 0 42px; } + @include media-breakpoint-down(md) { + flex-wrap: wrap; + } + a { background: #f7f7f7; border: none; @@ -136,6 +140,17 @@ } } +.authorSubscribeSocial { + align-items: center; + display: flex; + + @include media-breakpoint-down(sm) { + flex: 1 100%; + justify-content: center; + margin-top: 1em; + } +} + .buttonSubscribe { align-items: center; aspect-ratio: 1/1; @@ -180,9 +195,12 @@ } .authorPage { + @include media-breakpoint-down(md) { + justify-content: center; + } + .authorName { @include font-size(3.4rem); - font-weight: 500; margin-bottom: 0.2em; } @@ -195,10 +213,18 @@ .authorSubscribe { margin-top: 2rem; padding-left: 0; + + @include media-breakpoint-down(md) { + justify-content: center; + } } .authorDetails { display: block; + + @include media-breakpoint-down(md) { + flex: 1 100%; + } } .buttonLabel { @@ -237,6 +263,16 @@ .button { margin-right: 1.6rem; vertical-align: middle; + + &:last-of-type { + margin-right: 0; + } + + @include media-breakpoint-down(sm) { + display: block; + margin-bottom: 0.5em; + margin-right: 0; + } } } diff --git a/src/components/Author/Card.tsx b/src/components/Author/Card.tsx index 3daa4a10..680e2b8c 100644 --- a/src/components/Author/Card.tsx +++ b/src/components/Author/Card.tsx @@ -177,7 +177,9 @@ export const AuthorCard = (props: AuthorCardProps) => { - {(link) => } + diff --git a/src/components/Author/Full.scss b/src/components/Author/Full.scss index 13f5e9ca..801cd85c 100644 --- a/src/components/Author/Full.scss +++ b/src/components/Author/Full.scss @@ -1,11 +1,22 @@ .user-details { - margin-bottom: 5.4rem; + margin: 0 0 5.4rem; + + @include media-breakpoint-up(md) { + margin-left: 160px; + } + + @include media-breakpoint-up(lg) { + margin-left: 235px; + } + + @include media-breakpoint-down(md) { + text-align: center; + } } .author-page { .view-switcher { @include font-size(1.5rem); - margin-top: 0; button { diff --git a/src/components/Author/Full.tsx b/src/components/Author/Full.tsx index b240ae2b..0d621af4 100644 --- a/src/components/Author/Full.tsx +++ b/src/components/Author/Full.tsx @@ -5,7 +5,7 @@ import './Full.scss' export const AuthorFull = (props: { author: Author }) => { return (
-
+
diff --git a/src/components/Author/Userpic.module.scss b/src/components/Author/Userpic.module.scss index 20ed085e..18855e50 100644 --- a/src/components/Author/Userpic.module.scss +++ b/src/components/Author/Userpic.module.scss @@ -35,12 +35,16 @@ } .big.circlewrap { - margin-right: 4.8rem; + margin-right: 0; max-width: 168px; min-width: 168px; height: 168px; width: 168px; + @include media-breakpoint-up(md) { + margin-right: 4.8rem; + } + .userpic { font-size: 2em; line-height: 168px; diff --git a/src/components/Views/Author.module.scss b/src/components/Views/Author.module.scss new file mode 100644 index 00000000..9b279d03 --- /dev/null +++ b/src/components/Views/Author.module.scss @@ -0,0 +1,55 @@ +.ratingContainer { + @include font-size(1.5rem); + display: inline-block; + vertical-align: top; +} + +.ratingControl { + @include font-size(1.5rem); + display: inline-flex; + margin-left: 1em; + vertical-align: middle; +} + +.additionalControls { + white-space: nowrap; + + @include media-breakpoint-up(md) { + text-align: right; + } +} + +.userpic { + background: #fff; + box-shadow: 0 0 0 2px #fff; + display: inline-block; + margin-right: -1.2rem; + vertical-align: top; +} + +.subscribers { + cursor: pointer; + display: inline-block; + margin: -0.4rem 2em 0 0; + vertical-align: top; +} + +.subscribersCounter { + background: #fff; + border: 2px solid #000; + border-radius: 100%; + @include font-size(1rem); + font-weight: bold; + height: 32px; + line-height: 30px; + position: relative; + text-align: center; + width: 32px; + z-index: 1; +} + +.subscribersList { + max-height: 15em; + overflow: auto; + position: relative; +} diff --git a/src/components/Views/Author.tsx b/src/components/Views/Author.tsx index 37b3030a..a2aa1e99 100644 --- a/src/components/Views/Author.tsx +++ b/src/components/Views/Author.tsx @@ -1,7 +1,7 @@ -import { Show, createMemo, createSignal, For, onMount } from 'solid-js' +import { Show, createMemo, createSignal, Switch, onMount, For, Match, createEffect } from 'solid-js' import type { Author, Shout } from '../../graphql/types.gen' +import { Row1 } from '../Feed/Row1' import { Row2 } from '../Feed/Row2' -import { Row3 } from '../Feed/Row3' import { AuthorFull } from '../Author/Full' import { t } from '../../utils/intl' import { useAuthorsStore } from '../../stores/zine/authors' @@ -9,9 +9,17 @@ import { loadShouts, useArticlesStore } from '../../stores/zine/articles' import { useTopicsStore } from '../../stores/zine/topics' import { useRouter } from '../../stores/router' -import { Beside } from '../Feed/Beside' import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll' import { splitToPages } from '../../utils/splitToPages' +import { RatingControl } from '../Article/RatingControl' +import styles from './Author.module.scss' +import { clsx } from 'clsx' +import Userpic from '../Author/Userpic' +import { Popup } from '../_shared/Popup' +import { AuthorCard } from '../Author/Card' +import { loadReactionsBy, REACTIONS_AMOUNT_PER_PAGE } from '../../stores/zine/reactions' +import { apiClient } from '../../utils/apiClient' +import Comment from '../Article/Comment' // TODO: load reactions on client type AuthorProps = { @@ -23,7 +31,7 @@ type AuthorProps = { } type AuthorPageSearchParams = { - by: '' | 'viewed' | 'rating' | 'commented' | 'recent' | 'followed' + by: '' | 'viewed' | 'rating' | 'commented' | 'recent' | 'followed' | 'about' | 'popular' } export const PRERENDERED_ARTICLES_COUNT = 12 @@ -38,6 +46,7 @@ export const AuthorView = (props: AuthorProps) => { const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) const author = createMemo(() => authorEntities()[props.authorSlug]) + const subscribers = Array.from({ length: 12 }).fill(author()) const { searchParams, changeSearchParam } = useRouter() const loadMore = async () => { @@ -69,6 +78,23 @@ export const AuthorView = (props: AuthorProps) => { splitToPages(sortedArticles(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE) ) + console.log('!!! authorEntities():', author()) + const [commented, setCommented] = createSignal([]) + createEffect(async () => { + if (searchParams().by === 'commented') { + try { + const data = await apiClient.getReactionsBy({ + by: { comment: true, createdBy: props.authorSlug }, + limit: 100, + offset: 0 + }) + setCommented(data) + } catch (error) { + console.log('!!! error:', error) + } + } + }) + return (
{t('Loading')}
}> @@ -89,52 +115,91 @@ export const AuthorView = (props: AuthorProps) => {
  • +
  • +
  • + +
  • +
  • +
  • -
    -
    - {`${t('Show')} `} - {t('All posts')} +
    + + + + +
    12
    +
    + } + variant="tiny" + > +
      + + {(item: Author) => ( +
    • + +
    • + )} +
      +
    + + +
    + Карма +
    - - - - - + дефолтное состояние

    }> + +

    About

    +

    {JSON.stringify(authorEntities())}

    +
    + + {(comment) => } + + + + + + + + - - {(page) => ( - <> - - - - - )} - + + {(page) => ( + <> + + + + + + + + )} + - -

    - -

    -
    + +

    + +

    +
    +
    +
    ) diff --git a/src/components/_shared/Popup/Popup.module.scss b/src/components/_shared/Popup/Popup.module.scss index b1890f63..3325cc7c 100644 --- a/src/components/_shared/Popup/Popup.module.scss +++ b/src/components/_shared/Popup/Popup.module.scss @@ -4,18 +4,19 @@ .popup { background: #fff; - top: calc(100% + 8px); - opacity: 1; color: #000; - position: absolute; - z-index: 100; min-width: 144px; + opacity: 1; + position: absolute; + top: calc(100% + 8px); + z-index: 100; ul { margin-bottom: 0; li { position: relative; + &:last-child { margin-bottom: 0; } @@ -24,11 +25,12 @@ &.bordered { @include font-size(1.6rem); - border: 2px solid #000; padding: 2.4rem; + ul li { margin-bottom: 1.6rem; + &:last-child { margin-bottom: 0; } @@ -37,11 +39,12 @@ &.tiny { @include font-size(1.4rem); - box-shadow: 0 4px 60px rgba(0, 0, 0, 0.1); padding: 1rem; + ul li { margin-bottom: 1rem; + &:last-child { margin-bottom: 0; } @@ -67,22 +70,22 @@ white-space: nowrap; &:hover { - img { + .icon img { filter: invert(0); } } } - img { - filter: invert(1); - max-height: 2rem; - max-width: 2rem; - transition: filter 0.3s; - } - .icon { display: inline-block; width: 3.6rem; + + img { + filter: invert(1); + max-height: 2rem; + max-width: 2rem; + transition: filter 0.3s; + } } } diff --git a/src/locales/ru.json b/src/locales/ru.json index b9e8c8db..6eda3234 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -52,6 +52,7 @@ "Fill email": "Введите почту", "Follow": "Подписаться", "Follow the topic": "Подписаться на тему", + "Followers": "Подписчики", "Forgot password?": "Забыли пароль?", "Full name": "Имя и фамилия", "Get to know the most intelligent people of our time, edit and discuss the articles, share your expertise, rate and decide what to publish in the magazine": "Познакомитесь с выдающимися людьми нашего времени, участвуйте в редактировании и обсуждении статей, выступайте экспертом, оценивайте материалы других авторов со всего мира и определяйте, какие статьи будут опубликованы в журнале", diff --git a/src/utils/apiClient.ts b/src/utils/apiClient.ts index 113047bd..a3132aa6 100644 --- a/src/utils/apiClient.ts +++ b/src/utils/apiClient.ts @@ -12,7 +12,8 @@ import type { MutationCreateMessageArgs, Chat, QueryLoadRecipientsArgs, - ProfileInput + ProfileInput, + ReactionBy } from '../graphql/types.gen' import { publicGraphQLClient } from '../graphql/publicGraphQLClient' import { getToken, privateGraphQLClient } from '../graphql/privateGraphQLClient' @@ -269,7 +270,16 @@ export const apiClient = { if (resp.error) console.debug(resp) return resp.data.loadShouts }, - getReactionsBy: async ({ by, limit = REACTIONS_AMOUNT_PER_PAGE, offset = 0 }) => { + + getReactionsBy: async ({ + by, + limit = REACTIONS_AMOUNT_PER_PAGE, + offset = 0 + }: { + by: ReactionBy + limit: number + offset: number + }) => { const resp = await publicGraphQLClient.query(reactionsLoadBy, { by, limit, offset }).toPromise() console.debug(resp) return resp.data.loadReactionsBy