From 2ecd4a6306fb49f5377ce9e61e061175719652d2 Mon Sep 17 00:00:00 2001 From: cryptooda Date: Sun, 9 Nov 2025 13:10:40 +0700 Subject: [PATCH] Fix timeout and daisyui --- src/Managing.WebApp/package.json | 4 +- src/Managing.WebApp/postcss.config.js | 1 - .../src/components/mollecules/Tabs/Tabs.tsx | 33 ++-- src/Managing.WebApp/src/hooks/useTheme.tsx | 46 +++++- src/Managing.WebApp/src/styles/app.css | 12 +- src/Managing.WebApp/src/styles/globals.css | 36 ++++- src/Managing.WebApp/vite.config.ts | 5 +- src/Managing.Workers.Api/Dockerfile | 39 ----- .../Managing.Workers.csproj | 27 ---- src/Managing.Workers.Api/Worker.cs | 24 --- src/Managing.Workers/Program.cs | 146 ++++-------------- .../appsettings.ProductionLocal.json | 4 +- .../appsettings.SandboxLocal.json | 4 +- 13 files changed, 148 insertions(+), 233 deletions(-) delete mode 100644 src/Managing.Workers.Api/Dockerfile delete mode 100644 src/Managing.Workers.Api/Managing.Workers.csproj delete mode 100644 src/Managing.Workers.Api/Worker.cs diff --git a/src/Managing.WebApp/package.json b/src/Managing.WebApp/package.json index 403b783a..febbc609 100644 --- a/src/Managing.WebApp/package.json +++ b/src/Managing.WebApp/package.json @@ -22,6 +22,7 @@ "@privy-io/react-auth": "^2.7.2", "@privy-io/wagmi": "^1.0.3", "@tailwindcss/typography": "^0.5.0", + "@tailwindcss/vite": "^4.1.17", "@tanstack/react-query": "^5.67.1", "@tanstack/react-table": "^8.21.3", "@wagmi/chains": "^0.2.9", @@ -57,7 +58,6 @@ "react-table": "^7.8.0", "react-toastify": "^9.0.1", "reactflow": "^11.8.3", - "tailwindcss": "^3.0.23", "viem": "^2.x", "wagmi": "^2.15.0", "web3": "^4.16.0", @@ -82,7 +82,7 @@ "postcss": "^8.4.13", "prettier": "^2.6.1", "prettier-plugin-tailwind-css": "^1.5.0", - "tailwindcss": "^3.0.23", + "tailwindcss": "^4.1.17", "typescript": "^5.7.3", "vite": "^6.3.6", "whatwg-fetch": "^3.6.2" diff --git a/src/Managing.WebApp/postcss.config.js b/src/Managing.WebApp/postcss.config.js index 6e41d953..90d9fffc 100644 --- a/src/Managing.WebApp/postcss.config.js +++ b/src/Managing.WebApp/postcss.config.js @@ -1,6 +1,5 @@ module.exports = { plugins: { autoprefixer: {}, - tailwindcss: {}, }, } diff --git a/src/Managing.WebApp/src/components/mollecules/Tabs/Tabs.tsx b/src/Managing.WebApp/src/components/mollecules/Tabs/Tabs.tsx index 289bc999..b042d560 100644 --- a/src/Managing.WebApp/src/components/mollecules/Tabs/Tabs.tsx +++ b/src/Managing.WebApp/src/components/mollecules/Tabs/Tabs.tsx @@ -29,21 +29,20 @@ const Tabs: FC = ({ >
{tabs.map((tab: any) => ( - + ))} {addButton && ( - + )}
diff --git a/src/Managing.WebApp/src/hooks/useTheme.tsx b/src/Managing.WebApp/src/hooks/useTheme.tsx index ce0ac81c..0f1d88f8 100644 --- a/src/Managing.WebApp/src/hooks/useTheme.tsx +++ b/src/Managing.WebApp/src/hooks/useTheme.tsx @@ -157,7 +157,51 @@ const useTheme = () => { useEffect(() => { if (typeof window !== 'undefined') { - document.documentElement.setAttribute('data-theme', themeName) + const key = '[data-theme=' + themeName + ']' + const theme = themes[key] + + if (theme) { + // Set data-theme attribute + document.documentElement.setAttribute('data-theme', themeName) + + // Apply CSS custom properties from JavaScript theme definitions + const root = document.documentElement + Object.entries(theme).forEach(([key, value]) => { + if (key.startsWith('--')) { + // Already a CSS custom property, apply directly + root.style.setProperty(key, value) + } else { + // Convert color values to CSS custom properties format + // Map daisyUI color names to CSS variables + const cssVarMap: Record = { + accent: '--color-accent', + 'base-100': '--color-base-100', + 'base-200': '--color-base-200', + 'base-300': '--color-base-300', + 'base-content': '--color-base-content', + error: '--color-error', + 'error-content': '--color-error-content', + info: '--color-info', + 'info-content': '--color-info-content', + neutral: '--color-neutral', + 'neutral-content': '--color-neutral-content', + 'neutral-focus': '--color-neutral-focus', + primary: '--color-primary', + 'primary-content': '--color-primary-content', + secondary: '--color-secondary', + 'secondary-content': '--color-secondary-content', + success: '--color-success', + 'success-content': '--color-success-content', + warning: '--color-warning', + 'warning-content': '--color-warning-content', + 'accent-content': '--color-accent-content', + } + + const cssVarName = cssVarMap[key] || `--color-${key}` + root.style.setProperty(cssVarName, value) + } + }) + } } }, [themeName]) diff --git a/src/Managing.WebApp/src/styles/app.css b/src/Managing.WebApp/src/styles/app.css index 89065d8e..7974adbb 100644 --- a/src/Managing.WebApp/src/styles/app.css +++ b/src/Managing.WebApp/src/styles/app.css @@ -1,3 +1,5 @@ +@reference "tailwindcss"; + .App-logo { width: 1.5em; } @@ -17,8 +19,14 @@ } } -button { - font-size: calc(10px + 2vmin); +/* Base button font size - daisyUI size classes (btn-sm, btn-xs, btn-lg) will override this */ +button.btn:not(.btn-xs):not(.btn-sm):not(.btn-lg) { + font-size: 0.875rem; /* 14px - standard button text size */ +} + +/* Ensure buttons without daisyUI classes also have reasonable font size */ +button:not(.btn) { + font-size: 0.875rem; } .notificationWrapper { diff --git a/src/Managing.WebApp/src/styles/globals.css b/src/Managing.WebApp/src/styles/globals.css index 44c13ccf..48ab7e19 100644 --- a/src/Managing.WebApp/src/styles/globals.css +++ b/src/Managing.WebApp/src/styles/globals.css @@ -1,6 +1,36 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; +@plugin "daisyui" { + themes: black, coffee, cyberpunk, lofi, retro, kaigen; +}; + +@plugin "daisyui/theme" { + name: "kaigen"; + default: false; + prefersdark: true; + color-scheme: dark; + + --animation-btn: 0; + --animation-input: 0; + --btn-focus-scale: 1; + --btn-text-case: lowercase; + --rounded-badge: 0; + --rounded-box: 0; + --rounded-btn: 0; + --tab-radius: 0; + + --color-accent: #343232; + --color-base-100: #0B0B0B; + --color-base-200: #0D0D0D; + --color-base-300: #0B0B0B; + --color-error: #FF5340; + --color-info: #B0DB43; + --color-neutral: #151515; + --color-neutral-focus: #343232; + --color-primary: #54B5F9; + --color-secondary: #a3d9fe; + --color-success: #08C25F; + --color-warning: #EB6F22; +}; @layer base { html, body { diff --git a/src/Managing.WebApp/vite.config.ts b/src/Managing.WebApp/vite.config.ts index 9edde64a..a3115ece 100644 --- a/src/Managing.WebApp/vite.config.ts +++ b/src/Managing.WebApp/vite.config.ts @@ -1,5 +1,6 @@ import react from '@vitejs/plugin-react' -import { defineConfig } from 'vite' +import tailwindcss from '@tailwindcss/vite' +import {defineConfig} from 'vite' export default defineConfig({ build: { @@ -12,7 +13,7 @@ export default defineConfig({ target: 'es2022', }, }, - plugins: [react()], + plugins: [react(), tailwindcss()], publicDir: 'assets', server: { host: true, diff --git a/src/Managing.Workers.Api/Dockerfile b/src/Managing.Workers.Api/Dockerfile deleted file mode 100644 index 9a12b008..00000000 --- a/src/Managing.Workers.Api/Dockerfile +++ /dev/null @@ -1,39 +0,0 @@ -# Use the official Microsoft .NET runtime as the base image (no ASP.NET needed for console worker) -FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base -WORKDIR /app - -# Use the official Microsoft .NET SDK image to build the code. -FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build -WORKDIR /src - -# Copy project files for dependency restoration -COPY ["Managing.Workers/Managing.Workers.csproj", "Managing.Workers/"] -COPY ["Managing.Bootstrap/Managing.Bootstrap.csproj", "Managing.Bootstrap/"] -COPY ["Managing.Application/Managing.Application.csproj", "Managing.Application/"] -COPY ["Managing.Application.Abstractions/Managing.Application.Abstractions.csproj", "Managing.Application.Abstractions/"] -COPY ["Managing.Common/Managing.Common.csproj", "Managing.Common/"] -COPY ["Managing.Core/Managing.Core.csproj", "Managing.Core/"] -COPY ["Managing.Domain/Managing.Domain.csproj", "Managing.Domain/"] -COPY ["Managing.Infrastructure.Database/Managing.Infrastructure.Databases.csproj", "Managing.Infrastructure.Database/"] -COPY ["Managing.Infrastructure.Exchanges/Managing.Infrastructure.Exchanges.csproj", "Managing.Infrastructure.Exchanges/"] -COPY ["Managing.Infrastructure.Messengers/Managing.Infrastructure.Messengers.csproj", "Managing.Infrastructure.Messengers/"] -COPY ["Managing.Infrastructure.Storage/Managing.Infrastructure.Storage.csproj", "Managing.Infrastructure.Storage/"] -COPY ["Managing.Infrastructure.Web3/Managing.Infrastructure.Evm.csproj", "Managing.Infrastructure.Web3/"] - -# Restore dependencies for all projects -RUN dotnet restore "Managing.Workers/Managing.Workers.csproj" - -# Copy everything else and build -COPY . . -WORKDIR "/src/Managing.Workers" -RUN dotnet build "Managing.Workers.csproj" -c Release -o /app/build - -FROM build AS publish -RUN dotnet publish "Managing.Workers.csproj" -c Release -o /app/publish - -FROM base AS final -WORKDIR /app -COPY --from=publish /app/publish . - -ENTRYPOINT ["dotnet", "Managing.Workers.dll"] - diff --git a/src/Managing.Workers.Api/Managing.Workers.csproj b/src/Managing.Workers.Api/Managing.Workers.csproj deleted file mode 100644 index 90fe78bb..00000000 --- a/src/Managing.Workers.Api/Managing.Workers.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - net8.0 - enable - enable - dotnet-Managing.Workers-ff3f3987-4da4-4140-9180-b84c9e07b25f - - - - - - - - - - - - - - - - - - - - diff --git a/src/Managing.Workers.Api/Worker.cs b/src/Managing.Workers.Api/Worker.cs deleted file mode 100644 index be0622e8..00000000 --- a/src/Managing.Workers.Api/Worker.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Managing.Workers; - -public class Worker : BackgroundService -{ - private readonly ILogger _logger; - - public Worker(ILogger logger) - { - _logger = logger; - } - - protected override async Task ExecuteAsync(CancellationToken stoppingToken) - { - while (!stoppingToken.IsCancellationRequested) - { - if (_logger.IsEnabled(LogLevel.Information)) - { - _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); - } - - await Task.Delay(1000, stoppingToken); - } - } -} \ No newline at end of file diff --git a/src/Managing.Workers/Program.cs b/src/Managing.Workers/Program.cs index 2672108a..f9ace602 100644 --- a/src/Managing.Workers/Program.cs +++ b/src/Managing.Workers/Program.cs @@ -11,18 +11,6 @@ var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Development"; -// Log environment detection before host creation -var dotnetEnv = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT"); -var aspnetcoreEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); - -Console.WriteLine("═══════════════════════════════════════════════════════════"); -Console.WriteLine("🔧 Environment Configuration"); -Console.WriteLine("═══════════════════════════════════════════════════════════"); -Console.WriteLine($" DOTNET_ENVIRONMENT: {dotnetEnv ?? "(not set)"}"); -Console.WriteLine($" ASPNETCORE_ENVIRONMENT: {aspnetcoreEnv ?? "(not set)"}"); -Console.WriteLine($" Selected Environment: {environment}"); -Console.WriteLine("═══════════════════════════════════════════════════════════"); - var hostBuilder = new HostBuilder() .UseEnvironment(environment) .UseContentRoot(AppContext.BaseDirectory); @@ -31,11 +19,10 @@ var host = hostBuilder .ConfigureAppConfiguration((hostingContext, config) => { var detectedEnv = hostingContext.HostingEnvironment.EnvironmentName; - Console.WriteLine($" Detected Environment: {detectedEnv}"); if (detectedEnv != environment) { - Console.WriteLine($" ⚠️ WARNING: Environment mismatch! Expected: {environment}, Got: {detectedEnv}"); + Console.WriteLine($"⚠️ WARNING: Environment mismatch! Expected: {environment}, Got: {detectedEnv}"); } config.SetBasePath(AppContext.BaseDirectory); @@ -43,14 +30,12 @@ var host = hostBuilder // Load configuration files in order (later files override earlier ones) // 1. Base appsettings.json (always loaded) config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); - Console.WriteLine(" ✓ Loaded: appsettings.json"); // 2. Load ONLY the environment-specific file (not other environments) if (!string.IsNullOrEmpty(detectedEnv)) { var envFile = $"appsettings.{detectedEnv}.json"; config.AddJsonFile(envFile, optional: true, reloadOnChange: true); - Console.WriteLine($" ✓ Loaded: {envFile} (optional)"); } // 3. Environment variables (highest priority) @@ -68,8 +53,6 @@ var host = hostBuilder // User secrets not available, skip silently } } - - Console.WriteLine("═══════════════════════════════════════════════════════════"); }) .ConfigureServices((hostContext, services) => { @@ -90,39 +73,6 @@ var host = hostBuilder // Configure database var postgreSqlConnectionString = configuration.GetSection(Constants.Databases.PostgreSql)["ConnectionString"]; - // Log database connection details (mask password for security) - if (!string.IsNullOrEmpty(postgreSqlConnectionString)) - { - var connectionParts = postgreSqlConnectionString.Split(';') - .Where(p => !string.IsNullOrWhiteSpace(p)) - .Select(p => p.Trim()) - .ToDictionary( - p => p.Split('=')[0].Trim(), - p => p.Contains('=') ? p.Substring(p.IndexOf('=') + 1).Trim() : string.Empty, - StringComparer.OrdinalIgnoreCase); - - var dbHost = connectionParts.GetValueOrDefault("Host", "unknown"); - var port = connectionParts.GetValueOrDefault("Port", "unknown"); - var database = connectionParts.GetValueOrDefault("Database", "unknown"); - var username = connectionParts.GetValueOrDefault("Username", "unknown"); - var maskedConnectionString = postgreSqlConnectionString - .Replace(connectionParts.GetValueOrDefault("Password", ""), "***", StringComparison.OrdinalIgnoreCase); - - Console.WriteLine("═══════════════════════════════════════════════════════════"); - Console.WriteLine("📊 PostgreSQL Database Configuration"); - Console.WriteLine("═══════════════════════════════════════════════════════════"); - Console.WriteLine($" Host: {dbHost}"); - Console.WriteLine($" Port: {port}"); - Console.WriteLine($" Database: {database}"); - Console.WriteLine($" Username: {username}"); - Console.WriteLine($" Connection String: {maskedConnectionString}"); - Console.WriteLine("═══════════════════════════════════════════════════════════"); - } - else - { - Console.WriteLine("⚠️ WARNING: PostgreSQL connection string is empty or not configured!"); - } - services.Configure(configuration.GetSection(Constants.Databases.PostgreSql)); services.Configure(configuration.GetSection(Constants.Databases.InfluxDb)); @@ -201,95 +151,67 @@ var host = hostBuilder logging.ClearProviders(); logging.AddConsole(); logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); + + // Filter out EF Core database command logs (SQL queries) + logging.AddFilter("Microsoft.EntityFrameworkCore.Database.Command", LogLevel.Warning); }) .Build(); -// Log worker status var logger = host.Services.GetRequiredService>(); var config = host.Services.GetRequiredService(); -// Log PostgreSQL connection details +// Test database connection at startup var postgreSqlConnectionString = config.GetSection(Constants.Databases.PostgreSql)["ConnectionString"]; -if (!string.IsNullOrEmpty(postgreSqlConnectionString)) +if (string.IsNullOrEmpty(postgreSqlConnectionString)) { - var connectionParts = postgreSqlConnectionString.Split(';') - .Where(p => !string.IsNullOrWhiteSpace(p)) - .Select(p => p.Trim()) - .ToDictionary( - p => p.Split('=')[0].Trim(), - p => p.Contains('=') ? p.Substring(p.IndexOf('=') + 1).Trim() : string.Empty, - StringComparer.OrdinalIgnoreCase); - - var hostName = connectionParts.GetValueOrDefault("Host", "unknown"); - var port = connectionParts.GetValueOrDefault("Port", "unknown"); - var database = connectionParts.GetValueOrDefault("Database", "unknown"); - var username = connectionParts.GetValueOrDefault("Username", "unknown"); - - logger.LogInformation("═══════════════════════════════════════════════════════════"); - logger.LogInformation("📊 PostgreSQL Database Configuration"); - logger.LogInformation("═══════════════════════════════════════════════════════════"); - logger.LogInformation(" Host: {Host}", hostName); - logger.LogInformation(" Port: {Port}", port); - logger.LogInformation(" Database: {Database}", database); - logger.LogInformation(" Username: {Username}", username); - logger.LogInformation("═══════════════════════════════════════════════════════════"); - - // Test database connection + logger.LogWarning("⚠️ Database connection string is empty or not configured!"); +} +else +{ + // Parse and log database host name + try + { + var connectionParts = postgreSqlConnectionString.Split(';') + .Where(p => !string.IsNullOrWhiteSpace(p)) + .Select(p => p.Trim()) + .ToDictionary( + p => p.Split('=')[0].Trim(), + p => p.Contains('=') ? p.Substring(p.IndexOf('=') + 1).Trim() : string.Empty, + StringComparer.OrdinalIgnoreCase); + + var dbHost = connectionParts.GetValueOrDefault("Host", "unknown"); + logger.LogWarning("📊 Database Host: {Host}", dbHost); + } + catch + { + // Failed to parse connection string, continue anyway + } + try { using var scope = host.Services.CreateScope(); var dbContext = scope.ServiceProvider.GetRequiredService(); var canConnect = await dbContext.Database.CanConnectAsync(); - if (canConnect) + if (!canConnect) { - logger.LogInformation("✅ Database connection test: SUCCESS"); - } - else - { - logger.LogWarning("⚠️ Database connection test: FAILED - Cannot connect to database"); + logger.LogWarning("⚠️ Database connection test failed - Cannot connect to database"); } } catch (Exception ex) { - logger.LogError(ex, "❌ Database connection test: FAILED - {Error}", ex.Message); + logger.LogError(ex, "❌ Database connection test failed - {Error}", ex.Message); } } -else -{ - logger.LogWarning("⚠️ WARNING: PostgreSQL connection string is empty or not configured!"); -} var isBacktestWorkerEnabled = config.GetValue("WorkerBacktestCompute", false); var isGeneticWorkerEnabled = config.GetValue("WorkerGeneticCompute", false); -if (isBacktestWorkerEnabled) -{ - var taskSlot = Environment.GetEnvironmentVariable("TASK_SLOT") ?? - Environment.GetEnvironmentVariable("CAPROVER_TASK_SLOT") ?? - "0"; - var backtestWorkerId = Environment.GetEnvironmentVariable("WORKER_ID") ?? - config["BacktestComputeWorker:WorkerId"] ?? - $"{Environment.MachineName}-{taskSlot}"; - logger.LogInformation("BacktestComputeWorker is enabled and will be started."); - logger.LogInformation("Backtest Worker ID: {WorkerId} (Task Slot: {TaskSlot})", backtestWorkerId, taskSlot); -} -else +if (!isBacktestWorkerEnabled) { logger.LogWarning("BacktestComputeWorker is disabled via configuration. No backtest jobs will be processed."); } -if (isGeneticWorkerEnabled) -{ - var taskSlot = Environment.GetEnvironmentVariable("TASK_SLOT") ?? - Environment.GetEnvironmentVariable("CAPROVER_TASK_SLOT") ?? - "0"; - var geneticWorkerId = Environment.GetEnvironmentVariable("GENETIC_WORKER_ID") ?? - config["GeneticComputeWorker:WorkerId"] ?? - $"{Environment.MachineName}-genetic-{taskSlot}"; - logger.LogInformation("GeneticComputeWorker is enabled and will be started."); - logger.LogInformation("Genetic Worker ID: {WorkerId} (Task Slot: {TaskSlot})", geneticWorkerId, taskSlot); -} -else +if (!isGeneticWorkerEnabled) { logger.LogWarning("GeneticComputeWorker is disabled via configuration. No genetic jobs will be processed."); } diff --git a/src/Managing.Workers/appsettings.ProductionLocal.json b/src/Managing.Workers/appsettings.ProductionLocal.json index 68569778..2673fcce 100644 --- a/src/Managing.Workers/appsettings.ProductionLocal.json +++ b/src/Managing.Workers/appsettings.ProductionLocal.json @@ -1,8 +1,8 @@ { "Logging": { "LogLevel": { - "Default": "Information", - "Microsoft.Hosting.Lifetime": "Information" + "Default": "Warning", + "Microsoft.Hosting.Lifetime": "Warning" } }, "WorkerBacktestCompute": true, diff --git a/src/Managing.Workers/appsettings.SandboxLocal.json b/src/Managing.Workers/appsettings.SandboxLocal.json index c620ecef..6161d39f 100644 --- a/src/Managing.Workers/appsettings.SandboxLocal.json +++ b/src/Managing.Workers/appsettings.SandboxLocal.json @@ -1,8 +1,8 @@ { "Logging": { "LogLevel": { - "Default": "Information", - "Microsoft.Hosting.Lifetime": "Information" + "Default": "Warning", + "Microsoft.Hosting.Lifetime": "Warning" } }, "WorkerBacktestCompute": true,