|
@@ -1,218 +1,78 @@
|
|
|
-import { useState, useEffect, Fragment } from 'react'
|
|
|
+import { useState, useEffect } from 'react'
|
|
|
+import reactLogo from './assets/react.svg'
|
|
|
+import viteLogo from '/vite.svg'
|
|
|
import './App.css'
|
|
|
import {createBrowserHistory} from 'history';
|
|
|
-import {Router, Link} from 'react-router-dom'
|
|
|
-import {createQueryPub, NamedRoute, NamedLink, usePub} from './lib';
|
|
|
-import {MetaPlate} from './lib';
|
|
|
-
|
|
|
+import {Router} from 'react-router-dom'
|
|
|
+import {NamedRoute, NamedLink, HashRoute, createPrivateRoute} 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={}) =>
|
|
|
- fetch(shopUrl + 'graphql',{
|
|
|
- method: 'POST',
|
|
|
- headers: {
|
|
|
- 'Content-Type': 'application/json',
|
|
|
- Accept: 'application/json',
|
|
|
- Authorization: 'Bearer ' + token
|
|
|
- },
|
|
|
- body: JSON.stringify({query, variables})
|
|
|
- }).then(res => res.json())
|
|
|
-
|
|
|
-const {queryPub, createQuery, withQueryFunc} = createQueryPub({
|
|
|
- queryFunc: gql,
|
|
|
- cacheTimeout: 5000,
|
|
|
-})
|
|
|
-
|
|
|
-const {useCategoriesQuery} = createQuery({
|
|
|
- promiseName: 'categories',
|
|
|
- args: [`query MainCategories{
|
|
|
- CategoryFind(query: "[{}]"){
|
|
|
- _id name
|
|
|
- image{
|
|
|
- url
|
|
|
- }
|
|
|
- goods{
|
|
|
- _id
|
|
|
- name description price images{
|
|
|
- url
|
|
|
- }
|
|
|
- }
|
|
|
- subCategories{ name _id}
|
|
|
- }
|
|
|
- }
|
|
|
- `]
|
|
|
-})
|
|
|
-
|
|
|
-const {useMainCategoriesQuery} = createQuery({
|
|
|
- promiseName: 'mainCategories',
|
|
|
- args: [`query MainCategories{
|
|
|
- CategoryFind(query: "[{\\"parent\\":null}]"){
|
|
|
- _id name
|
|
|
- image{
|
|
|
- url
|
|
|
- }
|
|
|
- goods{
|
|
|
- _id
|
|
|
- name description price images{
|
|
|
- url
|
|
|
- }
|
|
|
- }
|
|
|
- subCategories{ name _id}
|
|
|
- }
|
|
|
- }
|
|
|
- `]
|
|
|
-})
|
|
|
-
|
|
|
-
|
|
|
-const {query: categoryQuery, useCategoryQuery} = createQuery({
|
|
|
- promiseName: 'category',
|
|
|
- args: ({_id}) => [`query categoryById($query:String){
|
|
|
- CategoryFindOne(query: $query){
|
|
|
- _id name
|
|
|
- image{
|
|
|
- url
|
|
|
- }
|
|
|
- goods{
|
|
|
- _id
|
|
|
- name description price images{
|
|
|
- url
|
|
|
- }
|
|
|
- }
|
|
|
- subCategories{ name _id}
|
|
|
- }
|
|
|
- }
|
|
|
- `, {query: JSON.stringify([{_id}])}]
|
|
|
-})
|
|
|
-
|
|
|
-
|
|
|
-//queryPub.subscribe(() => console.log(JSON.stringify(queryPub.queries.user, null, 4)))
|
|
|
-//
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-const Image = ({src}) => <img src={`${shopUrl}${src}`} style={{maxWidth: '50%'}}/>
|
|
|
-
|
|
|
-const Good = ({good, children}) => {
|
|
|
- useEffect(() => {
|
|
|
- console.log('good mount', good.name)
|
|
|
- },[])
|
|
|
- return (
|
|
|
- good ?
|
|
|
- <div className='Good'>
|
|
|
- <h2>{good.name}</h2>
|
|
|
- <p>{good.description}</p>
|
|
|
- <span>{good.price}</span>
|
|
|
- {children}
|
|
|
- </div>
|
|
|
- : <h3>null</h3>
|
|
|
- )
|
|
|
-}
|
|
|
-
|
|
|
-const Category = ({category:{name, _id}, children}) =>
|
|
|
-<div className='Category'>
|
|
|
- <h1>{name}</h1>
|
|
|
- {_id}
|
|
|
- {children}
|
|
|
-</div>
|
|
|
-
|
|
|
-const Categories = ({children, data}) =>
|
|
|
-<div style={{border: '2px solid', paddingLeft: '20px'}}>
|
|
|
- <h1>categories({data && data.length})</h1>
|
|
|
- {children}
|
|
|
+const SwapiPeople = ({data:{name, eye_color}}) =>
|
|
|
+<div>
|
|
|
+ <h3 style={{color: eye_color}}>{name}</h3>
|
|
|
+ <HashRoute path="/foo" component={() => <h1>FOO</h1>} />
|
|
|
+ <HashRoute path="/bar" component={() => <h1>BAR</h1>} />
|
|
|
+ <a href="#/foo">go to foo</a>
|
|
|
+ <a href="#/bar">go to bar</a>
|
|
|
</div>
|
|
|
|
|
|
-const Goods = ({children}) =>
|
|
|
-<div style={{border: '2px solid blue', paddingLeft: '10px'}}>
|
|
|
- <h2>goods</h2>
|
|
|
- {children}
|
|
|
+const SwapiPlanet = ({data:{name, diameter}}) =>
|
|
|
+<div>
|
|
|
+ <h3>{name}</h3>
|
|
|
+ <h4>{diameter}</h4>
|
|
|
</div>
|
|
|
|
|
|
-const PageCategory = ({data}) => {
|
|
|
- //usePub(queryPub) //IS IT REQUIRED?, or route mechanics enough (looks like this required for auto-refresh queries in PUB)
|
|
|
- //if its required, is useCategoryQuery gives same result?
|
|
|
- //yes, exactly. it required due to auto update of queryPub.
|
|
|
- //
|
|
|
- //useCategoryQuery({_id: useParams()._id}) //here we need id from url...
|
|
|
- console.log('page category update')
|
|
|
- return (
|
|
|
- <>
|
|
|
- <MetaPlate data={data.payload.data.CategoryFindOne}>
|
|
|
- <Category prop="category" keyDataKey="_id">
|
|
|
- <Goods sourceDataKey="goods">
|
|
|
- <Good prop="good" keyDataKey="_id">
|
|
|
- <div sourceDataKey="images">
|
|
|
- <Image prop="src" sourceDataKey="url"/>
|
|
|
- </div>
|
|
|
- </Good>
|
|
|
- </Goods>
|
|
|
- <Categories sourceDataKey="subCategories" prop='data'>
|
|
|
- <LeftMenuItem prop="category" keyDataKey="_id" />
|
|
|
- </Categories>
|
|
|
- </Category>
|
|
|
- </MetaPlate>
|
|
|
- </>
|
|
|
- )
|
|
|
-}
|
|
|
-
|
|
|
-const LeftMenuItem = ({category:{_id,name}})=>
|
|
|
-<li><NamedLink routeName='category' params={{_id}}>{name}</NamedLink></li>
|
|
|
-//<li><Link to={`/category/${_id}`}>{name}</Link></li>
|
|
|
-
|
|
|
-const LeftMenu = () => {
|
|
|
- const {payload} = useMainCategoriesQuery()
|
|
|
- return (
|
|
|
- <ul>
|
|
|
- {payload &&
|
|
|
- <MetaPlate data={payload.data.CategoryFind}>
|
|
|
- <>
|
|
|
- <LeftMenuItem prop="category" keyDataKey="_id"/>
|
|
|
- </>
|
|
|
- </MetaPlate>}
|
|
|
- </ul>
|
|
|
- )
|
|
|
+const queries = {
|
|
|
+ people({id}){
|
|
|
+ return fetch('https://swapi.dev/api/people/' + id).then(res => res.json())
|
|
|
+ },
|
|
|
+ planet({id}){
|
|
|
+ if (id == 2)
|
|
|
+ return {
|
|
|
+ "name": "Alderaan",
|
|
|
+ "diameter": "12500"
|
|
|
+ }
|
|
|
+ return fetch('https://swapi.dev/api/planets/' + id).then(res => res.json())
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-function App() {
|
|
|
- //const {payload} = useCategoriesQuery()
|
|
|
- //console.log('update', performance.now())
|
|
|
- //useEffect(() => console.log('effect',performance.now()), [payload])
|
|
|
- return (
|
|
|
- <Router history={history}>
|
|
|
+const Pending = () => <h1>Loading</h1>
|
|
|
+const Error = ({error}) => <h1>Error: {error.message}</h1>
|
|
|
|
|
|
- <LeftMenu />
|
|
|
- <NamedRoute name="category"
|
|
|
- query={categoryQuery}
|
|
|
- path="/category/:_id"
|
|
|
- component={PageCategory}/>
|
|
|
+const UserNamedRoute = createPrivateRoute(() => ['user'], history => history.goBack())(NamedRoute)
|
|
|
|
|
|
+const Dashboard = () => <h1>dashboard</h1>
|
|
|
|
|
|
|
|
|
- {/*payload &&
|
|
|
- <MetaPlate data={payload.data.CategoryFind}>
|
|
|
- <Categories prop='data'>
|
|
|
- <Category prop="category" keyDataKey="_id">
|
|
|
- <Goods sourceDataKey="goods">
|
|
|
- <Good prop="good" keyDataKey="_id">
|
|
|
- <div sourceDataKey="images">
|
|
|
- <Image prop="src" sourceDataKey="url"/>
|
|
|
- </div>
|
|
|
- </Good>
|
|
|
- </Goods>
|
|
|
- <Categories sourceDataKey="subCategories" prop='data'>
|
|
|
- <Category prop="category" keyDataKey="_id" />
|
|
|
- </Categories>
|
|
|
- </Category>
|
|
|
- </Categories>
|
|
|
- </MetaPlate> */ }
|
|
|
- </Router>
|
|
|
- )
|
|
|
+function App() {
|
|
|
+ return (
|
|
|
+ <Router history={history}>
|
|
|
+ <div>
|
|
|
+ <NamedRoute name="people"
|
|
|
+ query={queries.people}
|
|
|
+ path="/people/:id"
|
|
|
+ pendingQueryComponent={Pending}
|
|
|
+ errorQueryComponent={Error}
|
|
|
+ component={SwapiPeople}/>
|
|
|
+ <NamedRoute routeName="planet"
|
|
|
+ query={queries.planet}
|
|
|
+ pendingQueryComponent={Pending}
|
|
|
+ errorQueryComponent={Error}
|
|
|
+ path="/planet/:id"
|
|
|
+ component={SwapiPlanet}/>
|
|
|
+ <UserNamedRoute routeName="dashboard" path="/dashboard" component={Dashboard} roles={['admin']} />
|
|
|
+ </div>
|
|
|
+ <p className="read-the-docs">
|
|
|
+ <NamedLink routeName="people" params={{id: 1}}>Luke</NamedLink>
|
|
|
+ <NamedLink routeName="people" params={{id: 2}}>C3PO</NamedLink>
|
|
|
+ </p>
|
|
|
+ <p className="read-the-docs">
|
|
|
+ <NamedLink routeName="planet" params={{id: 1}}>Tatooin</NamedLink>
|
|
|
+ <NamedLink routeName="planet" params={{id: 2}}>Alderaan</NamedLink>
|
|
|
+ </p>
|
|
|
+ </Router>
|
|
|
+ )
|
|
|
}
|
|
|
|
|
|
export default App
|