implement tanstack and fetch all data

This commit is contained in:
rahat0078
2026-04-04 22:49:48 +06:00
parent d71b4ab17e
commit d96ab17169
26 changed files with 394 additions and 107 deletions
+49 -26
View File
@@ -36,7 +36,8 @@
"@radix-ui/react-toggle": "^1.1.9", "@radix-ui/react-toggle": "^1.1.9",
"@radix-ui/react-toggle-group": "^1.1.10", "@radix-ui/react-toggle-group": "^1.1.10",
"@radix-ui/react-tooltip": "^1.2.7", "@radix-ui/react-tooltip": "^1.2.7",
"@tanstack/react-query": "^5.83.0", "@tanstack/react-query": "^5.96.1",
"axios": "^1.14.0",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk": "^1.1.1", "cmdk": "^1.1.1",
@@ -2794,9 +2795,9 @@
} }
}, },
"node_modules/@tanstack/query-core": { "node_modules/@tanstack/query-core": {
"version": "5.83.0", "version": "5.96.1",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.83.0.tgz", "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.96.1.tgz",
"integrity": "sha512-0M8dA+amXUkyz5cVUm/B+zSk3xkQAcuXuz5/Q/LveT4ots2rBpPTZOzd7yJa2Utsf8D2Upl5KyjhHRY+9lB/XA==", "integrity": "sha512-u1yBgtavSy+N8wgtW3PiER6UpxcplMje65yXnnVgiHTqiMwLlxiw4WvQDrXyn+UD6lnn8kHaxmerJUzQcV/MMg==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"type": "github", "type": "github",
@@ -2804,12 +2805,12 @@
} }
}, },
"node_modules/@tanstack/react-query": { "node_modules/@tanstack/react-query": {
"version": "5.83.0", "version": "5.96.1",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.83.0.tgz", "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.96.1.tgz",
"integrity": "sha512-/XGYhZ3foc5H0VM2jLSD/NyBRIOK4q9kfeml4+0x2DlL6xVuAcVEW+hTlTapAmejObg0i3eNqhkr2dT+eciwoQ==", "integrity": "sha512-2X7KYK5KKWUKGeWCVcqxXAkYefJtrKB7tSKWgeG++b0H6BRHxQaLSSi8AxcgjmUnnosHuh9WsFZqvE16P1WCzA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@tanstack/query-core": "5.83.0" "@tanstack/query-core": "5.96.1"
}, },
"funding": { "funding": {
"type": "github", "type": "github",
@@ -3688,7 +3689,6 @@
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/autoprefixer": { "node_modules/autoprefixer": {
@@ -3729,6 +3729,17 @@
"postcss": "^8.1.0" "postcss": "^8.1.0"
} }
}, },
"node_modules/axios": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz",
"integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.11",
"form-data": "^4.0.5",
"proxy-from-env": "^2.1.0"
}
},
"node_modules/bail": { "node_modules/bail": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
@@ -3827,7 +3838,6 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"es-errors": "^1.3.0", "es-errors": "^1.3.0",
@@ -4065,7 +4075,6 @@
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"delayed-stream": "~1.0.0" "delayed-stream": "~1.0.0"
@@ -4375,7 +4384,6 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=0.4.0" "node": ">=0.4.0"
@@ -4456,7 +4464,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"call-bind-apply-helpers": "^1.0.1", "call-bind-apply-helpers": "^1.0.1",
@@ -4540,7 +4547,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@@ -4550,7 +4556,6 @@
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@@ -4567,7 +4572,6 @@
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"es-errors": "^1.3.0" "es-errors": "^1.3.0"
@@ -4580,7 +4584,6 @@
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"es-errors": "^1.3.0", "es-errors": "^1.3.0",
@@ -5058,6 +5061,26 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/follow-redirects": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/foreground-child": { "node_modules/foreground-child": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
@@ -5078,7 +5101,6 @@
"version": "4.0.5", "version": "4.0.5",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"asynckit": "^0.4.0", "asynckit": "^0.4.0",
@@ -5159,7 +5181,6 @@
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"call-bind-apply-helpers": "^1.0.2", "call-bind-apply-helpers": "^1.0.2",
@@ -5193,7 +5214,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"dunder-proto": "^1.0.1", "dunder-proto": "^1.0.1",
@@ -5276,7 +5296,6 @@
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@@ -5306,7 +5325,6 @@
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@@ -5319,7 +5337,6 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"has-symbols": "^1.0.3" "has-symbols": "^1.0.3"
@@ -6372,7 +6389,6 @@
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@@ -7261,7 +7277,6 @@
"version": "1.52.0", "version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
@@ -7271,7 +7286,6 @@
"version": "2.1.35", "version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"mime-db": "1.52.0" "mime-db": "1.52.0"
@@ -7861,6 +7875,15 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/proxy-from-env": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
"integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/psl": { "node_modules/psl": {
"version": "1.15.0", "version": "1.15.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
+2 -1
View File
@@ -41,7 +41,8 @@
"@radix-ui/react-toggle": "^1.1.9", "@radix-ui/react-toggle": "^1.1.9",
"@radix-ui/react-toggle-group": "^1.1.10", "@radix-ui/react-toggle-group": "^1.1.10",
"@radix-ui/react-tooltip": "^1.2.7", "@radix-ui/react-tooltip": "^1.2.7",
"@tanstack/react-query": "^5.83.0", "@tanstack/react-query": "^5.96.1",
"axios": "^1.14.0",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk": "^1.1.1", "cmdk": "^1.1.1",
+4 -4
View File
@@ -11,12 +11,12 @@ import ProjectDetails from "./pages/ProjectDetails";
import Blog from "./pages/Blog"; import Blog from "./pages/Blog";
import BlogArticle from "./pages/BlogArticle"; import BlogArticle from "./pages/BlogArticle";
import NotFound from "./pages/NotFound"; import NotFound from "./pages/NotFound";
import { QueryProvider } from "./provider/QueryProvider";
const queryClient = new QueryClient();
function AnimatedRoutes() { function AnimatedRoutes() {
const location = useLocation(); const location = useLocation();
return ( return (
<AnimatePresence mode="wait"> <AnimatePresence mode="wait">
<Routes location={location} key={location.pathname}> <Routes location={location} key={location.pathname}>
@@ -33,7 +33,7 @@ function AnimatedRoutes() {
} }
const App = () => ( const App = () => (
<QueryClientProvider client={queryClient}> <QueryProvider>
<ThemeProvider> <ThemeProvider>
<TooltipProvider> <TooltipProvider>
<Toaster /> <Toaster />
@@ -43,7 +43,7 @@ const App = () => (
</BrowserRouter> </BrowserRouter>
</TooltipProvider> </TooltipProvider>
</ThemeProvider> </ThemeProvider>
</QueryClientProvider> </QueryProvider>
); );
export default App; export default App;
+11
View File
@@ -0,0 +1,11 @@
import axios from "axios";
const axiosInstance = axios.create({
baseURL: import.meta.env.VITE_API_URL,
timeout: 5000,
headers: {
"Content-Type": "application/json",
},
});
export default axiosInstance;
+24
View File
@@ -0,0 +1,24 @@
import { T_blogs } from "@/types/blogs.type";
import axiosInstance from "../axiosInstance";
export interface IBlogQueryParams {
[key: string]: string | number | boolean | undefined;
}
export const blogService = {
getBlogs: (params?: IBlogQueryParams) =>
axiosInstance.get("/api/blogs", { params }).then(res => res.data),
getBlogById: (id: string) =>
axiosInstance.get(`/api/blogs/${id}`),
createBlog: (data: Partial<T_blogs>) =>
axiosInstance.post("/api/blogs", data),
updateBlog: (id: string, data: Partial<T_blogs>) =>
axiosInstance.patch(`/api/blogs/${id}`, data),
deleteBlog: (id: string) =>
axiosInstance.delete(`/api/blogs/${id}`),
};
+24
View File
@@ -0,0 +1,24 @@
import { T_projects } from '@/types/projects.type';
import axiosInstance from './../axiosInstance';
export interface IProjectsQueryParams {
[key: string]: string | number | boolean | undefined;
}
export const projectsService = {
getProjects: (params?: IProjectsQueryParams) =>
axiosInstance.get("/api/projects", { params }),
getProjectById: (id: string) =>
axiosInstance.get(`/api/projects/${id}`),
createProject: (data: Partial<T_projects>) =>
axiosInstance.post("/api/projects", data),
updateProject: (id: string, data: Partial<T_projects>) =>
axiosInstance.patch(`/api/projects/${id}`, data),
deleteProject: (id: string) =>
axiosInstance.delete(`/api/projects/${id}`),
};
+20
View File
@@ -0,0 +1,20 @@
import { T_reviews } from '@/types/review.type';
import axiosInstance from './../axiosInstance';
export const reviewsService = {
getReviews: () =>
axiosInstance.get("/api/reviews"),
getReviewById: (id: string) =>
axiosInstance.get(`/api/reviews/${id}`),
createReview: (data: Partial<T_reviews>) =>
axiosInstance.post("/api/reviews", data),
updateReview: (id: string, data: Partial<T_reviews>) =>
axiosInstance.patch(`/api/reviews/${id}`, data),
deleteReview: (id: string) =>
axiosInstance.delete(`/api/reviews/${id}`),
};
+19
View File
@@ -0,0 +1,19 @@
import { T_team } from '@/types/team.type';
import axiosInstance from './../axiosInstance';
export const teamService = {
getTeams: () =>
axiosInstance.get("/api/team"),
getTeamById: (id: string) =>
axiosInstance.get(`/api/team/${id}`),
createTeam: (data: Partial<T_team>) =>
axiosInstance.post("/api/team", data),
updateTeam: (id: string, data: Partial<T_team>) =>
axiosInstance.patch(`/api/team/${id}`, data),
deleteTeam: (id: string) =>
axiosInstance.delete(`/api/team/${id}`),
};
+10 -63
View File
@@ -8,72 +8,19 @@ import { Swiper, SwiperSlide } from "swiper/react";
// Import Swiper styles // Import Swiper styles
import "swiper/css"; import "swiper/css";
import "swiper/css/pagination"; import "swiper/css/pagination";
import { useTeam } from "@/hooks/queires/useTeam";
const team = [
// {
// name: "Md Abumahid Islam",
// role: "CEO & Founder",
// image:
// "https://res.cloudinary.com/dnxsk9rgl/image/upload/v1772734622/abumahid_ghax5c.png",
// bio: "Visionary founder building innovative digital technology solutions.",
// github: "https://github.com/abumahid",
// twitter: "https://x.com/Abumahidislam",
// linkedin: "https://www.linkedin.com/in/md-abu-mahid-islam",
// },
{
name: "Rimi Rahman",
role: "Front-end Developer",
image:
"https://res.cloudinary.com/dnxsk9rgl/image/upload/v1772735809/rimi_easbn4.png",
bio: "Technology leader designing scalable and reliable software systems.",
github: "https://github.com/sanjidaRimi023",
twitter: "",
linkedin: "https://www.linkedin.com/in/sanjidarimi023/",
},
{
name: "Utsob Saha",
role: "Social Media Manager",
image:
"https://res.cloudinary.com/dnxsk9rgl/image/upload/v1772733893/utsob_txy0qe.png",
bio: "Driving brand growth through creative social media strategy.",
github: "https://github.com/Utsob1621",
twitter: "",
linkedin: "https://www.linkedin.com/in/utsob-saha-211894350/",
},
{
name: "Yeassin Ali",
role: "Front-end Developer",
image:
"https://res.cloudinary.com/dnxsk9rgl/image/upload/v1772735363/yeassing_pf6ta6.png",
bio: "Frontend specialist creating fast and responsive web interfaces.",
github: "https://github.com/Yeassin7376",
twitter: "",
linkedin: "https://www.linkedin.com/in/yeassin-ali17/",
},
{
name: "Sharafat Hossain",
role: "Front-end Developer",
image:
"https://res.cloudinary.com/dnxsk9rgl/image/upload/v1772736523/sharafat_pydaih.png",
bio: "Building modern web applications with full stack expertise.",
github: "https://github.com/dev-sharafat",
twitter: "",
linkedin: "https://www.linkedin.com/in/sharafathassain23/",
},
{
name: "Ripa Akter Badhon",
role: "HR Manager",
image:
"https://res.cloudinary.com/dnxsk9rgl/image/upload/v1772991488/badhon_ny4nsr.png",
bio: "Supporting team growth and employee wellbeing.",
github: "",
twitter: "",
linkedin: "",
},
];
export default function TeamSection() { export default function TeamSection() {
const {data: teamdata} = useTeam();
const team = teamdata?.data.data;
const ref = useRef<HTMLElement>(null); const ref = useRef<HTMLElement>(null);
const isInView = useInView(ref, { once: true, margin: "-100px" }); const isInView = useInView(ref, { once: true, margin: "-100px" });
const shouldScroll = team.length >= 5; const shouldScroll = team.length >= 5;
+2
View File
@@ -540,6 +540,8 @@ LLMs are powerful tools, but they require thoughtful implementation. Start with
}, },
]; ];
export const getPostBySlug = (slug: string): BlogPost | undefined => { export const getPostBySlug = (slug: string): BlogPost | undefined => {
return blogPosts.find(post => post.slug === slug); return blogPosts.find(post => post.slug === slug);
}; };
+12
View File
@@ -0,0 +1,12 @@
export enum BlogCategory {
WEB_DEVELOPMENT = "Web Development",
MOBILE_DEVELOPMENT = "Mobile Development",
UI_UX_DESIGN = "UI/UX Design",
DEVOPS = "DevOps",
MACHINE_LEARNING = "Machine Learning",
CYBER_SECURITY = "Cyber Security",
CLOUD_COMPUTING = "Cloud Computing",
DATA_SCIENCE = "Data Science",
PROGRAMMING = "Programming",
CAREER_GUIDE = "Career Guide",
}
+5
View File
@@ -0,0 +1,5 @@
export enum BlogStatus {
PUBLISHED = "PUBLISHED",
DRAFT = "DRAFT",
ARCHIVED = "ARCHIVED"
}
+17
View File
@@ -0,0 +1,17 @@
export enum ProjectCategory {
WEB = "web",
MOBILE = "mobile",
DESKTOP = "desktop",
BACKEND = "backend",
FULLSTACK = "fullstack",
CLOUD = "cloud",
AI = "ai",
MACHINE_LEARNING = "machine-learning",
DATA_SCIENCE = "data-science",
DEVOPS = "devops",
ECOMMERCE = "ecommerce",
SAAS = "saas",
API = "api",
BLOCKCHAIN = "blockchain",
IOT = "iot"
}
+5
View File
@@ -0,0 +1,5 @@
export enum ProjectStatus {
COMPLETED = "completed",
ONGOING = "ongoing",
ARCHIVED = "archived"
}
+19
View File
@@ -0,0 +1,19 @@
import { blogService, IBlogQueryParams } from "@/api/services/blog.service";
import { queryKeys } from "@/utils/queryKeys";
import { useQuery } from "@tanstack/react-query";
export const useBlogs = (params?: IBlogQueryParams) => {
return useQuery({
queryKey: [...queryKeys.blogs, params],
queryFn: () => blogService.getBlogs(params),
});
};
export const useBlogById = (id: string) => {
return useQuery({
queryKey: queryKeys.blog(id),
queryFn: () => blogService.getBlogById(id),
enabled: !!id,
});
};
+19
View File
@@ -0,0 +1,19 @@
import { IProjectsQueryParams, projectsService } from "@/api/services/project.service";
import { queryKeys } from "@/utils/queryKeys";
import { useQuery } from "@tanstack/react-query";
export const useProjects = (params?: IProjectsQueryParams) => {
return useQuery({
queryKey: [...queryKeys.projects, params],
queryFn: () => projectsService.getProjects(params),
});
};
export const useProjectById = (id: string) => {
return useQuery({
queryKey: queryKeys.project(id),
queryFn: () => projectsService.getProjectById(id),
enabled: !!id,
});
};
+11
View File
@@ -0,0 +1,11 @@
import { reviewsService } from "@/api/services/review.service";
import { queryKeys } from "@/utils/queryKeys";
import { useQuery } from "@tanstack/react-query";
export const useReviews = () => {
return useQuery({
queryKey: [...queryKeys.reviews],
queryFn: () => reviewsService.getReviews(),
});
};
+11
View File
@@ -0,0 +1,11 @@
import { teamService } from "@/api/services/team.service";
import { queryKeys } from "@/utils/queryKeys";
import { useQuery } from "@tanstack/react-query";
export const useTeam = () => {
return useQuery({
queryKey: [...queryKeys.team],
queryFn: () => teamService.getTeams(),
});
};
+11 -6
View File
@@ -8,6 +8,7 @@ import Navbar from '@/components/Navbar';
import Footer from '@/components/Footer'; import Footer from '@/components/Footer';
import PageTransition from '@/components/PageTransition'; import PageTransition from '@/components/PageTransition';
import { blogPosts } from '@/data/blogData'; import { blogPosts } from '@/data/blogData';
import { useBlogs } from './../hooks/queires/useBlogs';
const categories = ['All', 'AI & Machine Learning', 'Cloud Solutions', 'Web Development', 'Mobile Development']; const categories = ['All', 'AI & Machine Learning', 'Cloud Solutions', 'Web Development', 'Mobile Development'];
@@ -29,13 +30,18 @@ const itemVariants = {
}; };
export default function Blog() { export default function Blog() {
const [activeCategory, setActiveCategory] = useState('All'); const [activeCategory, setActiveCategory] = useState('All');
const [searchQuery, setSearchQuery] = useState(''); const [searchQuery, setSearchQuery] = useState('');
const filteredPosts = blogPosts.filter(post => { const filteredPosts = blogPosts.filter(post => {
const matchesCategory = activeCategory === 'All' || post.category === activeCategory; const matchesCategory = activeCategory === 'All' || post.category === activeCategory;
const matchesSearch = post.title.toLowerCase().includes(searchQuery.toLowerCase()) || const matchesSearch = post.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
post.excerpt.toLowerCase().includes(searchQuery.toLowerCase()); post.excerpt.toLowerCase().includes(searchQuery.toLowerCase());
return matchesCategory && matchesSearch; return matchesCategory && matchesSearch;
}); });
@@ -110,11 +116,10 @@ export default function Blog() {
key={category} key={category}
variant={activeCategory === category ? 'default' : 'outline'} variant={activeCategory === category ? 'default' : 'outline'}
onClick={() => setActiveCategory(category)} onClick={() => setActiveCategory(category)}
className={`rounded-full px-6 transition-all duration-300 ${ className={`rounded-full px-6 transition-all duration-300 ${activeCategory === category
activeCategory === category ? 'neon-glow bg-primary text-primary-foreground'
? 'neon-glow bg-primary text-primary-foreground' : 'glass border-primary/30 hover:border-primary'
: 'glass border-primary/30 hover:border-primary' }`}
}`}
> >
{category} {category}
</Button> </Button>
+12 -7
View File
@@ -7,6 +7,10 @@ import Navbar from '@/components/Navbar';
import Footer from '@/components/Footer'; import Footer from '@/components/Footer';
import PageTransition from '@/components/PageTransition'; import PageTransition from '@/components/PageTransition';
import { projects } from '@/data/projectData'; import { projects } from '@/data/projectData';
import { useBlogById, useBlogs } from './../hooks/queires/useBlogs';
import { useProjectById, useProjects } from '@/hooks/queires/useProjects';
import { useTeam } from '@/hooks/queires/useTeam';
import { useReviews } from '@/hooks/queires/useReviews';
const categories = [ const categories = [
{ id: 'all', name: 'All Projects', icon: null }, { id: 'all', name: 'All Projects', icon: null },
@@ -36,6 +40,8 @@ const itemVariants = {
}; };
export default function Projects() { export default function Projects() {
const [activeCategory, setActiveCategory] = useState('all'); const [activeCategory, setActiveCategory] = useState('all');
const filteredProjects = activeCategory === 'all' const filteredProjects = activeCategory === 'all'
@@ -46,7 +52,7 @@ export default function Projects() {
<PageTransition> <PageTransition>
<div className="min-h-screen bg-background overflow-x-hidden"> <div className="min-h-screen bg-background overflow-x-hidden">
<Navbar /> <Navbar />
{/* Hero Section */} {/* Hero Section */}
<section className="pt-32 pb-16 relative overflow-hidden"> <section className="pt-32 pb-16 relative overflow-hidden">
<div className="absolute inset-0"> <div className="absolute inset-0">
@@ -98,11 +104,10 @@ export default function Projects() {
key={category.id} key={category.id}
variant={activeCategory === category.id ? 'default' : 'outline'} variant={activeCategory === category.id ? 'default' : 'outline'}
onClick={() => setActiveCategory(category.id)} onClick={() => setActiveCategory(category.id)}
className={`rounded-full px-6 transition-all duration-300 ${ className={`rounded-full px-6 transition-all duration-300 ${activeCategory === category.id
activeCategory === category.id ? 'neon-glow bg-primary text-primary-foreground'
? 'neon-glow bg-primary text-primary-foreground' : 'glass border-primary/30 hover:border-primary'
: 'glass border-primary/30 hover:border-primary' }`}
}`}
> >
{Icon && <Icon className="w-4 h-4 mr-2" />} {Icon && <Icon className="w-4 h-4 mr-2" />}
{category.name} {category.name}
@@ -140,7 +145,7 @@ export default function Projects() {
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110" className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110"
/> />
<div className="absolute inset-0 bg-gradient-to-t from-background via-background/50 to-transparent opacity-60" /> <div className="absolute inset-0 bg-gradient-to-t from-background via-background/50 to-transparent opacity-60" />
{/* Category Badge */} {/* Category Badge */}
<div className="absolute top-4 left-4"> <div className="absolute top-4 left-4">
<span className="px-3 py-1 rounded-full bg-primary/20 text-primary text-sm font-medium backdrop-blur-sm border border-primary/30"> <span className="px-3 py-1 rounded-full bg-primary/20 text-primary text-sm font-medium backdrop-blur-sm border border-primary/30">
+20
View File
@@ -0,0 +1,20 @@
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactNode } from "react";
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5,
refetchOnWindowFocus: false,
retry: 1,
},
},
});
export const QueryProvider = ({ children }: { children: ReactNode }) => {
return (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
);
};
+30
View File
@@ -0,0 +1,30 @@
import { BlogCategory } from "@/enums/blogCategory";
import { BlogStatus } from "@/enums/blogStatus";
export type T_socialLinks = {
github: string;
linkedin?: string;
twitter?: string;
portfolio?: string;
facebook?: string;
}
export type T_blogs = {
title: string;
content_description: string;
thumbnail: string;
images?: string[];
authorName: string;
authorImage: string;
authorDesignation: string;
authorEmail: string;
socialMediaLink: T_socialLinks;
category: BlogCategory;
tags: string[];
isFeatured: boolean;
status: BlogStatus;
createdAt: Date;
updatedAt: Date;
}
+19
View File
@@ -0,0 +1,19 @@
import { ProjectCategory } from "@/enums/projectCategory";
import { ProjectStatus } from "@/enums/projectStatus";
export type T_projects = {
name: string;
description: string;
thumbnail?: string;
images?: string[];
category: ProjectCategory;
githubLink: string;
liveLink?: string;
technologies: string[];
companyName: string;
completionYear?: number;
isFeatured: boolean;
status: ProjectStatus;
createdAt: Date;
updatedAt: Date;
}
+8
View File
@@ -0,0 +1,8 @@
export type T_reviews = {
rating: number;
review: string;
client_name: string;
thumbnail: string;
designation: string;
verified_link: string;
}
+17
View File
@@ -0,0 +1,17 @@
export type T_social_links = {
github: string;
linkedin?: string;
twitter?: string;
portfolio?: string;
facebook?: string;
}
export type T_team = {
name: string;
role: string;
description: string;
image: string;
socialLinks: T_social_links;
createdAt: Date;
updatedAt: Date;
}
+13
View File
@@ -0,0 +1,13 @@
export const queryKeys = {
blogs: ["blogs"],
blog: (id: string) => ["blogs", id],
projects: ["projects"],
project: (id: string) => ["projects", id],
reviews: ["reviews"],
review: (id: string) => ["reviews", id],
team: ["team"],
member: (id: string) => ["team", id],
};