Fix Tailwind CSS styling configuration

- Add tailwind.config.ts with proper content paths and theme config
- Add postcss.config.js for Tailwind and autoprefixer processing
- Downgrade tailwindcss to v3.4.17 and add missing PostCSS dependencies
- Update Dockerfile to clarify build process
- Fix UI styling issues in Docker environment
This commit is contained in:
mindesbunister
2025-07-12 23:29:42 +02:00
parent cf58d41444
commit a9bbcc7b5f
22 changed files with 3833 additions and 1020 deletions

View File

@@ -1,27 +1,242 @@
"use client"
import React, { useState } from 'react'
import React, { useState, useEffect } from 'react'
export default function DeveloperSettings() {
const [env, setEnv] = useState('')
const [settings, setSettings] = useState({
environment: 'production',
debugMode: false,
logLevel: 'info',
apiTimeout: 30000,
maxRetries: 3,
customEndpoint: ''
})
const [message, setMessage] = useState('')
const [loading, setLoading] = useState(false)
async function handleSave() {
// Example: Save env to localStorage or send to API
localStorage.setItem('devEnv', env)
setMessage('Settings saved!')
useEffect(() => {
// Load settings from localStorage
const saved = localStorage.getItem('devSettings')
if (saved) {
try {
setSettings(JSON.parse(saved))
} catch (e) {
console.error('Failed to parse saved settings:', e)
}
}
}, [])
const handleSettingChange = (key: string, value: any) => {
setSettings(prev => ({
...prev,
[key]: value
}))
}
const handleSave = async () => {
setLoading(true)
setMessage('')
try {
// Save to localStorage
localStorage.setItem('devSettings', JSON.stringify(settings))
// Optionally send to API
const response = await fetch('/api/developer-settings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(settings)
})
if (response.ok) {
setMessage('Settings saved successfully!')
} else {
setMessage('Settings saved locally (API unavailable)')
}
} catch (error) {
setMessage('Settings saved locally (API error)')
}
setLoading(false)
setTimeout(() => setMessage(''), 3000)
}
const handleReset = () => {
const defaultSettings = {
environment: 'production',
debugMode: false,
logLevel: 'info',
apiTimeout: 30000,
maxRetries: 3,
customEndpoint: ''
}
setSettings(defaultSettings)
localStorage.removeItem('devSettings')
setMessage('Settings reset to defaults')
setTimeout(() => setMessage(''), 3000)
}
return (
<div className="p-4 border rounded bg-gray-900">
<h2 className="text-lg font-bold mb-2">Developer Settings</h2>
<input
className="input input-bordered w-full mb-2"
placeholder="Custom ENV value"
value={env}
onChange={e => setEnv(e.target.value)}
/>
<button className="btn btn-primary w-full" onClick={handleSave}>Save</button>
{message && <div className="mt-2 text-green-400">{message}</div>}
<div className="card card-gradient">
<div className="flex items-center justify-between mb-6">
<h2 className="text-lg font-bold text-white flex items-center">
<span className="w-8 h-8 bg-gradient-to-br from-indigo-400 to-purple-600 rounded-lg flex items-center justify-center mr-3">
</span>
Developer Settings
</h2>
<div className="flex items-center space-x-2 text-sm text-gray-400">
<div className="w-2 h-2 bg-indigo-400 rounded-full"></div>
<span>Advanced</span>
</div>
</div>
<div className="space-y-6">
{/* Environment Selection */}
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">Environment</label>
<select
className="w-full px-3 py-2 bg-gray-800/50 border border-gray-700 rounded-lg text-white focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 transition-all"
value={settings.environment}
onChange={e => handleSettingChange('environment', e.target.value)}
>
<option value="development">Development</option>
<option value="staging">Staging</option>
<option value="production">Production</option>
</select>
</div>
{/* Debug Mode Toggle */}
<div className="flex items-center justify-between p-4 bg-gray-800/30 rounded-lg border border-gray-700">
<div>
<h3 className="text-sm font-semibold text-white">Debug Mode</h3>
<p className="text-xs text-gray-400 mt-1">Enable detailed logging and debugging features</p>
</div>
<label className="relative inline-flex items-center cursor-pointer">
<input
type="checkbox"
checked={settings.debugMode}
onChange={e => handleSettingChange('debugMode', e.target.checked)}
className="sr-only peer"
/>
<div className="w-11 h-6 bg-gray-600 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-indigo-300/20 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-indigo-600"></div>
</label>
</div>
{/* Log Level */}
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">Log Level</label>
<select
className="w-full px-3 py-2 bg-gray-800/50 border border-gray-700 rounded-lg text-white focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 transition-all"
value={settings.logLevel}
onChange={e => handleSettingChange('logLevel', e.target.value)}
>
<option value="error">Error</option>
<option value="warn">Warning</option>
<option value="info">Info</option>
<option value="debug">Debug</option>
<option value="trace">Trace</option>
</select>
</div>
{/* API Settings */}
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">API Timeout (ms)</label>
<input
type="number"
className="w-full px-3 py-2 bg-gray-800/50 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 transition-all"
value={settings.apiTimeout}
onChange={e => handleSettingChange('apiTimeout', parseInt(e.target.value) || 30000)}
min="1000"
max="300000"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">Max Retries</label>
<input
type="number"
className="w-full px-3 py-2 bg-gray-800/50 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 transition-all"
value={settings.maxRetries}
onChange={e => handleSettingChange('maxRetries', parseInt(e.target.value) || 3)}
min="0"
max="10"
/>
</div>
</div>
{/* Custom Endpoint */}
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">Custom API Endpoint</label>
<input
type="url"
className="w-full px-3 py-2 bg-gray-800/50 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 transition-all"
placeholder="https://api.example.com"
value={settings.customEndpoint}
onChange={e => handleSettingChange('customEndpoint', e.target.value)}
/>
</div>
{/* Status Message */}
{message && (
<div className={`p-3 rounded-lg text-sm ${
message.includes('successfully') || message.includes('saved locally')
? 'bg-green-500/10 border border-green-500/30 text-green-400'
: message.includes('reset')
? 'bg-blue-500/10 border border-blue-500/30 text-blue-400'
: 'bg-yellow-500/10 border border-yellow-500/30 text-yellow-400'
}`}>
{message}
</div>
)}
{/* Action Buttons */}
<div className="grid grid-cols-2 gap-3 pt-4 border-t border-gray-700">
<button
onClick={handleSave}
disabled={loading}
className={`py-3 px-4 rounded-lg font-semibold transition-all duration-300 ${
loading
? 'bg-gray-700 text-gray-400 cursor-not-allowed'
: 'btn-primary transform hover:scale-105 active:scale-95'
}`}
>
{loading ? (
<div className="flex items-center justify-center space-x-2">
<div className="spinner"></div>
<span>Saving...</span>
</div>
) : (
'Save Settings'
)}
</button>
<button
onClick={handleReset}
disabled={loading}
className="btn-secondary py-3 px-4 transform hover:scale-105 active:scale-95"
>
Reset to Defaults
</button>
</div>
{/* Current Settings Summary */}
<div className="p-3 bg-gray-800/20 rounded-lg border border-gray-700">
<h4 className="text-xs font-semibold text-gray-400 mb-2">Current Configuration</h4>
<div className="grid grid-cols-2 gap-2 text-xs">
<div className="text-gray-500">Environment:</div>
<div className="text-gray-300 capitalize">{settings.environment}</div>
<div className="text-gray-500">Debug:</div>
<div className={settings.debugMode ? 'text-green-400' : 'text-red-400'}>
{settings.debugMode ? 'Enabled' : 'Disabled'}
</div>
<div className="text-gray-500">Log Level:</div>
<div className="text-gray-300 capitalize">{settings.logLevel}</div>
<div className="text-gray-500">Timeout:</div>
<div className="text-gray-300">{settings.apiTimeout}ms</div>
</div>
</div>
</div>
</div>
)
}