fix: selectors and serialize/deserialize store

This commit is contained in:
Aidar Shaikhutdin @makeweb.space 2023-05-19 14:12:14 +06:00
parent 3df9f83e1e
commit b4fe8acb42
5 changed files with 25 additions and 24 deletions

View File

@ -2,20 +2,20 @@ import { useState } from 'react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux' import { useDispatch, useSelector } from 'react-redux'
import { actions, RootState } from '../../store' import { actions, selectors } from '../../store'
import routes from '../../routes' import { DatePicker } from '../DateTimePicker'
import MainButton from '../MainButton'
import Policy from '../Policy' import Policy from '../Policy'
import Purposes from '../Purposes' import Purposes from '../Purposes'
import Title from '../Title' import Title from '../Title'
import { DatePicker } from '../DateTimePicker' import routes from '../../routes'
import MainButton from '../MainButton'
import './styles.css' import './styles.css'
function BirthdayPage(): JSX.Element { function BirthdayPage(): JSX.Element {
const { t } = useTranslation() const { t } = useTranslation()
const dispatch = useDispatch() const dispatch = useDispatch()
const navigate = useNavigate() const navigate = useNavigate()
const birthdate = useSelector((state: RootState) => state.form.birthdate) const birthdate = useSelector(selectors.selectBirthdate)
const [isDisabled, setIsDisabled] = useState(true) const [isDisabled, setIsDisabled] = useState(true)
const links = [ const links = [
{ text: 'EULA', href: 'https://aura.wit.life/terms' }, { text: 'EULA', href: 'https://aura.wit.life/terms' },

View File

@ -1,10 +1,10 @@
import { useNavigate } from "react-router-dom" import { useNavigate } from "react-router-dom"
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux' import { useDispatch, useSelector } from 'react-redux'
import { actions, RootState } from '../../store' import { actions, selectors } from '../../store'
import { TimePicker } from "../DateTimePicker"
import Title from "../Title" import Title from "../Title"
import MainButton from "../MainButton" import MainButton from "../MainButton"
import { TimePicker } from "../DateTimePicker"
import routes from "../../routes" import routes from "../../routes"
import './styles.css' import './styles.css'
@ -12,7 +12,7 @@ function BirthtimePage(): JSX.Element {
const { t } = useTranslation() const { t } = useTranslation()
const dispatch = useDispatch() const dispatch = useDispatch()
const navigate = useNavigate(); const navigate = useNavigate();
const birthtime = useSelector((state: RootState) => state.form.birthtime) const birthtime = useSelector(selectors.selectBirthtime)
const handleNext = () => navigate(routes.client.createProfile()) const handleNext = () => navigate(routes.client.createProfile())
const handleChange = (value: string) => dispatch(actions.form.addTime(value)) const handleChange = (value: string) => dispatch(actions.form.addTime(value))
return ( return (

View File

@ -16,11 +16,12 @@ import routes from '../../routes'
function EmailEnterPage(): JSX.Element { function EmailEnterPage(): JSX.Element {
const api = useApi() const api = useApi()
const { user, signUp } = useAuth()
const { t, i18n } = useTranslation() const { t, i18n } = useTranslation()
const dispatch = useDispatch() const dispatch = useDispatch()
const navigate = useNavigate() const navigate = useNavigate()
const { user, signUp } = useAuth() const email = useSelector(selectors.selectEmail)
const { email, birthdate, birthtime } = useSelector(selectors.selectForm) const birthday = useSelector(selectors.selectBirthday)
const [isDisabled, setIsDisabled] = useState(true) const [isDisabled, setIsDisabled] = useState(true)
const [isLoading, setIsLoading] = useState(false) const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState<Error | null>(null) const [error, setError] = useState<Error | null>(null)
@ -44,17 +45,10 @@ function EmailEnterPage(): JSX.Element {
api.auth({ email, timezone, locale }) api.auth({ email, timezone, locale })
.then(({ auth: { token, user } }) => signUp(token, user)) .then(({ auth: { token, user } }) => signUp(token, user))
.then((token) => { .then((token) => {
const birthday = `${birthdate} ${birthtime}`
const payload = { user: { profile_attributes: { birthday } }, token } const payload = { user: { profile_attributes: { birthday } }, token }
return api.updateUser(payload) return api.updateUser(payload)
}) })
.then(({ user }) => { .then(({ user }) => dispatch(actions.user.update(user)))
// TODO: remove this when understand btoa issue
if (user?.profile?.sign?.char) {
user.profile.sign.char = ''
}
dispatch(actions.user.update(user))
})
.then(() => navigate(routes.client.subscription())) .then(() => navigate(routes.client.subscription()))
.catch((error: Error) => setError(error)) .catch((error: Error) => setError(error))
.finally(() => setIsLoading(false)) .finally(() => setIsLoading(false))

View File

@ -1,3 +1,4 @@
import { useAuth } from '../../auth'
import './styles.css' import './styles.css'
type NavbarProps = { type NavbarProps = {
@ -6,6 +7,7 @@ type NavbarProps = {
} }
function Navbar({ isOpen, closeMenu }: NavbarProps): JSX.Element { function Navbar({ isOpen, closeMenu }: NavbarProps): JSX.Element {
const { logout } = useAuth()
const combinedClassNames = ['navbar', isOpen && 'navbar--open'].filter(Boolean).join(' ') const combinedClassNames = ['navbar', isOpen && 'navbar--open'].filter(Boolean).join(' ')
return ( return (
<aside className={combinedClassNames}> <aside className={combinedClassNames}>
@ -25,6 +27,7 @@ function Navbar({ isOpen, closeMenu }: NavbarProps): JSX.Element {
<a href='#' target="_blank" rel="noreferrer nofollow">Money back policy</a> <a href='#' target="_blank" rel="noreferrer nofollow">Money back policy</a>
<a href='#' target="_blank" rel="noreferrer nofollow">FAQ</a> <a href='#' target="_blank" rel="noreferrer nofollow">FAQ</a>
<a href='#' target="_blank" rel="noreferrer nofollow">Contact us</a> <a href='#' target="_blank" rel="noreferrer nofollow">Contact us</a>
<a href='#' onClick={() => logout()}>Log Out</a>
</nav> </nav>
</div> </div>
</aside> </aside>

View File

@ -6,10 +6,9 @@ export const backupStore = (store: ToolkitStore) => {
const saveState = () => { const saveState = () => {
const state = store.getState() const state = store.getState()
try { try {
const serializedState = window.btoa(JSON.stringify(state)) const serializedState = serialize(state)
localStorage.setItem(storageKey, serializedState) localStorage.setItem(storageKey, serializedState)
} catch (err) { } catch (err) {
// nothing to do
console.error('Error while saving state', err) console.error('Error while saving state', err)
} }
} }
@ -29,11 +28,16 @@ export const backupStore = (store: ToolkitStore) => {
export const loadStore = () => { export const loadStore = () => {
try { try {
const serializedState = localStorage.getItem(storageKey) const serializedState = localStorage.getItem(storageKey)
if (serializedState === null) { return serializedState === null ? undefined : deserialize(serializedState)
return undefined
}
return JSON.parse(window.atob(serializedState))
} catch (err) { } catch (err) {
return undefined return undefined
} }
} }
function serialize(data: string) {
return JSON.stringify(btoa(encodeURIComponent(data)))
}
function deserialize(b64: string) {
return JSON.parse(decodeURIComponent(atob(b64)))
}