Fix modal window

This commit is contained in:
ilya-bkv 2024-01-27 09:21:48 +03:00
parent afed10dfd2
commit 5a47db8430
14 changed files with 57 additions and 30 deletions

View File

@ -405,6 +405,7 @@
"Upload userpic": "Upload userpic", "Upload userpic": "Upload userpic",
"Upload video": "Upload video", "Upload video": "Upload video",
"Uploading image": "Uploading image", "Uploading image": "Uploading image",
"User with this email already exists": "User with this email already exists",
"Username": "Username", "Username": "Username",
"Userpic": "Userpic", "Userpic": "Userpic",
"Users": "Users", "Users": "Users",

View File

@ -427,6 +427,7 @@
"Upload userpic": "Загрузить аватар", "Upload userpic": "Загрузить аватар",
"Upload video": "Загрузить видео", "Upload video": "Загрузить видео",
"Uploading image": "Загружаем изображение", "Uploading image": "Загружаем изображение",
"User with this email already exists": "Пользователь с таким email уже существует",
"Username": "Имя пользователя", "Username": "Имя пользователя",
"Userpic": "Аватар", "Userpic": "Аватар",
"Users": "Пользователи", "Users": "Пользователи",

View File

@ -92,11 +92,11 @@ export const App = (props: Props) => {
let is404 = props.is404 let is404 = props.is404
createEffect(() => { createEffect(() => {
if (!searchParams().modal) { if (!searchParams().m) {
hideModal() hideModal()
} }
const modal = MODALS[searchParams().modal] const modal = MODALS[searchParams().m]
if (modal) { if (modal) {
showModal(modal) showModal(modal)
} }

View File

@ -172,11 +172,11 @@ export const CommentsTree = (props: Props) => {
fallback={ fallback={
<div class={styles.signInMessage}> <div class={styles.signInMessage}>
{t('To write a comment, you must')}{' '} {t('To write a comment, you must')}{' '}
<a href="?modal=auth&mode=register" class={styles.link}> <a href="?m=auth&mode=register" class={styles.link}>
{t('sign up')} {t('sign up')}
</a>{' '} </a>{' '}
{t('or')}&nbsp; {t('or')}&nbsp;
<a href="?modal=auth&mode=login" class={styles.link}> <a href="?m=auth&mode=login" class={styles.link}>
{t('sign in')} {t('sign in')}
</a> </a>
</div> </div>

View File

@ -142,7 +142,7 @@ export const AuthorCard = (props: Props) => {
> >
<div class={styles.subscribersContainer}> <div class={styles.subscribersContainer}>
<Show when={props.followers && props.followers.length > 0}> <Show when={props.followers && props.followers.length > 0}>
<a href="?modal=followers" class={styles.subscribers}> <a href="?m=followers" class={styles.subscribers}>
<For each={props.followers.slice(0, 3)}> <For each={props.followers.slice(0, 3)}>
{(f) => ( {(f) => (
<Userpic size={'XS'} name={f.name} userpic={f.pic} class={styles.subscribersItem} /> <Userpic size={'XS'} name={f.name} userpic={f.pic} class={styles.subscribersItem} />
@ -155,7 +155,7 @@ export const AuthorCard = (props: Props) => {
</Show> </Show>
<Show when={props.following && props.following.length > 0}> <Show when={props.following && props.following.length > 0}>
<a href="?modal=following" class={styles.subscribers}> <a href="?m=following" class={styles.subscribers}>
<For each={props.following.slice(0, 3)}> <For each={props.following.slice(0, 3)}>
{(f) => { {(f) => {
if ('name' in f) { if ('name' in f) {

View File

@ -66,7 +66,7 @@ export const LoginForm = () => {
setIsEmailNotConfirmed(false) setIsEmailNotConfirmed(false)
setSubmitError('') setSubmitError('')
changeSearchParams({ mode: 'forgot-password' }) changeSearchParams({ mode: 'forgot-password' })
// NOTE: temporary solition, needs logix in authorizer // NOTE: temporary solution, needs logic in authorizer
/* FIXME: /* FIXME:
const { actions: { authorizer } } = useSession() const { actions: { authorizer } } = useSession()
const result = await authorizer().verifyEmail({ token }) const result = await authorizer().verifyEmail({ token })
@ -140,9 +140,9 @@ export const LoginForm = () => {
<div class={styles.authInfo}> <div class={styles.authInfo}>
<div class={styles.warn}>{submitError()}</div> <div class={styles.warn}>{submitError()}</div>
<Show when={isEmailNotConfirmed()}> <Show when={isEmailNotConfirmed()}>
<a href="#" onClick={handleSendLinkAgainClick}> <span class={'link'} onClick={handleSendLinkAgainClick}>
{t('Send link again')} {t('Send link again')}
</a> </span>
</Show> </Show>
</div> </div>
</Show> </Show>
@ -169,7 +169,7 @@ export const LoginForm = () => {
</Show> </Show>
</div> </div>
<PasswordField onInput={(value) => handlePasswordInput(value)} /> <PasswordField variant={'login'} onInput={(value) => handlePasswordInput(value)} />
<div> <div>
<button class={clsx('button', styles.submitButton)} disabled={isSubmitting()} type="submit"> <button class={clsx('button', styles.submitButton)} disabled={isSubmitting()} type="submit">

View File

@ -10,6 +10,7 @@ type Props = {
class?: string class?: string
errorMessage?: (error: string) => void errorMessage?: (error: string) => void
onInput: (value: string) => void onInput: (value: string) => void
variant?: 'login' | 'registration'
} }
export const PasswordField = (props: Props) => { export const PasswordField = (props: Props) => {
@ -49,7 +50,7 @@ export const PasswordField = (props: Props) => {
on( on(
() => error(), () => error(),
() => { () => {
props.errorMessage ?? props.errorMessage(error()) props.errorMessage && props.errorMessage(error())
}, },
{ defer: true }, { defer: true },
), ),
@ -59,7 +60,7 @@ export const PasswordField = (props: Props) => {
<div class={clsx(styles.PassportField, props.class)}> <div class={clsx(styles.PassportField, props.class)}>
<div <div
class={clsx('pretty-form__item', { class={clsx('pretty-form__item', {
'pretty-form__item--error': error(), 'pretty-form__item--error': error() && props.variant !== 'login',
})} })}
> >
<input <input
@ -78,7 +79,7 @@ export const PasswordField = (props: Props) => {
> >
<Icon class={styles.passwordToggleIcon} name={showPassword() ? 'eye-off' : 'eye'} /> <Icon class={styles.passwordToggleIcon} name={showPassword() ? 'eye-off' : 'eye'} />
</button> </button>
<Show when={error()}> <Show when={error() && props.variant !== 'login'}>
<div class={clsx(styles.registerPassword, styles.validationError)}>{error()}</div> <div class={clsx(styles.registerPassword, styles.validationError)}>{error()}</div>
</Show> </Show>
</div> </div>

View File

@ -118,13 +118,29 @@ export const RegisterForm = () => {
setIsSuccess(true) setIsSuccess(true)
} catch (error) { } catch (error) {
console.error(error) console.error(error)
if (error) {
// TODO: move to context/session if (error.message.includes('has already signed up')) {
if (error?.code === 'user_already_exists') { setValidationErrors((errors) => ({
return ...errors,
email: (
<>
{t('User with this email already exists')},{' '}
<span
class={'link'}
onClick={() =>
changeSearchParams({
mode: 'login',
})
}
>
{t('sign in')}
</span>
</>
),
}))
}
console.error(error)
} }
setSubmitError(error.message)
} finally { } finally {
setIsSubmitting(false) setIsSubmitting(false)
} }
@ -138,9 +154,7 @@ export const RegisterForm = () => {
<AuthModalHeader modalType="register" /> <AuthModalHeader modalType="register" />
<Show when={submitError()}> <Show when={submitError()}>
<div class={styles.authInfo}> <div class={styles.authInfo}>
<ul> <div class={styles.warn}>{submitError()}</div>
<li class={styles.warn}>{submitError()}</li>
</ul>
</div> </div>
</Show> </Show>
<div <div

View File

@ -187,7 +187,7 @@ export const HeaderAuth = (props: Props) => {
when={isAuthenticatedControlsVisible()} when={isAuthenticatedControlsVisible()}
fallback={ fallback={
<div class={clsx(styles.userControlItem, styles.userControlItemVerbose, 'loginbtn')}> <div class={clsx(styles.userControlItem, styles.userControlItemVerbose, 'loginbtn')}>
<a href="?modal=auth&mode=login"> <a href="?m=auth&mode=login">
<span class={styles.textLabel}>{t('Enter')}</span> <span class={styles.textLabel}>{t('Enter')}</span>
<Icon name="key" class={styles.icon} /> <Icon name="key" class={styles.icon} />
{/*<Icon name="user-default" class={clsx(styles.icon, styles.iconHover)} />*/} {/*<Icon name="user-default" class={clsx(styles.icon, styles.iconHover)} />*/}

View File

@ -29,7 +29,7 @@ export const ProfilePopup = (props: ProfilePopupProps) => {
<a href={getPagePath(router, 'drafts')}>{t('Drafts')}</a> <a href={getPagePath(router, 'drafts')}>{t('Drafts')}</a>
</li> </li>
<li> <li>
<a href={`${getPagePath(router, 'author', { slug: author().slug })}?modal=following`}> <a href={`${getPagePath(router, 'author', { slug: author().slug })}?m=following`}>
{t('Subscriptions')} {t('Subscriptions')}
</a> </a>
</li> </li>

View File

@ -41,7 +41,9 @@ export const InviteMembers = (props: Props) => {
] ]
const { sortedAuthors } = useAuthorsStore({ sortBy: 'name' }) const { sortedAuthors } = useAuthorsStore({ sortBy: 'name' })
const { actions } = useInbox() const {
actions: { loadChats, createChat },
} = useInbox()
const [authorsToInvite, setAuthorsToInvite] = createSignal<InviteAuthor[]>() const [authorsToInvite, setAuthorsToInvite] = createSignal<InviteAuthor[]>()
const [searchResultAuthors, setSearchResultAuthors] = createSignal<Author[]>() const [searchResultAuthors, setSearchResultAuthors] = createSignal<Author[]>()
@ -99,10 +101,10 @@ export const InviteMembers = (props: Props) => {
const handleCreate = async () => { const handleCreate = async () => {
try { try {
const initChat = await actions.createChat(collectionToInvite(), 'chat Title') const initChat = await createChat(collectionToInvite(), 'chat Title')
console.debug('[components.Inbox] create chat result:', initChat) console.debug('[components.Inbox] create chat result:', initChat)
hideModal() hideModal()
await actions.loadChats() await loadChats()
} catch (error) { } catch (error) {
console.error('handleCreate chat', error) console.error('handleCreate chat', error)
} }

View File

@ -23,7 +23,7 @@ export type PageProps = {
} }
export type RootSearchParams = { export type RootSearchParams = {
modal: string m: string // modal
lang: string lang: string
} }

View File

@ -152,9 +152,14 @@ export const useRouter = <TSearchParams extends Record<string, string> = Record<
searchParamsStore.open(newSearchParams, replace) searchParamsStore.open(newSearchParams, replace)
} }
const clearSearchParams = (replace = false) => {
searchParamsStore.open({}, replace)
}
return { return {
page, page,
searchParams, searchParams,
changeSearchParams, changeSearchParams,
clearSearchParams,
} }
} }

View File

@ -46,7 +46,7 @@ export const MODALS: Record<ModalType, ModalType> = {
const [modal, setModal] = createSignal<ModalType>(null) const [modal, setModal] = createSignal<ModalType>(null)
const { changeSearchParams } = useRouter< const { changeSearchParams, clearSearchParams } = useRouter<
AuthModalSearchParams & ConfirmEmailSearchParams & RootSearchParams AuthModalSearchParams & ConfirmEmailSearchParams & RootSearchParams
>() >()
@ -60,7 +60,10 @@ export const showModal = (modalType: ModalType, modalSource?: AuthModalSource) =
setModal(modalType) setModal(modalType)
} }
export const hideModal = () => setModal(null) export const hideModal = () => {
clearSearchParams()
setModal(null)
}
export const useModalStore = () => { export const useModalStore = () => {
return { return {