Refineを使用してshadcn/uiベースの管理画面をNext.jsで構築
導入
管理画面を気合いで開発していたところ、インターンの子から「Refineというのがありますよ。」という話を教えてもらい、実際にRefineを使用した管理画面を開発してみる
Refineとは?
簡単に管理画面を開発できるOSS。(現状の認識)
ローコードよりより詳細にかけて、Reactで動いているもの
実現したいこと
Shadcn UIで管理画面を開発していたのでShadcnのデザインにしたい。
導入
Shadcn UIとRefineが実現できるか調べたら公式がドキュメントを出していた。
このドキュメントではViteを使用した構築を紹介して居るが、自分が普段Next.jsでコードを書いて居るため、今回はNext.jsで構築していく。
プロジェクトファイルの作成
1. Refineを使用した初期化を実行
npm create refine-app@latest refine-shadcn
2. オプションの選択
DBはSupabaseを使用して居るので、Data ProviderはSupabaseを選択しました。
✔ Downloaded remote source successfully.
✔ Choose a project template · refine-nextjs
✔ What would you like to name your project?: · refine-shadcn-nextjs-example
✔ Choose your backend service to connect: · data-provider-supabase
✔ Do you want to use a UI Framework?: · no
✔ Do you want to add example pages?: · headless-example
✔ Choose a package manager: · npm
✔ Mind sharing your email? (We reach out to developers for free priority support, events, and SWAG kits. We never spam.) ·
時間が経つとプロジェクトの初期化が出来ました
Success! Created refine-shadcn-nextjs-example at /Users/sasaki/Documents/refine-shadcn-nextjs-example 🚀
Start developing by:
› cd /Users/sasaki/Documents/refine-shadcn-nextjs-example
› npm run dev
› Join us at https://discord.gg/refine
実行の確認
npm run dev
で実行を確認
http://localhost:3000/
にアクセスすると何も表示がされない。
事前調査でログイン画面が出てくることは確認していたので、何かバグっていると考えています。
もしくはlocalhost:3000で変なクッキーがあるか。
http://localhost:3000/blog-posts1
に直リンクしたら変なリダイレクトはなくなったのでOK。
追記
ログアウトしたら治った。Cookieが悪かったみたい
Shadcn UI を使用出来るようにする
各種パッケージをインストール
下記のコマンドを実行
npm install -D tailwindcss postcss autoprefixer
TailwindCSSを初期化
下記のコマンドを実行
npx tailwindcss init -p
Shadcn UIを初期化
npx shadcn-ui@latest init
オプション
ファイルを見ると、CSSファイルの場所がデフォルトと違うので注意
✔ Would you like to use TypeScript (recommended)? … yes
✔ Which style would you like to use? › Default
✔ Which color would you like to use as base color? › Slate
✔ Where is your global CSS file? … src/app/styles/global.css
✔ Would you like to use CSS variables for colors? … yes
✔ Are you using a custom tailwind prefix eg. tw-? (Leave blank if not) …
✔ Where is your tailwind.config.js located? … tailwind.config.js
✔ Configure the import alias for components: … @/components
✔ Configure the import alias for utils: … @/lib/utils
✔ Are you using React Server Components? … yes
✔ Write configuration to components.json. Proceed? … yes
global.cssに追記
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
Shadcn UIのインストール & 動作確認
コンポーネントのダウンロード
npx shadcn-ui@latest add button
を実行してButtonのコンポーネントをダウンロード
Logoutボタンを変更
"use client";
import { useLogout, useMenu } from "@refinedev/core";
import Link from "next/link";
+ import {Button} from "@components/ui/button";
export const Menu = () => {
const { mutate: logout } = useLogout();
const { menuItems, selectedKey } = useMenu();
return (
<nav className="menu">
<ul>
{menuItems.map((item) => (
<li key={item.key}>
<Link
href={item.route ?? "/"}
className={selectedKey === item.key ? "active" : ""}
>
{item.label}
</Link>
</li>
))}
</ul>
- <button onClick={() => logout()}>Logout</button>
+ <Button onClick={() => logout()}>Logout</Button>
</nav>
);
};
完了したら環境を再起動してください。(勝手に適応されてなかったので)
デザインの変更を確認
http://localhost:3000/categories
にアクセスするとButtonのデザインが変更されて居るのを確認
TableをShadcn UIに切り替える
簡単にCategoryのページをShadcn UIのテーブルに変更する
global.cssを変更
Tableのstyleが適応されて居るので削除を行う。
...code
-table {
- border-spacing: 0;
- border: 1px solid black;
-}
-
-table th,
-td {
- margin: 0;
- padding: 0.5rem;
- border-bottom: 1px solid black;
- border-right: 1px solid black;
-}
-
-table tr:last-child td {
- border-bottom: 0;
-}
-
-table th,
-td {
- margin: 0;
- padding: 0.5rem;
- border-bottom: 1px solid black;
- border-right: 1px solid black;
-}
-
-table th:last-child,
-td:last-child {
- border-right: 0;
-}
...code
Shadcnのコンポーネントをダウンロード
npx shadcn-ui@latest add table
でTableのコンポーネントをダウンロード
TableをShadcnのコンポーネントに変更
Tableを切り替えていく
ファイル上部でコンポーネントをインポート
import {
Table,
TableBody,
TableCaption,
TableCell,
TableFooter,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
テーブル部分のコードを以下に置換
<Table>
<TableHeader>
{getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<TableHead key={header.id}>
{!header.isPlaceholder &&
flexRender(
header.column.columnDef.header,
header.getContext()
)}
</TableHead>
))}
</TableRow>
))}
</TableHeader>
<TableBody>
{getRowModel().rows.map((row) => (
<TableRow key={row.id}>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
デザインの確認
http://localhost:3000/categories
にアクセス
基本的にフロントエンドを切り替えれば良さそう。
これにて調査終了かな。
そもそもRefineが何出来るかよくわかってないからそこの調査は必要。