Nextjs Refine P4 - Inferencer (Frontend)

Nextjs Refine P4 - Inferencer (Frontend)

Table of Contents

Create project using

npm create refine-app@latest

The configuration I’ve choosen is:

  1. REST
  2. ANT

Install Inferencer package

yarn add @refinedev/inferencer

Here is the How it works for inferencer

UI AntDesign is used here as I have added ANT UI

layout.tsx

Add this resource to resources props

{
    name: "topics",
    list: "/topics",
},

Create new route

Directory: /app/topics

Page: /app/topics/page.tsx

import React from "react";
import { AntdInferencer } from "@refinedev/inferencer/antd";
export default function ListTopics() {
  return (
    <div>
      <AntdInferencer />
    </div>
  );
}

Add layout too

Copy layout from other route and paste it to /topics

alt text

List Topics

Generated Code alt text

Paste this code at /topics/page.tsx

"use client";
import React from "react";
import { BaseRecord } from "@refinedev/core";
import { useTable, List } from "@refinedev/antd";
import { Table, Space } from "antd";

export default function TopicList() {
  const { tableProps } = useTable({
    syncWithLocation: true,
  });

  return (
    <List>
      <Table {...tableProps} rowKey="id">
        <Table.Column dataIndex="id" title="Id" />
        <Table.Column dataIndex="title" title="Title" />
      </Table>
    </List>
  );
}

Add use client and default function too as the generated code is for react.

Create Topic

{
name: "topics",
list: "/topics",
create: "/topics/create" --new
},

Update the resource at layout.tsx

Copy the same code to /app/topics/create

import React from "react";
import { AntdInferencer } from "@refinedev/inferencer/antd";
export default function CreateTopic() {
  return (
    <div>
      <AntdInferencer />
    </div>
  );
}

Visit browser

alt text

The new Create button is added on the right side of the table.

alt text

This is what it came up with!

"use client";
import React from "react";
import { Create, useForm } from "@refinedev/antd";
import { Form, Input } from "antd";

export default function TopicCreate() {
  const { formProps, saveButtonProps, query } = useForm();

  return (
    <Create saveButtonProps={saveButtonProps}>
      <Form {...formProps} layout="vertical">
        <Form.Item
          label="Title"
          name={["title"]}
          rules={[
            {
              required: true,
            },
          ]}
        >
          <Input />
        </Form.Item>
      </Form>
    </Create>
  );
}

Create is working fine!

Show Topic

Adding same function to topics/show/[id]/page.tsx

import React from "react";
import { AntdInferencer } from "@refinedev/inferencer/antd";
export default function TopicShow() {
  return (
    <div>
      <AntdInferencer />
    </div>
  );
}

Visit browser http://localhost:3000/topics/show/1

alt text

import React from "react";
import { useShow } from "@refinedev/core";
import { Show, NumberField, TagField, TextField } from "@refinedev/antd";
import { Typography } from "antd";

const { Title } = Typography;

export const TopicShow = () => {
  const { query } = useShow();
  const { data, isLoading } = query;

  const record = data?.data;

  return (
    <Show isLoading={isLoading}>
      <Title level={5}>Id</Title>
      <NumberField value={record?.id ?? ""} />
      <Title level={5}>Title</Title>
      <TextField value={record?.title} />
    </Show>
  );
};

Generated code

Paste this generated code to /topics/show/[id]/page.tsx

Edit Topic

Create route /topics/edit/[id]/page.tsx

Again add same code

import React from "react";
import { AntdInferencer } from "@refinedev/inferencer/antd";
export default function TopicEdit() {
  return (
    <div>
      <AntdInferencer />
    </div>
  );
}

Update the resources:

{
  "name": "topics",
  "list": "/topics",
  "create": "/topics/create",
  "show": "/topics/show/:id",
  "edit": "/topics/edit/:id" -- new
}

alt text

Generated code

import React from "react";
import { Edit, useForm } from "@refinedev/antd";
import { Form, Input } from "antd";

export const TopicEdit = () => {
  const { formProps, saveButtonProps, query } = useForm();

  const topicsData = query?.data?.data;

  return (
    <Edit saveButtonProps={saveButtonProps}>
      <Form {...formProps} layout="vertical">
        <Form.Item
          label="Id"
          name={["id"]}
          rules={[
            {
              required: true,
            },
          ]}
        >
          <Input readOnly disabled />
        </Form.Item>
        <Form.Item
          label="Title"
          name={["title"]}
          rules={[
            {
              required: true,
            },
          ]}
        >
          <Input />
        </Form.Item>
      </Form>
    </Edit>
  );
};

Delete Topic

Update the resource

{
  "name": "topics",
  "list": "/topics",
  "create": "/topics/create",
  "show": "/topics/show/:id",
  "edit": "/topics/edit/:id",
  "meta": {
    "canDelete": true
  }
}

With this meta

Final touch:

export default function TopicList() {
  const { tableProps } = useTable({
    syncWithLocation: true,
  });

  return (
    <List>
      <Table {...tableProps} rowKey="id">
        <Table.Column dataIndex="id" title="Id" />
        <Table.Column dataIndex="title" title="Title" />
        <Table.Column
          title={"Actions"}
          dataIndex="actions"
          render={(_, record: BaseRecord) => (
            <Space>
              <EditButton hideText size="small" recordItemId={record.id} />
              <ShowButton hideText size="small" recordItemId={record.id} />
              <DeleteButton hideText size="small" recordItemId={record.id} />
            </Space>
          )}
        />
      </Table>
    </List>
  );
}

Add action buttons to combine all the CRUD.

alt text

And that’s how you use the inferencer to infer the data.

Repo link

Till this commit

After this all the changes are covered in next blogs.