|
@@ -5,7 +5,7 @@ import {Router, Link} from 'react-router-dom'
|
|
|
import {createQueryPub, NamedRoute, NamedLink, usePub} from './lib';
|
|
|
import {MetaPlate} from './lib';
|
|
|
|
|
|
-import {createQueryRoutes} from './lib';
|
|
|
+import {createQueryRoutes, createPub} from './lib';
|
|
|
|
|
|
/*
|
|
|
CREATE QUERY ROUTE HUGE CONFIGURATION SAMPLE/TEST
|
|
@@ -13,10 +13,6 @@ import {createQueryRoutes} from './lib';
|
|
|
|
|
|
const history = createBrowserHistory()
|
|
|
|
|
|
-const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOnsiaWQiOiI2NjdmZjBkYTIyMzIxMjBjN2M4NzFmN2MiLCJsb2dpbiI6InRzdDE5IiwiYWNsIjpbIjY2N2ZmMGRhMjIzMjEyMGM3Yzg3MWY3YyIsInVzZXIiXX0sImlhdCI6MTcyMDI1OTEwN30.eDcInxQlskt32LjaCe5sdCcJ3B97BKYZtgUARxThYQM'
|
|
|
-
|
|
|
-//console.log(JSON.parse(atob(token.split('.')[1])).sub.id)
|
|
|
-
|
|
|
const shopUrl = 'http://shop-roles.node.ed.asmer.org.ua/'
|
|
|
|
|
|
const gql = (query, variables={}) =>
|
|
@@ -25,7 +21,8 @@ const gql = (query, variables={}) =>
|
|
|
headers: {
|
|
|
'Content-Type': 'application/json',
|
|
|
Accept: 'application/json',
|
|
|
- Authorization: 'Bearer ' + token
|
|
|
+ ...(authPub.token ?
|
|
|
+ { Authorization: 'Bearer ' + authPub.token } : {})
|
|
|
},
|
|
|
body: JSON.stringify({query, variables})
|
|
|
})
|
|
@@ -245,13 +242,120 @@ const queryRouteResult = createQueryRoutes({
|
|
|
}
|
|
|
`, {query: JSON.stringify([{_id}])}],
|
|
|
component: PageCategory
|
|
|
+ },
|
|
|
+ login: {
|
|
|
+ isMutation: true,
|
|
|
+ args: ({login, password}) => [`query login ($login:String, $password: String){
|
|
|
+ login(login:$login, password: $password)
|
|
|
+ }`, {login, password}]
|
|
|
+ },
|
|
|
+ user: {
|
|
|
+ args: ({_id}) => [`query userById($query:String){
|
|
|
+ UserFindOne(query: $query){
|
|
|
+ _id login nick
|
|
|
+ avatar { url }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ `, {query: JSON.stringify([{_id}])}],
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
|
|
|
-const { AllRoutes, queryRoutes: {category: {CategoryLink}}, queryPub } = queryRouteResult
|
|
|
+const { AllRoutes,
|
|
|
+ queryRoutes:
|
|
|
+ {
|
|
|
+ category: {CategoryLink},
|
|
|
+ login: {useLoginMutation, query: loginQuery},
|
|
|
+ user: {query: userQuery}
|
|
|
+ },
|
|
|
+ queryPub, withQueryFunc, flushCache } = queryRouteResult
|
|
|
+
|
|
|
|
|
|
-//queryPub.subscribe(() => console.log(JSON.stringify(queryPub, null, 4)))
|
|
|
+const authPub = createPub()
|
|
|
+const jwtDecode = token => {
|
|
|
+ try {
|
|
|
+ return JSON.parse(atob(token.split('.')[1]))
|
|
|
+ }
|
|
|
+ catch{ }
|
|
|
+}
|
|
|
+
|
|
|
+const actionLogout = () => {
|
|
|
+ authPub.login = null
|
|
|
+ authPub.token = null;
|
|
|
+ authPub.user = null;
|
|
|
+ authPub.decoded = null
|
|
|
+
|
|
|
+
|
|
|
+ flushCache()
|
|
|
+}
|
|
|
+
|
|
|
+const thunkLogin = async ({login, password}) => {
|
|
|
+ const loginResult = await loginQuery({login, password})
|
|
|
+ if (!loginResult || !loginResult?.payload){
|
|
|
+ actionLogout()
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const token = loginResult.payload
|
|
|
+ const decoded = jwtDecode(token)
|
|
|
+ if (!decoded){
|
|
|
+ actionLogout()
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ authPub.login = decoded.sub.login
|
|
|
+ authPub.token = token
|
|
|
+ authPub.decoded = decoded
|
|
|
+
|
|
|
+ const myUser = await userQuery({_id: decoded.sub.id})
|
|
|
+ if (!myUser.payload){
|
|
|
+ actionLogout()
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ authPub.user = myUser.payload
|
|
|
+}
|
|
|
+
|
|
|
+//authPub.subscribe(() => console.log(JSON.stringify(authPub, null, 4)))
|
|
|
+
|
|
|
+
|
|
|
+const LoginForm = () => {
|
|
|
+ const [login, setLogin] = useState('')
|
|
|
+ const [password, setPassword] = useState('')
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <input value={login} onChange={e => setLogin(e.target.value)} />
|
|
|
+ <input value={password} onChange={e => setPassword(e.target.value)} />
|
|
|
+ <button onClick={() => thunkLogin({login, password})}>Login...</button>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+const LogoutButton = () => {
|
|
|
+ usePub(authPub)
|
|
|
+ if (!authPub.login) return null;
|
|
|
+ return (
|
|
|
+ <button onClick={actionLogout}>{authPub.user?.nick || authPub.login} (logout)</button>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//works okay
|
|
|
+//const LoginForm = () => {
|
|
|
+ //const [login, setLogin] = useState('')
|
|
|
+ //const [password, setPassword] = useState('')
|
|
|
+
|
|
|
+ //const [loginQuery, data] = useLoginMutation()
|
|
|
+ //console.log(loginQuery, data);
|
|
|
+ //return (
|
|
|
+ //<div>
|
|
|
+ //<input value={login} onChange={e => setLogin(e.target.value)} />
|
|
|
+ //<input value={password} onChange={e => setPassword(e.target.value)} />
|
|
|
+ //<button onClick={() => loginQuery({login, password})}>Login...</button>
|
|
|
+ //</div>
|
|
|
+ //)
|
|
|
+//}
|
|
|
+
|
|
|
+//queryPub.subscribe(() => console.log(queryPub, JSON.stringify(queryPub, null, 4)))
|
|
|
|
|
|
function App() {
|
|
|
//const {payload} = useCategoriesQuery()
|
|
@@ -259,7 +363,8 @@ function App() {
|
|
|
//useEffect(() => console.log('effect',performance.now()), [payload])
|
|
|
return (
|
|
|
<Router history={history}>
|
|
|
-
|
|
|
+ <LogoutButton/>
|
|
|
+ <LoginForm />
|
|
|
<AllRoutes />
|
|
|
|
|
|
|