feat: Implement dark mode support across components and UI elements

- Added dark mode styles to TaskStatusDropdown, TaskStatusDropdownDebug, and TaskStatusDropdownSimple components.
- Introduced ThemeProvider and useTheme hook for managing theme state.
- Updated Button, Card, Input, Loading, Navigation, PageContainer, PageHeader, ProjectCalendarWidget, ProjectMap, SearchBar, States, Tooltip, and other UI components to support dark mode.
- Created ThemeToggle component for switching between light and dark modes.
- Enhanced i18n translations for settings related to theme and language preferences.
- Configured Tailwind CSS to support dark mode with class-based toggling.
This commit is contained in:
2025-09-25 08:58:03 +02:00
parent 96333ecced
commit fd87b66b06
33 changed files with 582 additions and 259 deletions

View File

@@ -318,43 +318,43 @@ export default function AuditLogViewer() {
)}
{/* Audit Logs Table */}
<div className="bg-white rounded-lg shadow overflow-hidden">
<div className="bg-white dark:bg-gray-800 rounded-lg shadow overflow-hidden">
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<table className="min-w-full divide-y divide-gray-200 dark:divide-gray-600">
<thead className="bg-gray-50 dark:bg-gray-700">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
Timestamp
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
User
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
Action
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
Resource
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
IP Address
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
Details
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
<tbody className="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-600">
{logs.map((log) => (
<tr key={log.id} className="hover:bg-gray-50">
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
<tr key={log.id} className="hover:bg-gray-50 dark:hover:bg-gray-700">
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
{formatTimestamp(log.timestamp)}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
<div>
<div className="font-medium">
{log.user_name || "Anonymous"}
</div>
<div className="text-gray-500">{log.user_email}</div>
<div className="text-gray-500 dark:text-gray-400">{log.user_email}</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm">
@@ -364,26 +364,26 @@ export default function AuditLogViewer() {
{log.action.replace(/_/g, " ").toUpperCase()}
</span>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">
<div>
<div className="font-medium">
{log.resource_type || "N/A"}
</div>
<div className="text-gray-500">
<div className="text-gray-500 dark:text-gray-400">
ID: {log.resource_id || "N/A"}
</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
{log.ip_address || "Unknown"}
</td>
<td className="px-6 py-4 text-sm text-gray-500">
<td className="px-6 py-4 text-sm text-gray-500 dark:text-gray-400">
{log.details && (
<details className="cursor-pointer">
<summary className="text-blue-600 hover:text-blue-800">
<summary className="text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300">
View Details
</summary>
<pre className="mt-2 text-xs bg-gray-100 p-2 rounded overflow-auto max-w-md">
<pre className="mt-2 text-xs bg-gray-100 dark:bg-gray-700 p-2 rounded overflow-auto max-w-md">
{JSON.stringify(log.details, null, 2)}
</pre>
</details>
@@ -396,7 +396,7 @@ export default function AuditLogViewer() {
</div>
{logs.length === 0 && !loading && (
<div className="text-center py-8 text-gray-500">
<div className="text-center py-8 text-gray-500 dark:text-gray-400">
No audit logs found matching your criteria.
</div>
)}