laravelの認証機構を見てみよう(5) : 手直し(アイコンなどなど詳細をつめる)
roleの表示
とりあえず何のroleになってるんかわからないのでそれを何とかわかるようにしたいというもの。
一覧と詳細に出しますかー
一覧の加工
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Roles
</th>
...
<td className="px-6 py-4 whitespace-nowrap">TODO</td>
こんな風味にしておく。
でまあ、rolesというのは実は所有してるんだけどリレーションがloadされてないんすよね
public function index(): Response
{
$users = User::all();
dd($users->toArray());
return Inertia::render('Users/Index', ['users' => $users]);
}
こんなんで確認してみると
こうなるだけだけど
public function index(): Response
{
$users = User::with('roles')->get();
dd($users->toArray());
// 略
こうやってwithで読みこんどくと
こうなるので、最終的にindexのコードは
public function index(): Response
{
$users = User::with('roles')->get();
return Inertia::render('Users/Index', ['users' => $users]);
}
こんな感じにして、viewは
<td className="px-6 py-4 whitespace-nowrap">
{user.roles && user.roles.length > 0 ? (
user.roles.map((role, index) => (
<span
key={index}
className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800"
>
{role.name}
</span>
))
) : (
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-200 text-gray-600">
No roles
</span>
)}
</td>
みたいな
同様にshowも。ただし、こちらは $user が既に引数につっこまれているのでwithは使わない
public function show(User $user): Response
{
$user->load('roles');
return Inertia::render('Users/Show', ['user' => $user]);
}
としておいたら
resources/js/Pages/Users/Show.jsx
<div>
<h3 className="text-lg font-medium leading-6 text-gray-900">Roles</h3>
<p className="mt-2 text-lg text-gray-500">
{user.roles && user.roles.length > 0 ? (
user.roles.map((role, index) => (
<span
key={index}
className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800"
>
{role.name}
</span>
))
) : (
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-200 text-gray-600">
No roles
</span>
)}
</p>
</div>
こんな感じでRolesを出力する。これらはほぼコピペ対応なので最終的にはcomponentにする(TODO)
アイコン (react-icon)
email verifiedとかの状況を何とか出したいのでこれを呼びこんでくる。
npm install react-icons
でinstall
% ./vendor/bin/sail npm install react-icons
added 1 package, removed 183 packages, and audited 174 packages in 4s
29 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
でまあ適当に検索してみると…
とか出てくるので最初にヒットしたGoVerifiedを使ってみましょうか
import { GoVerified, GoUnverified } from "react-icons/go";
とか書いといて
<td className="px-6 py-4 whitespace-nowrap">
<GoVerified />
<GoUnverified />
{user.email}
</td>
みたいにすると
こうなるので、これを加工する
まあこんな感じである。ちなみに塗り潰されているのがよければセットを変更した方がよさそう。VscVerifiedFilledとかに変更してみる
import { VscVerifiedFilled, VscUnverified } from "react-icons/vsc";
略
{ user.email_verified_at !== null ? (
<VscVerifiedFilled className="text-green-500 mr-2" />
) : (
<VscUnverified className="text-red-500 mr-2" />
)}
<span>{user.email}</span>
この辺は好みによるけど、このようにサクっと変更可能なのがよいところであろう。なお、text-xlとかtext-lgとかいれるとちょっとでかくなる。
まあこれもcomponentにするとよいだろう。
showに関しては
<div>
<h3 className="text-lg font-medium leading-6 text-gray-900">Email</h3>
<div className="mt-2 flex items-center text-lg text-gray-500">
{ user.email_verified_at !== null ? (
<VscVerifiedFilled className="text-green-500 mr-2 text-xl" />
) : (
<VscUnverified className="text-red-500 mr-2 text-lg" />
)}
<span>{user.email}</span>
</div>
</div>
とかやっておけば
とまあこんなのでいいんじゃないかな?
detailsボタン
でまあ今VSCアイコンを使ってるんで、まあなるべくこういうのは統一感があった方がいんじゃなかろうかということで…
import { VscVerifiedFilled, VscUnverified, VscInfo } from "react-icons/vsc";
略
<button className="bg-blue-500 hover:bg-blue-700 text-white py-1 px-2 rounded flex items-center">
<VscInfo className="mr-2"/>
Details
</button>
まあこの辺はいろいろ遊んでみてくださいなっと。
Usersメニューで詳細に入ったら下線がなくなるやつ
これ自体は ./vendor/tightenco/ziggy/src/js/Router.js ってやつがやってるんですがー、まあ読むと面倒なくらい長いのでとりあえず
<div className="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
<NavLink href={route('dashboard')} active={route().current('dashboard')}>
Dashboard
</NavLink>
{props.auth.isAdmin && (
<NavLink href={route('users.index')} active={route().current('users.*')}>
Users
</NavLink>
)}
</div>
みたいにワイルドカードで書いといたらええと思うで(それだけかーいw)
breadcrumb
これはまあ
ここでやった奴を導入するだけね(てかこれ最終的にsurveyの奴と統合する予定)。
% ./vendor/bin/sail composer require robertboes/inertia-breadcrumbs
% ./vendor/bin/sail artisan vendor:publish --tag="inertia-breadcrumbs-config"
% ./vendor/bin/sail composer require diglactic/laravel-breadcrumbs
import React from 'react';
import { usePage } from '@inertiajs/react';
import { AiOutlineDoubleRight } from 'react-icons/ai';
const Breadcrumbs = () => {
const { props: { breadcrumbs } } = usePage();
if (!breadcrumbs) {
return null;
}
return (
<div className="border-t border-gray-200 py-2">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<ol className="flex space-x-2">
{breadcrumbs.map((breadcrumb, index, arr) => (
<React.Fragment key={index}>
<li>
<a href={breadcrumb.url} className={breadcrumb.current ? "border-b-2 border-blue-400" : ""}>
{breadcrumb.title}
</a>
</li>
{index < arr.length - 1 && <li className="flex items-center text-gray-500"><AiOutlineDoubleRight className="mx-1" size={12} /></li>}
</React.Fragment>
))}
</ol>
</div>
</div>
);
};
export default Breadcrumbs;
さすがにちょいチューニングした
次回
もうちょい踏みこんでいくやつ。ユーザーの削除検討、活動ログ収集(ログイン時間とかそれ以外とか)
新規とか編集はまだやりません。面倒だからやらないかもしれないし、ここまで読んでたら自作できるんじゃないかな?