diff --git a/package.json b/package.json index 38557c1..32a97ae 100644 --- a/package.json +++ b/package.json @@ -45,8 +45,11 @@ "vite": "^5.0.11" }, "dependencies": { + "@reduxjs/toolkit": "^2.0.1", + "axios": "^1.6.5", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-redux": "^9.1.0", "react-router-dom": "^6.21.2" } } diff --git a/src/commons/constant.ts b/src/commons/constant.ts new file mode 100644 index 0000000..e101ae6 --- /dev/null +++ b/src/commons/constant.ts @@ -0,0 +1 @@ +export const API_URL : string = process.env.API_URL || "http://localhost:5000" \ No newline at end of file diff --git a/src/commons/routes.tsx b/src/commons/routes.tsx new file mode 100644 index 0000000..11923b3 --- /dev/null +++ b/src/commons/routes.tsx @@ -0,0 +1,13 @@ +import { createBrowserRouter } from "react-router-dom" +import Homepage from "../pages/Homepage" + +const routes = [ + { + path: "/", + element: , + }, +] + +const routeBrowser = createBrowserRouter(routes) + +export default routeBrowser \ No newline at end of file diff --git a/src/components/hello.tsx b/src/components/hello.tsx new file mode 100644 index 0000000..dc15da3 --- /dev/null +++ b/src/components/hello.tsx @@ -0,0 +1,23 @@ +import { useDispatch, useSelector } from "react-redux" +import { exampleAction, exampleState } from "../redux/reducers/example" +import { useEffect } from "react" + +const Hello =() =>{ + const helloState = useSelector(exampleState) + const dispatch = useDispatch() + useEffect(() => { + + dispatch(exampleAction.setName({name:"React Boilerplate TS By Saddam"})) + + },[]) + + return( +
+

+ {helloState.name} +

+
+ ) +} + +export default Hello \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index ea32631..9c5e524 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,11 +1,17 @@ import React from "react"; import ReactDOM from "react-dom/client"; import "./index.css"; +import { RouterProvider } from "react-router-dom"; +import routes from "./commons/routes"; +import { Provider } from "react-redux"; +import store from "./redux/store"; ReactDOM.createRoot(document.getElementById("root")!).render( -
-

Hello

-
+ + + + +
, ); diff --git a/src/pages/Homepage.tsx b/src/pages/Homepage.tsx new file mode 100644 index 0000000..d9c7eba --- /dev/null +++ b/src/pages/Homepage.tsx @@ -0,0 +1,11 @@ +import Hello from "../components/hello" + +const Homepage = () => { + return ( + <> + + + ) +} + +export default Homepage \ No newline at end of file diff --git a/src/pkg/axios.ts b/src/pkg/axios.ts new file mode 100644 index 0000000..f3fc989 --- /dev/null +++ b/src/pkg/axios.ts @@ -0,0 +1,6 @@ +import axios from 'axios'; +import { API_URL } from '../commons/constant'; + +export default axios.create({ + baseURL: API_URL, +}); \ No newline at end of file diff --git a/src/redux/reducers/example.ts b/src/redux/reducers/example.ts new file mode 100644 index 0000000..cdd98cc --- /dev/null +++ b/src/redux/reducers/example.ts @@ -0,0 +1,27 @@ +import { PayloadAction, createSlice } from "@reduxjs/toolkit" +import store from "../store" + +interface IExample{ + name: string +} + +const initialExample : IExample = { + name: "" +} + +const exampleSlicer = createSlice({ + name: "example", + initialState: initialExample, + reducers:{ + setName: (state: IExample, action : PayloadAction)=>{ + state.name = action.payload.name + } + } +}) + +const exampleReducer = exampleSlicer.reducer +export const exampleAction = exampleSlicer.actions + +export const exampleState = (state: store) => state.posts + +export default exampleReducer \ No newline at end of file diff --git a/src/redux/store.ts b/src/redux/store.ts new file mode 100644 index 0000000..7824a2c --- /dev/null +++ b/src/redux/store.ts @@ -0,0 +1,14 @@ +import { configureStore } from '@reduxjs/toolkit' +import exampleReducer from './reducers/example' + +export const store = configureStore({ + reducer: { + posts: exampleReducer, + }, +}) + +export type store = ReturnType +export type AppDispatch = typeof store.dispatch + + +export default store \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index c78a793..a848a49 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1486,6 +1486,16 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@reduxjs/toolkit@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-2.0.1.tgz#0a5233c1e35c1941b03aece39cceade3467a1062" + integrity sha512-fxIjrR9934cmS8YXIGd9e7s1XRsEU++aFc9DVNMFMRTM5Vtsg2DCRMj21eslGtDt43IUf9bJL3h5bwUlZleibA== + dependencies: + immer "^10.0.3" + redux "^5.0.0" + redux-thunk "^3.1.0" + reselect "^5.0.1" + "@remix-run/router@1.14.2": version "1.14.2" resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.14.2.tgz#4d58f59908d9197ba3179310077f25c88e49ed17" @@ -1753,6 +1763,11 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== +"@types/use-sync-external-store@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43" + integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== + "@types/yargs-parser@*": version "21.0.3" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" @@ -2163,6 +2178,15 @@ axe-core@=4.7.0: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== +axios@^1.6.5: + version "1.6.5" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.5.tgz#2c090da14aeeab3770ad30c3a1461bc970fb0cd8" + integrity sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg== + dependencies: + follow-redirects "^1.15.4" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + axobject-query@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" @@ -3235,6 +3259,11 @@ flatted@^3.2.9: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== +follow-redirects@^1.15.4: + version "1.15.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" + integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== + for-each@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -3526,6 +3555,11 @@ ignore@^5.2.0, ignore@^5.2.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== +immer@^10.0.3: + version "10.0.3" + resolved "https://registry.yarnpkg.com/immer/-/immer-10.0.3.tgz#a8de42065e964aa3edf6afc282dfc7f7f34ae3c9" + integrity sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A== + import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -4922,6 +4956,11 @@ prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" @@ -4970,6 +5009,14 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-redux@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-9.1.0.tgz#46a46d4cfed4e534ce5452bb39ba18e1d98a8197" + integrity sha512-6qoDzIO+gbrza8h3hjMA9aq4nwVFCKFtY2iLxCtVT38Swyy2C/dJCGBXHeHLtx6qlg/8qzc2MrhOeduf5K32wQ== + dependencies: + "@types/use-sync-external-store" "^0.0.3" + use-sync-external-store "^1.0.0" + react-refresh@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" @@ -5036,6 +5083,16 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +redux-thunk@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-3.1.0.tgz#94aa6e04977c30e14e892eae84978c1af6058ff3" + integrity sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw== + +redux@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-5.0.1.tgz#97fa26881ce5746500125585d5642c77b6e9447b" + integrity sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w== + reflect.getprototypeof@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3" @@ -5110,6 +5167,11 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== +reselect@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-5.1.0.tgz#c479139ab9dd91be4d9c764a7f3868210ef8cd21" + integrity sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg== + resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" @@ -5746,6 +5808,11 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" +use-sync-external-store@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"