In this blog, we'll show you how to create a React admin panel using Refine and PrimeReact.
First, we'll explain what Refine is and how it helps build admin panels easily.
Next, we'll guide you step-by-step on creating a new Refine application and installing PrimeReact. You'll learn how to combine these technologies to make a fully functional React admin panel.
Throughout this post, we'll also cover the basics of PrimeReact, including its components and how to use them in your app.
By the end of this blog, you'll have a fully functional React admin panel that you can use as a starting point for your future projects.
Let's get started and explore the power of Refine and PrimeReact together!
Refine is a powerful framework for building web applications, specifically focused on creating admin panels, internal tools, and dashboards. It provides hooks and components that simplify the development process, making it faster and more efficient.
Instead of building everything from scratch, Refine comes with ready-made features like data handling, authentication, access control, and more. You can also customize these features to suit your needs. This way, you can focus on building your app's core functionality instead of worrying about the infrastructure.
Moreover, Refine is designed to be "headless" which gives you the freedom to style it exactly as you want. So, you can use any UI library like PrimeReact to build your app's user interface. Additionally, it supports out-of-the-box UI libraries.
You can learn more about Refine from the documentation.
We have two scaffolder options for bootstrapping a new Refine application: Browser-based Scaffolder and CLI-based Scaffolder. You can choose whichever you prefer.
With Browser-based
With CLI-based
With Browser-based
The Browser-based Scaffolder is an efficient tool that allows you to create Refine app seamlessly in your browser.
You can choose the libraries and frameworks you want to work with, and the tool will generate a boilerplate code for you.
For this tutorial, we'll be select the following options:
React Platform: Vite
UI Framework: Headless
Backend: REST API
Authentication Provider: No Auth
Once you've completed the steps, you'll have the ability to download your project. From there, proceed to the project directory and run your app with:
npm run dev
With CLI-based
We'll use the npm create refine-app command to interactively initialize the project.
✔ Choose a project template · refine-react ✔ What would you like to name your project?: · refine-with-primereact ✔ Choose your backend service to connect: · REST API ✔ Do you want to use a UI Framework?: · Headless ✔ Do you want to add example pages?: · Yes ✔ Do you need i18n (Internationalization) support?: · No ✔ Choose a package manager: · npm ✔ Would you mind sending us your choices so that we can improve create refine-app? · yes
Once the setup is complete, navigate to the project folder and start your app with:
npm run dev
Your project created according to the options we selected. It includes CRUD pages for the products and categories resources with a simple layout. The CRUD pages are generated using inferencer, which is a powerful tool that allows you to create CRUD pages automatically based on your API. Most of time, it's great point to start building your admin panel.
In this blog, we won't be using the generated pages. Instead, we'll build our admin panel pages from scratch to show you everything from the ground up. However, you can play around with the generated pages to get a feel for how inferencer works.
Once your project is successfully run, you will see the following page:
PrimeReact is a free and open source UI library specifically designed for React. It provides a rich set of components that you can use to build your app's user interface.
One of the standout features of PrimeReact is its theme designer, which allows you to customize the look and feel of your applications effortlessly. Additionally, you have the option to choose from various theme alternatives, such as Material, Bootstrap, and Tailwind, giving you the flexibility to match your project's design to your preferences.
PrimeReact also includes premium templates to further enhance the appearance and functionality of your apps. And if you ever need help or support, you can rely on their professional support team.
Now that we've covered the basics of Refine and PrimeReact, let's build a React admin panel using these technologies.
At the end of this tutorial, we'll have a project structure like below:
We'll use the fake restaurant API for our data. It's a REST API that provides data for products, categories, orders, and specific endpoints for the dashboard.
Previously, we mentioned that the scaffolded project includes auto-generated CRUD pages and basic styling. We'll remove these to start with a clean state.
Replace the App.css with the following:
App.css
html{ font-size:14px; } body{ margin:0px; // Build-in PrimeReact themes use this variable font-family:var(--font-family); }
Since we won't be using the generated CRUD pages for this example app, we'll remove the src/pages directory.
After these changes, we ready to start building our admin panel step-by-step. In the next sections, we'll update the src/App.tsx file to add the necessary components and pages.
If you don't have any experience with Refine, we recommend you to check out the tutorial to learn more about the framework.
We'll start by creating a dashboard page. It will be the first page that users see when they open our admin panel. The dashboard will display KPI cards, charts and recent orders to give users a quick overview of the business.
First, let's create a <Dashboard /> component in src/pages/dashboard/index.tsx directory with the following code:
Let's start enhancing the dashboard by adding KPI cards to display the weekly revenue, weekly orders, and new customers. For this, we'll create a <KpiCard /> component in src/components/dashboard/kpiCard/index.tsx directory with the following code:
This component is built using PrimeReact and PrimeFlex libraries. If you want to dive deeper into the code, you can explore PrimeFlex and PrimeReact Card for a better understanding.
In the code above, we created a <KpiCard /> component that renders a card with the given props. It displays the title, total, trend, and icon. The formatTotal prop allows you to format the total value as you wish.
Let's import the <KpiCard /> component in src/pages/dashboard/index.tsx and pass the necessary props to render the cards. Before that, we need to fetch the data from the API. For this, we'll use the useCustom hook from Refine and dayjs to arrange query parameters.
useCustom allows us to make specific requests to the API. It should be used on non-resource endpoints which means that it doesn't have a CRUD operation. In our case, we'll use it to fetch the data for the KPI cards and charts.
Before continuing, let's install dayjs using the following command:
npm i dayjs
After the installation is complete, update the <Dashboard /> component as follows:
We used the useCustom hook to fetch the data for the KPI cards. It makes a request to the /dailyRevenue, /dailyOrders, and /newCustomers endpoints with the query parameters. The query parameters are used to get the data for the last 7 days.
After fetching the data, we passed the necessary props to the <KpiCard /> component to render the cards. After these changes, our dashboard looks like below:
Next, we'll add charts to the dashboard to display the KPI data visually. We'll use the <ChartView /> component to render the charts. It will display the daily revenue, daily orders, and new customers charts. For this, let's create a <ChartView /> component in src/components/dashboard/chartView/index.tsx directory.
In the code above, we created a <ChartView /> component that renders a tab view with three charts. It uses the <Chart /> component from PrimeReact to render the charts.
Let's import the <ChartView /> component in src/pages/dashboard/index.tsx and pass the necessary props to render the charts. At this point, we'll use same endpoints that we used for the KPI cards. So there is no need to fetch the data again. We'll pass the data that we fetched previously to the <ChartView /> component.
You can simply copy-paste the highlighted code below into the src/pages/dashboard/index.tsx file.
Lastly, we'll add a table to display the recent sales. We'll use the <RecentSales /> component to render the table. It will display the recent sales with the order id, amount, ordered by, status, and date.
Let's create a <RecentSales /> component in src/components/dashboard/recentSales/index.tsx directory with the following code:
In the code above, we used the <DataTable /> component from PrimeReact for UI and the useTable hook from Refine for data fetching, pagination, sorting, and filtering.
Let's import the <RecentSales /> component in src/pages/dashboard/index.tsx and render it below the charts.
You can simply copy the highlighted code below and paste it into the src/pages/dashboard/index.tsx file.
The resource definition above don't create any CRUD pages. It just defines the routes for the CRUD pages. The routes are used by Refine hooks and components. For example, the useNavigation hook uses the list, create, edit, and show routes to navigate between the pages. Also, data hooks like useTable use the resource name when you don't pass the resource prop.
You can find more information about resources on the Refine documentation.
Let's create the product CRUD pages step by step and add routes for rendering them.
The product list page will display the products in a table. It will allow users to filter, sort, and paginate the products. For this, we'll use the useTable hook from Refine and the <DataTable /> component from PrimeReact.
Let's create a <ProductList /> component in src/pages/products/list.tsx directory with the following code:
We used the useTable hook to fetch the data for the table. It makes a request to the /products endpoint with the query parameters. The query parameters are used to filter, sort, and paginate the products. Since we defined the products resource in src/App.tsx, the useTable hook knows which endpoint to use for fetching the data.
After fetching the data, we passed the necessary props to the <DataTable /> component to render the table.
Additionally, we used the useDelete hook and confirmDialog method from PrimeReact to delete the products. To open the delete confirmation dialog, we should to render <ConfirmDialog /> component in the root of the application. So we'll also add it in src/App.tsx.
To export the product CRUD pages, let's create an index.ts file in src/pages/products directory with the following code:
src/pages/products/index.ts
export*from"./list";
Next, import the <ProductList /> component in src/App.tsx and add a route for rendering it.
The product create page will display a form to create a new product. It will allow users to create a new product by filling the form. For this, we'll use the useForm hook from @refinedev/react-hook-form and the input components from PrimeReact.
Before continuing, let's install react-hook-form to use unexported components from @refinedev/react-hook-form.
npm i react-hook-form
After the installation is complete, let's create a <ProductCreate /> component in src/pages/products/create.tsx directory with the following code:
In the code above, we used the useForm hook to manage the form state. It also makes a request to the /products endpoint with the POST method when the form is submitted.
Additionally, we used the useSelect hook to fetch the categories for the dropdown. It makes a request to the /categories endpoint with the GET method to fetch the categories.
To render the form, we used the PrimeReact input components and we used the React Hook Form as recommended by the PrimeReact documentation.
First, let's export the product create page on src/pages/products/index.tsx file as follows:
src/pages/products/index.tsx
export*from"./list"; export*from"./create";
Next, import the <ProductCreate /> to add a route for rendering it. For this, you can simply copy the highlighted code below and paste it into the src/App.tsx file.
The product edit page will display a form to edit an existing product. It will allow users to edit an existing product by filling the form. For this, we'll use again the useForm hook from @refinedev/react-hook-form and the input components from PrimeReact.
Let's create a <ProductEdit /> component in src/pages/products/edit.tsx directory with the following code:
In the code above, we used the useForm hook to manage the form state. It also makes a request to the /products/:id endpoint with the GET method when the hook is mounted. It fetches the product with the given id and fills the form with the fetched data. When the form is submitted, it makes a request to the /products/:id endpoint with the PATCH method.
useForm hook can distinguish between the create and edit operations by checking the resource definition. If the resource definition has an edit path, it assumes that the form is used for editing an existing record. Otherwise, it assumes that the form is used for creating a new record.
First, let's export the product edit page on src/pages/products/index.tsx file as follows:
Next, import the <ProductEdit /> to add a route for rendering it. For this, you can simply copy the highlighted code below and paste it into the src/App.tsx file.
The product show page will display the details of an existing product. It will allow users to see the details of an existing product. For this, we'll use the useShow hook from Refine.
Let's create a <ProductShow /> component in src/pages/products/show.tsx directory with the following code:
In the code above, we used the useShow hook to fetch the product details. It makes a request to the /products/:id endpoint to fetch the product details. After fetching the data, we used the useOne hook to fetch the category details related to the product.
First, let's export the product show page on src/pages/products/index.tsx file as follows:
Next, import the <ProductShow /> to add a route for rendering it. For this, you can simply copy the highlighted code below and paste it into the src/App.tsx file.
In the previous sections, we learned how to build CRUD pages for the "product" resource. Now, we'll apply a similar approach to create CRUD pages for the "category" resource. The process will be very similar to what we did for products, so we won't repeat the explanations for the common parts. If you require more details, you can refer back to the previous sections for reference.
Let's start by defining the "category" resource in src/App.tsx file as follows:
Let's update the <Layout /> component in src/components/layout/index.tsx file to render the <Menu /> and <Breadcrumb /> components which we'll create in the next sections.
Breadcrumb component is used to display the current page location within a navigational hierarchy. We'll update it to render the <Breadcrumb /> component from PrimeReact.
useBreadcrumb hook returns the breadcrumb items according to the resources defined in the <Refine /> component. If there is only one breadcrumb item, we won't render the <Breadcrumb /> component. Because there is no need to display the breadcrumb if there is only one item.
After these changes, you can see the final result as below. Also, you can interact with the admin panel on CodeSandbox.
In this blog post, we explored the powerful combination of Refine and PrimeReact to build a fully functional React admin panel. We started by understanding what Refine is and how it simplifies the process of creating admin panels.
Then, we created a new Refine app and installed PrimeReact to enhance our UI with a rich set of components. We built various features for our admin panel, including a dashboard with KPI cards, charts, and recent sales information.
Next, we created CRUD pages for managing products and categories, showcasing how easy it is to handle data with Refine. We also updated the layout, menu, and breadcrumb to improve the overall user experience.
Throughout the development process, we learned how Refine and PrimeReact work seamlessly together and we've seen how easy it is to adapt and customize the components to suit our specific needs.
By now, you should have a good understanding of how to create a React admin panel using Refine and PrimeReact. Feel free to experiment and customize further to suit your specific project requirements.
With this new knowledge in hand, you are well-equipped to build powerful and feature-rich admin panels for your web applications. Happy coding!