From 477f7f96ebb7b2aed18f7989b652678a69f6c9c5 Mon Sep 17 00:00:00 2001 From: Bas van den Aakster Date: Fri, 3 Oct 2025 15:39:10 +0200 Subject: [PATCH] Integrate Payload CMS theme system and add clickable flag names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Theme Integration: - Added useTheme hook from @payloadcms/ui - Replaced all hardcoded colors with CSS custom properties - Created getThemeStyles() function for consistent theming - Updated all UI elements to respect dark/light theme settings - Added proper contrast for text, backgrounds, and borders Navigation Enhancement: - Made feature flag names clickable links - Links navigate to /admin/collections/feature-flags/{id} for editing - Added hover effects with underline on flag name links - Used theme-aware link color (info blue) The interface now properly adapts to Payload's admin panel theme, supporting both dark and light modes seamlessly. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/views/FeatureFlagsView.tsx | 144 ++++++++++++++++++++------------- 1 file changed, 90 insertions(+), 54 deletions(-) diff --git a/src/views/FeatureFlagsView.tsx b/src/views/FeatureFlagsView.tsx index f0e6f53..4b6001a 100644 --- a/src/views/FeatureFlagsView.tsx +++ b/src/views/FeatureFlagsView.tsx @@ -1,6 +1,6 @@ 'use client' import { useState, useEffect, useCallback, useMemo, memo } from 'react' -import { useConfig } from '@payloadcms/ui' +import { useConfig, useTheme } from '@payloadcms/ui' interface FeatureFlag { id: string @@ -22,6 +22,7 @@ interface FeatureFlag { const FeatureFlagsViewComponent = () => { const { config } = useConfig() + const { theme } = useTheme() const [flags, setFlags] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState('') @@ -168,27 +169,47 @@ const FeatureFlagsViewComponent = () => { return {sortDirection === 'asc' ? '↑' : '↓'} } + // Theme-aware styles + const getThemeStyles = () => ({ + background: 'var(--theme-bg)', + surface: 'var(--theme-elevation-50)', + surfaceHover: 'var(--theme-elevation-100)', + border: 'var(--theme-elevation-150)', + text: 'var(--theme-text)', + textMuted: 'var(--theme-text-400)', + textSubdued: 'var(--theme-text-600)', + primary: 'var(--theme-success-500)', + warning: 'var(--theme-warning-500)', + error: 'var(--theme-error-500)', + info: 'var(--theme-info-500)', + inputBg: 'var(--theme-elevation-0)', + inputBorder: 'var(--theme-elevation-250)', + headerBg: 'var(--theme-elevation-100)', + }) + + const styles = getThemeStyles() + if (loading) { return ( -
-
Loading feature flags...
+
+
Loading feature flags...
) } return ( -
+
{/* Header */}

Feature Flags Dashboard

-

+

Manage all feature flags in a spreadsheet view

@@ -199,7 +220,7 @@ const FeatureFlagsViewComponent = () => { position: 'fixed', top: '20px', right: '20px', - backgroundColor: '#10b981', + backgroundColor: styles.primary, color: 'white', padding: '0.75rem 1.5rem', borderRadius: '0.5rem', @@ -213,11 +234,11 @@ const FeatureFlagsViewComponent = () => { {error && (
Error: {error}
@@ -238,25 +259,27 @@ const FeatureFlagsViewComponent = () => { onChange={(e) => setSearch(e.target.value)} style={{ padding: '0.5rem 1rem', - border: '1px solid #d1d5db', + border: `1px solid ${styles.inputBorder}`, borderRadius: '0.5rem', fontSize: '0.875rem', - width: '300px' + width: '300px', + backgroundColor: styles.inputBg, + color: styles.text }} />
-
+
{filteredAndSortedFlags.length} of {flags.filter(f => f && f.name).length} flags