diff --git a/package-lock.json b/package-lock.json index 10593d9..037d88c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,7 +36,8 @@ "@radix-ui/react-toggle": "^1.1.9", "@radix-ui/react-toggle-group": "^1.1.10", "@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", "clsx": "^2.1.1", "cmdk": "^1.1.1", @@ -2794,9 +2795,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.83.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.83.0.tgz", - "integrity": "sha512-0M8dA+amXUkyz5cVUm/B+zSk3xkQAcuXuz5/Q/LveT4ots2rBpPTZOzd7yJa2Utsf8D2Upl5KyjhHRY+9lB/XA==", + "version": "5.96.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.96.1.tgz", + "integrity": "sha512-u1yBgtavSy+N8wgtW3PiER6UpxcplMje65yXnnVgiHTqiMwLlxiw4WvQDrXyn+UD6lnn8kHaxmerJUzQcV/MMg==", "license": "MIT", "funding": { "type": "github", @@ -2804,12 +2805,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.83.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.83.0.tgz", - "integrity": "sha512-/XGYhZ3foc5H0VM2jLSD/NyBRIOK4q9kfeml4+0x2DlL6xVuAcVEW+hTlTapAmejObg0i3eNqhkr2dT+eciwoQ==", + "version": "5.96.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.96.1.tgz", + "integrity": "sha512-2X7KYK5KKWUKGeWCVcqxXAkYefJtrKB7tSKWgeG++b0H6BRHxQaLSSi8AxcgjmUnnosHuh9WsFZqvE16P1WCzA==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.83.0" + "@tanstack/query-core": "5.96.1" }, "funding": { "type": "github", @@ -3688,7 +3689,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, "license": "MIT" }, "node_modules/autoprefixer": { @@ -3729,6 +3729,17 @@ "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": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", @@ -3827,7 +3838,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -4065,7 +4075,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -4375,7 +4384,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -4456,7 +4464,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -4540,7 +4547,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4550,7 +4556,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4567,7 +4572,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -4580,7 +4584,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -5058,6 +5061,26 @@ "dev": true, "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": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", @@ -5078,7 +5101,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -5159,7 +5181,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -5193,7 +5214,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -5276,7 +5296,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -5306,7 +5325,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -5319,7 +5337,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -6372,7 +6389,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -7261,7 +7277,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -7271,7 +7286,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -7861,6 +7875,15 @@ "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": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", diff --git a/package.json b/package.json index 8020c87..5a6e204 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,8 @@ "@radix-ui/react-toggle": "^1.1.9", "@radix-ui/react-toggle-group": "^1.1.10", "@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", "clsx": "^2.1.1", "cmdk": "^1.1.1", diff --git a/src/App.tsx b/src/App.tsx index e665e8f..3fbfb8c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,12 +11,12 @@ import ProjectDetails from "./pages/ProjectDetails"; import Blog from "./pages/Blog"; import BlogArticle from "./pages/BlogArticle"; import NotFound from "./pages/NotFound"; +import { QueryProvider } from "./provider/QueryProvider"; -const queryClient = new QueryClient(); function AnimatedRoutes() { const location = useLocation(); - + return ( @@ -33,7 +33,7 @@ function AnimatedRoutes() { } const App = () => ( - + @@ -43,7 +43,7 @@ const App = () => ( - + ); export default App; diff --git a/src/api/axiosInstance.ts b/src/api/axiosInstance.ts new file mode 100644 index 0000000..52cbe91 --- /dev/null +++ b/src/api/axiosInstance.ts @@ -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; \ No newline at end of file diff --git a/src/api/services/blog.service.ts b/src/api/services/blog.service.ts new file mode 100644 index 0000000..0035a2c --- /dev/null +++ b/src/api/services/blog.service.ts @@ -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) => + axiosInstance.post("/api/blogs", data), + + updateBlog: (id: string, data: Partial) => + axiosInstance.patch(`/api/blogs/${id}`, data), + + deleteBlog: (id: string) => + axiosInstance.delete(`/api/blogs/${id}`), +}; \ No newline at end of file diff --git a/src/api/services/project.service.ts b/src/api/services/project.service.ts new file mode 100644 index 0000000..253f520 --- /dev/null +++ b/src/api/services/project.service.ts @@ -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) => + axiosInstance.post("/api/projects", data), + + updateProject: (id: string, data: Partial) => + axiosInstance.patch(`/api/projects/${id}`, data), + + deleteProject: (id: string) => + axiosInstance.delete(`/api/projects/${id}`), +}; \ No newline at end of file diff --git a/src/api/services/review.service.ts b/src/api/services/review.service.ts new file mode 100644 index 0000000..707b1ca --- /dev/null +++ b/src/api/services/review.service.ts @@ -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) => + axiosInstance.post("/api/reviews", data), + + updateReview: (id: string, data: Partial) => + axiosInstance.patch(`/api/reviews/${id}`, data), + + deleteReview: (id: string) => + axiosInstance.delete(`/api/reviews/${id}`), +}; \ No newline at end of file diff --git a/src/api/services/team.service.ts b/src/api/services/team.service.ts new file mode 100644 index 0000000..46397aa --- /dev/null +++ b/src/api/services/team.service.ts @@ -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) => + axiosInstance.post("/api/team", data), + + updateTeam: (id: string, data: Partial) => + axiosInstance.patch(`/api/team/${id}`, data), + + deleteTeam: (id: string) => + axiosInstance.delete(`/api/team/${id}`), +}; \ No newline at end of file diff --git a/src/components/TeamSection.tsx b/src/components/TeamSection.tsx index 892a5aa..73bbcf1 100644 --- a/src/components/TeamSection.tsx +++ b/src/components/TeamSection.tsx @@ -8,72 +8,19 @@ import { Swiper, SwiperSlide } from "swiper/react"; // Import Swiper styles import "swiper/css"; 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() { + + const {data: teamdata} = useTeam(); + + const team = teamdata?.data.data; + + + + + const ref = useRef(null); const isInView = useInView(ref, { once: true, margin: "-100px" }); const shouldScroll = team.length >= 5; diff --git a/src/data/blogData.ts b/src/data/blogData.ts index f82e485..1d8e4d7 100644 --- a/src/data/blogData.ts +++ b/src/data/blogData.ts @@ -540,6 +540,8 @@ LLMs are powerful tools, but they require thoughtful implementation. Start with }, ]; + + export const getPostBySlug = (slug: string): BlogPost | undefined => { return blogPosts.find(post => post.slug === slug); }; diff --git a/src/enums/blogCategory.ts b/src/enums/blogCategory.ts new file mode 100644 index 0000000..a895ed7 --- /dev/null +++ b/src/enums/blogCategory.ts @@ -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", +} \ No newline at end of file diff --git a/src/enums/blogStatus.ts b/src/enums/blogStatus.ts new file mode 100644 index 0000000..431ac27 --- /dev/null +++ b/src/enums/blogStatus.ts @@ -0,0 +1,5 @@ +export enum BlogStatus { + PUBLISHED = "PUBLISHED", + DRAFT = "DRAFT", + ARCHIVED = "ARCHIVED" +} \ No newline at end of file diff --git a/src/enums/projectCategory.ts b/src/enums/projectCategory.ts new file mode 100644 index 0000000..aeae91b --- /dev/null +++ b/src/enums/projectCategory.ts @@ -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" +} \ No newline at end of file diff --git a/src/enums/projectStatus.ts b/src/enums/projectStatus.ts new file mode 100644 index 0000000..7a9fbdc --- /dev/null +++ b/src/enums/projectStatus.ts @@ -0,0 +1,5 @@ +export enum ProjectStatus { + COMPLETED = "completed", + ONGOING = "ongoing", + ARCHIVED = "archived" +} \ No newline at end of file diff --git a/src/hooks/queires/useBlogs.ts b/src/hooks/queires/useBlogs.ts new file mode 100644 index 0000000..55af82f --- /dev/null +++ b/src/hooks/queires/useBlogs.ts @@ -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, + }); +}; \ No newline at end of file diff --git a/src/hooks/queires/useProjects.ts b/src/hooks/queires/useProjects.ts new file mode 100644 index 0000000..72783bb --- /dev/null +++ b/src/hooks/queires/useProjects.ts @@ -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, + }); +}; \ No newline at end of file diff --git a/src/hooks/queires/useReviews.ts b/src/hooks/queires/useReviews.ts new file mode 100644 index 0000000..885cc85 --- /dev/null +++ b/src/hooks/queires/useReviews.ts @@ -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(), + }); +}; diff --git a/src/hooks/queires/useTeam.ts b/src/hooks/queires/useTeam.ts new file mode 100644 index 0000000..9fdf8e7 --- /dev/null +++ b/src/hooks/queires/useTeam.ts @@ -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(), + }); +}; \ No newline at end of file diff --git a/src/pages/Blog.tsx b/src/pages/Blog.tsx index 2110689..c400fcb 100644 --- a/src/pages/Blog.tsx +++ b/src/pages/Blog.tsx @@ -8,6 +8,7 @@ import Navbar from '@/components/Navbar'; import Footer from '@/components/Footer'; import PageTransition from '@/components/PageTransition'; import { blogPosts } from '@/data/blogData'; +import { useBlogs } from './../hooks/queires/useBlogs'; const categories = ['All', 'AI & Machine Learning', 'Cloud Solutions', 'Web Development', 'Mobile Development']; @@ -29,13 +30,18 @@ const itemVariants = { }; export default function Blog() { + + + + + const [activeCategory, setActiveCategory] = useState('All'); const [searchQuery, setSearchQuery] = useState(''); const filteredPosts = blogPosts.filter(post => { const matchesCategory = activeCategory === 'All' || post.category === activeCategory; const matchesSearch = post.title.toLowerCase().includes(searchQuery.toLowerCase()) || - post.excerpt.toLowerCase().includes(searchQuery.toLowerCase()); + post.excerpt.toLowerCase().includes(searchQuery.toLowerCase()); return matchesCategory && matchesSearch; }); @@ -110,11 +116,10 @@ export default function Blog() { key={category} variant={activeCategory === category ? 'default' : 'outline'} onClick={() => setActiveCategory(category)} - className={`rounded-full px-6 transition-all duration-300 ${ - activeCategory === category - ? 'neon-glow bg-primary text-primary-foreground' - : 'glass border-primary/30 hover:border-primary' - }`} + className={`rounded-full px-6 transition-all duration-300 ${activeCategory === category + ? 'neon-glow bg-primary text-primary-foreground' + : 'glass border-primary/30 hover:border-primary' + }`} > {category} diff --git a/src/pages/Projects.tsx b/src/pages/Projects.tsx index 8f35f12..e965b7e 100644 --- a/src/pages/Projects.tsx +++ b/src/pages/Projects.tsx @@ -7,6 +7,10 @@ import Navbar from '@/components/Navbar'; import Footer from '@/components/Footer'; import PageTransition from '@/components/PageTransition'; 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 = [ { id: 'all', name: 'All Projects', icon: null }, @@ -36,6 +40,8 @@ const itemVariants = { }; export default function Projects() { + + const [activeCategory, setActiveCategory] = useState('all'); const filteredProjects = activeCategory === 'all' @@ -46,7 +52,7 @@ export default function Projects() {
- + {/* Hero Section */}
@@ -98,11 +104,10 @@ export default function Projects() { key={category.id} variant={activeCategory === category.id ? 'default' : 'outline'} onClick={() => setActiveCategory(category.id)} - className={`rounded-full px-6 transition-all duration-300 ${ - activeCategory === category.id - ? 'neon-glow bg-primary text-primary-foreground' - : 'glass border-primary/30 hover:border-primary' - }`} + className={`rounded-full px-6 transition-all duration-300 ${activeCategory === category.id + ? 'neon-glow bg-primary text-primary-foreground' + : 'glass border-primary/30 hover:border-primary' + }`} > {Icon && } {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" />
- + {/* Category Badge */}
diff --git a/src/provider/QueryProvider.tsx b/src/provider/QueryProvider.tsx new file mode 100644 index 0000000..92f62af --- /dev/null +++ b/src/provider/QueryProvider.tsx @@ -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 ( + + {children} + + ); +}; \ No newline at end of file diff --git a/src/types/blogs.type.ts b/src/types/blogs.type.ts new file mode 100644 index 0000000..0ea118c --- /dev/null +++ b/src/types/blogs.type.ts @@ -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; +} \ No newline at end of file diff --git a/src/types/projects.type.ts b/src/types/projects.type.ts new file mode 100644 index 0000000..13b8fa8 --- /dev/null +++ b/src/types/projects.type.ts @@ -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; +} \ No newline at end of file diff --git a/src/types/review.type.ts b/src/types/review.type.ts new file mode 100644 index 0000000..de42e03 --- /dev/null +++ b/src/types/review.type.ts @@ -0,0 +1,8 @@ +export type T_reviews = { + rating: number; + review: string; + client_name: string; + thumbnail: string; + designation: string; + verified_link: string; +} \ No newline at end of file diff --git a/src/types/team.type.ts b/src/types/team.type.ts new file mode 100644 index 0000000..5200fc3 --- /dev/null +++ b/src/types/team.type.ts @@ -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; +} \ No newline at end of file diff --git a/src/utils/queryKeys.ts b/src/utils/queryKeys.ts new file mode 100644 index 0000000..0e0e848 --- /dev/null +++ b/src/utils/queryKeys.ts @@ -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], +}; \ No newline at end of file