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"