Skip to content

Instantly share code, notes, and snippets.

@Spoki4
Created October 17, 2020 10:37
Show Gist options
  • Save Spoki4/1e5db20aaac07fe9ee5088829b6b2117 to your computer and use it in GitHub Desktop.
Save Spoki4/1e5db20aaac07fe9ee5088829b6b2117 to your computer and use it in GitHub Desktop.
import { setTokenForRequest } from '@/features/api/common/request'
import { loginFx, LoginFxParams, LoginFxResponse } from '@/features/api/login'
import { navigateReplace } from '@/features/navigation'
import { loadSessionFx } from '@/features/session'
import { createEffectorField } from '@/lib/effector/field-generator'
import { Response } from '@/lib/request'
import { isEmailValid } from '@/lib/validators/email'
import { getPasswordErrors, isPasswordValid } from '@/lib/validators/password'
import { attach, combine, createEvent, forward, guard, sample, split } from 'effector-root'
import { every } from 'patronum'
import { addToast } from '@/features/toasts/toasts.model'
const resetFields = createEvent()
export const submitForm = createEvent()
const loadCurrentSessionFx = attach({
effect: loadSessionFx,
mapParams: (params) => params,
})
const sendLoginFormFx = attach({
effect: loginFx,
mapParams: (params: LoginFxParams) => params,
})
const { userNotFound } = split(sendLoginFormFx.failData, {
userNotFound: ({ status }) => status === 400,
})
export const [$email, emailChanged, $emailError, $isEmailCorrect] = createEffectorField({
defaultValue: '',
validator: (email): string | null => (isEmailValid(email) ? null : 'Некорректный email адрес'),
reset: resetFields,
})
export const [$password, passwordChanged, $passwordError, $isPasswordCorrect] = createEffectorField(
{
defaultValue: '',
validator: (password): string[] =>
isPasswordValid(password) ? [] : getPasswordErrors(password),
reset: resetFields,
}
)
export const $form = combine({
email: $email,
password: $password,
})
export const $errors = combine({
email: $emailError,
password: $passwordError,
})
const $isFormCorrect = every({
stores: [$isEmailCorrect, $isPasswordCorrect],
predicate: true,
})
export const $canSubmit = combine(
$isFormCorrect,
sendLoginFormFx.pending,
loadCurrentSessionFx.pending,
(isFormCorrect, loginPending, sessionPending) => isFormCorrect && !loginPending && !sessionPending
)
sample({
clock: guard({ source: submitForm, filter: $canSubmit }),
source: $form,
target: sendLoginFormFx,
})
forward({
from: sendLoginFormFx.doneData,
to: [
setTokenForRequest.prepend(({ body }: Response<LoginFxResponse>) => body.token),
loadCurrentSessionFx,
],
})
forward({
from: sendLoginFormFx.fail,
to: addToast.prepend(() => ({ type: 'error', message: 'Отсутствует подключение к интернету' })),
})
forward({
from: loadCurrentSessionFx.doneData,
to: [navigateReplace.prepend(() => ({ name: 'user.projects' })), resetFields],
})
forward({
from: userNotFound,
to: addToast.prepend(() => ({ type: 'error', message: 'Пользователь не найден' })),
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment