feed period select (#340)
* feed period select * fix, unused code removed * Fix styles * Fix styles * Fix styles --------- Co-authored-by: Igor Lobanov <igor.lobanov@onetwotrip.com> Co-authored-by: ilya-bkv <i.yablokov@ccmp.me>
This commit is contained in:
parent
88d35ce2bc
commit
3a7d138eef
|
@ -357,9 +357,12 @@
|
||||||
"This comment has not yet been rated": "This comment has not yet been rated",
|
"This comment has not yet been rated": "This comment has not yet been rated",
|
||||||
"This email is already taken. If it's you": "This email is already taken. If it's you",
|
"This email is already taken. If it's you": "This email is already taken. If it's you",
|
||||||
"This functionality is currently not available, we would like to work on this issue. Use the download link.": "This functionality is currently not available, we would like to work on this issue. Use the download link.",
|
"This functionality is currently not available, we would like to work on this issue. Use the download link.": "This functionality is currently not available, we would like to work on this issue. Use the download link.",
|
||||||
|
"This month": "This month",
|
||||||
"This post has not been rated yet": "This post has not been rated yet",
|
"This post has not been rated yet": "This post has not been rated yet",
|
||||||
"This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted": "This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted",
|
"This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted": "This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted",
|
||||||
"This way you ll be able to subscribe to authors, interesting topics and customize your feed": "This way you ll be able to subscribe to authors, interesting topics and customize your feed",
|
"This way you ll be able to subscribe to authors, interesting topics and customize your feed": "This way you ll be able to subscribe to authors, interesting topics and customize your feed",
|
||||||
|
"This week": "This week",
|
||||||
|
"This year": "This year",
|
||||||
"To leave a comment please": "To leave a comment please",
|
"To leave a comment please": "To leave a comment please",
|
||||||
"To write a comment, you must": "To write a comment, you must",
|
"To write a comment, you must": "To write a comment, you must",
|
||||||
"Top authors": "Authors rating",
|
"Top authors": "Authors rating",
|
||||||
|
|
|
@ -377,9 +377,12 @@
|
||||||
"This comment has not yet been rated": "Этот комментарий еще пока никто не оценил",
|
"This comment has not yet been rated": "Этот комментарий еще пока никто не оценил",
|
||||||
"This email is already taken. If it's you": "Такой email уже зарегистрирован. Если это вы",
|
"This email is already taken. If it's you": "Такой email уже зарегистрирован. Если это вы",
|
||||||
"This functionality is currently not available, we would like to work on this issue. Use the download link.": "В данный момент этот функционал не доступен, бы работаем над этой проблемой. Воспользуйтесь загрузкой по ссылке.",
|
"This functionality is currently not available, we would like to work on this issue. Use the download link.": "В данный момент этот функционал не доступен, бы работаем над этой проблемой. Воспользуйтесь загрузкой по ссылке.",
|
||||||
|
"This month": "За месяц",
|
||||||
"This post has not been rated yet": "Эту публикацию еще пока никто не оценил",
|
"This post has not been rated yet": "Эту публикацию еще пока никто не оценил",
|
||||||
"This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted": "Так мы поймем, что вы реальный человек, и учтем ваш голос. А вы увидите, как проголосовали другие",
|
"This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted": "Так мы поймем, что вы реальный человек, и учтем ваш голос. А вы увидите, как проголосовали другие",
|
||||||
"This way you ll be able to subscribe to authors, interesting topics and customize your feed": "Так вы сможете подписаться на авторов, интересные темы и настроить свою ленту",
|
"This way you ll be able to subscribe to authors, interesting topics and customize your feed": "Так вы сможете подписаться на авторов, интересные темы и настроить свою ленту",
|
||||||
|
"This week": "За неделю",
|
||||||
|
"This year": "За год",
|
||||||
"To leave a comment please": "Чтобы оставить комментарий, необходимо",
|
"To leave a comment please": "Чтобы оставить комментарий, необходимо",
|
||||||
"To write a comment, you must": "Чтобы написать комментарий, необходимо",
|
"To write a comment, you must": "Чтобы написать комментарий, необходимо",
|
||||||
"Top authors": "Рейтинг авторов",
|
"Top authors": "Рейтинг авторов",
|
||||||
|
|
|
@ -135,7 +135,7 @@ export const FullArticle = (props: Props) => {
|
||||||
scrollTo(commentsRef.current)
|
scrollTo(commentsRef.current)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { searchParams, changeSearchParam } = useRouter<ArticlePageSearchParams>()
|
const { searchParams, changeSearchParams } = useRouter<ArticlePageSearchParams>()
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
if (props.scrollToComments) {
|
if (props.scrollToComments) {
|
||||||
|
@ -146,7 +146,7 @@ export const FullArticle = (props: Props) => {
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
if (searchParams()?.scrollTo === 'comments' && commentsRef.current) {
|
if (searchParams()?.scrollTo === 'comments' && commentsRef.current) {
|
||||||
scrollToComments()
|
scrollToComments()
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
scrollTo: null,
|
scrollTo: null,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ export const FullArticle = (props: Props) => {
|
||||||
`[id='comment_${searchParams().commentId}']`,
|
`[id='comment_${searchParams().commentId}']`,
|
||||||
)
|
)
|
||||||
|
|
||||||
changeSearchParam({ commentId: null })
|
changeSearchParams({ commentId: null })
|
||||||
|
|
||||||
if (commentElement) {
|
if (commentElement) {
|
||||||
scrollTo(commentElement)
|
scrollTo(commentElement)
|
||||||
|
|
|
@ -13,7 +13,7 @@ type Props = {
|
||||||
|
|
||||||
export const AuthGuard = (props: Props) => {
|
export const AuthGuard = (props: Props) => {
|
||||||
const { isAuthenticated, isSessionLoaded } = useSession()
|
const { isAuthenticated, isSessionLoaded } = useSession()
|
||||||
const { changeSearchParam } = useRouter<RootSearchParams & AuthModalSearchParams>()
|
const { changeSearchParams } = useRouter<RootSearchParams & AuthModalSearchParams>()
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
if (props.disabled) {
|
if (props.disabled) {
|
||||||
|
@ -23,7 +23,7 @@ export const AuthGuard = (props: Props) => {
|
||||||
if (isAuthenticated()) {
|
if (isAuthenticated()) {
|
||||||
hideModal()
|
hideModal()
|
||||||
} else {
|
} else {
|
||||||
changeSearchParam(
|
changeSearchParams(
|
||||||
{
|
{
|
||||||
source: 'authguard',
|
source: 'authguard',
|
||||||
modal: 'auth',
|
modal: 'auth',
|
||||||
|
|
|
@ -29,7 +29,7 @@ export const AuthorBadge = (props: Props) => {
|
||||||
subscriptions,
|
subscriptions,
|
||||||
actions: { loadSubscriptions, requireAuthentication },
|
actions: { loadSubscriptions, requireAuthentication },
|
||||||
} = useSession()
|
} = useSession()
|
||||||
const { changeSearchParam } = useRouter()
|
const { changeSearchParams } = useRouter()
|
||||||
const { t, formatDate } = useLocalize()
|
const { t, formatDate } = useLocalize()
|
||||||
const subscribed = createMemo(() =>
|
const subscribed = createMemo(() =>
|
||||||
subscriptions().authors.some((author) => author.slug === props.author.slug),
|
subscriptions().authors.some((author) => author.slug === props.author.slug),
|
||||||
|
@ -54,7 +54,7 @@ export const AuthorBadge = (props: Props) => {
|
||||||
const initChat = () => {
|
const initChat = () => {
|
||||||
requireAuthentication(() => {
|
requireAuthentication(() => {
|
||||||
openPage(router, `inbox`)
|
openPage(router, `inbox`)
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
initChat: props.author.id.toString(),
|
initChat: props.author.id.toString(),
|
||||||
})
|
})
|
||||||
}, 'discussions')
|
}, 'discussions')
|
||||||
|
|
|
@ -72,11 +72,11 @@ export const AuthorCard = (props: Props) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: reimplement AuthorCard
|
// TODO: reimplement AuthorCard
|
||||||
const { changeSearchParam } = useRouter()
|
const { changeSearchParams } = useRouter()
|
||||||
const initChat = () => {
|
const initChat = () => {
|
||||||
requireAuthentication(() => {
|
requireAuthentication(() => {
|
||||||
openPage(router, `inbox`)
|
openPage(router, `inbox`)
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
initChat: props.author.id.toString(),
|
initChat: props.author.id.toString(),
|
||||||
})
|
})
|
||||||
}, 'discussions')
|
}, 'discussions')
|
||||||
|
|
|
@ -7,7 +7,7 @@ import styles from './Hero.module.scss'
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const { changeSearchParam } = useRouter<AuthModalSearchParams>()
|
const { changeSearchParams } = useRouter<AuthModalSearchParams>()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={styles.aboutDiscours}>
|
<div class={styles.aboutDiscours}>
|
||||||
|
@ -28,7 +28,7 @@ export default () => {
|
||||||
class="button"
|
class="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
showModal('auth')
|
showModal('auth')
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
mode: 'register',
|
mode: 'register',
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -98,11 +98,11 @@ export const ArticleCard = (props: ArticleCardProps) => {
|
||||||
|
|
||||||
const canEdit = () => props.article.authors?.some((a) => a.slug === user()?.slug)
|
const canEdit = () => props.article.authors?.some((a) => a.slug === user()?.slug)
|
||||||
|
|
||||||
const { changeSearchParam } = useRouter()
|
const { changeSearchParams } = useRouter()
|
||||||
const scrollToComments = (event) => {
|
const scrollToComments = (event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
openPage(router, 'article', { slug: props.article.slug })
|
openPage(router, 'article', { slug: props.article.slug })
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
scrollTo: 'comments',
|
scrollTo: 'comments',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ type FormFields = {
|
||||||
type ValidationErrors = Partial<Record<keyof FormFields, string | JSX.Element>>
|
type ValidationErrors = Partial<Record<keyof FormFields, string | JSX.Element>>
|
||||||
|
|
||||||
export const ForgotPasswordForm = () => {
|
export const ForgotPasswordForm = () => {
|
||||||
const { changeSearchParam } = useRouter<AuthModalSearchParams>()
|
const { changeSearchParams } = useRouter<AuthModalSearchParams>()
|
||||||
const { t, lang } = useLocalize()
|
const { t, lang } = useLocalize()
|
||||||
const handleEmailInput = (newEmail: string) => {
|
const handleEmailInput = (newEmail: string) => {
|
||||||
setValidationErrors(({ email: _notNeeded, ...rest }) => rest)
|
setValidationErrors(({ email: _notNeeded, ...rest }) => rest)
|
||||||
|
@ -119,7 +119,7 @@ export const ForgotPasswordForm = () => {
|
||||||
href="#"
|
href="#"
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
mode: 'register',
|
mode: 'register',
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
|
@ -141,7 +141,7 @@ export const ForgotPasswordForm = () => {
|
||||||
<span
|
<span
|
||||||
class={styles.authLink}
|
class={styles.authLink}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
mode: 'login',
|
mode: 'login',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ export const LoginForm = () => {
|
||||||
actions: { signIn },
|
actions: { signIn },
|
||||||
} = useSession()
|
} = useSession()
|
||||||
|
|
||||||
const { changeSearchParam } = useRouter<AuthModalSearchParams>()
|
const { changeSearchParams } = useRouter<AuthModalSearchParams>()
|
||||||
|
|
||||||
const [password, setPassword] = createSignal('')
|
const [password, setPassword] = createSignal('')
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ export const LoginForm = () => {
|
||||||
<span
|
<span
|
||||||
class="link"
|
class="link"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
mode: 'forgot-password',
|
mode: 'forgot-password',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ export const LoginForm = () => {
|
||||||
<span
|
<span
|
||||||
class={styles.authLink}
|
class={styles.authLink}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
mode: 'register',
|
mode: 'register',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ const handleEmailInput = (newEmail: string) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RegisterForm = () => {
|
export const RegisterForm = () => {
|
||||||
const { changeSearchParam } = useRouter<AuthModalSearchParams>()
|
const { changeSearchParams } = useRouter<AuthModalSearchParams>()
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const { emailChecks } = useEmailChecks()
|
const { emailChecks } = useEmailChecks()
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ export const RegisterForm = () => {
|
||||||
href="#"
|
href="#"
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
mode: 'login',
|
mode: 'login',
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
|
@ -255,7 +255,7 @@ export const RegisterForm = () => {
|
||||||
<span
|
<span
|
||||||
class={styles.authLink}
|
class={styles.authLink}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
mode: 'login',
|
mode: 'login',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ export const NotificationView = (props: Props) => {
|
||||||
actions: { markNotificationAsRead, hideNotificationsPanel },
|
actions: { markNotificationAsRead, hideNotificationsPanel },
|
||||||
} = useNotifications()
|
} = useNotifications()
|
||||||
|
|
||||||
const { changeSearchParam } = useRouter<ArticlePageSearchParams>()
|
const { changeSearchParams } = useRouter<ArticlePageSearchParams>()
|
||||||
|
|
||||||
const { t, formatDate, formatTime } = useLocalize()
|
const { t, formatDate, formatTime } = useLocalize()
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ export const NotificationView = (props: Props) => {
|
||||||
openPage(router, 'article', { slug: data().shout.slug })
|
openPage(router, 'article', { slug: data().shout.slug })
|
||||||
|
|
||||||
if (data().reactionIds) {
|
if (data().reactionIds) {
|
||||||
changeSearchParam({ commentId: data().reactionIds[0].toString() })
|
changeSearchParams({ commentId: data().reactionIds[0].toString() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ const ALPHABET = [...'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫ
|
||||||
export const AllAuthorsView = (props: Props) => {
|
export const AllAuthorsView = (props: Props) => {
|
||||||
const { t, lang } = useLocalize()
|
const { t, lang } = useLocalize()
|
||||||
const [limit, setLimit] = createSignal(PAGE_SIZE)
|
const [limit, setLimit] = createSignal(PAGE_SIZE)
|
||||||
const { searchParams, changeSearchParam } = useRouter<AllAuthorsPageSearchParams>()
|
const { searchParams, changeSearchParams } = useRouter<AllAuthorsPageSearchParams>()
|
||||||
const { sortedAuthors } = useAuthorsStore({
|
const { sortedAuthors } = useAuthorsStore({
|
||||||
authors: props.authors,
|
authors: props.authors,
|
||||||
sortBy: searchParams().by || 'shouts',
|
sortBy: searchParams().by || 'shouts',
|
||||||
|
@ -41,7 +41,7 @@ export const AllAuthorsView = (props: Props) => {
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
if (!searchParams().by) {
|
if (!searchParams().by) {
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
by: 'shouts',
|
by: 'shouts',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ const ALPHABET = [...'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫ
|
||||||
|
|
||||||
export const AllTopicsView = (props: Props) => {
|
export const AllTopicsView = (props: Props) => {
|
||||||
const { t, lang } = useLocalize()
|
const { t, lang } = useLocalize()
|
||||||
const { searchParams, changeSearchParam } = useRouter<AllTopicsPageSearchParams>()
|
const { searchParams, changeSearchParams } = useRouter<AllTopicsPageSearchParams>()
|
||||||
const [limit, setLimit] = createSignal(PAGE_SIZE)
|
const [limit, setLimit] = createSignal(PAGE_SIZE)
|
||||||
|
|
||||||
const { sortedTopics } = useTopicsStore({
|
const { sortedTopics } = useTopicsStore({
|
||||||
|
@ -43,7 +43,7 @@ export const AllTopicsView = (props: Props) => {
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
if (!searchParams().by) {
|
if (!searchParams().by) {
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
by: 'shouts',
|
by: 'shouts',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ export const Expo = (props: Props) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const getLoadShoutsFilters = (additionalFilters: LoadShoutsFilters = {}): LoadShoutsFilters => {
|
const getLoadShoutsFilters = (additionalFilters: LoadShoutsFilters = {}): LoadShoutsFilters => {
|
||||||
const filters = { ...additionalFilters }
|
const filters = { visibility: 'public', ...additionalFilters }
|
||||||
|
|
||||||
if (props.layout) {
|
if (props.layout) {
|
||||||
filters.layout = props.layout
|
filters.layout = props.layout
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
.feedFilter {
|
.feedFilter {
|
||||||
margin-bottom: 4.8rem;
|
|
||||||
margin-top: 0.2em;
|
|
||||||
|
|
||||||
@include media-breakpoint-down(md) {
|
@include media-breakpoint-down(md) {
|
||||||
margin-right: 4rem !important;
|
margin-right: 4rem !important;
|
||||||
}
|
}
|
||||||
|
@ -192,3 +189,25 @@
|
||||||
|
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filtersContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
|
||||||
|
.feedFilter {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
& > li {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.periodSwitcher {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import type { Author, LoadShoutsOptions, Reaction, Shout } from '../../../graphq
|
||||||
import { getPagePath } from '@nanostores/router'
|
import { getPagePath } from '@nanostores/router'
|
||||||
import { Meta } from '@solidjs/meta'
|
import { Meta } from '@solidjs/meta'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
import { createEffect, createSignal, For, on, onMount, Show } from 'solid-js'
|
import { createEffect, createMemo, createSignal, For, on, onMount, Show } from 'solid-js'
|
||||||
|
|
||||||
import { useLocalize } from '../../../context/localize'
|
import { useLocalize } from '../../../context/localize'
|
||||||
import { useReactions } from '../../../context/reactions'
|
import { useReactions } from '../../../context/reactions'
|
||||||
|
@ -13,6 +13,8 @@ import { useTopAuthorsStore } from '../../../stores/zine/topAuthors'
|
||||||
import { useTopicsStore } from '../../../stores/zine/topics'
|
import { useTopicsStore } from '../../../stores/zine/topics'
|
||||||
import { apiClient } from '../../../utils/apiClient'
|
import { apiClient } from '../../../utils/apiClient'
|
||||||
import { getImageUrl } from '../../../utils/getImageUrl'
|
import { getImageUrl } from '../../../utils/getImageUrl'
|
||||||
|
import { getServerDate } from '../../../utils/getServerDate'
|
||||||
|
import { DropDown } from '../../_shared/DropDown'
|
||||||
import { Icon } from '../../_shared/Icon'
|
import { Icon } from '../../_shared/Icon'
|
||||||
import { Loading } from '../../_shared/Loading'
|
import { Loading } from '../../_shared/Loading'
|
||||||
import { CommentDate } from '../../Article/CommentDate'
|
import { CommentDate } from '../../Article/CommentDate'
|
||||||
|
@ -28,8 +30,16 @@ import stylesTopic from '../../Feed/CardTopic.module.scss'
|
||||||
export const FEED_PAGE_SIZE = 20
|
export const FEED_PAGE_SIZE = 20
|
||||||
const UNRATED_ARTICLES_COUNT = 5
|
const UNRATED_ARTICLES_COUNT = 5
|
||||||
|
|
||||||
|
type FeedPeriod = 'week' | 'month' | 'year'
|
||||||
|
|
||||||
|
type PeriodItem = {
|
||||||
|
value: FeedPeriod
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
|
||||||
type FeedSearchParams = {
|
type FeedSearchParams = {
|
||||||
by: 'publish_date' | 'rating' | 'last_comment'
|
by: 'publish_date' | 'rating' | 'last_comment'
|
||||||
|
period: FeedPeriod
|
||||||
}
|
}
|
||||||
|
|
||||||
const getOrderBy = (by: FeedSearchParams['by']) => {
|
const getOrderBy = (by: FeedSearchParams['by']) => {
|
||||||
|
@ -53,7 +63,16 @@ type Props = {
|
||||||
|
|
||||||
export const Feed = (props: Props) => {
|
export const Feed = (props: Props) => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const { page, searchParams } = useRouter<FeedSearchParams>()
|
|
||||||
|
const monthPeriod: PeriodItem = { value: 'month', title: t('This month') }
|
||||||
|
|
||||||
|
const periods: PeriodItem[] = [
|
||||||
|
{ value: 'week', title: t('This week') },
|
||||||
|
monthPeriod,
|
||||||
|
{ value: 'year', title: t('This year') },
|
||||||
|
]
|
||||||
|
|
||||||
|
const { page, searchParams, changeSearchParams } = useRouter<FeedSearchParams>()
|
||||||
const [isLoading, setIsLoading] = createSignal(false)
|
const [isLoading, setIsLoading] = createSignal(false)
|
||||||
const [isRightColumnLoaded, setIsRightColumnLoaded] = createSignal(false)
|
const [isRightColumnLoaded, setIsRightColumnLoaded] = createSignal(false)
|
||||||
|
|
||||||
|
@ -64,6 +83,16 @@ export const Feed = (props: Props) => {
|
||||||
const [topComments, setTopComments] = createSignal<Reaction[]>([])
|
const [topComments, setTopComments] = createSignal<Reaction[]>([])
|
||||||
const [unratedArticles, setUnratedArticles] = createSignal<Shout[]>([])
|
const [unratedArticles, setUnratedArticles] = createSignal<Shout[]>([])
|
||||||
|
|
||||||
|
const currentPeriod = createMemo(() => {
|
||||||
|
const period = periods.find((p) => p.value === searchParams().period)
|
||||||
|
|
||||||
|
if (!period) {
|
||||||
|
return monthPeriod
|
||||||
|
}
|
||||||
|
|
||||||
|
return period
|
||||||
|
})
|
||||||
|
|
||||||
const {
|
const {
|
||||||
actions: { loadReactionsBy },
|
actions: { loadReactionsBy },
|
||||||
} = useReactions()
|
} = useReactions()
|
||||||
|
@ -86,7 +115,7 @@ export const Feed = (props: Props) => {
|
||||||
|
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(
|
||||||
() => page().route + searchParams().by,
|
() => page().route + searchParams().by + searchParams().period,
|
||||||
() => {
|
() => {
|
||||||
resetSortedArticles()
|
resetSortedArticles()
|
||||||
loadMore()
|
loadMore()
|
||||||
|
@ -94,6 +123,21 @@ export const Feed = (props: Props) => {
|
||||||
{ defer: true },
|
{ defer: true },
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const getFromDate = (period: FeedPeriod): Date => {
|
||||||
|
const now = new Date()
|
||||||
|
switch (period) {
|
||||||
|
case 'week': {
|
||||||
|
return new Date(now.setDate(now.getDate() - 7))
|
||||||
|
}
|
||||||
|
case 'month': {
|
||||||
|
return new Date(now.setMonth(now.getMonth() - 1))
|
||||||
|
}
|
||||||
|
case 'year': {
|
||||||
|
return new Date(now.setFullYear(now.getFullYear() - 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
const loadFeedShouts = () => {
|
const loadFeedShouts = () => {
|
||||||
const options: LoadShoutsOptions = {
|
const options: LoadShoutsOptions = {
|
||||||
limit: FEED_PAGE_SIZE,
|
limit: FEED_PAGE_SIZE,
|
||||||
|
@ -106,6 +150,12 @@ export const Feed = (props: Props) => {
|
||||||
options.order_by = orderBy
|
options.order_by = orderBy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (searchParams().by && searchParams().by !== 'publish_date') {
|
||||||
|
const period = searchParams().period || 'month'
|
||||||
|
const fromDate = getFromDate(period)
|
||||||
|
options.filters = { fromDate: getServerDate(fromDate) }
|
||||||
|
}
|
||||||
|
|
||||||
return props.loadShouts(options)
|
return props.loadShouts(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,32 +198,49 @@ export const Feed = (props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-12 offset-xl-1">
|
<div class="col-md-12 offset-xl-1">
|
||||||
<ul class={clsx(styles.feedFilter, 'view-switcher')}>
|
<div class={styles.filtersContainer}>
|
||||||
<li
|
<ul class={clsx('view-switcher', styles.feedFilter)}>
|
||||||
class={clsx({
|
<li
|
||||||
'view-switcher__item--selected': searchParams().by === 'publish_date' || !searchParams().by,
|
class={clsx({
|
||||||
})}
|
'view-switcher__item--selected':
|
||||||
>
|
searchParams().by === 'publish_date' || !searchParams().by,
|
||||||
<a href={getPagePath(router, page().route)}>{t('Recent')}</a>
|
})}
|
||||||
</li>
|
>
|
||||||
{/*<li>*/}
|
<a href={getPagePath(router, page().route)}>{t('Recent')}</a>
|
||||||
{/* <a href="/feed/?by=views">{t('Most read')}</a>*/}
|
</li>
|
||||||
{/*</li>*/}
|
{/*<li>*/}
|
||||||
<li
|
{/* <a href="/feed/?by=views">{t('Most read')}</a>*/}
|
||||||
class={clsx({
|
{/*</li>*/}
|
||||||
'view-switcher__item--selected': searchParams().by === 'rating',
|
<li
|
||||||
})}
|
class={clsx({
|
||||||
>
|
'view-switcher__item--selected': searchParams().by === 'rating',
|
||||||
<a href={`${getPagePath(router, page().route)}?by=rating`}>{t('Top rated')}</a>
|
})}
|
||||||
</li>
|
>
|
||||||
<li
|
<span class="link" onClick={() => changeSearchParams({ by: 'rating' })}>
|
||||||
class={clsx({
|
{t('Top rated')}
|
||||||
'view-switcher__item--selected': searchParams().by === 'last_comment',
|
</span>
|
||||||
})}
|
</li>
|
||||||
>
|
<li
|
||||||
<a href={`${getPagePath(router, page().route)}?by=last_comment`}>{t('Most commented')}</a>
|
class={clsx({
|
||||||
</li>
|
'view-switcher__item--selected': searchParams().by === 'last_comment',
|
||||||
</ul>
|
})}
|
||||||
|
>
|
||||||
|
<span class="link" onClick={() => changeSearchParams({ by: 'last_comment' })}>
|
||||||
|
{t('Most commented')}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<Show when={searchParams().by && searchParams().by !== 'publish_date'}>
|
||||||
|
<div>
|
||||||
|
<DropDown
|
||||||
|
options={periods}
|
||||||
|
currentOption={currentPeriod()}
|
||||||
|
triggerCssClass={styles.periodSwitcher}
|
||||||
|
onChange={(period) => changeSearchParams({ period: period.value })}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Show when={!isLoading()} fallback={<Loading />}>
|
<Show when={!isLoading()} fallback={<Loading />}>
|
||||||
<Show when={sortedArticles().length > 0}>
|
<Show when={sortedArticles().length > 0}>
|
||||||
|
|
|
@ -115,9 +115,7 @@ export const HomeView = (props: Props) => {
|
||||||
wrapper={'top-article'}
|
wrapper={'top-article'}
|
||||||
nodate={true}
|
nodate={true}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Row3 articles={sortedArticles().slice(6, 9)} nodate={true} />
|
<Row3 articles={sortedArticles().slice(6, 9)} nodate={true} />
|
||||||
|
|
||||||
<Beside
|
<Beside
|
||||||
beside={sortedArticles()[9]}
|
beside={sortedArticles()[9]}
|
||||||
title={t('Top authors')}
|
title={t('Top authors')}
|
||||||
|
@ -125,15 +123,11 @@ export const HomeView = (props: Props) => {
|
||||||
wrapper={'author'}
|
wrapper={'author'}
|
||||||
nodate={true}
|
nodate={true}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Show when={topMonthArticles()}>
|
<Show when={topMonthArticles()}>
|
||||||
<ArticleCardSwiper title={t('Top month articles')} slides={topMonthArticles()} />
|
<ArticleCardSwiper title={t('Top month articles')} slides={topMonthArticles()} />
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<Row2 articles={sortedArticles().slice(10, 12)} nodate={true} />
|
<Row2 articles={sortedArticles().slice(10, 12)} nodate={true} />
|
||||||
|
|
||||||
<RowShort articles={sortedArticles().slice(12, 16)} />
|
<RowShort articles={sortedArticles().slice(12, 16)} />
|
||||||
|
|
||||||
<Row1 article={sortedArticles()[16]} nodate={true} />
|
<Row1 article={sortedArticles()[16]} nodate={true} />
|
||||||
<Row3 articles={sortedArticles().slice(17, 20)} nodate={true} />
|
<Row3 articles={sortedArticles().slice(17, 20)} nodate={true} />
|
||||||
<Row3
|
<Row3
|
||||||
|
@ -141,13 +135,10 @@ export const HomeView = (props: Props) => {
|
||||||
header={<h2>{t('Top commented')}</h2>}
|
header={<h2>{t('Top commented')}</h2>}
|
||||||
nodate={true}
|
nodate={true}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{randomLayout()}
|
{randomLayout()}
|
||||||
|
|
||||||
<Show when={topArticles()}>
|
<Show when={topArticles()}>
|
||||||
<ArticleCardSwiper title={t('Favorite')} slides={topArticles()} />
|
<ArticleCardSwiper title={t('Favorite')} slides={topArticles()} />
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<Beside
|
<Beside
|
||||||
beside={sortedArticles()[20]}
|
beside={sortedArticles()[20]}
|
||||||
title={t('Top topics')}
|
title={t('Top topics')}
|
||||||
|
@ -156,11 +147,8 @@ export const HomeView = (props: Props) => {
|
||||||
isTopicCompact={true}
|
isTopicCompact={true}
|
||||||
nodate={true}
|
nodate={true}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Row3 articles={sortedArticles().slice(21, 24)} nodate={true} />
|
<Row3 articles={sortedArticles().slice(21, 24)} nodate={true} />
|
||||||
|
|
||||||
<Banner />
|
<Banner />
|
||||||
|
|
||||||
<Row2 articles={sortedArticles().slice(24, 26)} nodate={true} />
|
<Row2 articles={sortedArticles().slice(24, 26)} nodate={true} />
|
||||||
<Row3 articles={sortedArticles().slice(26, 29)} nodate={true} />
|
<Row3 articles={sortedArticles().slice(26, 29)} nodate={true} />
|
||||||
<Row2 articles={sortedArticles().slice(29, 31)} nodate={true} />
|
<Row2 articles={sortedArticles().slice(29, 31)} nodate={true} />
|
||||||
|
|
|
@ -52,7 +52,7 @@ export const InboxView = () => {
|
||||||
const [isClear, setClear] = createSignal(false)
|
const [isClear, setClear] = createSignal(false)
|
||||||
const { session } = useSession()
|
const { session } = useSession()
|
||||||
const currentUserId = createMemo(() => session()?.user.id)
|
const currentUserId = createMemo(() => session()?.user.id)
|
||||||
const { changeSearchParam, searchParams } = useRouter<InboxSearchParams>()
|
const { changeSearchParams, searchParams } = useRouter<InboxSearchParams>()
|
||||||
// Поиск по диалогам
|
// Поиск по диалогам
|
||||||
const getQuery = (query) => {
|
const getQuery = (query) => {
|
||||||
if (query().length >= 2) {
|
if (query().length >= 2) {
|
||||||
|
@ -67,7 +67,7 @@ export const InboxView = () => {
|
||||||
|
|
||||||
const handleOpenChat = async (chat: Chat) => {
|
const handleOpenChat = async (chat: Chat) => {
|
||||||
setCurrentDialog(chat)
|
setCurrentDialog(chat)
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
chat: chat.id,
|
chat: chat.id,
|
||||||
})
|
})
|
||||||
try {
|
try {
|
||||||
|
@ -126,7 +126,7 @@ export const InboxView = () => {
|
||||||
try {
|
try {
|
||||||
const newChat = await createChat([Number(searchParams().initChat)], '')
|
const newChat = await createChat([Number(searchParams().initChat)], '')
|
||||||
await loadChats()
|
await loadChats()
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
initChat: null,
|
initChat: null,
|
||||||
chat: newChat.chat.id,
|
chat: newChat.chat.id,
|
||||||
})
|
})
|
||||||
|
|
|
@ -41,7 +41,7 @@ const LOAD_MORE_PAGE_SIZE = 9 // Row3 + Row3 + Row3
|
||||||
|
|
||||||
export const TopicView = (props: Props) => {
|
export const TopicView = (props: Props) => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const { searchParams, changeSearchParam } = useRouter<TopicsPageSearchParams>()
|
const { searchParams, changeSearchParams } = useRouter<TopicsPageSearchParams>()
|
||||||
|
|
||||||
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ export const TopicView = (props: Props) => {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
by: 'recent',
|
by: 'recent',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -135,17 +135,17 @@ export const TopicView = (props: Props) => {
|
||||||
</li>
|
</li>
|
||||||
{/*TODO: server sort*/}
|
{/*TODO: server sort*/}
|
||||||
{/*<li classList={{ 'view-switcher__item--selected': getSearchParams().by === 'rating' }}>*/}
|
{/*<li classList={{ 'view-switcher__item--selected': getSearchParams().by === 'rating' }}>*/}
|
||||||
{/* <button type="button" onClick={() => changeSearchParam('by', 'rating')}>*/}
|
{/* <button type="button" onClick={() => changeSearchParams('by', 'rating')}>*/}
|
||||||
{/* {t('Popular')}*/}
|
{/* {t('Popular')}*/}
|
||||||
{/* </button>*/}
|
{/* </button>*/}
|
||||||
{/*</li>*/}
|
{/*</li>*/}
|
||||||
{/*<li classList={{ 'view-switcher__item--selected': getSearchParams().by === 'viewed' }}>*/}
|
{/*<li classList={{ 'view-switcher__item--selected': getSearchParams().by === 'viewed' }}>*/}
|
||||||
{/* <button type="button" onClick={() => changeSearchParam('by', 'viewed')}>*/}
|
{/* <button type="button" onClick={() => changeSearchParams('by', 'viewed')}>*/}
|
||||||
{/* {t('Views')}*/}
|
{/* {t('Views')}*/}
|
||||||
{/* </button>*/}
|
{/* </button>*/}
|
||||||
{/*</li>*/}
|
{/*</li>*/}
|
||||||
{/*<li classList={{ 'view-switcher__item--selected': getSearchParams().by === 'commented' }}>*/}
|
{/*<li classList={{ 'view-switcher__item--selected': getSearchParams().by === 'commented' }}>*/}
|
||||||
{/* <button type="button" onClick={() => changeSearchParam('by', 'commented')}>*/}
|
{/* <button type="button" onClick={() => changeSearchParams('by', 'commented')}>*/}
|
||||||
{/* {t('Discussing')}*/}
|
{/* {t('Discussing')}*/}
|
||||||
{/* </button>*/}
|
{/* </button>*/}
|
||||||
{/*</li>*/}
|
{/*</li>*/}
|
||||||
|
|
7
src/components/_shared/DropDown/DropDown.module.scss
Normal file
7
src/components/_shared/DropDown/DropDown.module.scss
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
.chevron {
|
||||||
|
vertical-align: top;
|
||||||
|
|
||||||
|
&.rotate {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
69
src/components/_shared/DropDown/DropDown.tsx
Normal file
69
src/components/_shared/DropDown/DropDown.tsx
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
import type { PopupProps } from '../Popup'
|
||||||
|
|
||||||
|
import { clsx } from 'clsx'
|
||||||
|
import { createSignal, For, Show } from 'solid-js'
|
||||||
|
|
||||||
|
import { Popup } from '../Popup'
|
||||||
|
|
||||||
|
import styles from './DropDown.module.scss'
|
||||||
|
|
||||||
|
export type Option = {
|
||||||
|
value: string | number
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Props<TOption> = {
|
||||||
|
class?: string
|
||||||
|
popupProps?: PopupProps
|
||||||
|
options: TOption[]
|
||||||
|
currentOption: TOption
|
||||||
|
triggerCssClass?: string
|
||||||
|
onChange: (option: TOption) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const Chevron = (props: { class?: string }) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
class={props.class}
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="18"
|
||||||
|
height="18"
|
||||||
|
viewBox="0 0 18 18"
|
||||||
|
fill="none"
|
||||||
|
>
|
||||||
|
<path d="M13.5 6L9 12L4.5 6H13.5Z" fill="#141414" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DropDown = <TOption extends Option = Option>(props: Props<TOption>) => {
|
||||||
|
const [isPopupVisible, setIsPopupVisible] = createSignal(false)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Show when={props.currentOption} keyed={true}>
|
||||||
|
<Popup
|
||||||
|
trigger={
|
||||||
|
<div class={props.triggerCssClass}>
|
||||||
|
{props.currentOption.title}{' '}
|
||||||
|
<Chevron
|
||||||
|
class={clsx(styles.chevron, {
|
||||||
|
[styles.rotate]: isPopupVisible(),
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
variant="tiny"
|
||||||
|
onVisibilityChange={(isVisible) => setIsPopupVisible(isVisible)}
|
||||||
|
{...props.popupProps}
|
||||||
|
>
|
||||||
|
<For each={props.options.filter((p) => p.value !== props.currentOption.value)}>
|
||||||
|
{(option) => (
|
||||||
|
<div class="link" onClick={() => props.onChange(option)}>
|
||||||
|
{option.title}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</Popup>
|
||||||
|
</Show>
|
||||||
|
)
|
||||||
|
}
|
1
src/components/_shared/DropDown/index.ts
Normal file
1
src/components/_shared/DropDown/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export { DropDown } from './DropDown'
|
|
@ -32,7 +32,9 @@ export const Popup = (props: PopupProps) => {
|
||||||
useOutsideClickHandler({
|
useOutsideClickHandler({
|
||||||
containerRef,
|
containerRef,
|
||||||
predicate: () => isVisible(),
|
predicate: () => isVisible(),
|
||||||
handler: () => setIsVisible(false),
|
handler: () => {
|
||||||
|
setIsVisible(false)
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const toggle = () => setIsVisible((oldVisible) => !oldVisible)
|
const toggle = () => setIsVisible((oldVisible) => !oldVisible)
|
||||||
|
|
|
@ -32,7 +32,7 @@ export function useLocalize() {
|
||||||
|
|
||||||
export const LocalizeProvider = (props: { children: JSX.Element }) => {
|
export const LocalizeProvider = (props: { children: JSX.Element }) => {
|
||||||
const [lang, setLang] = createSignal<Language>(i18next.language === 'en' ? 'en' : 'ru')
|
const [lang, setLang] = createSignal<Language>(i18next.language === 'en' ? 'en' : 'ru')
|
||||||
const { searchParams, changeSearchParam } = useRouter<{
|
const { searchParams, changeSearchParams } = useRouter<{
|
||||||
lng: string
|
lng: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ export const LocalizeProvider = (props: { children: JSX.Element }) => {
|
||||||
changeLanguage(lng)
|
changeLanguage(lng)
|
||||||
setLang(lng)
|
setLang(lng)
|
||||||
Cookie.set('lng', lng)
|
Cookie.set('lng', lng)
|
||||||
changeSearchParam({ lng: null }, true)
|
changeSearchParams({ lng: null }, true)
|
||||||
})
|
})
|
||||||
|
|
||||||
const formatTime = (date: Date, options: Intl.DateTimeFormatOptions = {}) => {
|
const formatTime = (date: Date, options: Intl.DateTimeFormatOptions = {}) => {
|
||||||
|
|
|
@ -12,7 +12,10 @@ import { loadMyFeed, loadShouts, resetSortedArticles } from '../stores/zine/arti
|
||||||
const handleFeedLoadShouts = (options: LoadShoutsOptions) => {
|
const handleFeedLoadShouts = (options: LoadShoutsOptions) => {
|
||||||
return loadShouts({
|
return loadShouts({
|
||||||
...options,
|
...options,
|
||||||
filters: { visibility: 'community' },
|
filters: {
|
||||||
|
visibility: 'community',
|
||||||
|
...options.filters,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ export const useRouter = <TSearchParams extends Record<string, string> = Record<
|
||||||
const page = useStore(routerStore)
|
const page = useStore(routerStore)
|
||||||
const searchParams = useStore(searchParamsStore) as unknown as Accessor<TSearchParams>
|
const searchParams = useStore(searchParamsStore) as unknown as Accessor<TSearchParams>
|
||||||
|
|
||||||
const changeSearchParam = (newValues: Partial<TSearchParams>, replace = false) => {
|
const changeSearchParams = (newValues: Partial<TSearchParams>, replace = false) => {
|
||||||
const newSearchParams = { ...searchParamsStore.get() }
|
const newSearchParams = { ...searchParamsStore.get() }
|
||||||
|
|
||||||
Object.keys(newValues).forEach((key) => {
|
Object.keys(newValues).forEach((key) => {
|
||||||
|
@ -155,6 +155,6 @@ export const useRouter = <TSearchParams extends Record<string, string> = Record<
|
||||||
return {
|
return {
|
||||||
page,
|
page,
|
||||||
searchParams,
|
searchParams,
|
||||||
changeSearchParam,
|
changeSearchParams,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,13 +42,13 @@ export const MODALS: Record<ModalType, ModalType> = {
|
||||||
|
|
||||||
const [modal, setModal] = createSignal<ModalType>(null)
|
const [modal, setModal] = createSignal<ModalType>(null)
|
||||||
|
|
||||||
const { searchParams, changeSearchParam } = useRouter<
|
const { searchParams, changeSearchParams } = useRouter<
|
||||||
AuthModalSearchParams & ConfirmEmailSearchParams & RootSearchParams
|
AuthModalSearchParams & ConfirmEmailSearchParams & RootSearchParams
|
||||||
>()
|
>()
|
||||||
|
|
||||||
export const showModal = (modalType: ModalType, modalSource?: AuthModalSource) => {
|
export const showModal = (modalType: ModalType, modalSource?: AuthModalSource) => {
|
||||||
if (modalSource) {
|
if (modalSource) {
|
||||||
changeSearchParam({
|
changeSearchParams({
|
||||||
source: modalSource,
|
source: modalSource,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ export const hideModal = () => {
|
||||||
newSearchParams.mode = null
|
newSearchParams.mode = null
|
||||||
}
|
}
|
||||||
|
|
||||||
changeSearchParam(newSearchParams, true)
|
changeSearchParams(newSearchParams, true)
|
||||||
|
|
||||||
setModal(null)
|
setModal(null)
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,7 +204,7 @@ a:hover,
|
||||||
a:visited,
|
a:visited,
|
||||||
a:link,
|
a:link,
|
||||||
.link {
|
.link {
|
||||||
border-bottom: 1px solid rgb(0 0 0 / 30%);
|
border-bottom: 2px solid rgb(0 0 0 / 30%);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
@ -624,6 +624,10 @@ figure {
|
||||||
margin-bottom: 0.6em;
|
margin-bottom: 0.6em;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
|
.link {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
@ -645,9 +649,10 @@ figure {
|
||||||
}
|
}
|
||||||
|
|
||||||
a,
|
a,
|
||||||
|
.link,
|
||||||
.linkReplacement,
|
.linkReplacement,
|
||||||
button {
|
button {
|
||||||
border-bottom: 2px solid transparent;
|
border-bottom: 1px solid transparent;
|
||||||
color: var(--link-color);
|
color: var(--link-color);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: inherit;
|
font-weight: inherit;
|
||||||
|
@ -662,6 +667,7 @@ figure {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
a,
|
a,
|
||||||
|
.link,
|
||||||
.linkReplacement,
|
.linkReplacement,
|
||||||
button {
|
button {
|
||||||
border-bottom: 2px solid #000;
|
border-bottom: 2px solid #000;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user