User Tag Display Component
Overview
The User Tag Display Component (src/components/UserTagDisplay.tsx) provides a comprehensive interface for displaying a user’s access level and assigned tags. It shows the user’s permissions within the tag-based access control system, helping users understand their current access rights and available features.
Key Features
Access Level Visualization
- Current user display: Shows logged-in user’s email and status
- Tag assignment overview: Visual representation of assigned tags
- Permission explanation: Clear descriptions of what each tag provides
- System tag overview: Complete list of available tags with assignment status
Tag Management Integration
- Real-time tag loading: Fetches current tag configuration from Firebase
- Assignment verification: Shows which tags are assigned to the current user
- Visual indicators: Color-coded display for assigned vs. unassigned tags
- Tag descriptions: Detailed explanations of each tag’s purpose
Component Structure
Props Interface
interface UserTagDisplayProps {
currentUser: User | null;
}
Data Dependencies
- Firebase User: Current authenticated user object
- Tag System: Integration with the application’s tag-based access control
- Access Control: Uses getUserAssignedTags utility function
Core Functionality
Tag Loading
const [tags, setTags] = useState<Tag[]>([]);
useEffect(() => {
const loadTags = async () => {
try {
const allTags = await FirebaseService.getAllTags();
setTags(allTags);
} catch (error) {
console.error('Failed to load tags:', error);
}
};
loadTags();
}, []);
User Tag Assignment
const userAssignedTags = getUserAssignedTags(tags, currentUser);
getUserAssignedTags Function:
- Evaluates user’s email against tag access control rules
- Supports domain-based, email-based, and group-based access
- Returns array of tag IDs that the user has access to
UI Implementation
Card Layout
<Card className="mb-6">
<CardHeader>
<CardTitle>Your Access Level</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
{/* User information */}
<div className="grid grid-cols-2 gap-4 text-sm">
<div>
<strong>Current User:</strong> {currentUser?.email || 'Not logged in'}
</div>
<div>
<strong>Available Tags:</strong> {tags.length}
</div>
</div>
{/* Assigned tags display */}
<div className="bg-blue-50 p-3 rounded-lg">
<div className="text-sm font-medium">Your Assigned Tags:</div>
<div className="text-xs mt-1">
{/* Tag display logic */}
</div>
</div>
{/* Tag descriptions */}
<div className="text-xs text-muted-foreground">
{/* Permission explanations */}
</div>
{/* System tags overview */}
<div className="text-xs text-muted-foreground">
{/* All available tags */}
</div>
</CardContent>
</Card>
Assigned Tags Display
{userAssignedTags.length > 0 ? (
<div className="flex flex-wrap gap-1">
{userAssignedTags.map(tagId => {
const tag = tags.find(t => t.id === tagId);
const tagName = tag?.name || tagId;
// Different colors for different tag types
const getTagColor = (name: string) => {
if (name === 'admin-tools') return 'bg-red-100 text-red-800 border-red-200';
if (name === 'beta-testers') return 'bg-purple-100 text-purple-800 border-purple-200';
if (name === 'finance-team') return 'bg-green-100 text-green-800 border-green-200';
if (name === 'ONE') return 'bg-blue-100 text-blue-800 border-blue-200';
return 'bg-gray-100 text-gray-800 border-gray-200';
};
return (
<span
key={tagId}
className={`px-2 py-1 rounded text-xs border ${getTagColor(tagName)}`}
>
{tagName}
</span>
);
})}
</div>
) : (
<span className="text-gray-500">No special access tags assigned</span>
)}
Tag Color Coding
const getTagColor = (name: string) => {
if (name === 'admin-tools') return 'bg-red-100 text-red-800 border-red-200';
if (name === 'beta-testers') return 'bg-purple-100 text-purple-800 border-purple-200';
if (name === 'finance-team') return 'bg-green-100 text-green-800 border-green-200';
if (name === 'ONE') return 'bg-blue-100 text-blue-800 border-blue-200';
return 'bg-gray-100 text-gray-800 border-gray-200';
};
Color Scheme:
- admin-tools: Red (high privilege level)
- beta-testers: Purple (experimental features)
- finance-team: Green (financial access)
- ONE: Blue (organization-specific)
- Default: Gray (standard tags)
Permission Descriptions
Tag Capability Explanations
<div className="text-xs text-muted-foreground">
<div><strong>What do these tags give you access to?</strong></div>
<div className="mt-2 space-y-1">
<div>• <strong>admin-tools</strong>: Access to advanced models, all data sources, and administrative features</div>
<div>• <strong>beta-testers</strong>: Early access to experimental features and tools</div>
<div>• <strong>ONE</strong>: Access to Our New Energy internal documents and data</div>
<div>• <strong>finance-team</strong>: Access to financial data sources and analysis tools</div>
</div>
</div>
System Tags Overview
<div className="text-xs text-muted-foreground">
<div><strong>System Tags ({tags.length} total):</strong></div>
{tags.map(tag => {
const isAssigned = userAssignedTags.includes(tag.id);
return (
<div key={tag.id} className="ml-2 mt-1 flex items-center gap-2">
<span className={isAssigned ? 'text-green-600' : 'text-gray-400'}>
{isAssigned ? '✅' : '❌'}
</span>
<span className={isAssigned ? 'font-medium' : ''}>{tag.name}</span>
<span className="text-gray-500">({tag.accessControl.type})</span>
</div>
);
})}
</div>
Display Features:
- Visual indicators: ✅ for assigned, ❌ for not assigned
- Tag names: Full tag names from system configuration
- Access control type: Shows the type of access control (domain, email, etc.)
- Assignment highlighting: Bold text for assigned tags
Access Control Integration
Tag Assignment Logic
The component relies on the getUserAssignedTags function from the access control library:
import { getUserAssignedTags } from '@/lib/access-control';
const userAssignedTags = getUserAssignedTags(tags, currentUser);
Tag Types Supported
- Domain-based: Tags assigned based on email domain
- Email-based: Tags assigned to specific email addresses
- Group-based: Tags assigned to user groups
- Role-based: Tags assigned based on user roles
Error Handling
Loading Error Management
useEffect(() => {
const loadTags = async () => {
try {
const allTags = await FirebaseService.getAllTags();
setTags(allTags);
} catch (error) {
console.error('Failed to load tags:', error);
// Component gracefully handles empty tags array
}
};
loadTags();
}, []);
Missing User Handling
<strong>Current User:</strong> {currentUser?.email || 'Not logged in'}
Empty Tag Handling
{userAssignedTags.length > 0 ? (
// Display assigned tags
) : (
<span className="text-gray-500">No special access tags assigned</span>
)}
Integration Examples
Admin Dashboard Usage
import UserTagDisplay from '@/components/UserTagDisplay';
function AdminDashboard() {
const { currentUser } = useAuth();
return (
<div className="admin-dashboard">
<h1>Admin Dashboard</h1>
{/* Show user's current access level */}
<UserTagDisplay currentUser={currentUser} />
{/* Other admin content */}
</div>
);
}
Profile Page Integration
function UserProfile() {
const { user } = useFirebaseAuth();
return (
<div className="profile-page">
<h2>User Profile</h2>
{/* Personal information */}
<div className="personal-info">
{/* User details */}
</div>
{/* Access level information */}
<UserTagDisplay currentUser={user} />
</div>
);
}
Settings Page Usage
function SettingsPage() {
const { currentUser } = useFirebaseAuth();
return (
<div className="settings-page">
<h1>Settings</h1>
<div className="settings-sections">
{/* General settings */}
{/* Access level display */}
<section>
<h3>Access Level</h3>
<UserTagDisplay currentUser={currentUser} />
</section>
</div>
</div>
);
}
Accessibility Features
Screen Reader Support
- Semantic HTML: Proper use of headings and structure
- Descriptive text: Clear descriptions of access levels
- Icon alternatives: Text alternatives for visual indicators
Keyboard Navigation
- Tab support: While primarily informational, respects tab order
- Focus indicators: Standard focus handling for interactive elements
Visual Accessibility
- High contrast: Clear color distinctions between tag types
- Text sizing: Readable text sizes throughout
- Color coding: Meaningful color coding with text alternatives
Performance Considerations
Efficient Loading
- Single API call: Loads all tags in one request
- Client-side evaluation: Tag assignment calculated client-side
- Minimal re-renders: Component only re-renders when user or tags change
Memory Management
- Lightweight state: Minimal state management
- No subscriptions: No real-time subscriptions, loads once
- Error recovery: Graceful handling of loading failures
Styling and Theme
CSS Classes Used
- Layout: Card-based layout with consistent spacing
- Typography: Hierarchical text sizing and weights
- Colors: Theme-aware colors with semantic meaning
- Spacing: Consistent margin and padding using Tailwind scale
Customization Points
- Tag colors: Easy to modify color scheme for different tag types
- Layout: Flexible grid layout for user information
- Typography: Consistent font sizing and hierarchy
- Card styling: Standard card component with customizable styling
Related Components
- TagSelector - Tag selection interface
- TagAccessDialog - Tag management dialog
- Tag Permission System - Complete tag system overview
- Tag Admin Guide - Administrative guide for tags
Future Enhancements
Planned Features
- Real-time updates: Live updates when tags are modified
- Tag requests: Interface for requesting additional tags
- Permission details: Detailed view of what each permission enables
- Usage statistics: Show how tags are being used
UX Improvements
- Interactive tooltips: Hover details for each tag
- Permission preview: Preview what features each tag unlocks
- Tag comparison: Compare access levels between users
- Export functionality: Export access summary for auditing
Troubleshooting
Common Issues
Tags not loading
// Check Firebase connection
// Verify getAllTags() function implementation
// Check user permissions for reading tags
// Review console for error messages
User assignment not showing
// Verify getUserAssignedTags() function
// Check currentUser object structure
// Ensure tag access control rules are configured
// Test with different user accounts
Colors not displaying correctly
// Check getTagColor() function logic
// Verify CSS classes are available
// Ensure tag names match expected values
// Test with different tag configurations