feat: Add CMS context, hooks, and types for managing CMS data

- Implemented CmsContext and CmsProvider for global state management of CMS data.
- Created a custom hook `useGetCms` to fetch CMS data using React Query.
- Defined TypeScript interfaces for CMS response and its related data structures.
- Added error handling for data fetching in both the service and context.
This commit is contained in:
AmirReza Jamali
2025-11-11 15:22:12 +03:30
parent 910e8aed89
commit efbdb82535
12 changed files with 198 additions and 107 deletions
+4 -21
View File
@@ -1,5 +1,6 @@
"use client";
import { CmsData } from "@/types/TCms";
import { ApexOptions } from "apexcharts";
import dynamic from "next/dynamic";
import { useEffect, useState } from "react";
@@ -15,7 +16,7 @@ interface ChartState {
options: ApexOptions;
}
const ApexChart = () => {
const ApexChart = ({ cmsData }: { cmsData?: CmsData }) => {
const [state, setState] = useState<ChartState | null>(null);
useEffect(() => {
@@ -23,10 +24,7 @@ const ApexChart = () => {
series: [
{
name: "Sales",
data: [
182, 192, 230, 198, 243, 234, 244, 210, 274, 220, 225, 289, 265,
304,
],
data: cmsData?.chart.data.map((item) => item.value) || [10, 10, 10],
},
],
options: {
@@ -58,22 +56,7 @@ const ApexChart = () => {
colors: ["#0164FF"],
xaxis: {
type: "datetime",
categories: [
"1/11/2024",
"2/11/2024",
"3/11/2024",
"5/11/2024",
"6/11/2024",
"7/11/2024",
"8/11/2024",
"9/11/2024",
"10/11/2024",
"11/11/2024",
"12/11/2024",
"1/11/2025",
"2/11/2025",
"3/11/2025",
],
categories: cmsData?.chart.data.map((item) => item.key),
tickAmount: 0,
labels: {
formatter: function (value: any, timestamp: any, opts: any) {
+19 -3
View File
@@ -1,4 +1,6 @@
import ApexChart from "@/app/_components/ApexChart";
import { cmsService } from "@/hooks/useCmsQueries";
import { CmsResponse } from "@/types/TCms";
import { Metadata } from "next";
import Image from "next/image";
@@ -21,7 +23,20 @@ export const metadata: Metadata = {
},
};
export default function Home() {
interface IProps {
params: { id: string };
}
export default async function Home({ params }: IProps) {
const { id } = params;
let cmsData: CmsResponse | null = null;
try {
cmsData = await cmsService.getCms(id);
} catch (error) {
console.error("Error fetching CMS data:", error);
}
const centerFrames = [
{
src: "/magnifier.svg",
@@ -45,6 +60,7 @@ export default function Home() {
"We operate on a partnership model. We only succeed when you win. This aligns our goals and makes us a true partner in your growth.",
},
];
return (
<>
<section className="block lg:flex justify-around items-center">
@@ -52,13 +68,13 @@ export default function Home() {
<div className="flex flex-col gap-8">
<h2>
<span>$</span>
<span>12,345,678</span>
<span>{cmsData?.data.chart.missedAmount ?? 1672}</span>
</h2>
<h2 className="capitalize text-2xl font-bold lg:text-3xl">
total tender amount you missed today
</h2>
</div>
<ApexChart />
<ApexChart cmsData={cmsData?.data} />
</div>
<div className="m-auto w-xs lg:m-0 lg:w-auto -z-20 relative flex justify-center h-[650px] lg:h-[750px]">
<Image
+1 -1
View File
@@ -136,7 +136,7 @@ export default async function RootLayout({
<FooterForm />
<div className="relative z-10 container px-4 py-4 m-auto flex flex-col justify-center items-center mt-96 ">
<div className="relative z-10 container px-4 py-4 m-auto flex flex-col justify-center items-center mt-80 ">
<div className="flex justify-between flex-col lg:flex-row gap-14 w-full lg:w-1/2">
<div className="flex flex-col gap-10">
<Image
+6 -6
View File
@@ -124,7 +124,7 @@ export default function Home() {
</p>
</div>
<ul className="flex flex-col gap-4 lg:flex-row lg:justify-between">
<li className="flex flex-col gap-4 lg:w-80">
<li className="flex flex-col lg:w-80 gap-4 transition duration-500 hover:shadow-2xl p-5 rounded-2xl hover:transform hover:scale-110">
<div className="p-4">
<Image
src={"/clock.svg"}
@@ -139,10 +139,10 @@ export default function Home() {
monitor the market and prepare high-quality bids.
</p>
</li>
<li className="flex flex-col gap-4 lg:w-80">
<li className="flex flex-col gap-4 lg:w-80 transition duration-500 hover:shadow-2xl p-5 rounded-2xl hover:transform hover:scale-110">
<div className="p-4">
<Image
src={"/clipboard.svg"}
src={"/file.svg"}
alt="clipboard icon"
width={36}
height={36}
@@ -154,7 +154,7 @@ export default function Home() {
corporations with dedicated tender departments.
</p>
</li>
<li className="flex flex-col gap-4 lg:w-80">
<li className="flex flex-col gap-4 lg:w-80 transition duration-500 hover:shadow-2xl p-5 rounded-2xl hover:transform hover:scale-110">
<div className="p-4">
<Image
src={"/arrow-up.svg"}
@@ -176,7 +176,7 @@ export default function Home() {
The Opplens Advantage
</h2>
<div className="flex flex-col gap-10 lg:flex-row">
<article className="flex flex-col gap-7 bg-[#FFF7EB] p-10 rounded-3xl lg:pb-20">
<article className="flex flex-col gap-7 bg-[#FFF7EB] p-10 rounded-3xl lg:pb-20 hover:shadow-2xl hover:transform hover:scale-110 hover:border border-[#ffdca7] transition duration-500">
<Image
src={"people.svg"}
width={48}
@@ -192,7 +192,7 @@ export default function Home() {
</p>
</div>
</article>
<article className="flex flex-col gap-7 bg-[#E5EFFF] p-10 rounded-3xl lg:pb-20">
<article className="flex flex-col gap-7 bg-[#E5EFFF] p-10 rounded-3xl lg:pb-20 hover:shadow-2xl hover:transform hover:scale-110 hover:border border-(--primary) transition duration-500">
<Image
src={"shield-tick.svg"}
width={48}