{"id":18868491,"url":"https://github.com/erhantezer/cart-reducer","last_synced_at":"2026-05-04T23:32:50.056Z","repository":{"id":154633636,"uuid":"630646222","full_name":"erhantezer/cart-reducer","owner":"erhantezer","description":null,"archived":false,"fork":false,"pushed_at":"2023-04-25T11:11:10.000Z","size":80,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-30T15:51:30.152Z","etag":null,"topics":["api-data","context","html-css-javascript","loading","mock-data","reactjs","reducer","svg-images","vitejs"],"latest_commit_sha":null,"homepage":"https://cart-reducer-xi.vercel.app","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erhantezer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-04-20T20:45:53.000Z","updated_at":"2023-04-25T10:58:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"21202628-1231-46fc-b846-e0c5bb26e320","html_url":"https://github.com/erhantezer/cart-reducer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/erhantezer/cart-reducer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erhantezer%2Fcart-reducer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erhantezer%2Fcart-reducer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erhantezer%2Fcart-reducer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erhantezer%2Fcart-reducer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erhantezer","download_url":"https://codeload.github.com/erhantezer/cart-reducer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erhantezer%2Fcart-reducer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32628829,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-04T10:08:07.713Z","status":"ssl_error","status_checked_at":"2026-05-04T10:08:02.005Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-data","context","html-css-javascript","loading","mock-data","reactjs","reducer","svg-images","vitejs"],"created_at":"2024-11-08T05:13:50.744Z","updated_at":"2026-05-04T23:32:50.048Z","avatar_url":"https://github.com/erhantezer.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CART\n\n## App.jsx\n```js\nimport Home from \"./pages/Home\";\n\nfunction App() {\n  return (\n    \u003c\u003e\n      \u003cHome/\u003e\n    \u003c/\u003e\n  )\n}\n\nexport default App;\n```\n\n## Home:jsx\n```js\nimport Navbar from '../components/Navbar';\nimport CarContainer from '../components/cart/CarContainer';\nimport { useGlobalContext } from '../context';\n\nconst Home = () =\u003e {\n    const { loading } = useGlobalContext();\n\n    return (\n        \u003c\u003e\n            {loading ?\n                (\u003cdiv className='loading' \u003e\n                    \u003ch1\u003eLoading...\u003c/h1\u003e\n                \u003c/div \u003e) : (\n                    \u003cmain\u003e\n                        \u003cNavbar /\u003e\n                        \u003cCarContainer /\u003e\n                    \u003c/main\u003e\n                )\n            }\n        \u003c/\u003e\n    )\n}\n\nexport default Home;\n```\n\n## Navbar.jsx\n```js\nimport { useGlobalContext } from \"../context\";\n\nconst Navbar = () =\u003e {\n const {amount} = useGlobalContext()\n    \n    return (\n        \u003cnav\u003e\n            \u003cdiv className='nav-center'\u003e\n                \u003ch3\u003euseReducer\u003c/h3\u003e\n                \u003cdiv className='nav-container'\u003e\n                    \u003csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'\u003e\n                        \u003cpath d='M16 6v2h2l2 12H0L2 8h2V6a6 6 0 1 1 12 0zm-2 0a4 4 0 1 0-8 0v2h8V6zM4 10v2h2v-2H4zm10 0v2h2v-2h-2z' /\u003e\n                    \u003c/svg\u003e\n                    \u003cdiv className='amount-container'\u003e\n                        \u003cp className='total-amount'\u003e{amount}\u003c/p\u003e\n                    \u003c/div\u003e\n                \u003c/div\u003e\n            \u003c/div\u003e\n        \u003c/nav\u003e\n    )\n}\n\nexport default Navbar;\n```\n\n## CartContainer.jsx\n```js\nimport { useGlobalContext } from \"../../context\"\nimport CartItem from \"./CartItem\"\n\nconst CarContainer = () =\u003e {\n    const { cart, total, clearCart, fetchData } = useGlobalContext()\n\n    if (cart.length === 0) {\n        return (\n            \u003csection className='cart'\u003e\n                \u003cheader\u003e\n                    \u003ch2\u003eyour bag\u003c/h2\u003e\n                    \u003ch4 className='empty-cart'\u003eis currently empty\u003c/h4\u003e\n                    \u003cbutton className=\"btn reloaded-btn\" onClick={() =\u003e fetchData()}\u003e\n                        reloaded\n                    \u003c/button\u003e\n                \u003c/header\u003e\n            \u003c/section\u003e\n        )\n    }\n\n    return (\n        \u003csection className=\"cart\"\u003e\n            \u003cheader\u003e\n                \u003ch2\u003eyour bag\u003c/h2\u003e\n            \u003c/header\u003e\n            \u003cdiv\u003e\n                {cart.map((item) =\u003e {\n                    return \u003cCartItem key={item.id} {...item} /\u003e\n                })}\n            \u003c/div\u003e\n            \u003cfooter\u003e\n                \u003chr /\u003e\n                \u003cdiv className=\"cart-total\"\u003e\n                    \u003ch4\u003e\n                        total \u003cspan\u003e${total}\u003c/span\u003e\n                    \u003c/h4\u003e\n                \u003c/div\u003e\n                \u003cbutton className=\"btn clear-btn\" onClick={() =\u003e clearCart()}\u003e\n                    clear cart\n                \u003c/button\u003e\n\n            \u003c/footer\u003e\n        \u003c/section\u003e\n    )\n}\n\nexport default CarContainer\n```\n\n##\n```js\nimport { useGlobalContext } from \"../../context\"\n\n\nconst CartItem = ({ id, img, title, price, amount }) =\u003e {\n    const {remove, increase, decrease, toggleAmount} = useGlobalContext();\n\n    return (\n        \u003carticle className=\"cart-item\"\u003e\n            \u003cimg src={img} alt={title} /\u003e\n            \u003cdiv\u003e\n                \u003ch4\u003e{title}\u003c/h4\u003e\n                \u003ch4 className=\"item-price\"\u003e${price}\u003c/h4\u003e\n                \u003cbutton className=\"remove-btn\" onClick={() =\u003e remove(id)}\u003e\n                    remove\n                \u003c/button\u003e\n            \u003c/div\u003e\n            \u003cdiv\u003e\n                \u003cbutton className=\"amount-btn\" onClick={() =\u003e toggleAmount(id, 'inc')}\u003e\n                    \u003csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'\u003e\n                        \u003cpath d='M10.707 7.05L10 6.343 4.343 12l1.414 1.414L10 9.172l4.243 4.242L15.657 12z' /\u003e\n                    \u003c/svg\u003e\n                \u003c/button\u003e\n                \u003cp className=\"amount\"\u003e{amount}\u003c/p\u003e\n                \u003cbutton className='amount-btn' onClick={() =\u003e toggleAmount(id, 'dec')}\u003e\n                    \u003csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'\u003e\n                        \u003cpath d='M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z' /\u003e\n                    \u003c/svg\u003e\n                \u003c/button\u003e\n            \u003c/div\u003e\n        \u003c/article\u003e\n    )\n}\n\nexport default CartItem;\n```\n\n## context.jsx\n```js\nimport { createContext, useContext, useEffect, useReducer } from \"react\";\nimport reducer from './reducer';\n// import cartItems from \"./helper/data\";\nimport axios from \"axios\";\n\nconst AppContext = createContext();\n\nexport const useGlobalContext = () =\u003e {\n    return useContext(AppContext);\n};\n\n\nconst initialState = {\n    loading: false,\n    cart: [],\n    total: 0,\n    amount: 0,\n}\n\nconst url = 'https://course-api.com/react-useReducer-cart-project';\n\nexport const AppProvider = ({ children }) =\u003e {\n    // const [loading, setLoading] = useState(false);\n    const [state, dispatch] = useReducer(reducer, initialState);\n\n    const clearCart = () =\u003e {\n        dispatch({ type: \"CLEAR_CART\" })\n    };\n\n    const remove = (id) =\u003e {\n        dispatch({ type: \"REMOVE_CART\", payload: id })\n    };\n\n    const increase = (id) =\u003e {\n        dispatch({ type: \"INCREASE\", payload: id })\n    };\n\n    const decrease = (id) =\u003e {\n        dispatch({ type: \"DECREASE\", payload: id })\n    };\n\n    const toggleAmount = (id, type) =\u003e {\n        dispatch({ type: \"TOGGLE_AMOUNT\", payload: { id, type } })\n    };\n\n\n    const fetchData = async () =\u003e {\n        dispatch({ type: \"LOADING\" });\n        const { data } = await axios(url)\n        dispatch({ type: \"DISPLAY_ITEMS\", payload: data })\n    };\n\n    useEffect(() =\u003e {\n        fetchData();\n    }, [])\n\n\n    useEffect(() =\u003e {\n        dispatch({ type: \"GET_TOTALS\" })\n    }, [state.cart]);\n\n    return (\n        \u003cAppContext.Provider value={{\n            ...state,\n            clearCart,\n            remove,\n            increase,\n            decrease,\n            toggleAmount,\n            fetchData,\n        }}\u003e\n            {children}\n        \u003c/AppContext.Provider\u003e\n    )\n};\n```\n\n## reducer.jsx\n```js\nexport default (state, action) =\u003e {\n    \n    if (action.type === \"LOADING\") {\n        return { ...state, loading: true }\n    };\n\n    if (action.type === \"CLEAR_CART\") {\n        return { ...state, cart:[] }\n    };\n\n    if (action.type === 'REMOVE_CART') {\n        return { ...state, cart: state.cart.filter((cartItem) =\u003e cartItem.id !== action.payload)}\n    };\n\n    if (action.type === 'DISPLAY_ITEMS') {\n        return { ...state, cart: action.payload, loading: false}\n    };\n\n\n    if (action.type === 'GET_TOTALS') {\n        let { total, amount } = state.cart.reduce(\n            (cartTotal, cartItem) =\u003e {\n                const { price, amount } = cartItem\n                const itemTotal = price * amount\n\n                cartTotal.total += itemTotal\n                cartTotal.amount += amount\n                return cartTotal\n            },\n            {\n                total: 0,\n                amount: 0,\n            }\n        )\n        total = parseFloat(total.toFixed(2))\n\n        return { ...state, total, amount }\n    }\n\n    if (action.type === 'INCREASE') {\n        let tempCart = state.cart.map((cartItem) =\u003e {\n            if (cartItem.id === action.payload) {\n                return { ...cartItem, amount: cartItem.amount + 1 }\n            }\n            return cartItem\n        })\n        return { ...state, cart: tempCart }\n    }\n\n    if (action.type === 'DECREASE') {\n        let tempCart = state.cart\n            .map((cartItem) =\u003e {\n                if (cartItem.id === action.payload) {\n                    return { ...cartItem, amount: cartItem.amount - 1 }\n                }\n                return cartItem\n            })\n            .filter((cartItem) =\u003e cartItem.amount !== 0)\n        return { ...state, cart: tempCart }\n    }\n\n    if (action.type === 'TOGGLE_AMOUNT') {\n        let tempCart = state.cart\n            .map((cartItem) =\u003e {\n                if (cartItem.id === action.payload.id) {\n                    if (action.payload.type === 'inc') {\n                        return { ...cartItem, amount: cartItem.amount + 1 }\n                    }\n                    if (action.payload.type === 'dec') {\n                        return { ...cartItem, amount: cartItem.amount - 1 }\n                    }\n                }\n                return cartItem\n            })\n            .filter((cartItem) =\u003e cartItem.amount !== 0)\n        return { ...state, cart: tempCart }\n    }\n    throw new Error('no matching action type')\n\n}\n\n```\n\n```md\n│   App.jsx\n│   context.jsx\n│   index.css\n│   main.jsx\n│   reducer.jsx\n│\n├───assets\n│       react.svg\n│\n├───components\n│   │   Navbar.jsx\n│   │\n│   └───cart\n│           CarContainer.jsx\n│           CartItem.jsx\n│\n├───helper\n│       data.jsx\n│\n└───pages\n        Home.jsx\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferhantezer%2Fcart-reducer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferhantezer%2Fcart-reducer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferhantezer%2Fcart-reducer/lists"}