Skip to content

Instantly share code, notes, and snippets.

@Spoki4
Created August 19, 2020 12:35
Show Gist options
  • Save Spoki4/9496fc441af27511a086e181bdc883a2 to your computer and use it in GitHub Desktop.
Save Spoki4/9496fc441af27511a086e181bdc883a2 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_ERROR'),
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: 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