From e837e191c233c9a662c997c00fc15dcc634070ee Mon Sep 17 00:00:00 2001 From: Toutsu Date: Mon, 18 May 2026 09:54:56 +0300 Subject: [PATCH 1/3] feat: refresh dashboard design with fantasy RPG aesthetic - Replace Inter font with Cinzel (headings) + Jura (body) - Deepen dark background palette with atmospheric gradient orbs - Add subtle noise texture overlay for depth - Refine glass cards with animated gradient border glow on hover - Sharpen accent colors: violet #8b5cf6 + cyan #22d3ee - Improve button tactile feedback and shadow system - Add k8s manifests for minikube local deployment Co-Authored-By: Claude Opus 4.7 --- k8s/01-namespace.yaml | 4 + k8s/02-secrets.yaml | 10 + k8s/03-configmap.yaml | 9 + k8s/04-postgres.yaml | 68 ++ k8s/05-web.yaml | 88 +++ k8s/06-bot.yaml | 42 ++ src/GmRelay.Web/Components/App.razor | 2 +- .../Components/Layout/MainLayout.razor.css | 8 +- .../Components/Layout/NavMenu.razor.css | 16 +- src/GmRelay.Web/wwwroot/app.css | 661 +++++++++++++++--- 10 files changed, 786 insertions(+), 122 deletions(-) create mode 100644 k8s/01-namespace.yaml create mode 100644 k8s/02-secrets.yaml create mode 100644 k8s/03-configmap.yaml create mode 100644 k8s/04-postgres.yaml create mode 100644 k8s/05-web.yaml create mode 100644 k8s/06-bot.yaml diff --git a/k8s/01-namespace.yaml b/k8s/01-namespace.yaml new file mode 100644 index 0000000..a1c9461 --- /dev/null +++ b/k8s/01-namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: gmrelay-test diff --git a/k8s/02-secrets.yaml b/k8s/02-secrets.yaml new file mode 100644 index 0000000..0c7da3b --- /dev/null +++ b/k8s/02-secrets.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: gmrelay-secrets + namespace: gmrelay-test +type: Opaque +stringData: + POSTGRES_PASSWORD: "TestPassword123" + TELEGRAM_BOT_TOKEN: "8641931558:AAGBARuuTZUXX7V3YrtJwN3y_q0NUVkFrqk" + TELEGRAM_BOT_USERNAME: "GmRelayTestBot" diff --git a/k8s/03-configmap.yaml b/k8s/03-configmap.yaml new file mode 100644 index 0000000..7c3ea26 --- /dev/null +++ b/k8s/03-configmap.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: gmrelay-config + namespace: gmrelay-test +data: + ConnectionStrings__gmrelaydb: "Host=postgres;Port=5432;Database=gmrelay_db;Username=gmrelay;Password=$(POSTGRES_PASSWORD)" + Telegram__MiniAppUrl: "" + ASPNETCORE_URLS: "http://+:8080" diff --git a/k8s/04-postgres.yaml b/k8s/04-postgres.yaml new file mode 100644 index 0000000..ea60c59 --- /dev/null +++ b/k8s/04-postgres.yaml @@ -0,0 +1,68 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: postgres-pvc + namespace: gmrelay-test +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgres + namespace: gmrelay-test +spec: + replicas: 1 + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + spec: + containers: + - name: postgres + image: postgres:17-alpine + ports: + - containerPort: 5432 + env: + - name: POSTGRES_USER + value: "gmrelay" + - name: POSTGRES_DB + value: "gmrelay_db" + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: gmrelay-secrets + key: POSTGRES_PASSWORD + volumeMounts: + - name: postgres-data + mountPath: /var/lib/postgresql/data + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "512Mi" + cpu: "500m" + volumes: + - name: postgres-data + persistentVolumeClaim: + claimName: postgres-pvc +--- +apiVersion: v1 +kind: Service +metadata: + name: postgres + namespace: gmrelay-test +spec: + selector: + app: postgres + ports: + - port: 5432 + targetPort: 5432 diff --git a/k8s/05-web.yaml b/k8s/05-web.yaml new file mode 100644 index 0000000..9563a5e --- /dev/null +++ b/k8s/05-web.yaml @@ -0,0 +1,88 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gmrelay-web + namespace: gmrelay-test +spec: + replicas: 1 + selector: + matchLabels: + app: gmrelay-web + template: + metadata: + labels: + app: gmrelay-web + spec: + containers: + - name: web + image: gmrelay-web:design-refresh + ports: + - containerPort: 8080 + envFrom: + - configMapRef: + name: gmrelay-config + env: + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: gmrelay-secrets + key: POSTGRES_PASSWORD + - name: ConnectionStrings__gmrelaydb + value: "Host=postgres;Port=5432;Database=gmrelay_db;Username=gmrelay;Password=$(POSTGRES_PASSWORD)" + - name: Telegram__BotToken + valueFrom: + secretKeyRef: + name: gmrelay-secrets + key: TELEGRAM_BOT_TOKEN + - name: Telegram__BotUsername + valueFrom: + secretKeyRef: + name: gmrelay-secrets + key: TELEGRAM_BOT_USERNAME + - name: Telegram__MiniAppUrl + value: "" + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "512Mi" + cpu: "500m" + volumeMounts: + - name: dataprotection-keys + mountPath: /app/dataprotection-keys + volumes: + - name: dataprotection-keys + emptyDir: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: gmrelay-web + namespace: gmrelay-test +spec: + selector: + app: gmrelay-web + ports: + - port: 8080 + targetPort: 8080 +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: gmrelay-web + namespace: gmrelay-test + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +spec: + rules: + - host: gmrelay.local + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: gmrelay-web + port: + number: 8080 diff --git a/k8s/06-bot.yaml b/k8s/06-bot.yaml new file mode 100644 index 0000000..a4ccc56 --- /dev/null +++ b/k8s/06-bot.yaml @@ -0,0 +1,42 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gmrelay-bot + namespace: gmrelay-test +spec: + replicas: 1 + selector: + matchLabels: + app: gmrelay-bot + template: + metadata: + labels: + app: gmrelay-bot + spec: + containers: + - name: bot + image: gmrelay-bot:design-refresh + ports: + - containerPort: 8081 + env: + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: gmrelay-secrets + key: POSTGRES_PASSWORD + - name: ConnectionStrings__gmrelaydb + value: "Host=postgres;Port=5432;Database=gmrelay_db;Username=gmrelay;Password=$(POSTGRES_PASSWORD)" + - name: Telegram__BotToken + valueFrom: + secretKeyRef: + name: gmrelay-secrets + key: TELEGRAM_BOT_TOKEN + - name: Telegram__MiniAppUrl + value: "" + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "256Mi" + cpu: "500m" diff --git a/src/GmRelay.Web/Components/App.razor b/src/GmRelay.Web/Components/App.razor index 374c17b..3a904ab 100644 --- a/src/GmRelay.Web/Components/App.razor +++ b/src/GmRelay.Web/Components/App.razor @@ -10,7 +10,7 @@ - + diff --git a/src/GmRelay.Web/Components/Layout/MainLayout.razor.css b/src/GmRelay.Web/Components/Layout/MainLayout.razor.css index 47c29e4..2953d97 100644 --- a/src/GmRelay.Web/Components/Layout/MainLayout.razor.css +++ b/src/GmRelay.Web/Components/Layout/MainLayout.razor.css @@ -30,8 +30,9 @@ /* === Error UI === */ #blazor-error-ui { - background: var(--bg-secondary); - border-top: 1px solid var(--border-color); + background: var(--status-danger-bg); + color: var(--status-danger); + border-top: 1px solid rgba(239, 68, 68, 0.15); bottom: 0; box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.3); box-sizing: border-box; @@ -41,8 +42,9 @@ position: fixed; width: 100%; z-index: 1000; - color: var(--text-secondary); font-size: 0.875rem; + font-family: 'Jura', sans-serif; + font-weight: 500; } #blazor-error-ui .reload { diff --git a/src/GmRelay.Web/Components/Layout/NavMenu.razor.css b/src/GmRelay.Web/Components/Layout/NavMenu.razor.css index 4194f99..5eb2268 100644 --- a/src/GmRelay.Web/Components/Layout/NavMenu.razor.css +++ b/src/GmRelay.Web/Components/Layout/NavMenu.razor.css @@ -23,12 +23,11 @@ } .nav-brand-text { + font-family: 'Cinzel Decorative', 'Cinzel', serif; font-size: 1.125rem; font-weight: 700; - background: var(--accent-gradient); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; + letter-spacing: 0.04em; + color: var(--text-primary); } .nav-toggle { @@ -87,9 +86,10 @@ } .nav-section ::deep .nav-item.active { - background: rgba(124, 58, 237, 0.15); - color: var(--accent-primary); - border: 1px solid rgba(124, 58, 237, 0.2); + background: linear-gradient(135deg, rgba(139, 92, 246, 0.15) 0%, rgba(34, 211, 238, 0.08) 100%); + color: var(--text-accent); + border: 1px solid rgba(139, 92, 246, 0.25); + box-shadow: 0 0 12px rgba(139, 92, 246, 0.1); } .nav-icon { @@ -145,7 +145,7 @@ border: 1px solid transparent; border-radius: var(--radius-sm); color: var(--text-muted); - font-family: 'Inter', sans-serif; + font-family: 'Jura', sans-serif; font-size: 0.8125rem; cursor: pointer; transition: all var(--transition-normal); diff --git a/src/GmRelay.Web/wwwroot/app.css b/src/GmRelay.Web/wwwroot/app.css index 8b837b4..3561089 100644 --- a/src/GmRelay.Web/wwwroot/app.css +++ b/src/GmRelay.Web/wwwroot/app.css @@ -1,60 +1,58 @@ /* ============================================ - GM-Relay Design System v1.9.9 - Dark RPG Dashboard Theme + GM-Relay Design System v2.0.0 + Dark RPG Dashboard Theme — Refined ============================================ */ -/* --- Google Fonts loaded in App.razor --- */ - /* === CSS Custom Properties === */ :root { - /* Background */ - --bg-primary: #0a0e1a; - --bg-secondary: #111827; - --bg-card: rgba(17, 24, 39, 0.7); - --bg-card-hover: rgba(24, 33, 54, 0.85); - --bg-surface: rgba(255, 255, 255, 0.04); - --bg-input: rgba(255, 255, 255, 0.06); + /* Background — deeper, richer darks */ + --bg-primary: #050810; + --bg-secondary: #0a0f1c; + --bg-card: rgba(10, 15, 28, 0.75); + --bg-card-hover: rgba(15, 22, 40, 0.9); + --bg-surface: rgba(255, 255, 255, 0.035); + --bg-input: rgba(255, 255, 255, 0.05); - /* Accent */ - --accent-primary: #7c3aed; - --accent-primary-hover: #6d28d9; - --accent-secondary: #06b6d4; - --accent-gradient: linear-gradient(135deg, #7c3aed 0%, #06b6d4 100%); - --accent-gradient-hover: linear-gradient(135deg, #6d28d9 0%, #0891b2 100%); + /* Accent — sharper, more vibrant */ + --accent-primary: #8b5cf6; + --accent-primary-hover: #7c3aed; + --accent-secondary: #22d3ee; + --accent-gradient: linear-gradient(135deg, #8b5cf6 0%, #22d3ee 100%); + --accent-gradient-hover: linear-gradient(135deg, #7c3aed 0%, #06b6d4 100%); /* Text */ - --text-primary: #f1f5f9; + --text-primary: #e2e8f0; --text-secondary: #94a3b8; --text-muted: #64748b; --text-accent: #a78bfa; /* Status */ --status-success: #22c55e; - --status-success-bg: rgba(34, 197, 94, 0.15); + --status-success-bg: rgba(34, 197, 94, 0.12); --status-warning: #f59e0b; - --status-warning-bg: rgba(245, 158, 11, 0.15); + --status-warning-bg: rgba(245, 158, 11, 0.12); --status-danger: #ef4444; - --status-danger-bg: rgba(239, 68, 68, 0.15); - --status-info: #06b6d4; - --status-info-bg: rgba(6, 182, 212, 0.15); + --status-danger-bg: rgba(239, 68, 68, 0.12); + --status-info: #22d3ee; + --status-info-bg: rgba(34, 211, 238, 0.12); --status-neutral: #64748b; - --status-neutral-bg: rgba(100, 116, 139, 0.15); + --status-neutral-bg: rgba(100, 116, 139, 0.12); /* Border */ - --border-color: rgba(255, 255, 255, 0.08); - --border-glow: rgba(124, 58, 237, 0.4); + --border-color: rgba(255, 255, 255, 0.06); + --border-glow: rgba(139, 92, 246, 0.35); /* Glass */ - --glass-bg: rgba(255, 255, 255, 0.05); - --glass-border: rgba(255, 255, 255, 0.1); - --glass-blur: 16px; + --glass-bg: rgba(255, 255, 255, 0.04); + --glass-border: rgba(255, 255, 255, 0.08); + --glass-blur: 20px; /* Shadows */ - --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3); - --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.4); - --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.5); - --shadow-glow: 0 0 20px rgba(124, 58, 237, 0.2); - --shadow-glow-hover: 0 0 30px rgba(124, 58, 237, 0.35); + --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.4); + --shadow-md: 0 4px 20px rgba(0, 0, 0, 0.5); + --shadow-lg: 0 8px 40px rgba(0, 0, 0, 0.6); + --shadow-glow: 0 0 24px rgba(139, 92, 246, 0.18); + --shadow-glow-hover: 0 0 36px rgba(139, 92, 246, 0.3); /* Radius */ --radius-sm: 8px; @@ -64,8 +62,8 @@ /* Transition */ --transition-fast: 0.15s ease; - --transition-normal: 0.25s ease; - --transition-smooth: 0.35s cubic-bezier(0.4, 0, 0.2, 1); + --transition-normal: 0.3s cubic-bezier(0.4, 0, 0.2, 1); + --transition-smooth: 0.4s cubic-bezier(0.4, 0, 0.2, 1); /* Sidebar */ --sidebar-width: 260px; @@ -96,7 +94,7 @@ html { } html, body { - font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + font-family: 'Jura', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background-color: var(--bg-primary); color: var(--text-primary); margin: 0; @@ -106,22 +104,61 @@ html, body { -moz-osx-font-smoothing: grayscale; } +/* Atmospheric background */ +body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 0; + background: + radial-gradient(ellipse 80% 60% at 20% 40%, rgba(139, 92, 246, 0.08) 0%, transparent 60%), + radial-gradient(ellipse 60% 50% at 80% 20%, rgba(34, 211, 238, 0.05) 0%, transparent 50%), + radial-gradient(ellipse 50% 40% at 50% 90%, rgba(139, 92, 246, 0.06) 0%, transparent 50%); + animation: atmosphere-drift 25s ease-in-out infinite alternate; +} + +@keyframes atmosphere-drift { + 0% { transform: translate(0, 0) scale(1); } + 100% { transform: translate(-2%, 1%) scale(1.02); } +} + +/* Subtle grain overlay */ +body::after { + content: ''; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 1; + opacity: 0.025; + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E"); + background-repeat: repeat; + background-size: 256px 256px; +} + /* === Typography === */ h1, h2, h3, h4, h5, h6 { + font-family: 'Cinzel', 'Cinzel Decorative', serif; color: var(--text-primary); font-weight: 600; - letter-spacing: -0.02em; + letter-spacing: 0.02em; line-height: 1.3; margin-top: 0; } -h1 { font-size: 1.875rem; } -h2 { font-size: 1.5rem; } -h3 { font-size: 1.25rem; } +h1 { font-size: 1.75rem; } +h2 { font-size: 1.375rem; } +h3 { font-size: 1.125rem; } h1:focus { outline: none; } -p { line-height: 1.6; } +p { line-height: 1.7; } a { color: var(--accent-secondary); @@ -130,13 +167,13 @@ a { } a:hover { - color: #22d3ee; + color: #67e8f9; } /* === Scrollbar === */ ::-webkit-scrollbar { - width: 6px; - height: 6px; + width: 5px; + height: 5px; } ::-webkit-scrollbar-track { @@ -144,12 +181,12 @@ a:hover { } ::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.15); + background: rgba(255, 255, 255, 0.12); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.25); + background: rgba(255, 255, 255, 0.22); } /* === Glass Card === */ @@ -161,13 +198,34 @@ a:hover { border-radius: var(--radius-lg); padding: 1.5rem; transition: all var(--transition-smooth); + position: relative; + z-index: 2; +} + +.glass-card::before { + content: ''; + position: absolute; + inset: 0; + border-radius: inherit; + padding: 1px; + background: linear-gradient(135deg, rgba(139, 92, 246, 0.15) 0%, transparent 40%, transparent 60%, rgba(34, 211, 238, 0.1) 100%); + -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); + -webkit-mask-composite: xor; + mask-composite: exclude; + pointer-events: none; + opacity: 0; + transition: opacity var(--transition-normal); +} + +.glass-card:hover::before { + opacity: 1; } .glass-card:hover { background: var(--bg-card-hover); border-color: var(--border-glow); box-shadow: var(--shadow-glow-hover); - transform: translateY(-2px); + transform: translateY(-3px); } /* === Buttons === */ @@ -178,44 +236,53 @@ a:hover { padding: 0.625rem 1.25rem; border: none; border-radius: var(--radius-sm); - font-family: 'Inter', sans-serif; + font-family: 'Jura', sans-serif; font-size: 0.875rem; - font-weight: 500; + font-weight: 600; cursor: pointer; transition: all var(--transition-normal); text-decoration: none; line-height: 1.4; + letter-spacing: 0.02em; + position: relative; + overflow: hidden; + z-index: 2; } .btn-gm-primary { background: var(--accent-gradient); color: white; - box-shadow: 0 2px 12px rgba(124, 58, 237, 0.3); + box-shadow: 0 2px 16px rgba(139, 92, 246, 0.35); } .btn-gm-primary:hover { background: var(--accent-gradient-hover); - box-shadow: 0 4px 20px rgba(124, 58, 237, 0.45); - transform: translateY(-1px); + box-shadow: 0 4px 24px rgba(139, 92, 246, 0.5); + transform: translateY(-2px); color: white; } .btn-gm-primary:active { transform: translateY(0); + box-shadow: 0 1px 8px rgba(139, 92, 246, 0.3); } .btn-gm-success { background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%); color: white; - box-shadow: 0 2px 12px rgba(34, 197, 94, 0.3); + box-shadow: 0 2px 16px rgba(34, 197, 94, 0.3); } .btn-gm-success:hover { - box-shadow: 0 4px 20px rgba(34, 197, 94, 0.45); - transform: translateY(-1px); + box-shadow: 0 4px 24px rgba(34, 197, 94, 0.45); + transform: translateY(-2px); color: white; } +.btn-gm-success:active { + transform: translateY(0); +} + .btn-gm-outline { background: transparent; color: var(--text-secondary); @@ -226,22 +293,28 @@ a:hover { background: var(--bg-surface); color: var(--text-primary); border-color: var(--glass-border); + box-shadow: 0 0 12px rgba(139, 92, 246, 0.1); } .btn-gm-danger { background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); color: white; + box-shadow: 0 2px 12px rgba(239, 68, 68, 0.25); } .btn-gm-danger:hover { box-shadow: 0 4px 20px rgba(239, 68, 68, 0.4); - transform: translateY(-1px); + transform: translateY(-2px); color: white; } +.btn-gm-danger:active { + transform: translateY(0); +} + .btn-gm[disabled], .btn-gm:disabled { - opacity: 0.5; + opacity: 0.45; pointer-events: none; } @@ -254,14 +327,15 @@ a:hover { border-radius: 9999px; font-size: 0.75rem; font-weight: 600; - letter-spacing: 0.02em; + letter-spacing: 0.03em; white-space: nowrap; + font-family: 'Jura', sans-serif; } .status-badge::before { content: ''; - width: 6px; - height: 6px; + width: 5px; + height: 5px; border-radius: 50%; flex-shrink: 0; } @@ -269,35 +343,35 @@ a:hover { .status-success { background: var(--status-success-bg); color: var(--status-success); - border: 1px solid rgba(34, 197, 94, 0.25); + border: 1px solid rgba(34, 197, 94, 0.2); } .status-success::before { background: var(--status-success); box-shadow: 0 0 6px var(--status-success); } .status-warning { background: var(--status-warning-bg); color: var(--status-warning); - border: 1px solid rgba(245, 158, 11, 0.25); + border: 1px solid rgba(245, 158, 11, 0.2); } .status-warning::before { background: var(--status-warning); box-shadow: 0 0 6px var(--status-warning); } .status-danger { background: var(--status-danger-bg); color: var(--status-danger); - border: 1px solid rgba(239, 68, 68, 0.25); + border: 1px solid rgba(239, 68, 68, 0.2); } .status-danger::before { background: var(--status-danger); box-shadow: 0 0 6px var(--status-danger); } .status-info { background: var(--status-info-bg); color: var(--status-info); - border: 1px solid rgba(6, 182, 212, 0.25); + border: 1px solid rgba(34, 211, 238, 0.2); } .status-info::before { background: var(--status-info); box-shadow: 0 0 6px var(--status-info); } .status-neutral { background: var(--status-neutral-bg); color: var(--status-neutral); - border: 1px solid rgba(100, 116, 139, 0.25); + border: 1px solid rgba(100, 116, 139, 0.2); } .status-neutral::before { background: var(--status-neutral); } @@ -309,16 +383,18 @@ a:hover { border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-primary); - font-family: 'Inter', sans-serif; + font-family: 'Jura', sans-serif; font-size: 0.875rem; + font-weight: 500; transition: all var(--transition-normal); outline: none; + letter-spacing: 0.01em; } .gm-form-control:focus { border-color: var(--accent-primary); - box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.15); - background: rgba(255, 255, 255, 0.08); + box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.12); + background: rgba(255, 255, 255, 0.07); } .gm-form-control::placeholder { @@ -329,9 +405,10 @@ a:hover { display: block; margin-bottom: 0.375rem; font-size: 0.8125rem; - font-weight: 500; + font-weight: 600; color: var(--text-secondary); - letter-spacing: 0.01em; + letter-spacing: 0.03em; + font-family: 'Jura', sans-serif; } .gm-form-hint { @@ -357,10 +434,12 @@ select { border: 1px solid var(--border-color) !important; border-radius: var(--radius-sm) !important; color: var(--text-primary) !important; - font-family: 'Inter', sans-serif !important; + font-family: 'Jura', sans-serif !important; font-size: 0.875rem !important; + font-weight: 500 !important; padding: 0.625rem 0.875rem !important; transition: all var(--transition-normal) !important; + letter-spacing: 0.01em !important; } .form-control:focus, @@ -368,14 +447,14 @@ input:focus, textarea:focus, select:focus { border-color: var(--accent-primary) !important; - box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.15) !important; - background: rgba(255, 255, 255, 0.08) !important; + box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.12) !important; + background: rgba(255, 255, 255, 0.07) !important; outline: none !important; } /* Color scheme for date/time pickers */ input[type="datetime-local"]::-webkit-calendar-picker-indicator { - filter: invert(0.7); + filter: invert(0.65); } select option { @@ -389,18 +468,20 @@ select option { border-collapse: separate; border-spacing: 0; font-size: 0.875rem; + font-family: 'Jura', sans-serif; } .gm-table thead th { - padding: 0.75rem 1rem; + padding: 0.875rem 1rem; text-align: left; - font-weight: 600; - font-size: 0.75rem; + font-weight: 700; + font-size: 0.7rem; text-transform: uppercase; - letter-spacing: 0.06em; + letter-spacing: 0.08em; color: var(--text-muted); border-bottom: 1px solid var(--border-color); background: transparent; + font-family: 'Jura', sans-serif; } .gm-table tbody td { @@ -470,23 +551,26 @@ select option { display: flex; align-items: center; gap: 0.625rem; + font-weight: 500; + position: relative; + z-index: 2; } .gm-alert-info { background: var(--status-info-bg); - border: 1px solid rgba(6, 182, 212, 0.2); + border: 1px solid rgba(34, 211, 238, 0.15); color: var(--status-info); } .gm-alert-danger { background: var(--status-danger-bg); - border: 1px solid rgba(239, 68, 68, 0.2); + border: 1px solid rgba(239, 68, 68, 0.15); color: var(--status-danger); } .gm-alert-success { background: var(--status-success-bg); - border: 1px solid rgba(34, 197, 94, 0.2); + border: 1px solid rgba(34, 197, 94, 0.15); color: var(--status-success); } @@ -499,6 +583,9 @@ select option { padding: 0; margin: 0 0 1.5rem 0; font-size: 0.8125rem; + font-family: 'Jura', sans-serif; + position: relative; + z-index: 2; } .gm-breadcrumb li { @@ -525,13 +612,14 @@ select option { .gm-breadcrumb .active { color: var(--text-primary); + font-weight: 600; } /* === Loading Skeleton === */ .skeleton { background: linear-gradient(90deg, var(--bg-surface) 25%, - rgba(255, 255, 255, 0.08) 50%, + rgba(255, 255, 255, 0.06) 50%, var(--bg-surface) 75%); background-size: 200% 100%; animation: skeleton-shimmer 1.5s ease-in-out infinite; @@ -562,6 +650,8 @@ select option { justify-content: center; padding: 3rem 1.5rem; text-align: center; + position: relative; + z-index: 2; } .empty-state-icon { @@ -575,12 +665,14 @@ select option { font-weight: 600; color: var(--text-primary); margin-bottom: 0.5rem; + font-family: 'Cinzel', serif; } .empty-state-text { font-size: 0.875rem; color: var(--text-muted); max-width: 320px; + line-height: 1.6; } /* === Page Container === */ @@ -588,22 +680,29 @@ select option { max-width: 960px; margin: 0 auto; padding: 1.5rem; - animation: fadeIn 0.4s ease-out; + animation: fadeIn 0.5s ease-out; + position: relative; + z-index: 2; } .page-header { margin-bottom: 2rem; + position: relative; + z-index: 2; } .page-header h2 { - font-size: 1.5rem; + font-size: 1.375rem; margin-bottom: 0.25rem; + font-family: 'Cinzel', serif; + font-weight: 700; } .page-header p { color: var(--text-muted); font-size: 0.875rem; margin: 0; + font-family: 'Jura', sans-serif; } /* === Grid === */ @@ -611,6 +710,8 @@ select option { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1rem; + position: relative; + z-index: 2; } /* === Batch bulk operations === */ @@ -618,6 +719,8 @@ select option { display: grid; gap: 1rem; margin-bottom: 1.5rem; + position: relative; + z-index: 2; } .batch-bulk-card { @@ -627,6 +730,14 @@ select option { border: 1px solid var(--glass-border); border-radius: var(--radius-md); padding: 1.25rem; + position: relative; + z-index: 2; + transition: all var(--transition-smooth); +} + +.batch-bulk-card:hover { + border-color: var(--border-glow); + box-shadow: var(--shadow-glow); } .batch-bulk-header { @@ -641,6 +752,7 @@ select option { font-size: 1rem; margin-bottom: 0.25rem; overflow-wrap: anywhere; + font-family: 'Cinzel', serif; } .batch-bulk-header p { @@ -676,6 +788,8 @@ select option { /* === Campaign templates === */ .campaign-template-panel { margin-bottom: 1.5rem; + position: relative; + z-index: 2; } .campaign-template-fields { @@ -707,6 +821,7 @@ select option { font-size: 0.9375rem; margin-bottom: 0.25rem; overflow-wrap: anywhere; + font-family: 'Cinzel', serif; } .campaign-template-info p { @@ -747,12 +862,12 @@ select option { /* === Animations === */ @keyframes fadeIn { - from { opacity: 0; transform: translateY(8px); } + from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } @keyframes slideUp { - from { opacity: 0; transform: translateY(20px); } + from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: translateY(0); } } @@ -767,28 +882,28 @@ select option { } @keyframes glow-pulse { - 0%, 100% { box-shadow: 0 0 15px rgba(124, 58, 237, 0.15); } - 50% { box-shadow: 0 0 25px rgba(124, 58, 237, 0.3); } + 0%, 100% { box-shadow: 0 0 15px rgba(139, 92, 246, 0.12); } + 50% { box-shadow: 0 0 28px rgba(139, 92, 246, 0.25); } } .animate-fade-in { - animation: fadeIn 0.4s ease-out both; + animation: fadeIn 0.5s ease-out both; } .animate-slide-up { - animation: slideUp 0.5s cubic-bezier(0.4, 0, 0.2, 1) both; + animation: slideUp 0.6s cubic-bezier(0.4, 0, 0.2, 1) both; } /* Stagger children animation */ .stagger-children > * { - animation: fadeIn 0.4s ease-out both; + animation: fadeIn 0.5s ease-out both; } -.stagger-children > *:nth-child(1) { animation-delay: 0.05s; } -.stagger-children > *:nth-child(2) { animation-delay: 0.1s; } -.stagger-children > *:nth-child(3) { animation-delay: 0.15s; } -.stagger-children > *:nth-child(4) { animation-delay: 0.2s; } -.stagger-children > *:nth-child(5) { animation-delay: 0.25s; } -.stagger-children > *:nth-child(6) { animation-delay: 0.3s; } +.stagger-children > *:nth-child(1) { animation-delay: 0.06s; } +.stagger-children > *:nth-child(2) { animation-delay: 0.12s; } +.stagger-children > *:nth-child(3) { animation-delay: 0.18s; } +.stagger-children > *:nth-child(4) { animation-delay: 0.24s; } +.stagger-children > *:nth-child(5) { animation-delay: 0.30s; } +.stagger-children > *:nth-child(6) { animation-delay: 0.36s; } /* === Blazor Overrides === */ .valid.modified:not([type=checkbox]) { @@ -809,7 +924,7 @@ select option { .blazor-error-boundary { background: var(--status-danger-bg); - border: 1px solid rgba(239, 68, 68, 0.2); + border: 1px solid rgba(239, 68, 68, 0.15); padding: 1rem 1.25rem; color: var(--status-danger); border-radius: var(--radius-md); @@ -824,7 +939,9 @@ select option { .form-label { color: var(--text-secondary) !important; font-size: 0.8125rem !important; - font-weight: 500 !important; + font-weight: 600 !important; + font-family: 'Jura', sans-serif !important; + letter-spacing: 0.03em !important; } .form-text { @@ -850,8 +967,10 @@ select option { left: -50%; width: 200%; height: 200%; - background: radial-gradient(ellipse at 30% 50%, rgba(124, 58, 237, 0.12) 0%, transparent 50%), - radial-gradient(ellipse at 70% 50%, rgba(6, 182, 212, 0.08) 0%, transparent 50%); + background: + radial-gradient(ellipse at 30% 50%, rgba(139, 92, 246, 0.15) 0%, transparent 50%), + radial-gradient(ellipse at 70% 50%, rgba(34, 211, 238, 0.1) 0%, transparent 50%), + radial-gradient(ellipse at 50% 80%, rgba(139, 92, 246, 0.08) 0%, transparent 40%); animation: bg-drift 20s ease-in-out infinite alternate; } @@ -862,10 +981,10 @@ select option { .login-card { position: relative; - z-index: 1; + z-index: 2; background: var(--glass-bg); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); + backdrop-filter: blur(24px); + -webkit-backdrop-filter: blur(24px); border: 1px solid var(--glass-border); border-radius: var(--radius-xl); padding: 2.5rem; @@ -873,7 +992,21 @@ select option { max-width: 400px; margin: 1rem; text-align: center; - animation: slideUp 0.6s cubic-bezier(0.4, 0, 0.2, 1); + animation: slideUp 0.7s cubic-bezier(0.4, 0, 0.2, 1); + box-shadow: 0 8px 40px rgba(0, 0, 0, 0.5), 0 0 30px rgba(139, 92, 246, 0.1); +} + +.login-card::before { + content: ''; + position: absolute; + inset: 0; + border-radius: inherit; + padding: 1px; + background: linear-gradient(135deg, rgba(139, 92, 246, 0.2) 0%, transparent 35%, transparent 65%, rgba(34, 211, 238, 0.15) 100%); + -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); + -webkit-mask-composite: xor; + mask-composite: exclude; + pointer-events: none; } .login-logo { @@ -894,12 +1027,15 @@ select option { -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; + font-family: 'Cinzel Decorative', 'Cinzel', serif; + letter-spacing: 0.04em; } .login-subtitle { color: var(--text-muted); font-size: 0.875rem; margin-bottom: 2rem; + font-family: 'Jura', sans-serif; } /* === Telegram Mini App entry === */ @@ -911,6 +1047,8 @@ select option { justify-content: center; padding: 1rem; background: var(--bg-primary); + position: relative; + z-index: 2; } .mini-app-auth-card { @@ -921,6 +1059,8 @@ select option { border-radius: var(--radius-md); background: var(--glass-bg); text-align: center; + position: relative; + z-index: 2; } .mini-app-logo { @@ -936,6 +1076,7 @@ select option { .mini-app-auth-card h1 { font-size: 1.375rem; margin-bottom: 0.5rem; + font-family: 'Cinzel Decorative', 'Cinzel', serif; } .mini-app-auth-card p { @@ -966,6 +1107,8 @@ body.telegram-mini-app .content { /* === Mobile Sessions Cards (instead of table) === */ .session-card-mobile { display: none; + position: relative; + z-index: 2; } body.telegram-mini-app .session-table-desktop { @@ -984,10 +1127,13 @@ body.telegram-mini-app .session-card-mobile { padding: 1rem; margin-bottom: 0.75rem; transition: all var(--transition-smooth); + position: relative; + z-index: 2; } .session-card:hover { border-color: var(--border-glow); + box-shadow: var(--shadow-glow); } .session-card-header { @@ -1094,6 +1240,8 @@ body.telegram-mini-app .session-card-mobile { text-align: center; padding: 2rem; animation: fadeIn 0.5s ease-out; + position: relative; + z-index: 2; } .error-page-icon { @@ -1105,6 +1253,7 @@ body.telegram-mini-app .session-card-mobile { font-size: 1.5rem; font-weight: 700; margin-bottom: 0.5rem; + font-family: 'Cinzel', serif; } .error-page-text { @@ -1128,10 +1277,12 @@ body.telegram-mini-app .session-card-mobile { /* === Participant list === */ .participant-panel { - background: rgba(0, 0, 0, 0.2); + background: rgba(0, 0, 0, 0.25); border-radius: 0.75rem; padding: 0.75rem; margin: 0.5rem 0; + position: relative; + z-index: 2; } .participant-list { @@ -1148,6 +1299,11 @@ body.telegram-mini-app .session-card-mobile { background: rgba(255, 255, 255, 0.03); border-radius: 0.5rem; gap: 0.5rem; + transition: background var(--transition-fast); +} + +.participant-row:hover { + background: rgba(255, 255, 255, 0.05); } .participant-info { @@ -1159,8 +1315,9 @@ body.telegram-mini-app .session-card-mobile { } .participant-name { - font-weight: 500; + font-weight: 600; color: var(--text-primary); + font-family: 'Jura', sans-serif; } .participant-username { @@ -1172,9 +1329,293 @@ body.telegram-mini-app .session-card-mobile { background: transparent; border: none; color: var(--text-primary); - font-weight: 500; + font-weight: 600; cursor: pointer; font-size: inherit; - font-family: inherit; + font-family: 'Jura', sans-serif; padding: 0; + transition: color var(--transition-fast); +} + +.btn-gm-link:hover { + color: var(--accent-secondary); +} + +/* === Sidebar refinements (MainLayout & NavMenu) === */ +.page { + display: flex; + min-height: 100vh; + position: relative; + z-index: 2; +} + +.sidebar { + width: var(--sidebar-width); + background: var(--bg-secondary); + border-right: 1px solid var(--border-color); + display: flex; + flex-direction: column; + position: fixed; + top: 0; + left: 0; + bottom: 0; + z-index: 10; + overflow-y: auto; + overflow-x: hidden; +} + +.main-area { + flex: 1; + margin-left: var(--sidebar-width); + min-height: 100vh; + position: relative; + z-index: 2; +} + +.content { + padding: 1.5rem; + min-height: 100vh; +} + +.nav-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 1.25rem 1rem; + border-bottom: 1px solid var(--border-color); +} + +.nav-brand { + display: flex; + align-items: center; + gap: 0.75rem; + text-decoration: none; + color: var(--text-primary); +} + +.nav-brand-icon { + width: 1.75rem; + height: 1.75rem; + object-fit: contain; +} + +.nav-brand-text { + font-family: 'Cinzel Decorative', 'Cinzel', serif; + font-size: 1.125rem; + font-weight: 700; + letter-spacing: 0.04em; + color: var(--text-primary); +} + +.nav-toggle { + display: none; + background: none; + border: none; + color: var(--text-secondary); + cursor: pointer; + padding: 0.5rem; + border-radius: var(--radius-sm); + transition: all var(--transition-fast); +} + +.nav-toggle:hover { + background: var(--bg-surface); + color: var(--text-primary); +} + +.nav-body { + flex: 1; + display: flex; + flex-direction: column; + padding: 1rem; + gap: 0.5rem; +} + +.nav-section { + display: flex; + flex-direction: column; + gap: 0.25rem; + margin-bottom: auto; +} + +.nav-item { + display: flex; + align-items: center; + gap: 0.75rem; + padding: 0.625rem 0.875rem; + border-radius: var(--radius-sm); + color: var(--text-secondary); + text-decoration: none; + font-size: 0.875rem; + font-weight: 600; + font-family: 'Jura', sans-serif; + letter-spacing: 0.02em; + transition: all var(--transition-fast); + border: 1px solid transparent; +} + +.nav-item:hover { + background: var(--bg-surface); + color: var(--text-primary); + border-color: var(--border-color); +} + +.nav-item.active { + background: linear-gradient(135deg, rgba(139, 92, 246, 0.15) 0%, rgba(34, 211, 238, 0.08) 100%); + color: var(--text-accent); + border-color: rgba(139, 92, 246, 0.25); + box-shadow: 0 0 12px rgba(139, 92, 246, 0.1); +} + +.nav-item.active .nav-icon { + color: var(--accent-primary); +} + +.nav-icon { + width: 1.125rem; + height: 1.125rem; + flex-shrink: 0; + color: var(--text-muted); + transition: color var(--transition-fast); +} + +.nav-item:hover .nav-icon { + color: var(--text-primary); +} + +.nav-footer { + margin-top: auto; + padding-top: 1rem; + border-top: 1px solid var(--border-color); + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.nav-user { + display: flex; + align-items: center; + gap: 0.625rem; + padding: 0.5rem 0.75rem; +} + +.nav-user-avatar { + width: 2rem; + height: 2rem; + border-radius: 50%; + background: var(--accent-gradient); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.875rem; + font-weight: 700; + color: white; + flex-shrink: 0; + font-family: 'Jura', sans-serif; +} + +.nav-user-name { + font-size: 0.8125rem; + font-weight: 600; + color: var(--text-secondary); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-family: 'Jura', sans-serif; +} + +.nav-logout-btn { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 0.75rem; + border-radius: var(--radius-sm); + color: var(--text-muted); + background: transparent; + border: 1px solid transparent; + cursor: pointer; + font-size: 0.8125rem; + font-weight: 600; + font-family: 'Jura', sans-serif; + letter-spacing: 0.02em; + transition: all var(--transition-fast); + width: 100%; +} + +.nav-logout-btn:hover { + background: rgba(239, 68, 68, 0.08); + color: var(--status-danger); + border-color: rgba(239, 68, 68, 0.15); +} + +.nav-version { + font-size: 0.6875rem; + color: var(--text-muted); + text-align: center; + font-family: 'Jura', sans-serif; + letter-spacing: 0.05em; + opacity: 0.6; +} + +/* === Blazor error UI === */ +#blazor-error-ui { + background: var(--status-danger-bg); + color: var(--status-danger); + bottom: 0; + box-shadow: 0 -1px 2px rgba(0,0,0,0.2); + display: none; + left: 0; + padding: 0.6rem 1.25rem; + position: fixed; + width: 100%; + z-index: 1000; + font-family: 'Jura', sans-serif; + font-size: 0.875rem; + font-weight: 500; +} + +#blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; +} + +#blazor-error-ui .reload { + color: var(--text-accent); + margin-left: 0.5rem; + text-decoration: underline; +} + +/* === Mobile responsive sidebar === */ +@media (max-width: 768px) { + .sidebar { + width: 100%; + position: fixed; + z-index: 100; + transform: translateX(-100%); + transition: transform var(--transition-normal); + } + + .sidebar.open { + transform: translateX(0); + } + + .main-area { + margin-left: 0; + } + + .nav-toggle { + display: block; + position: fixed; + top: 1rem; + left: 1rem; + z-index: 101; + background: var(--bg-secondary); + border: 1px solid var(--border-color); + } + + .nav-body.open { + display: flex; + } } From 8e57f8b07a0a7ea5d3913ad36f9369f296c28cc2 Mon Sep 17 00:00:00 2001 From: Toutsu Date: Mon, 18 May 2026 11:04:22 +0300 Subject: [PATCH 2/3] chore: migrate k8s manifests to dedicated repo All Kubernetes manifests moved to git.codeanddice.ru/Toutsu/gmrelay-k8s. Co-Authored-By: Claude Opus 4.7 --- k8s/01-namespace.yaml | 4 -- k8s/02-secrets.yaml | 10 ----- k8s/03-configmap.yaml | 9 ----- k8s/04-postgres.yaml | 68 --------------------------------- k8s/05-web.yaml | 88 ------------------------------------------- k8s/06-bot.yaml | 42 --------------------- 6 files changed, 221 deletions(-) delete mode 100644 k8s/01-namespace.yaml delete mode 100644 k8s/02-secrets.yaml delete mode 100644 k8s/03-configmap.yaml delete mode 100644 k8s/04-postgres.yaml delete mode 100644 k8s/05-web.yaml delete mode 100644 k8s/06-bot.yaml diff --git a/k8s/01-namespace.yaml b/k8s/01-namespace.yaml deleted file mode 100644 index a1c9461..0000000 --- a/k8s/01-namespace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: gmrelay-test diff --git a/k8s/02-secrets.yaml b/k8s/02-secrets.yaml deleted file mode 100644 index 0c7da3b..0000000 --- a/k8s/02-secrets.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: gmrelay-secrets - namespace: gmrelay-test -type: Opaque -stringData: - POSTGRES_PASSWORD: "TestPassword123" - TELEGRAM_BOT_TOKEN: "8641931558:AAGBARuuTZUXX7V3YrtJwN3y_q0NUVkFrqk" - TELEGRAM_BOT_USERNAME: "GmRelayTestBot" diff --git a/k8s/03-configmap.yaml b/k8s/03-configmap.yaml deleted file mode 100644 index 7c3ea26..0000000 --- a/k8s/03-configmap.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: gmrelay-config - namespace: gmrelay-test -data: - ConnectionStrings__gmrelaydb: "Host=postgres;Port=5432;Database=gmrelay_db;Username=gmrelay;Password=$(POSTGRES_PASSWORD)" - Telegram__MiniAppUrl: "" - ASPNETCORE_URLS: "http://+:8080" diff --git a/k8s/04-postgres.yaml b/k8s/04-postgres.yaml deleted file mode 100644 index ea60c59..0000000 --- a/k8s/04-postgres.yaml +++ /dev/null @@ -1,68 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: postgres-pvc - namespace: gmrelay-test -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: postgres - namespace: gmrelay-test -spec: - replicas: 1 - selector: - matchLabels: - app: postgres - template: - metadata: - labels: - app: postgres - spec: - containers: - - name: postgres - image: postgres:17-alpine - ports: - - containerPort: 5432 - env: - - name: POSTGRES_USER - value: "gmrelay" - - name: POSTGRES_DB - value: "gmrelay_db" - - name: POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: gmrelay-secrets - key: POSTGRES_PASSWORD - volumeMounts: - - name: postgres-data - mountPath: /var/lib/postgresql/data - resources: - requests: - memory: "128Mi" - cpu: "100m" - limits: - memory: "512Mi" - cpu: "500m" - volumes: - - name: postgres-data - persistentVolumeClaim: - claimName: postgres-pvc ---- -apiVersion: v1 -kind: Service -metadata: - name: postgres - namespace: gmrelay-test -spec: - selector: - app: postgres - ports: - - port: 5432 - targetPort: 5432 diff --git a/k8s/05-web.yaml b/k8s/05-web.yaml deleted file mode 100644 index 9563a5e..0000000 --- a/k8s/05-web.yaml +++ /dev/null @@ -1,88 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: gmrelay-web - namespace: gmrelay-test -spec: - replicas: 1 - selector: - matchLabels: - app: gmrelay-web - template: - metadata: - labels: - app: gmrelay-web - spec: - containers: - - name: web - image: gmrelay-web:design-refresh - ports: - - containerPort: 8080 - envFrom: - - configMapRef: - name: gmrelay-config - env: - - name: POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: gmrelay-secrets - key: POSTGRES_PASSWORD - - name: ConnectionStrings__gmrelaydb - value: "Host=postgres;Port=5432;Database=gmrelay_db;Username=gmrelay;Password=$(POSTGRES_PASSWORD)" - - name: Telegram__BotToken - valueFrom: - secretKeyRef: - name: gmrelay-secrets - key: TELEGRAM_BOT_TOKEN - - name: Telegram__BotUsername - valueFrom: - secretKeyRef: - name: gmrelay-secrets - key: TELEGRAM_BOT_USERNAME - - name: Telegram__MiniAppUrl - value: "" - resources: - requests: - memory: "128Mi" - cpu: "100m" - limits: - memory: "512Mi" - cpu: "500m" - volumeMounts: - - name: dataprotection-keys - mountPath: /app/dataprotection-keys - volumes: - - name: dataprotection-keys - emptyDir: {} ---- -apiVersion: v1 -kind: Service -metadata: - name: gmrelay-web - namespace: gmrelay-test -spec: - selector: - app: gmrelay-web - ports: - - port: 8080 - targetPort: 8080 ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: gmrelay-web - namespace: gmrelay-test - annotations: - nginx.ingress.kubernetes.io/rewrite-target: / -spec: - rules: - - host: gmrelay.local - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: gmrelay-web - port: - number: 8080 diff --git a/k8s/06-bot.yaml b/k8s/06-bot.yaml deleted file mode 100644 index a4ccc56..0000000 --- a/k8s/06-bot.yaml +++ /dev/null @@ -1,42 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: gmrelay-bot - namespace: gmrelay-test -spec: - replicas: 1 - selector: - matchLabels: - app: gmrelay-bot - template: - metadata: - labels: - app: gmrelay-bot - spec: - containers: - - name: bot - image: gmrelay-bot:design-refresh - ports: - - containerPort: 8081 - env: - - name: POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: gmrelay-secrets - key: POSTGRES_PASSWORD - - name: ConnectionStrings__gmrelaydb - value: "Host=postgres;Port=5432;Database=gmrelay_db;Username=gmrelay;Password=$(POSTGRES_PASSWORD)" - - name: Telegram__BotToken - valueFrom: - secretKeyRef: - name: gmrelay-secrets - key: TELEGRAM_BOT_TOKEN - - name: Telegram__MiniAppUrl - value: "" - resources: - requests: - memory: "128Mi" - cpu: "100m" - limits: - memory: "256Mi" - cpu: "500m" From cea6ec801a9565b34e3cf3227d8292dff86f5ab8 Mon Sep 17 00:00:00 2001 From: Toutsu Date: Mon, 18 May 2026 11:22:00 +0300 Subject: [PATCH 3/3] chore: bump version to 2.1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Synchronize version across all 4 files: - Directory.Build.props - compose.yaml (bot + web images) - .gitea/workflows/deploy.yml - NavMenu.razor Bump version → 2.1.0 Co-Authored-By: Claude Opus 4.7 --- .gitea/workflows/deploy.yml | 2 +- Directory.Build.props | 2 +- compose.yaml | 4 ++-- src/GmRelay.Web/Components/Layout/NavMenu.razor | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 79733de..ca3b1c9 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -6,7 +6,7 @@ on: - main env: - VERSION: 2.0.1 + VERSION: 2.1.0 jobs: # ЧАСТЬ 1: Собираем образы и кладем в Gitea (чтобы делиться с ребятами) diff --git a/Directory.Build.props b/Directory.Build.props index e0f3902..60e9423 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 2.0.1 + 2.1.0 net10.0 preview enable diff --git a/compose.yaml b/compose.yaml index 710a96a..2fe9c78 100644 --- a/compose.yaml +++ b/compose.yaml @@ -49,7 +49,7 @@ services: crond -f bot: - image: git.codeanddice.ru/toutsu/gmrelay-bot:2.0.1 + image: git.codeanddice.ru/toutsu/gmrelay-bot:2.1.0 restart: always depends_on: db: @@ -67,7 +67,7 @@ services: retries: 3 web: - image: git.codeanddice.ru/toutsu/gmrelay-web:2.0.1 + image: git.codeanddice.ru/toutsu/gmrelay-web:2.1.0 restart: always depends_on: db: diff --git a/src/GmRelay.Web/Components/Layout/NavMenu.razor b/src/GmRelay.Web/Components/Layout/NavMenu.razor index e4c7049..a54f6d4 100644 --- a/src/GmRelay.Web/Components/Layout/NavMenu.razor +++ b/src/GmRelay.Web/Components/Layout/NavMenu.razor @@ -56,7 +56,7 @@ - +