refactor contextual modals (#141)
* refactor contextual modals * refactor by review comments * refactored auth modal header to separate component, lint --------- Co-authored-by: bniwredyc <bniwredyc@gmail.com>
This commit is contained in:
parent
ed5f34ac69
commit
d86d5e6028
10
.eslintrc.js
10
.eslintrc.js
|
@ -30,16 +30,12 @@ module.exports = {
|
|||
'@typescript-eslint/no-unused-vars': [
|
||||
'warn',
|
||||
{
|
||||
argsIgnorePattern: '^_',
|
||||
varsIgnorePattern: '^log$'
|
||||
argsIgnorePattern: '^_'
|
||||
}
|
||||
],
|
||||
// TODO: Remove any usage and enable
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-non-null-assertion': 'error',
|
||||
|
||||
// solid-js fix
|
||||
'import/no-unresolved': [2, { ignore: ['solid-js/'] }]
|
||||
// TODO: Remove any usage and enable
|
||||
'@typescript-eslint/no-explicit-any': 'off'
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -61,11 +61,11 @@
|
|||
"Create Chat": "Create Chat",
|
||||
"Create Group": "Create a group",
|
||||
"Create account": "Create an account",
|
||||
"Create account from bookmark": "Create an account to add to your bookmarks",
|
||||
"Create account from discussions": "Create an account to participate in discussions",
|
||||
"Create account from follow": "Create an account to subscribe",
|
||||
"Create account from subscribe": "Create an account to subscribe to new publications",
|
||||
"Create account from vote": "Create an account to vote",
|
||||
"Create an account to add to your bookmarks": "Create an account to add to your bookmarks",
|
||||
"Create an account to participate in discussions": "Create an account to participate in discussions",
|
||||
"Create an account to subscribe": "Create an account to subscribe",
|
||||
"Create an account to subscribe to new publications": "Create an account to subscribe to new publications",
|
||||
"Create an account to vote": "Create an account to vote",
|
||||
"Create gallery": "Create gallery",
|
||||
"Create post": "Create post",
|
||||
"Create video": "Create video",
|
||||
|
@ -91,6 +91,15 @@
|
|||
"Enter image title": "Enter image title",
|
||||
"Enter text": "Enter text",
|
||||
"Enter the Discours": "Enter the Discours",
|
||||
"Enter the Discours to add to your bookmarks": "Enter the Discours to add to your bookmarks",
|
||||
"Enter the Discours to participate in discussions": "Enter the Discours to participate in discussions",
|
||||
"Enter the Discours to subscribe": "Enter the Discours to subscribe",
|
||||
"Enter the Discours to subscribe to new publications": "Enter the Discours to subscribe to new publications",
|
||||
"Enter the Discours to vote": "Enter the Discours to vote",
|
||||
"In bookmarks, you can save favorite discussions and materials that you want to return to": "In bookmarks, you can save favorite discussions and materials that you want to return to",
|
||||
"You ll be able to participate in discussions, rate others' comments and learn about new responses": "You ll be able to participate in discussions, rate others' comments and learn about new responses",
|
||||
"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 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",
|
||||
"Enter the code or click the link from email to confirm": "Enter the code from the email or follow the link in the email to confirm registration",
|
||||
"Enter your new password": "Enter your new password",
|
||||
"Error": "Error",
|
||||
|
|
|
@ -65,11 +65,11 @@
|
|||
"Create Chat": "Создать чат",
|
||||
"Create Group": "Создать группу",
|
||||
"Create account": "Создать аккаунт",
|
||||
"Create account from bookmark": "Создайте аккаунт, чтобы добавить в закладки",
|
||||
"Create account from discussions": "Создайте аккаунт для участия в дискуссиях",
|
||||
"Create account from follow": "Создайте аккаунт, чтобы подписаться",
|
||||
"Create account from subscribe": "Создайте аккаунт для подписки на новые публикации",
|
||||
"Create account from vote": "Создайте аккаунт, чтобы голосовать",
|
||||
"Create an account to add to your bookmarks": "Создайте аккаунт, чтобы добавить в закладки",
|
||||
"Create an account to participate in discussions": "Создайте аккаунт для участия в дискуссиях",
|
||||
"Create an account to subscribe": "Создайте аккаунт, чтобы подписаться",
|
||||
"Create an account to subscribe to new publications": "Создайте аккаунт для подписки на новые публикации",
|
||||
"Create an account to vote": "Создайте аккаунт, чтобы голосовать",
|
||||
"Create gallery": "Создать галерею",
|
||||
"Create post": "Создать публикацию",
|
||||
"Create video": "Создать видео",
|
||||
|
@ -96,6 +96,15 @@
|
|||
"Enter image title": "Введите название изображения",
|
||||
"Enter text": "Введите текст",
|
||||
"Enter the Discours": "Войти в Дискурс",
|
||||
"Enter the Discours to add to your bookmarks": "Войдите в Дискурс, чтобы добавить в закладки",
|
||||
"Enter the Discours to participate in discussions": "Войдите в Дискурс для участия в дискуссиях",
|
||||
"Enter the Discours to subscribe to new publications": "Войдите в Дискурс, чтобы подписаться",
|
||||
"Enter the Discours to subscribe": "Войдите в Дискурс для подписки на новые публикации",
|
||||
"Enter the Discours to vote": "Войдите в Дискурс, чтобы голосовать",
|
||||
"In bookmarks, you can save favorite discussions and materials that you want to return to": "В закладках можно сохранять избранные дискуссии и материалы, к которым хочется вернуться",
|
||||
"You ll be able to participate in discussions, rate others' comments and learn about new responses": "Вы сможете участвовать в обсуждениях, оценивать комментарии других и узнавать о новых ответах",
|
||||
"This way you ll be able to subscribe to authors, interesting topics and customize your feed": "Так вы сможете подписаться на авторов, интересные темы и настроить свою ленту",
|
||||
"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": "Так мы поймем, что вы реальный человек, и учтем ваш голос. А вы увидите, как проголосовали другие",
|
||||
"Enter the code or click the link from email to confirm": "Введите код из письма или пройдите по ссылке в письме для подтверждения регистрации",
|
||||
"Enter your new password": "Введите новый пароль",
|
||||
"Error": "Ошибка",
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { createSignal, Show } from 'solid-js'
|
||||
import MarkdownIt from 'markdown-it'
|
||||
import { clsx } from 'clsx'
|
||||
import styles from './Message.module.scss'
|
||||
import DialogAvatar from './DialogAvatar'
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
.authFormDescription {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 18px;
|
||||
letter-spacing: -0.14px;
|
||||
margin: 12px 0 54px;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
import styles from './AuthModalHeader.module.scss'
|
||||
import { Show } from 'solid-js'
|
||||
import { useLocalize } from '../../../../context/localize'
|
||||
import { useRouter } from '../../../../stores/router'
|
||||
import { AuthModalSearchParams } from '../types'
|
||||
|
||||
type Props = {
|
||||
modalType: 'login' | 'register'
|
||||
}
|
||||
|
||||
export const AuthModalHeader = (props: Props) => {
|
||||
const { t } = useLocalize()
|
||||
const { searchParams } = useRouter<AuthModalSearchParams>()
|
||||
const { source } = searchParams()
|
||||
|
||||
const generateModalTextsFromSource = (
|
||||
modalType: 'login' | 'register'
|
||||
): { title: string; description: string } => {
|
||||
const title = modalType === 'login' ? 'Enter the Discours' : 'Create account'
|
||||
|
||||
switch (source) {
|
||||
case 'bookmark': {
|
||||
return {
|
||||
title: t(`${title} to add to your bookmarks`),
|
||||
description: t(
|
||||
'In bookmarks, you can save favorite discussions and materials that you want to return to'
|
||||
)
|
||||
}
|
||||
}
|
||||
case 'discussions': {
|
||||
return {
|
||||
title: t(`${title} to participate in discussions`),
|
||||
description: t(
|
||||
"You ll be able to participate in discussions, rate others' comments and learn about new responses"
|
||||
)
|
||||
}
|
||||
}
|
||||
case 'follow': {
|
||||
return {
|
||||
title: t(`${title} to subscribe`),
|
||||
description: t(
|
||||
'This way you ll be able to subscribe to authors, interesting topics and customize your feed'
|
||||
)
|
||||
}
|
||||
}
|
||||
case 'subscribe': {
|
||||
return {
|
||||
title: t(`${title} to subscribe to new publications`),
|
||||
description: t(
|
||||
'This way you ll be able to subscribe to authors, interesting topics and customize your feed'
|
||||
)
|
||||
}
|
||||
}
|
||||
case 'vote': {
|
||||
return {
|
||||
title: t(`${title} to vote`),
|
||||
description: t(
|
||||
'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'
|
||||
)
|
||||
}
|
||||
}
|
||||
default: {
|
||||
return {
|
||||
title: t(title),
|
||||
description: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const { title, description } = generateModalTextsFromSource(props.modalType)
|
||||
|
||||
return (
|
||||
<>
|
||||
<h4>{title}</h4>
|
||||
<Show when={description}>
|
||||
<p class={styles.authFormDescription} innerHTML={description} />
|
||||
</Show>
|
||||
</>
|
||||
)
|
||||
}
|
1
src/components/Nav/AuthModal/AuthModalHeader/index.ts
Normal file
1
src/components/Nav/AuthModal/AuthModalHeader/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export { AuthModalHeader } from './AuthModalHeader'
|
|
@ -10,11 +10,10 @@ import { hideModal } from '../../../stores/ui'
|
|||
import { useSession } from '../../../context/session'
|
||||
import { signSendLink } from '../../../stores/auth'
|
||||
import { validateEmail } from '../../../utils/validateEmail'
|
||||
import { generateModalTitleFromSource } from '../../../utils/custom-i18n'
|
||||
|
||||
import { useSnackbar } from '../../../context/snackbar'
|
||||
import { useLocalize } from '../../../context/localize'
|
||||
import { Icon } from '../../_shared/Icon'
|
||||
import { AuthModalHeader } from './AuthModalHeader'
|
||||
|
||||
type FormFields = {
|
||||
email: string
|
||||
|
@ -118,7 +117,7 @@ export const LoginForm = () => {
|
|||
return (
|
||||
<form onSubmit={handleSubmit} class={styles.authForm}>
|
||||
<div>
|
||||
<h4>{generateModalTitleFromSource('login')}</h4>
|
||||
<AuthModalHeader modalType="login" />
|
||||
<Show when={submitError()}>
|
||||
<div class={styles.authInfo}>
|
||||
<div class={styles.warn}>{submitError()}</div>
|
||||
|
|
|
@ -12,7 +12,7 @@ import { checkEmail, useEmailChecks } from '../../../stores/emailChecks'
|
|||
import { register } from '../../../stores/auth'
|
||||
import { useLocalize } from '../../../context/localize'
|
||||
import { validateEmail } from '../../../utils/validateEmail'
|
||||
import { generateModalTitleFromSource } from '../../../utils/custom-i18n'
|
||||
import { AuthModalHeader } from './AuthModalHeader'
|
||||
|
||||
type FormFields = {
|
||||
name: string
|
||||
|
@ -137,7 +137,7 @@ export const RegisterForm = () => {
|
|||
<Show when={!isSuccess()}>
|
||||
<form onSubmit={handleSubmit} class={styles.authForm}>
|
||||
<div>
|
||||
<h4>{generateModalTitleFromSource('register')}</h4>
|
||||
<AuthModalHeader modalType="register" />
|
||||
<Show when={submitError()}>
|
||||
<div class={styles.authInfo}>
|
||||
<ul>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Dynamic } from 'solid-js/web'
|
||||
import { Component, createEffect, createMemo } from 'solid-js'
|
||||
import { Show, Component, createEffect, createMemo } from 'solid-js'
|
||||
import { hideModal } from '../../../stores/ui'
|
||||
import { useRouter } from '../../../stores/router'
|
||||
import { clsx } from 'clsx'
|
||||
|
@ -24,6 +24,8 @@ export const AuthModal = () => {
|
|||
const { t } = useLocalize()
|
||||
const { searchParams } = useRouter<AuthModalSearchParams>()
|
||||
|
||||
const { source } = searchParams()
|
||||
|
||||
const mode = createMemo<AuthModalMode>(() => {
|
||||
return AUTH_MODAL_MODES[searchParams().mode] ? searchParams().mode : 'login'
|
||||
})
|
||||
|
@ -37,39 +39,47 @@ export const AuthModal = () => {
|
|||
return (
|
||||
<div
|
||||
ref={rootRef}
|
||||
class={clsx('row', styles.view)}
|
||||
class={clsx(styles.view, {
|
||||
row: !source
|
||||
})}
|
||||
classList={{ [styles.signUp]: mode() === 'register' || mode() === 'confirm-email' }}
|
||||
>
|
||||
<div class={clsx('col-md-12 d-none d-md-flex', styles.authImage)}>
|
||||
<div
|
||||
class={styles.authImageText}
|
||||
classList={{ [styles.hidden]: mode() !== 'register' && mode() !== 'confirm-email' }}
|
||||
>
|
||||
<div>
|
||||
<h4>{t(`Join the global community of authors!`)}</h4>
|
||||
<p class={styles.authBenefits}>
|
||||
{t(
|
||||
'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'
|
||||
)}
|
||||
.
|
||||
{t('New stories every day and even more!')}
|
||||
<Show when={!source}>
|
||||
<div class={clsx('col-md-12 d-none d-md-flex', styles.authImage)}>
|
||||
<div
|
||||
class={styles.authImageText}
|
||||
classList={{ [styles.hidden]: mode() !== 'register' && mode() !== 'confirm-email' }}
|
||||
>
|
||||
<div>
|
||||
<h4>{t(`Join the global community of authors!`)}</h4>
|
||||
<p class={styles.authBenefits}>
|
||||
{t(
|
||||
'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'
|
||||
)}
|
||||
.
|
||||
{t('New stories every day and even more!')}
|
||||
</p>
|
||||
</div>
|
||||
<p class={styles.disclaimer}>
|
||||
{t('By signing up you agree with our')}{' '}
|
||||
<a
|
||||
href="/about/terms-of-use"
|
||||
onClick={() => {
|
||||
hideModal()
|
||||
}}
|
||||
>
|
||||
{t('terms of use')}
|
||||
</a>
|
||||
, {t('personal data usage and email notifications')}.
|
||||
</p>
|
||||
</div>
|
||||
<p class={styles.disclaimer}>
|
||||
{t('By signing up you agree with our')}{' '}
|
||||
<a
|
||||
href="/about/terms-of-use"
|
||||
onClick={() => {
|
||||
hideModal()
|
||||
}}
|
||||
>
|
||||
{t('terms of use')}
|
||||
</a>
|
||||
, {t('personal data usage and email notifications')}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class={clsx('col-md-12', styles.auth)}>
|
||||
</div>{' '}
|
||||
</Show>
|
||||
<div
|
||||
class={clsx(styles.auth, {
|
||||
'col-md-12': !source
|
||||
})}
|
||||
>
|
||||
<Dynamic component={AUTH_MODAL_MODES[mode()]} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -22,24 +22,24 @@ type Props = {
|
|||
scrollToComments?: (value: boolean) => void
|
||||
}
|
||||
|
||||
type HeaderSearchParams = {
|
||||
source?: string
|
||||
}
|
||||
|
||||
export const Header = (props: Props) => {
|
||||
const { t } = useLocalize()
|
||||
|
||||
// signals
|
||||
const { modal } = useModalStore()
|
||||
|
||||
const { page, searchParams } = useRouter<HeaderSearchParams>()
|
||||
|
||||
const [getIsScrollingBottom, setIsScrollingBottom] = createSignal(false)
|
||||
const [getIsScrolled, setIsScrolled] = createSignal(false)
|
||||
const [fixed, setFixed] = createSignal(false)
|
||||
const [isSharePopupVisible, setIsSharePopupVisible] = createSignal(false)
|
||||
const [isProfilePopupVisible, setIsProfilePopupVisible] = createSignal(false)
|
||||
|
||||
const { modal } = useModalStore()
|
||||
|
||||
const { page } = useRouter()
|
||||
|
||||
// methods
|
||||
|
||||
const toggleFixed = () => setFixed((oldFixed) => !oldFixed)
|
||||
// effects
|
||||
|
||||
let windowScrollTop = 0
|
||||
|
||||
|
@ -91,7 +91,7 @@ export const Header = (props: Props) => {
|
|||
[styles.headerWithTitle]: Boolean(props.title)
|
||||
}}
|
||||
>
|
||||
<Modal variant="wide" name="auth" noPadding={true}>
|
||||
<Modal variant={searchParams().source ? 'narrow' : 'wide'} name="auth" noPadding={true}>
|
||||
<AuthModal />
|
||||
</Modal>
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { createEffect, createSignal, Show } from 'solid-js'
|
||||
import type { JSX } from 'solid-js'
|
||||
import { clsx } from 'clsx'
|
||||
|
||||
import { hideModal, useModalStore } from '../../../stores/ui'
|
||||
import { useEscKeyDownHandler } from '../../../utils/useEscKeyDownHandler'
|
||||
import { clsx } from 'clsx'
|
||||
|
||||
import styles from './Modal.module.scss'
|
||||
|
||||
interface ModalProps {
|
||||
|
@ -16,6 +18,8 @@ interface ModalProps {
|
|||
export const Modal = (props: ModalProps) => {
|
||||
const { modal } = useModalStore()
|
||||
|
||||
const [visible, setVisible] = createSignal(false)
|
||||
|
||||
const handleHide = () => {
|
||||
if (modal()) {
|
||||
hideModal()
|
||||
|
@ -25,8 +29,6 @@ export const Modal = (props: ModalProps) => {
|
|||
|
||||
useEscKeyDownHandler(handleHide)
|
||||
|
||||
const [visible, setVisible] = createSignal(false)
|
||||
|
||||
createEffect(() => {
|
||||
setVisible(modal() === props.name)
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { createEffect, createSignal, For, Match, Show, Switch, on } from 'solid-js'
|
||||
import { createEffect, createSignal, For, Show, on } from 'solid-js'
|
||||
import { MediaItem, UploadedFile } from '../../../pages/types'
|
||||
import { Icon } from '../Icon'
|
||||
import { Popover } from '../Popover'
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import type { Accessor, JSX } from 'solid-js'
|
||||
import { createContext, createSignal, useContext, createMemo } from 'solid-js'
|
||||
import { createSubClient } from '../graphql/privateGraphQLClient'
|
||||
import { createContext, createSignal, useContext } from 'solid-js'
|
||||
// import { createSubClient } from '../graphql/privateGraphQLClient'
|
||||
import type { Chat, Message, MutationCreateMessageArgs } from '../graphql/types.gen'
|
||||
import { apiClient } from '../utils/apiClient'
|
||||
import newMessage from '../graphql/subs/new-message'
|
||||
import type { Client } from '@urql/core'
|
||||
import { pipe, subscribe } from 'wonka'
|
||||
// import type { Client } from '@urql/core'
|
||||
import { loadMessages } from '../stores/inbox'
|
||||
|
||||
type InboxContextType = {
|
||||
|
@ -29,7 +27,7 @@ export function useInbox() {
|
|||
export const InboxProvider = (props: { children: JSX.Element }) => {
|
||||
const [chats, setChats] = createSignal<Chat[]>([])
|
||||
const [messages, setMessages] = createSignal<Message[]>([])
|
||||
const subclient = createMemo<Client>(() => createSubClient())
|
||||
// const subclient = createMemo<Client>(() => createSubClient())
|
||||
const loadChats = async () => {
|
||||
try {
|
||||
const newChats = await apiClient.getChats({ limit: 50, offset: 0 })
|
||||
|
|
|
@ -64,7 +64,7 @@ export const hideModal = () => {
|
|||
}
|
||||
|
||||
changeSearchParam('modal', null, true)
|
||||
changeSearchParam('source', null, true)
|
||||
changeSearchParam('source', null)
|
||||
|
||||
setModal(null)
|
||||
}
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
import { useRouter } from '../stores/router'
|
||||
import type { AuthModalSearchParams } from '../components/Nav/AuthModal/types'
|
||||
import { useLocalize } from '../context/localize'
|
||||
|
||||
export const generateModalTitleFromSource = (modalType: 'login' | 'register') => {
|
||||
const { searchParams } = useRouter<AuthModalSearchParams>()
|
||||
const { t } = useLocalize()
|
||||
|
||||
const { source } = searchParams()
|
||||
|
||||
let title = modalType === 'login' ? 'Enter the Discours' : 'Create account'
|
||||
|
||||
if (source) title = `${title} from ${source}`
|
||||
|
||||
return t(title)
|
||||
}
|
Loading…
Reference in New Issue
Block a user