feat(cms): Add CMS details page and update related components

- Implement new edit marketing page with dynamic routing
- Update CMS and contact us table components with placeholder content
- Add new query hook for fetching CMS details by ID
- Modify CMS service to support fetching individual CMS details
- Update type definitions for CMS-related data structures
- Add initial breadcrumb navigation for edit marketing page
- Prepare infrastructure for future CMS editing functionality
This commit is contained in:
AmirReza Jamali
2025-11-10 09:53:22 +03:30
parent ed18d86960
commit 5640febf40
7 changed files with 210 additions and 155 deletions
+33
View File
@@ -0,0 +1,33 @@
import Loading from "@/app/loading";
import Breadcrumb from "@/components/Breadcrumbs/Breadcrumb";
import { useGetCmsDetails } from "@/hooks/queries/useCmsQueries";
import { BreadcrumbItem } from "@/types/shared";
import { use } from "react";
interface IProps {
params: Promise<{ id: string }>;
}
const EditMarketingPage = async ({ params }: IProps) => {
const { id } = use(params);
const { data, isPending } = useGetCmsDetails(id);
const breadcrumbItems: BreadcrumbItem[] = [
{
href: "/",
name: "Dashboard",
},
{
href: "/marketing",
name: "Marketing",
},
{
href: `/marketing/${id}`,
name: "Edit Marketing",
},
];
if (isPending) return <Loading />;
return (
<>
<Breadcrumb items={breadcrumbItems} />
</>
);
};
+1 -1
View File
@@ -28,7 +28,7 @@ const CmsTable = () => {
columns={columns} columns={columns}
emptyMessage="No Cms were found" emptyMessage="No Cms were found"
> >
Hollo Cms list will be added
</EmptyListWrapper> </EmptyListWrapper>
</TableBody> </TableBody>
</Table> </Table>
+11 -9
View File
@@ -1,16 +1,12 @@
"use client"; "use client";
import { import EmptyListWrapper from "@/components/HOC/EmptyListWrapper";
Table, import { Table, TableHead, TableHeader, TableRow } from "@/components/ui/table";
TableBody,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import TableSkeleton from "@/components/ui/TableSkeleton"; import TableSkeleton from "@/components/ui/TableSkeleton";
import { useContactUsListPresenter } from "./useContactUsListPresenter"; import { useContactUsListPresenter } from "./useContactUsListPresenter";
const ContactUsTable = () => { const ContactUsTable = () => {
const { columns, pathname, router, isPending } = useContactUsListPresenter(); const { columns, pathname, router, isPending, data } =
useContactUsListPresenter();
return ( return (
<div className="flex flex-col rounded-[10px] bg-white px-7.5 pb-4 pt-7.5 shadow-1 dark:bg-gray-dark dark:shadow-card"> <div className="flex flex-col rounded-[10px] bg-white px-7.5 pb-4 pt-7.5 shadow-1 dark:bg-gray-dark dark:shadow-card">
<Table> <Table>
@@ -28,7 +24,13 @@ const ContactUsTable = () => {
</TableRow> </TableRow>
</TableHeader> </TableHeader>
{isPending && <TableSkeleton column={columns.length} />} {isPending && <TableSkeleton column={columns.length} />}
<TableBody></TableBody> <EmptyListWrapper
list={data ?? []}
columns={columns}
emptyMessage="No contact us is submitted"
>
Contact us table will be initialized here
</EmptyListWrapper>
</Table> </Table>
</div> </div>
); );
@@ -2,7 +2,7 @@
import { useReadAllContactUs } from "@/hooks/queries/useContactUsQuery"; import { useReadAllContactUs } from "@/hooks/queries/useContactUsQuery";
import { usePathname, useRouter } from "next/navigation"; import { usePathname, useRouter } from "next/navigation";
export const useContactUsListPresenter = () => { export const useContactUsListPresenter = () => {
const columns: string[] = []; const columns: string[] = ["row", "actions"];
const pathname = usePathname(); const pathname = usePathname();
const router = useRouter(); const router = useRouter();
const { data, isPending } = useReadAllContactUs(); const { data, isPending } = useReadAllContactUs();
+7
View File
@@ -10,6 +10,13 @@ export const useGetCmsList = () => {
queryFn: cmsService.getCms, queryFn: cmsService.getCms,
}); });
}; };
export const useGetCmsDetails = (id: string) => {
const queryKey = useMemo(() => [API_ENDPOINTS.CMS.BASE(id)], [id]);
return useQuery({
queryKey,
queryFn: () => cmsService.getCmsDetails(id),
});
};
export const useCreateCms = () => { export const useCreateCms = () => {
const mutationKey = useMemo( const mutationKey = useMemo(
() => [API_ENDPOINTS.CMS.BASE(), "Create cms"], () => [API_ENDPOINTS.CMS.BASE(), "Create cms"],
+10 -2
View File
@@ -1,10 +1,10 @@
import api from "../axios"; import api from "../axios";
import { API_ENDPOINTS } from "../endpoints"; import { API_ENDPOINTS } from "../endpoints";
import { ApiResponse } from "../types"; import { ApiResponse } from "../types";
import { TCmsResponse } from "../types/TCms"; import { TCmsListResponse } from "../types/TCms";
export const cmsService = { export const cmsService = {
getCms: async (): Promise<ApiResponse<TCmsResponse>> => { getCms: async (): Promise<ApiResponse<TCmsListResponse>> => {
try { try {
return (await api.get(API_ENDPOINTS.CMS.BASE())).data; return (await api.get(API_ENDPOINTS.CMS.BASE())).data;
} catch (error) { } catch (error) {
@@ -20,4 +20,12 @@ export const cmsService = {
throw error; throw error;
} }
}, },
getCmsDetails: async (id: string) => {
try {
return (await api.get(API_ENDPOINTS.CMS.BASE(id))).data;
} catch (error) {
console.error("Error Caught In CMS Service => getCmsDetails: ", error);
throw error;
}
},
}; };
+13 -8
View File
@@ -1,6 +1,7 @@
import { z } from "zod"; import { z } from "zod";
export const CmsCredentials = z.object({ advantages: z.object({ export const CmsCredentials = z.object({
advantages: z.object({
cards: z.array( cards: z.array(
z.object({ z.object({
description: z.string(), description: z.string(),
@@ -69,10 +70,9 @@ export const CmsCredentials = z.object({ advantages: z.object({
description: z.string(), description: z.string(),
gifFile: z.string(), gifFile: z.string(),
title: z.string(), title: z.string(),
})}) }),
});
const CmsSchema = z.object({ const CmsSchema = z.object({
cms: z.array(
z.object({
advantages: z.object({ advantages: z.object({
cards: z.array( cards: z.array(
z.object({ z.object({
@@ -148,8 +148,13 @@ const CmsSchema = z.object({
id: z.string(), id: z.string(),
key: z.string(), key: z.string(),
type: z.string(), type: z.string(),
}),
),
}); });
export type TCmsResponse = z.infer<typeof CmsSchema>; export const cmsListResponseSchema = z.object({
export type TCmsCredentials = z.infer<typeof CmsCredentials> cms: z.array(CmsSchema),
});
export const cmsDetailsResponse = z.object({
cms: CmsSchema,
});
export type TCmsListResponse = z.infer<typeof cmsListResponseSchema>;
export type TCmsDetailsResponse = z.infer<typeof cmsDetailsResponse>
export type TCmsCredentials = z.infer<typeof CmsCredentials>;