Features
Internal components

Boilerplate internal components

newForm

How to make a CRUD in 20 minutes

One of the things we like most about the boilerplate and what saves us the most time is the newForm component. In this guide we are going to see how to implement it to make a crud in 20 minutes maximum.

CRUD of a membership plan - EXAMPLE

The path where we have the crud frontend files is in

src/app/[locale]/(superAdmin)/admin/(billingModule)/billing/plans/plans

enter image description here

List

In the UI folder we have a component that lists the plans

    const BillingPlansList = async () => {
     const { data } = await getAllPlans(); //getAllPlans is a server action

We import this component in the page.tsx of our route folder

Create

To create and update we will use a single UpsertPlan file located in the UI folder since we are going to use it in /add and /edit two paths and two different files

import NewForm, { Field } from "@/components/core/NewForm";
import { upsertPlan } from "@/actions/superAdmin/superAdminBillingModule/upsert-plan";
 
const UpsertPlan = ({ planId, values }: { planId?: number, values?: any }) => {
  const formInfo = {
    name: "Create Plan",
    description: "Create a new plan for your organization",
  };
 
  const fields: Field[] = [
    {
      name: "name",
      label: "Name",
      type: "text",
      hasLanguageSupport: true,
      required: true,
    },
    {
      name: "status",
      label: "Status",
      type: "select",
      required: true,
      options: [
        {
          optionName: "Active",
          optionValue: "ACTIVE",
        },
        {
          optionName: "Inactive",
          optionValue: "INACTIVE",
        },
      ],
    },
    {
      name: "description",
      label: "Description",
      type: "textarea",
      required: true,
      hasLanguageSupport: true,
    },
  ];
 
  return (
    <>
      <NewForm
        values={values ?? []}
        info={formInfo}
        fields={fields}
        modelToUpdate={planId}
        onSubmit={upsertPlan}
      />
    </>
  );
};
 
export default UpsertPlan;

planId, values: They are injected into the UpsertPlan component when it is called on the edit page. These two variables tell newForm what to update and to set the form fields to the existing values.

Edit

In page.tsx of /edit/[id]

const SuperAdminBillingModuleEditPlanPage = async ({
  params,
}: {
  params: {
    id: string,
  },
}) => {
  const plan = await getPlanDetails(Number(params.id));
  const capabilities = await getAllCapabilities();
 
  return (
    <div>
      <PageName name={"Edit Plan"} isSubPage={true} />
      <Suspense fallback={<TableLoaderSkeleton count={10} />}>
        <UpsertPlan planId={Number(params.id)} values={plan} />
        <UpsertPlanCapabilities planOnEdit={plan} capabilities={capabilities} />
        {plan && (
          <div className="mb-20">
            <PlanPricingSection plan={plan} pricings={plan?.pricing ?? []} />
          </div>
        )}
      </Suspense>
    </div>
  );
};

We obtain the plan id from the url, obtain the data and pass it to UpsertPlan

PageName

Standardize all the headers of our administration panels

<PageName
  name={t("plans")}
  isSubPage={true}
  breadcrumbs={[
    {
      name: "Dashboard",
      href: "/admin",
    },
    {
      name: "Billing",
      href: "/admin/billing/plans/plans",
    },
  ]}
  btn1={{
    name: t("addPlan"),
    href: "plans/add",
  }}
/>