diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx
index a23c3db..1f17551 100644
--- a/src/components/App/index.tsx
+++ b/src/components/App/index.tsx
@@ -5,11 +5,16 @@ import './App.css'
import { Theater } from '../Theater'
import { Auth } from '../Auth'
-import { $user } from '../../models/auth'
-import {AppGate} from '../../models/app'
+import {$router} from '../../models/router'
+import {AppGate, Route} from '../../models/app'
export const App = () => {
useGate(AppGate)
- const {email} = useStore($user)
- return email ? () : ()
+ const [, route] = useStore($router)
+ useGate(Route, { name: route ? route : '' })
+
+ if (route === 'theater') {
+ return
+ }
+ return
}
\ No newline at end of file
diff --git a/src/models/app/index.ts b/src/models/app/index.ts
index e73b6bf..4584351 100644
--- a/src/models/app/index.ts
+++ b/src/models/app/index.ts
@@ -5,4 +5,6 @@ import { Config } from './types'
export const initAppFx = createEffect()
-export const AppGate = createGate()
\ No newline at end of file
+export const AppGate = createGate()
+
+export const Route = createGate<{name: string}>()
\ No newline at end of file
diff --git a/src/models/app/init.ts b/src/models/app/init.ts
index 9e28b73..4736b0e 100644
--- a/src/models/app/init.ts
+++ b/src/models/app/init.ts
@@ -2,11 +2,13 @@ import { initializeApp } from 'firebase'
import { forward } from 'effector'
import {
- initAppFx, AppGate
+ initAppFx, AppGate, Route
} from './'
import { fetchUsersFx } from '../users'
+import { checkAuthFx } from '../auth'
+
import {
appId,
projectId,
@@ -41,5 +43,9 @@ initAppFx({
forward({
from: AppGate.open,
- to: fetchUsersFx
+ to: [fetchUsersFx, checkAuthFx]
+})
+
+Route.state.updates.watch(({name}) => {
+ history.pushState({}, '', `/${name}`)
})
\ No newline at end of file
diff --git a/src/models/auth/index.ts b/src/models/auth/index.ts
index 126fca4..5878bb6 100644
--- a/src/models/auth/index.ts
+++ b/src/models/auth/index.ts
@@ -10,12 +10,20 @@ export const logout = createEvent()
export const updateSignInForm = createEvent<{ value: string; fieldName: string }>()
+export const checkAuth = createEvent()
+
+export const restoredAuth = createEvent()
+
export const manageGmailProviderFx = createEffect()
export const manageEmailProviderFx = createEffect()
export const signUpViaEmailFx = createEffect()
+export const checkAuthFx = createEffect()
+
+export const dropUserAuthFx = createEffect()
+
export const $user = createStore({
email: ''
})
diff --git a/src/models/auth/init.ts b/src/models/auth/init.ts
index 551815a..3ad7fa7 100644
--- a/src/models/auth/init.ts
+++ b/src/models/auth/init.ts
@@ -1,4 +1,4 @@
-import { forward, sample } from 'effector'
+import { forward, sample, guard } from 'effector'
import { auth } from 'firebase'
import {
@@ -6,9 +6,13 @@ import {
signIn,
logout,
updateSignInForm,
+ checkAuth,
+ restoredAuth,
manageGmailProviderFx,
manageEmailProviderFx,
signUpViaEmailFx,
+ checkAuthFx,
+ dropUserAuthFx,
$user,
$signInForm
} from './'
@@ -17,9 +21,12 @@ import {
addUserFx,
updateUsersTableFx,
deleteUserFx,
- $firebaseUsers
+ $firebaseUsers,
+ $usersByEmail
} from '../users'
+import { User } from './types'
+
const gProvider = new auth.GoogleAuthProvider()
manageGmailProviderFx.use(async () => {
@@ -43,10 +50,22 @@ signUpViaEmailFx.use(async ({email, password}) => {
return {email}
})
+checkAuthFx.use(() => {
+ auth().onAuthStateChanged(value => {
+ if (value !== null) {
+ checkAuth(value as User)
+ }
+ })
+})
+
+dropUserAuthFx.use(async () => {
+ await auth().signOut()
+})
+
$user
.reset(logout)
.on([
- manageGmailProviderFx.doneData, signUpViaEmailFx.doneData, manageEmailProviderFx.doneData
+ manageGmailProviderFx.doneData, signUpViaEmailFx.doneData, manageEmailProviderFx.doneData, restoredAuth
],
(_, user) => user
)
@@ -82,13 +101,32 @@ forward({
})
sample({
- source: $firebaseUsers,
- clock: logout,
- //@ts-ignore
- fn: (users, email) => Object.keys(users).find((id) => {
- if (email === users[id].email) {
- return id
- }
+ source: guard({
+ source: sample({
+ source: $usersByEmail,
+ clock: [
+ manageGmailProviderFx.doneData,
+ signUpViaEmailFx.doneData,
+ manageEmailProviderFx.doneData
+ ],
+ fn: (users, user) => users[user.email]
+ }),
+ filter: Boolean
}),
+ fn: (user) => user.id!,
target: deleteUserFx
+})
+
+forward({
+ from: logout,
+ to: dropUserAuthFx
+})
+
+forward({
+ from: checkAuth.filterMap((user) => {
+ if (user !== null) {
+ return user
+ }
+ }),
+ to: restoredAuth
})
\ No newline at end of file
diff --git a/src/models/init.ts b/src/models/init.ts
index 8d14fc7..dec0931 100644
--- a/src/models/init.ts
+++ b/src/models/init.ts
@@ -1,4 +1,5 @@
import './app/init'
import './auth/init'
import './users/init'
-import './tables/init'
\ No newline at end of file
+import './tables/init'
+import './router/init'
\ No newline at end of file
diff --git a/src/models/router/index.ts b/src/models/router/index.ts
new file mode 100644
index 0000000..9bee945
--- /dev/null
+++ b/src/models/router/index.ts
@@ -0,0 +1,5 @@
+import {createEvent, createStore} from 'effector'
+
+export const redirect = createEvent()
+
+export const $router = createStore([])
\ No newline at end of file
diff --git a/src/models/router/init.ts b/src/models/router/init.ts
new file mode 100644
index 0000000..6ea479c
--- /dev/null
+++ b/src/models/router/init.ts
@@ -0,0 +1,15 @@
+import {sample} from 'effector'
+
+import {$user} from '../auth'
+import {redirect, $router} from './'
+
+$router.on(redirect, (routes, link) => ([
+ ...routes,
+ link
+]))
+
+sample({
+ source: $user,
+ fn: (user) => user.email ? 'theater' : '',
+ target: redirect
+})
\ No newline at end of file
diff --git a/src/models/users/index.ts b/src/models/users/index.ts
index 2063604..b72c3b7 100644
--- a/src/models/users/index.ts
+++ b/src/models/users/index.ts
@@ -15,7 +15,7 @@ export const $users = $firebaseUsers.map((fUsers) =>
Object.keys(fUsers).map((id) => fUsers[id])
)
export const $usersByEmail = $firebaseUsers.map((fUsers) => {
- return Object.keys(fUsers).reduce((usersByEmail, id) => {
+ return Object.keys(fUsers).reduce((usersByEmail, id) => {
const email = fUsers[id].email;
return {
[email]: {