UI polish: grouped dropdowns, analytics readability, invite tag picker
- Messages: group users by role in recipient dropdown (SelectGroup) - Analytics: full country names via Intl.DisplayNames, format SNAKE_CASE labels to Title Case, custom tooltips, increased font sizes - Invite: replace free-text tag input with grouped dropdown from DB tags using Command/Popover, showing tags organized by category with colors Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,9 @@ import { Switch } from '@/components/ui/switch'
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
SelectLabel,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select'
|
||||
@@ -321,11 +323,44 @@ export default function MessagesPage() {
|
||||
<SelectValue placeholder="Choose a user..." />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{(users as { users: Array<{ id: string; name: string | null; email: string }> } | undefined)?.users?.map((u) => (
|
||||
<SelectItem key={u.id} value={u.id}>
|
||||
{u.name || u.email}
|
||||
</SelectItem>
|
||||
))}
|
||||
{(() => {
|
||||
const userList = (users as { users: Array<{ id: string; name: string | null; email: string; role: string }> } | undefined)?.users
|
||||
if (!userList) return null
|
||||
|
||||
const grouped = userList.reduce<Record<string, typeof userList>>((acc, u) => {
|
||||
const role = u.role || 'OTHER'
|
||||
if (!acc[role]) acc[role] = []
|
||||
acc[role].push(u)
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
const roleLabels: Record<string, string> = {
|
||||
SUPER_ADMIN: 'Super Admins',
|
||||
PROGRAM_ADMIN: 'Program Admins',
|
||||
JURY_MEMBER: 'Jury Members',
|
||||
MENTOR: 'Mentors',
|
||||
OBSERVER: 'Observers',
|
||||
APPLICANT: 'Applicants',
|
||||
OTHER: 'Other',
|
||||
}
|
||||
|
||||
const roleOrder = ['SUPER_ADMIN', 'PROGRAM_ADMIN', 'JURY_MEMBER', 'MENTOR', 'OBSERVER', 'APPLICANT', 'OTHER']
|
||||
|
||||
return roleOrder
|
||||
.filter((role) => grouped[role]?.length)
|
||||
.map((role) => (
|
||||
<SelectGroup key={role}>
|
||||
<SelectLabel>{roleLabels[role] || role}</SelectLabel>
|
||||
{grouped[role]
|
||||
.sort((a, b) => (a.name || a.email).localeCompare(b.name || b.email))
|
||||
.map((u) => (
|
||||
<SelectItem key={u.id} value={u.id}>
|
||||
{u.name || u.email}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
))
|
||||
})()}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user