PMFlow/frontend/src/design/tokens/roles.ts

157 lines
3.2 KiB
TypeScript

/**
* Role Design Tokens
*
* Color scheme and styling constants for RBAC roles
* Aligns with the Linear/Enterprise dark theme
*/
import type { UserRole } from '../../api/users'
export interface RoleStyle {
border: string
background: string
text: string
icon: string
glow: string
}
export const roleColors: Record<UserRole, RoleStyle> = {
OWNER: {
border: '#f59e0b',
background: 'rgba(245, 158, 11, 0.15)',
text: '#f59e0b',
icon: 'crown',
glow: 'rgba(245, 158, 11, 0.3)',
},
REVIEWER: {
border: '#f97316',
background: 'rgba(249, 115, 22, 0.15)',
text: '#f97316',
icon: 'shield',
glow: 'rgba(249, 115, 22, 0.3)',
},
BUILDER: {
border: '#a855f7',
background: 'rgba(168, 85, 247, 0.15)',
text: '#a855f7',
icon: 'brain',
glow: 'rgba(168, 85, 247, 0.3)',
},
OPERATOR: {
border: '#10b981',
background: 'rgba(16, 185, 129, 0.15)',
text: '#10b981',
icon: 'line-chart',
glow: 'rgba(16, 185, 129, 0.3)',
},
}
/**
* Get role style by role type
*/
export function getRoleStyle(role: UserRole): RoleStyle {
return roleColors[role] || roleColors.BUILDER
}
/**
* Get role border color
*/
export function getRoleBorderColor(role: UserRole): string {
return getRoleStyle(role).border
}
/**
* Get role background color
*/
export function getRoleBackgroundColor(role: UserRole): string {
return getRoleStyle(role).background
}
/**
* Get role text color
*/
export function getRoleTextColor(role: UserRole): string {
return getRoleStyle(role).text
}
/**
* Get role icon name
*/
export function getRoleIconName(role: UserRole): string {
return getRoleStyle(role).icon
}
/**
* Get role display label
*/
export function getRoleLabel(role: UserRole): string {
const labels: Record<UserRole, string> = {
OWNER: '负责人',
REVIEWER: '评审',
BUILDER: '构建者',
OPERATOR: '运营',
}
return labels[role] || role
}
/**
* Get workload color based on value
*/
export function getWorkloadColor(workload: number): { border: string; background: string; text: string } {
if (workload < 50) {
return {
border: '#10b981',
background: 'rgba(16, 185, 129, 0.15)',
text: '#10b981',
}
}
if (workload < 80) {
return {
border: '#f59e0b',
background: 'rgba(245, 158, 11, 0.15)',
text: '#f59e0b',
}
}
return {
border: '#ef4444',
background: 'rgba(239, 68, 68, 0.15)',
text: '#ef4444',
}
}
/**
* Get status color
*/
export function getStatusColor(status: 'active' | 'away' | 'offline'): { border: string; background: string; text: string } {
const colors = {
active: {
border: '#10b981',
background: 'rgba(16, 185, 129, 0.15)',
text: '#10b981',
},
away: {
border: '#f59e0b',
background: 'rgba(245, 158, 11, 0.15)',
text: '#f59e0b',
},
offline: {
border: '#71717a',
background: 'rgba(113, 113, 122, 0.15)',
text: '#71717a',
},
}
return colors[status] || colors.offline
}
/**
* Get initials from name
*/
export function getInitials(name: string): string {
return name
.split(' ')
.map(n => n[0])
.join('')
.toUpperCase()
.slice(0, 2)
}