diff --git a/app/_components/ApexChart.tsx b/app/_components/ApexChart.tsx index 1fce3ce..6599110 100644 --- a/app/_components/ApexChart.tsx +++ b/app/_components/ApexChart.tsx @@ -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(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) { diff --git a/app/marketing/[id]/page.tsx b/app/marketing/[id]/page.tsx index 2e948dc..b0c9cbd 100644 --- a/app/marketing/[id]/page.tsx +++ b/app/marketing/[id]/page.tsx @@ -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 ( <>
@@ -52,13 +68,13 @@ export default function Home() {

$ - 12,345,678 + {cmsData?.data.chart.missedAmount ?? 1672}

total tender amount you missed today

- +
-
+
    -
  • +
  • -
  • +
  • clipboard icon
  • -
  • +
  • -
    +
    -
    +
    (undefined); + +interface CmsProviderProps { + children: ReactNode; + cmsData: CmsResponse | null; +} + +export const CmsProvider: React.FC = ({ + children, + cmsData, +}) => { + return ( + {children} + ); +}; + +export const useCms = (): CmsContextType => { + const context = useContext(CmsContext); + if (context === undefined) { + throw new Error("useCms must be used within a CmsProvider"); + } + return context; +}; + +export async function fetchCmsData( + id: string, + cmsService: { getCms: (id: string) => Promise } +): Promise { + try { + const cmsData = await cmsService.getCms(id); + return cmsData; + } catch (error) { + console.error("Error fetching CMS data:", error); + return null; + } +} diff --git a/hooks/useCmsQueries.ts b/hooks/useCmsQueries.ts new file mode 100644 index 0000000..564c776 --- /dev/null +++ b/hooks/useCmsQueries.ts @@ -0,0 +1,21 @@ +import api from "@/service/api"; +import { CmsResponse } from "@/types/TCms"; +import { useQuery } from "@tanstack/react-query"; +import { useMemo } from "react"; +export const cmsService = { + getCms: async (id: string): Promise => { + try { + return (await api.get(`cms/${id}`)).data; + } catch (error) { + console.log("Error fetching CMS data:", error); + throw error; + } + }, +}; +export const useGetCms = (pageId: string) => { + const queryKey = useMemo(() => ["cms", pageId], [pageId]); + return useQuery({ + queryKey, + queryFn: () => cmsService.getCms(pageId), + }); +}; diff --git a/package-lock.json b/package-lock.json index 8f1d9f2..ed9a9dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "tm-landing", "version": "0.1.0", "dependencies": { + "@tanstack/react-query": "^5.90.7", "apexcharts": "^5.3.5", "axios": "^1.12.2", "next": "15.5.5", @@ -1015,6 +1016,32 @@ "tailwindcss": "4.1.14" } }, + "node_modules/@tanstack/query-core": { + "version": "5.90.7", + "resolved": "https://registry.npmmirror.com/@tanstack/query-core/-/query-core-5.90.7.tgz", + "integrity": "sha512-6PN65csiuTNfBMXqQUxQhCNdtm1rV+9kC9YwWAIKcaxAauq3Wu7p18j3gQY3YIBJU70jT/wzCCZ2uqto/vQgiQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.90.7", + "resolved": "https://registry.npmmirror.com/@tanstack/react-query/-/react-query-5.90.7.tgz", + "integrity": "sha512-wAHc/cgKzW7LZNFloThyHnV/AX9gTg3w5yAv0gvQHPZoCnepwqCMtzbuPbb2UvfvO32XZ46e8bPOYbfZhzVnnQ==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.90.7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, "node_modules/@types/node": { "version": "20.19.21", "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.19.21.tgz", diff --git a/package.json b/package.json index 136babb..a54c41e 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "start": "next start" }, "dependencies": { + "@tanstack/react-query": "^5.90.7", "apexcharts": "^5.3.5", "axios": "^1.12.2", "next": "15.5.5", diff --git a/public/file.svg b/public/file.svg index 004145c..72db25e 100644 --- a/public/file.svg +++ b/public/file.svg @@ -1 +1,4 @@ - \ No newline at end of file + + + + diff --git a/public/mobile.gif b/public/mobile.gif index 2419790..6eaa3be 100644 Binary files a/public/mobile.gif and b/public/mobile.gif differ diff --git a/public/mobile.svg b/public/mobile.svg deleted file mode 100644 index 2436784..0000000 --- a/public/mobile.svg +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/types/TCms.ts b/types/TCms.ts new file mode 100644 index 0000000..5be57c3 --- /dev/null +++ b/types/TCms.ts @@ -0,0 +1,72 @@ +export interface CmsResponse { + success: boolean; + message: string; + data: CmsData; +} + +export interface CmsData { + id: string; + key: string; + hero: CmsHero; + chart: CmsChart; + features: CmsSectionWithCards; + challenges: CmsSectionWithCards; + advantages: CmsSectionWithCards; + contact: CmsContact; + footer: CmsFooter; + created_at: number; + updated_at: number; +} + +export interface CmsHero { + Title: string; + Description: string; + ButtonText: string; + ButtonLink: string; + GifFile: string; +} + +export interface CmsChart { + title: string; + missedAmount: string; + data: CmsChartDataItem[]; +} + +export interface CmsChartDataItem { + key: string; + value: number; +} + +export interface CmsSectionWithCards { + Title: string; + Description: string; + Cards: CmsCard[]; +} + +export interface CmsCard { + Icon: string; + Title: string; + Description: string; +} + +export interface CmsContact { + Title: string; + Description: string; + SubmitButtonText: string; + Fields: CmsContactField[]; +} + +export interface CmsContactField { + Name: string; + Label: string; + Placeholder: string; + Required: boolean; +} + +export interface CmsFooter { + Email: string; + Phone: string; + Location: string; + Tagline: string; + Copyright: string; +}