From d86d5e602879ede0a4c869cfecd235578bc7a613 Mon Sep 17 00:00:00 2001 From: Arkadzi Rakouski Date: Sun, 30 Jul 2023 15:31:54 +0300 Subject: [PATCH] refactor contextual modals (#141) * refactor contextual modals * refactor by review comments * refactored auth modal header to separate component, lint --------- Co-authored-by: bniwredyc --- .eslintrc.js | 10 +-- public/locales/en/translation.json | 19 +++-- public/locales/ru/translation.json | 19 +++-- src/components/Inbox/Message.tsx | 1 - .../AuthModalHeader.module.scss | 7 ++ .../AuthModalHeader/AuthModalHeader.tsx | 81 +++++++++++++++++++ .../Nav/AuthModal/AuthModalHeader/index.ts | 1 + src/components/Nav/AuthModal/LoginForm.tsx | 5 +- src/components/Nav/AuthModal/RegisterForm.tsx | 4 +- src/components/Nav/AuthModal/index.tsx | 70 +++++++++------- src/components/Nav/Header.tsx | 18 ++--- src/components/Nav/Modal/Modal.tsx | 8 +- .../_shared/SolidSwiper/SolidSwiper.tsx | 2 +- src/context/inbox.tsx | 10 +-- src/stores/ui.ts | 2 +- src/utils/custom-i18n.ts | 16 ---- 16 files changed, 184 insertions(+), 89 deletions(-) create mode 100644 src/components/Nav/AuthModal/AuthModalHeader/AuthModalHeader.module.scss create mode 100644 src/components/Nav/AuthModal/AuthModalHeader/AuthModalHeader.tsx create mode 100644 src/components/Nav/AuthModal/AuthModalHeader/index.ts delete mode 100644 src/utils/custom-i18n.ts diff --git a/.eslintrc.js b/.eslintrc.js index 6bbae672..187fdf0c 100644 --- a/.eslintrc.js +++ b/.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' } } ], diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index eec2686a..0afcdd79 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -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", diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index 8d69d693..86ed351b 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -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": "Ошибка", diff --git a/src/components/Inbox/Message.tsx b/src/components/Inbox/Message.tsx index 1d0c41de..c01f1c0a 100644 --- a/src/components/Inbox/Message.tsx +++ b/src/components/Inbox/Message.tsx @@ -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' diff --git a/src/components/Nav/AuthModal/AuthModalHeader/AuthModalHeader.module.scss b/src/components/Nav/AuthModal/AuthModalHeader/AuthModalHeader.module.scss new file mode 100644 index 00000000..7cd236c6 --- /dev/null +++ b/src/components/Nav/AuthModal/AuthModalHeader/AuthModalHeader.module.scss @@ -0,0 +1,7 @@ +.authFormDescription { + font-size: 14px; + font-weight: 400; + line-height: 18px; + letter-spacing: -0.14px; + margin: 12px 0 54px; +} diff --git a/src/components/Nav/AuthModal/AuthModalHeader/AuthModalHeader.tsx b/src/components/Nav/AuthModal/AuthModalHeader/AuthModalHeader.tsx new file mode 100644 index 00000000..311e42fe --- /dev/null +++ b/src/components/Nav/AuthModal/AuthModalHeader/AuthModalHeader.tsx @@ -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() + 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 ( + <> +

{title}

+ +

+ + + ) +} diff --git a/src/components/Nav/AuthModal/AuthModalHeader/index.ts b/src/components/Nav/AuthModal/AuthModalHeader/index.ts new file mode 100644 index 00000000..62ebf6a4 --- /dev/null +++ b/src/components/Nav/AuthModal/AuthModalHeader/index.ts @@ -0,0 +1 @@ +export { AuthModalHeader } from './AuthModalHeader' diff --git a/src/components/Nav/AuthModal/LoginForm.tsx b/src/components/Nav/AuthModal/LoginForm.tsx index f62bb35f..387e61c6 100644 --- a/src/components/Nav/AuthModal/LoginForm.tsx +++ b/src/components/Nav/AuthModal/LoginForm.tsx @@ -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 (

-

{generateModalTitleFromSource('login')}

+
{submitError()}
diff --git a/src/components/Nav/AuthModal/RegisterForm.tsx b/src/components/Nav/AuthModal/RegisterForm.tsx index 91775e3f..903ea0ed 100644 --- a/src/components/Nav/AuthModal/RegisterForm.tsx +++ b/src/components/Nav/AuthModal/RegisterForm.tsx @@ -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 = () => {
-

{generateModalTitleFromSource('register')}

+
    diff --git a/src/components/Nav/AuthModal/index.tsx b/src/components/Nav/AuthModal/index.tsx index 37d584b0..7a2a8e27 100644 --- a/src/components/Nav/AuthModal/index.tsx +++ b/src/components/Nav/AuthModal/index.tsx @@ -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() + const { source } = searchParams() + const mode = createMemo(() => { return AUTH_MODAL_MODES[searchParams().mode] ? searchParams().mode : 'login' }) @@ -37,39 +39,47 @@ export const AuthModal = () => { return (
    -
    -
    -
    -

    {t(`Join the global community of authors!`)}

    -

    - {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!')} + +

    +
    +
    +

    {t(`Join the global community of authors!`)}

    +

    + {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!')} +

    +
    +

    + {t('By signing up you agree with our')}{' '} + { + hideModal() + }} + > + {t('terms of use')} + + , {t('personal data usage and email notifications')}.

    -

    - {t('By signing up you agree with our')}{' '} - { - hideModal() - }} - > - {t('terms of use')} - - , {t('personal data usage and email notifications')}. -

    -
    -
    -
    +
    {' '} + +
    diff --git a/src/components/Nav/Header.tsx b/src/components/Nav/Header.tsx index eb952895..5d52a8a3 100644 --- a/src/components/Nav/Header.tsx +++ b/src/components/Nav/Header.tsx @@ -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() + 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) }} > - + diff --git a/src/components/Nav/Modal/Modal.tsx b/src/components/Nav/Modal/Modal.tsx index c1e89acf..c568e150 100644 --- a/src/components/Nav/Modal/Modal.tsx +++ b/src/components/Nav/Modal/Modal.tsx @@ -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) }) diff --git a/src/components/_shared/SolidSwiper/SolidSwiper.tsx b/src/components/_shared/SolidSwiper/SolidSwiper.tsx index 3a98b24c..be79fb67 100644 --- a/src/components/_shared/SolidSwiper/SolidSwiper.tsx +++ b/src/components/_shared/SolidSwiper/SolidSwiper.tsx @@ -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' diff --git a/src/context/inbox.tsx b/src/context/inbox.tsx index 06084b2e..1356bf4c 100644 --- a/src/context/inbox.tsx +++ b/src/context/inbox.tsx @@ -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([]) const [messages, setMessages] = createSignal([]) - const subclient = createMemo(() => createSubClient()) + // const subclient = createMemo(() => createSubClient()) const loadChats = async () => { try { const newChats = await apiClient.getChats({ limit: 50, offset: 0 }) diff --git a/src/stores/ui.ts b/src/stores/ui.ts index f0313605..3d03f5d3 100644 --- a/src/stores/ui.ts +++ b/src/stores/ui.ts @@ -64,7 +64,7 @@ export const hideModal = () => { } changeSearchParam('modal', null, true) - changeSearchParam('source', null, true) + changeSearchParam('source', null) setModal(null) } diff --git a/src/utils/custom-i18n.ts b/src/utils/custom-i18n.ts deleted file mode 100644 index ba900f7c..00000000 --- a/src/utils/custom-i18n.ts +++ /dev/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() - const { t } = useLocalize() - - const { source } = searchParams() - - let title = modalType === 'login' ? 'Enter the Discours' : 'Create account' - - if (source) title = `${title} from ${source}` - - return t(title) -}