import React, {useState, useEffect, useRef} from 'react' import logoDefault from './logo.svg'; import './App.scss'; import {Provider, connect} from 'react-redux'; import {createStore, combineReducers, applyMiddleware} from 'redux'; import thunk from 'redux-thunk'; const jwtDecode = token => { try { let arrToken = token.split('.') let base64Token = atob(arrToken[1]) return JSON.parse(base64Token) } catch (e) { console.log('Лажа, Бро ' + e); } } function authReducer(state, { type, token }) { if (!state) { if (localStorage.authToken) { type = 'AUTH_LOGIN' token = localStorage.authToken } else state = {} } if (type === 'AUTH_LOGIN') { localStorage.setItem('authToken', token) let payload = jwtDecode(token) if (typeof payload === 'object') { return { ...state, token, payload } } else return {} } if (type === 'AUTH_LOGOUT') { localStorage.removeItem('authToken') return {} } return state } const actionAuthLogin = token => ({ type: 'AUTH_LOGIN', token }) const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' }) function cartReducer(state = {}, { type, good = {}, count = 1 }) { const { _id } = good const types = { CART_ADD() { count = +count if (!count) return state return { ...state, [_id]: { good, count: count + (state[_id]?.count || 0) } } }, CART_CHANGE() { count = +count if (!count) return state return { ...state, [_id]: { good, count: count } } }, CART_REMOVE() { let { [_id]: remove, ...newState } = state return { ...newState } }, CART_CLEAR() { return {} }, } if (type in types) { return types[type]() } return state } const actionCartAdd = (good, count=1) => ({type: "CART_ADD", good, count}); function promiseReducer(state = {}, { type, status, payload, error, name }) { if (type === 'PROMISE') { return { ...state, [name]: { status, payload, error } } } return state; } const actionPending = name => ({ type: 'PROMISE', status: 'PENDING', name }) const actionResolved = (name, payload) => ({ type: 'PROMISE', status: 'RESOLVED', name, payload }) const actionRejected = (name, error) => ({ type: 'PROMISE', status: 'REJECTED', name, error }) const actionPromise = (name, promise) => async dispatch => { dispatch(actionPending(name)) try { let data = await promise dispatch(actionResolved(name, data)) return data } catch (error) { dispatch(actionRejected(name, error)) } } const getGQL = url => async (query, variables = {}) => { let obj = await fetch(url, { method: 'POST', headers: { "Content-Type": "application/json", Authorization: localStorage.authToken ? 'Bearer ' + localStorage.authToken : {}, }, body: JSON.stringify({ query, variables }) }) let a = await obj.json() if (!a.data && a.errors) throw new Error(JSON.stringify(a.errors)) return a.data[Object.keys(a.data)[0]] } const backURL = 'http://shop-roles.asmer.fs.a-level.com.ua' const gql = getGQL(backURL + '/graphql'); const actionLogin = (login, password) => ( actionPromise('login', gql(`query log($login: String, $password: String) { login(login: $login, password: $password) }`, {login, password})) ) const actionFullLogin = (login, password) => ( async (dispatch) => { let token = await dispatch(actionLogin(login, password)) if (token) { dispatch(actionAuthLogin(token)) } } ) const actionRootCats = () => actionPromise('rootCats', gql(`query { CategoryFind(query: "[{\\"parent\\":null}]"){ _id name } }`)) const actionCatById = (_id) => actionPromise('catById', gql(`query catById($q: String){ CategoryFindOne(query: $q){ subCategories{name, _id} _id name goods { _id name price images { url } } } }`, { q: JSON.stringify([{ _id }]) })) const store = createStore(combineReducers({promise: promiseReducer, auth: authReducer, cart: cartReducer}), applyMiddleware(thunk)) store.subscribe(() => console.log(store.getState())) store.dispatch(actionRootCats()) store.dispatch(actionCatById('5dc49f4d5df9d670df48cc64')) const Logo = ({logo=logoDefault}) => const Koshik = ({cart}) => { let count = 0; let sum = Object.entries(cart).map(([, val]) => val.count) count = sum.reduce((a, b) => a + b, 0) //перебрать cart, посчитать суммарный count return (
{count}
) } const CKoshik = connect(({cart}) => ({cart}))(Koshik) const Header = ({logo=logoDefault}) =>
const Footer = ({logo=logoDefault}) => const defaultRootCats = [ { "_id": "5dc49f4d5df9d670df48cc64", "name": "Airconditions" }, { "_id": "5dc458985df9d670df48cc47", "name": " Smartphones" }, { "_id": "5dc4b2553f23b553bf354101", "name": "Крупная бытовая техника" }, { "_id": "5dcac1b56d09c45440d14cf8", "name": "Макароны" }] const RootCategory = ({cat:{_id, name}={}}) =>
  • {name}
  • const RootCategories = ({cats=defaultRootCats}) => const CRootCategories = connect(state => ({cats: state.promise.rootCats?.payload || []})) (RootCategories) const Aside = () => const Content = ({children}) =>
    {children}
    const defaultCat ={ "subCategories": null, "_id": "5dc458985df9d670df48cc47", "name": " Smartphones", "goods": [ { "_id": "61b105f9c750c12ba6ba4524", "name": "iPhone ", "price": 1200, "images": [ { "url": "images/50842a3af34bfa28be037aa644910d07" } ] }, { "_id": "61b1069ac750c12ba6ba4526", "name": "iPhone ", "price": 1000, "images": [ { "url": "images/d12b07d983dac81ccad404582a54d8be" } ] }, { "_id": "61b23f94c750c12ba6ba472a", "name": "name1", "price": 1214, "images": [ { "url": null } ] }, { "_id": "61b23fbac750c12ba6ba472c", "name": "smart", "price": 1222, "images": [ { "url": "images/871f4e6edbf86c35f70b72dcdebcd8b2" } ] } ] } const SubCategories = ({cats}) => <> const GoodCard = ({good:{_id, name, price, images}={}, onCartAdd}) =>

    {name}

    {images && images[0] && images[0].url && } {price}
    const CGoodCard = connect(null, {onCartAdd: actionCartAdd})(GoodCard) const Category = ({cat:{_id, name, goods, subCategories}=defaultCat}) =>

    {name}

    {subCategories && } {(goods || []).map(good => )}
    const CCategory = connect(state => ({cat: state.promise.catById?.payload}))(Category) const Main = () =>
    const JSONTest = ({data}) =>
        {JSON.stringify(data, null, 4)}
        {Math.random() > 0.5 && 

    asdfasf

    }
    const ReduxJSON = connect(state => ({data:state}))(JSONTest) const ListItem = ({item}) =>
  • {item}
  • const List = ({data=["пиво", "чипсы", "сиги"]}) => const _ = React.createElement.bind(React) const List2 = ({data=["пиво", "чипсы", "сиги"]}) => _('ul',null, data.map(item => _(ListItem,{ item })) ) const LowerCase = ({children}) => ( <> {children.toLowerCase()} ) const Input = () => { const [text, setText] = useState("text") // text !== 'ДРУГОЙ ТЕКСТ' && setTimeout(() => setText('ДРУГОЙ ТЕКСТ'), 2000) return ( <>

    {text}

    {text.length}

    {text}

    setText(e.target.value)}/> ) } const Spoiler = ({children}) => { const [open, setOpen] = useState(false) return (

    setOpen(!open)}>{open ? 'hide' : 'show'}

    {open && children}
    ) } const RGBInput = () => { const [red, setRed] = useState(0) const [green, setGreen] = useState(0) const [blue, setBlue] = useState(0) const color = `rgba(${red},${green},${blue},1)` useEffect(() => { console.log('component did mount') return () => { console.log('component will unmount') } }, []) const bounds = x => x < 0 ? 0 : (x > 255 ? 255 : x) return (
    setRed(bounds(+e.target.value))}/> setGreen(bounds(+e.target.value))}/> setBlue(bounds(+e.target.value))}/>
    ) } const Timer = ({ms=1000, onDelete}) => { const [counter, setCounter] = useState(0) const ref = useRef(0) useEffect(() => { console.log('+eff') const interval = setInterval(() => { setCounter((counter) => counter + 1) }, ms) return () => { console.log('-eff') clearInterval(interval) } }, [ms]) /* console.log(ref.current++) */ return ( <>
    {counter}
    ) } const Timers = () => { // const [timer, setTimer] = useState(0) // const arr = [] // for (let i=0; i {ms} {timers.map((i) => setTimers(timers.filter(t => t !== i))}/>)} ) } const LoginForm = ({onLogin}) => { const [login, setLogin] = useState("") const [pass, setPass] = useState("") return (
    setLogin(e.target.value)}/> setPass(e.target.value)}/>
    ) } const CLoginForm = connect(null, {onLogin: actionFullLogin})(LoginForm) function App() { const worstka =

    {Math.random()}

    const worstkaNative = React.createElement("h1", null, Math.random()) const worstkaNative2 = React.createElement("h1", {children: [Math.random()]}) console.log(worstkaNative2) const listQQQ = React.createElement(List2, {data:["aaaa", "uuuuuuu", "сиги"]}) return (
    {/* console.log(l,p)}/> {worstka} {worstkaNative} {worstkaNative2} {listQQQ} */} {/* */}
    ); } export default App;