Commit 439f259f by Arjun Jhukal

updated the page creations form

parent 1ee3bae2
"use client";
import ReactQuillEditor from '@/components/molecules/ReactQuill' import AddPageForm from '@/components/pages/dashboard/adminDashboard/pages/add-page';
import { Button, OutlinedInput } from '@mui/material'
import React, { useState } from 'react'
export default function AddGeneralPage() { export default function AddGeneralPage() {
const [pageField, setPageField] = useState(1);
return ( return (
<> <section className='add__page__root'>
<OutlinedInput placeholder='Page Title' /> <AddPageForm />
<OutlinedInput placeholder='Slug' /> </section>
{Array.from({ length: pageField }).map((_, i) => (
<div className="grid lg:grid-cols-12 gap-4" key={i}>
<div className="col-span-3">
<OutlinedInput placeholder='Heading' />
</div>
<div className="col-span-9">
<ReactQuillEditor />
</div>
</div>
)
)}
<Button variant='contained' color='primary' onClick={() => {
setPageField(prev => prev + 1)
}}>Add More</Button>
</>
) )
} }
"use client";
import React from "react";
import { useFormik } from "formik";
import * as Yup from "yup";
import {
Button,
InputLabel,
OutlinedInput,
FormHelperText,
IconButton,
} from "@mui/material";
import ReactQuillEditor from "@/components/molecules/ReactQuill";
import { pageInitialData } from "@/types/page"; // should match your type
import { CloseCircle } from "@wandersonalwes/iconsax-react";
import { useCreatePageMutation } from "@/services/pageApi";
import { showToast, ToastVariant } from "@/slice/toastSlice";
import { useAppDispatch } from "@/hooks/hook";
import { useRouter } from "next/navigation";
export default function AddPageForm() {
const [createPage, { isLoading: creatingPage }
] = useCreatePageMutation();
const dispatch = useAppDispatch();
const route = useRouter();
const formik = useFormik({
initialValues: pageInitialData,
enableReinitialize: true,
validationSchema: Yup.object({
name: Yup.string().required("Page title is required"),
slug: Yup.string().required("Slug is required"),
description: Yup.string().required("Description is required"),
content: Yup.array().of(
Yup.object({
heading: Yup.string().required("Heading is required"),
description: Yup.string().required("Description cannot be empty"),
})
),
}),
onSubmit: async (values) => {
const formData = new FormData();
formData.append("name", values.name);
formData.append("slug", values.slug);
formData.append("description", values.description);
// Add dynamic content fields
values.content.forEach((item, index) => {
formData.append(`content[${index}][heading]`, item.heading);
formData.append(`content[${index}][description]`, item.description);
});
try {
const response = await createPage(formData).unwrap();
dispatch(
showToast({
message: response.message || "Page created successfully",
variant: ToastVariant.SUCCESS
})
)
} catch (e: any) {
// console.error("Error submitting form:", e);
dispatch(
showToast({
message: e.message || "Something went wrong",
variant: ToastVariant.ERROR
})
)
}
},
});
const handleAddPageContent = () => {
formik.setFieldValue("content", [
...formik.values.content,
{ heading: "", description: "" },
]);
};
const handleRemovePageContent = (index: number) => {
const updated = [...formik.values.content];
updated.splice(index, 1);
formik.setFieldValue("content", updated);
};
return (
<form onSubmit={formik.handleSubmit} className="space-y-6">
{/* Title */}
<div className="input__field">
<InputLabel>
Page Title <span className="text-red-500">*</span>
</InputLabel>
<OutlinedInput
fullWidth
placeholder="Page Title"
name="name"
value={formik.values.name}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.touched.name && Boolean(formik.errors.name)}
/>
{formik.touched.name && formik.errors.name && (
<FormHelperText error>{formik.errors.name}</FormHelperText>
)}
</div>
{/* Slug */}
<div className="input__field">
<InputLabel>
Slug <span className="text-red-500">*</span>
</InputLabel>
<OutlinedInput
fullWidth
placeholder="Page Slug"
name="slug"
value={formik.values.slug}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.touched.slug && Boolean(formik.errors.slug)}
/>
{formik.touched.slug && formik.errors.slug && (
<FormHelperText error>{formik.errors.slug}</FormHelperText>
)}
</div>
{/* Dynamic Content */}
<InputLabel className="mb-2">Page Content</InputLabel>
<div className="space-y-6">
{formik.values.content.map((item, i) => (
<div
key={i}
className="grid grid-cols-1 lg:grid-cols-12 gap-4 items-start border border-gray-200 p-4 rounded-lg relative"
>
{/* Heading */}
<div className="lg:col-span-4">
<OutlinedInput
fullWidth
placeholder="Heading"
name={`content[${i}].heading`}
value={item.heading}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={
!!(
formik.touched.content?.[i]?.heading &&
(formik.errors.content?.[i] as any)?.heading
)
}
/>
{formik.touched.content?.[i]?.heading &&
(formik.errors.content?.[i] as any)?.heading && (
<FormHelperText error>
{(formik.errors.content?.[i] as any)?.heading}
</FormHelperText>
)}
</div>
{/* Description */}
<div className="lg:col-span-8">
<ReactQuillEditor
value={item.description}
onChange={(val: string) =>
formik.setFieldValue(`content[${i}].description`, val)
}
/>
{formik.touched.content?.[i]?.description &&
(formik.errors.content?.[i] as any)?.description && (
<FormHelperText error>
{(formik.errors.content?.[i] as any)?.description}
</FormHelperText>
)}
</div>
{/* Remove Button */}
{formik.values.content.length > 1 && <div className="absolute right-0 top-0">
<IconButton
color="error"
onClick={() => handleRemovePageContent(i)}
>
<CloseCircle />
</IconButton>
</div>}
</div>
))}
</div>
{/* Buttons */}
<div className="flex gap-3">
<Button
variant="contained"
color="primary"
type="button"
onClick={handleAddPageContent}
>
Add More Content
</Button>
<Button type="submit" variant="contained" color="secondary">
Save Page Content
</Button>
</div>
</form>
);
}
...@@ -9,6 +9,7 @@ import { providerApi } from "@/services/providerApi"; ...@@ -9,6 +9,7 @@ import { providerApi } from "@/services/providerApi";
import { transactionApi } from "@/services/transaction"; import { transactionApi } from "@/services/transaction";
import { userApi } from "@/services/userApi"; import { userApi } from "@/services/userApi";
import { settingApi } from "@/services/settingApi"; import { settingApi } from "@/services/settingApi";
import { pageApi } from "@/services/pageApi";
export const store = configureStore({ export const store = configureStore({
reducer: { reducer: {
...@@ -22,6 +23,7 @@ export const store = configureStore({ ...@@ -22,6 +23,7 @@ export const store = configureStore({
[transactionApi.reducerPath]: transactionApi.reducer, [transactionApi.reducerPath]: transactionApi.reducer,
[userApi.reducerPath]: userApi.reducer, [userApi.reducerPath]: userApi.reducer,
[settingApi.reducerPath]: settingApi.reducer, [settingApi.reducerPath]: settingApi.reducer,
[pageApi.reducerPath]: pageApi.reducer,
}, },
middleware: (getDefaultMiddleware) => middleware: (getDefaultMiddleware) =>
getDefaultMiddleware() getDefaultMiddleware()
...@@ -32,6 +34,7 @@ export const store = configureStore({ ...@@ -32,6 +34,7 @@ export const store = configureStore({
.concat(transactionApi.middleware) .concat(transactionApi.middleware)
.concat(userApi.middleware) .concat(userApi.middleware)
.concat(settingApi.middleware) .concat(settingApi.middleware)
.concat(pageApi.middleware)
}) })
......
import { createApi } from "@reduxjs/toolkit/query/react";
import { baseQuery } from "./baseQuery";
import { GlobalResponse, QueryParams } from "@/types/config";
export const pageApi = createApi({
reducerPath: "pageApi",
baseQuery: baseQuery,
tagTypes: ['pages'],
endpoints: (builder) => ({
createPage: builder.mutation<GlobalResponse, FormData>({
query: (body) => ({
url: "/api/admin/page/store",
method: "POST",
body: body
})
}),
getAllPage: builder.mutation<GlobalResponse, QueryParams>({
query: (body) => ({
url: "/api/admin/page/list",
method: "GET",
})
}),
updatePageById: builder.mutation<GlobalResponse, { id: string, body: FormData }>({
query: ({ id, body }) => ({
url: `/api/admin/page/update/${id}`,
method: "POST",
body: body
})
}),
deletePageById: builder.mutation<GlobalResponse, { id: string }>({
query: ({ id }) => ({
url: `/api/admin/page/delete/${id}`,
method: "POST",
})
})
})
})
export const {
useCreatePageMutation,
useGetAllPageMutation,
useUpdatePageByIdMutation,
useDeletePageByIdMutation
} = pageApi;
\ No newline at end of file
export interface pageRequestProps {
name: string;
slug: string;
description: string;
content: {
description: string;
heading: string;
}[]
}
export const pageInitialData = {
name: "",
slug: "",
description: "",
content: [{
description: "",
heading: "",
}]
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment