修正:UI 優化與使用者角色分配改為單選
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Successful in 51s
Koori-ERP-Deploy-System / deploy-production (push) Has been skipped

This commit is contained in:
2026-01-16 12:05:45 +08:00
parent 43d7cada34
commit a2c99e3a36
6 changed files with 85 additions and 54 deletions

View File

@@ -348,7 +348,7 @@ export default function AuthenticatedLayout({
<DropdownMenuTrigger className="flex items-center gap-2 outline-none group">
<div className="hidden md:flex flex-col items-end mr-1">
<span className="text-sm font-medium text-slate-700 group-hover:text-slate-900 transition-colors">
{user.name}
{user.name} ({user.username})
</span>
<span className="text-xs text-slate-500">
{user.role_labels?.[0] || user.roles?.[0] || '一般用戶'}

View File

@@ -117,7 +117,7 @@ export default function LandlordLayout({ children, title }: LandlordLayoutProps)
<DropdownMenuTrigger className="flex items-center gap-2 outline-none group">
<div className="flex flex-col items-end mr-1">
<span className="text-sm font-medium text-slate-700 group-hover:text-slate-900 transition-colors">
{user.name}
{user.name} ({user.username})
</span>
<span className="text-xs text-slate-500">
{user.role_labels?.[0] || user.roles?.[0] || '系統管理員'}

View File

@@ -4,7 +4,7 @@ import { Users, ArrowLeft, Check, Lock, Mail, User } from 'lucide-react';
import { Button } from '@/Components/ui/button';
import { Input } from '@/Components/ui/input';
import { Label } from '@/Components/ui/label';
import { Checkbox } from '@/Components/ui/checkbox';
import { RadioGroup, RadioGroupItem } from '@/Components/ui/radio-group';
import { FormEvent } from 'react';
interface Props {
@@ -26,14 +26,6 @@ export default function UserCreate({ roles }: Props) {
post(route('users.store'));
};
const toggleRole = (roleName: string) => {
if (data.roles.includes(roleName)) {
setData('roles', data.roles.filter(r => r !== roleName));
} else {
setData('roles', [...data.roles, roleName]);
}
};
return (
<AuthenticatedLayout
@@ -131,30 +123,37 @@ export default function UserCreate({ roles }: Props) {
{/* Roles */}
<div className="bg-white p-6 rounded-xl border border-gray-200 shadow-sm">
<h3 className="font-bold text-gray-900 border-b pb-2 mb-4"></h3>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<h3 className="font-bold text-gray-900 border-b pb-2 mb-4"> ()</h3>
<RadioGroup
value={data.roles[0] || ''}
onValueChange={(value) => setData('roles', [value])}
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"
>
{Object.entries(roles).map(([roleName, displayName]) => (
<div key={roleName} className="flex items-center space-x-3 p-3 border border-gray-100 bg-gray-50/50 hover:bg-gray-100 rounded-lg transition-colors">
<Checkbox
<Label
key={roleName}
htmlFor={`role-${roleName}`}
className={`flex items-center space-x-3 p-3 border rounded-lg transition-colors cursor-pointer ${data.roles.includes(roleName)
? 'border-primary-main bg-primary-lightest'
: 'border-gray-100 bg-gray-50/50 hover:bg-gray-100'
}`}
>
<RadioGroupItem
value={roleName}
id={`role-${roleName}`}
checked={data.roles.includes(roleName)}
onCheckedChange={() => toggleRole(roleName)}
className="text-primary-main border-gray-300"
/>
<div className="grid gap-1 leading-none">
<label
htmlFor={`role-${roleName}`}
className="text-sm font-medium leading-none cursor-pointer"
onClick={() => toggleRole(roleName)}
>
<span className="text-sm font-medium leading-none">
{displayName}
</label>
<p className="text-xs text-gray-500 font-mono">
</span>
<span className="text-xs text-gray-500 font-mono">
{roleName}
</p>
</span>
</div>
</div>
</Label>
))}
</div>
</RadioGroup>
{errors.roles && <p className="text-sm text-red-500 mt-2">{errors.roles}</p>}
</div>

View File

@@ -4,7 +4,7 @@ import { Users, ArrowLeft, Check, Lock, Mail, User, AlertCircle } from 'lucide-r
import { Button } from '@/Components/ui/button';
import { Input } from '@/Components/ui/input';
import { Label } from '@/Components/ui/label';
import { Checkbox } from '@/Components/ui/checkbox';
import { RadioGroup, RadioGroupItem } from '@/Components/ui/radio-group';
import { FormEvent } from 'react';
interface Role {
@@ -41,15 +41,6 @@ export default function UserEdit({ user, roles, currentRoles }: Props) {
put(route('users.update', user.id));
};
const toggleRole = (roleName: string) => {
if (data.roles.includes(roleName)) {
setData('roles', data.roles.filter(r => r !== roleName));
} else {
setData('roles', [...data.roles, roleName]);
}
};
return (
<AuthenticatedLayout
breadcrumbs={[
@@ -146,30 +137,37 @@ export default function UserEdit({ user, roles, currentRoles }: Props) {
{/* Roles */}
<div className="bg-white p-6 rounded-xl border border-gray-200 shadow-sm">
<h3 className="font-bold text-gray-900 border-b pb-2 mb-4"></h3>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<h3 className="font-bold text-gray-900 border-b pb-2 mb-4"> ()</h3>
<RadioGroup
value={data.roles[0] || ''}
onValueChange={(value) => setData('roles', [value])}
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"
>
{roles.map((role) => (
<div key={role.id} className="flex items-center space-x-3 p-3 border border-gray-100 bg-gray-50/50 hover:bg-gray-100 rounded-lg transition-colors">
<Checkbox
<Label
key={role.id}
htmlFor={`role-${role.id}`}
className={`flex items-center space-x-3 p-3 border rounded-lg transition-colors cursor-pointer ${data.roles.includes(role.name)
? 'border-primary-main bg-primary-lightest'
: 'border-gray-100 bg-gray-50/50 hover:bg-gray-100'
}`}
>
<RadioGroupItem
value={role.name}
id={`role-${role.id}`}
checked={data.roles.includes(role.name)}
onCheckedChange={() => toggleRole(role.name)}
className="text-primary-main border-gray-300"
/>
<div className="grid gap-1 leading-none">
<label
htmlFor={`role-${role.id}`}
className="text-sm font-medium leading-none cursor-pointer"
onClick={() => toggleRole(role.name)}
>
<span className="text-sm font-medium leading-none">
{role.display_name}
</label>
<p className="text-xs text-gray-500 font-mono">
</span>
<span className="text-xs text-gray-500 font-mono">
{role.name}
</p>
</span>
</div>
</div>
</Label>
))}
</div>
</RadioGroup>
{errors.roles && <p className="text-sm text-red-500 mt-2">{errors.roles}</p>}
</div>