updated admin panel style

This commit is contained in:
onysd 2026-07-22 01:16:29 +03:00
parent 9844d78c5b
commit deae6c4a4a
26 changed files with 493 additions and 1356 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -3,9 +3,10 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>telesrv admin</title> <link rel="icon" type="image/png" href="/logo.png" />
<script type="module" crossorigin src="/assets/index-ybbM_ULl.js"></script> <title>OwpenGram Admin</title>
<link rel="stylesheet" crossorigin href="/assets/index-BVA68zgn.css"> <script type="module" crossorigin src="/assets/index-CpvYOqis.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Da0KbwLb.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

BIN
cmd/telesrv-admin/web/dist/logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -3,7 +3,8 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>telesrv admin</title> <link rel="icon" type="image/png" href="/logo.png" />
<title>OwpenGram Admin</title>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -12,7 +12,7 @@ import {
} from "lucide-react"; } from "lucide-react";
import { useEffect, useState, type ReactNode } from "react"; import { useEffect, useState, type ReactNode } from "react";
import { api } from "../api"; import { api } from "../api";
import { LanguageSwitch, useI18n } from "../i18n"; import { useI18n } from "../i18n";
import { type Navigate, type RouteState, routeSubtitle, routeTitle } from "../routing"; import { type Navigate, type RouteState, routeSubtitle, routeTitle } from "../routing";
import { AppLink } from "./AppLink"; import { AppLink } from "./AppLink";
@ -21,9 +21,9 @@ export function BootScreen() {
return ( return (
<div className="boot-screen"> <div className="boot-screen">
<div className="brand compact brand-elevated"> <div className="brand compact brand-elevated">
<span className="brand-mark">T</span> <span className="brand-mark"><img src="/logo.png" alt="OwpenGram" /></span>
<span> <span>
<strong>telesrv</strong> <strong>OwpenGram</strong>
<small>{t("app.adminConsole")}</small> <small>{t("app.adminConsole")}</small>
</span> </span>
</div> </div>
@ -64,9 +64,9 @@ export function Shell({
<div className="shell"> <div className="shell">
<aside className="sidebar"> <aside className="sidebar">
<AppLink className="brand" href="/" navigate={navigate}> <AppLink className="brand" href="/" navigate={navigate}>
<span className="brand-mark">T</span> <span className="brand-mark"><img src="/logo.png" alt="OwpenGram" /></span>
<span> <span>
<strong>telesrv</strong> <strong>OwpenGram</strong>
<small>{t("app.adminConsole")}</small> <small>{t("app.adminConsole")}</small>
</span> </span>
</AppLink> </AppLink>
@ -123,7 +123,6 @@ export function Shell({
<h1>{routeTitle(route.path, t)}</h1> <h1>{routeTitle(route.path, t)}</h1>
</div> </div>
<div className="topbar-actions"> <div className="topbar-actions">
<LanguageSwitch />
<span className="actor-pill">{t("layout.actor", { actor })}</span> <span className="actor-pill">{t("layout.actor", { actor })}</span>
<button className="btn ghost icon-text" type="button" onClick={logout} title={t("layout.logout")}> <button className="btn ghost icon-text" type="button" onClick={logout} title={t("layout.logout")}>
<LogOut size={16} /> {t("layout.logout")} <LogOut size={16} /> {t("layout.logout")}

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@ import type { FormEvent } from "react";
import { useState } from "react"; import { useState } from "react";
import { api, errorMessage } from "../api"; import { api, errorMessage } from "../api";
import { Alert } from "../components/ui"; import { Alert } from "../components/ui";
import { LanguageSwitch, useI18n } from "../i18n"; import { useI18n } from "../i18n";
export function LoginPage({ onLogin }: { onLogin: (actor: string) => void }) { export function LoginPage({ onLogin }: { onLogin: (actor: string) => void }) {
const { t } = useI18n(); const { t } = useI18n();
@ -29,14 +29,13 @@ export function LoginPage({ onLogin }: { onLogin: (actor: string) => void }) {
<section className="login-panel"> <section className="login-panel">
<div className="login-head"> <div className="login-head">
<div className="brand brand-elevated"> <div className="brand brand-elevated">
<span className="brand-mark">T</span> <span className="brand-mark"><img src="/logo.png" alt="OwpenGram" /></span>
<span> <span>
<strong>telesrv</strong> <strong>OwpenGram</strong>
<small>{t("app.adminConsole")}</small> <small>{t("app.adminConsole")}</small>
</span> </span>
</div> </div>
<div className="login-head-actions"> <div className="login-head-actions">
<LanguageSwitch />
<span className="login-chip">{t("app.localAccess")}</span> <span className="login-chip">{t("app.localAccess")}</span>
</div> </div>
</div> </div>

View file

@ -1,24 +1,31 @@
@font-face { font-family: "Plus Jakarta Sans"; font-style: normal; font-weight: 400; font-display: swap; src: url("/fonts/plus-jakarta-sans-400.woff2") format("woff2"); }
@font-face { font-family: "Plus Jakarta Sans"; font-style: normal; font-weight: 500; font-display: swap; src: url("/fonts/plus-jakarta-sans-500.woff2") format("woff2"); }
@font-face { font-family: "Plus Jakarta Sans"; font-style: normal; font-weight: 600; font-display: swap; src: url("/fonts/plus-jakarta-sans-600.woff2") format("woff2"); }
@font-face { font-family: "Plus Jakarta Sans"; font-style: normal; font-weight: 700; font-display: swap; src: url("/fonts/plus-jakarta-sans-700.woff2") format("woff2"); }
@font-face { font-family: "Plus Jakarta Sans"; font-style: normal; font-weight: 800; font-display: swap; src: url("/fonts/plus-jakarta-sans-800.woff2") format("woff2"); }
:root { :root {
color-scheme: light; color-scheme: light;
--bg: #f3f5f7; --bg: #f7f9fc;
--panel: #ffffff; --panel: #ffffff;
--panel-subtle: #f8fafb; --panel-subtle: #f7f9fc;
--panel-strong: #eef2f5; --panel-strong: #f1f5f9;
--line: #d9e1e8; --line: #e2e8f0;
--line-strong: #c2ccd6; --line-strong: #cbd5e1;
--text: #101828; --text: #0f1720;
--muted: #667085; --muted: #64748b;
--muted-2: #98a2b3; --muted-2: #94a3b8;
--brand: #176d61; --brand: #2563eb;
--brand-2: #245b9d; --brand-2: #38bdf8;
--grad: linear-gradient(135deg, #38bdf8 0%, #2563eb 55%, #1e40af 100%);
--good: #167447; --good: #167447;
--warn: #a15c07; --warn: #a15c07;
--danger: #b42318; --danger: #b42318;
--sidebar: #11161d; --sidebar: #08080e;
--sidebar-soft: #1b222b; --sidebar-soft: #12121a;
--sidebar-line: #2c3541; --sidebar-line: #222228;
--focus: rgba(23, 109, 97, 0.16); --focus: rgba(37, 99, 235, 0.16);
--shadow: 0 18px 52px rgba(16, 24, 40, 0.14); --shadow: 0 28px 70px -36px rgba(5, 5, 8, 0.35);
} }
* { * {
@ -35,7 +42,7 @@ body {
margin: 0; margin: 0;
color: var(--text); color: var(--text);
background: var(--bg); background: var(--bg);
font: 13px/1.45 Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; font: 13px/1.45 "Plus Jakarta Sans", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
} }
button, button,
@ -81,20 +88,18 @@ a {
justify-content: center; justify-content: center;
} }
.brand-elevated .brand-mark {
box-shadow: 0 8px 24px rgba(23, 109, 97, 0.26);
}
.brand-mark { .brand-mark {
display: grid; display: grid;
width: 34px; width: 34px;
height: 34px; height: 34px;
place-items: center; place-items: center;
color: #ffffff; }
background: var(--brand);
border: 1px solid rgba(255, 255, 255, 0.2); .brand-mark img {
border-radius: 8px; display: block;
font-weight: 800; width: 100%;
height: 100%;
object-fit: contain;
} }
.brand strong { .brand strong {
@ -261,37 +266,6 @@ a {
gap: 8px; gap: 8px;
} }
.language-switch {
display: inline-flex;
min-height: 30px;
align-items: center;
padding: 2px;
background: var(--panel-subtle);
border: 1px solid var(--line);
border-radius: 999px;
}
.language-switch button {
min-width: 42px;
min-height: 24px;
padding: 0 9px;
color: var(--muted);
background: transparent;
border: 0;
border-radius: 999px;
cursor: pointer;
font-weight: 800;
}
.language-switch button.active {
color: #ffffff;
background: var(--brand);
}
.language-switch button:focus-visible {
outline: 2px solid var(--brand);
outline-offset: 2px;
}
.actor-pill { .actor-pill {
display: inline-flex; display: inline-flex;

View file

@ -110,8 +110,8 @@
height: 38px; height: 38px;
place-items: center; place-items: center;
color: var(--brand); color: var(--brand);
background: #edf7f4; background: #eaf2fd;
border: 1px solid #c9e2dc; border: 1px solid #c7dcf9;
border-radius: 8px; border-radius: 8px;
} }
@ -217,9 +217,9 @@
align-items: center; align-items: center;
gap: 8px; gap: 8px;
padding: 7px 9px; padding: 7px 9px;
color: #0f3f38; color: #1e3a8a;
background: #eef8f5; background: #eaf2fe;
border: 1px solid #b9dcd3; border: 1px solid #c3d9f7;
border-radius: 7px; border-radius: 7px;
} }
@ -291,7 +291,7 @@
.picker-row:hover, .picker-row:hover,
.picker-row.selected { .picker-row.selected {
background: #f3f8f6; background: #eef4ff;
} }
.picker-row strong, .picker-row strong,
@ -410,7 +410,7 @@ textarea:focus {
} }
.btn.primary:hover:not(:disabled) { .btn.primary:hover:not(:disabled) {
background: #12594f; background: #1d4ed8;
} }
.btn.ghost { .btn.ghost {

View file

@ -265,12 +265,12 @@
flex: 0 0 auto; flex: 0 0 auto;
place-items: center; place-items: center;
color: var(--brand); color: var(--brand);
background: #eaf6f3; background: #eaf2fd;
border: 1px solid #c7e3dc; border: 1px solid #c7dcf9;
} }
.gift-format-chips { display: flex; flex: 0 0 auto; flex-wrap: wrap; justify-content: flex-end; gap: 6px; } .gift-format-chips { display: flex; flex: 0 0 auto; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
.gift-format-chips span { padding: 4px 8px; color: #33645d; background: #eef8f5; border: 1px solid #cfe5df; border-radius: 999px; font-size: 10px; font-weight: 800; letter-spacing: .02em; } .gift-format-chips span { padding: 4px 8px; color: #1e40af; background: #eaf2fe; border: 1px solid #cbdcf7; border-radius: 999px; font-size: 10px; font-weight: 800; letter-spacing: .02em; }
.gift-list-summary { margin-left: auto; color: var(--muted); font-size: 11px; font-weight: 700; } .gift-list-summary { margin-left: auto; color: var(--muted); font-size: 11px; font-weight: 700; }
@ -284,12 +284,12 @@
.official-gift-categories { display: flex; flex-wrap: wrap; gap: 7px; } .official-gift-categories { display: flex; flex-wrap: wrap; gap: 7px; }
.official-gift-categories button { .official-gift-categories button {
display: inline-flex; align-items: center; gap: 7px; min-height: 32px; padding: 5px 10px; display: inline-flex; align-items: center; gap: 7px; min-height: 32px; padding: 5px 10px;
color: #49605c; background: #f7faf9; border: 1px solid #d7e2df; border-radius: 999px; color: #3f5a78; background: #f5f8fd; border: 1px solid #d7e2f4; border-radius: 999px;
font: inherit; font-size: 11px; font-weight: 800; cursor: pointer; font: inherit; font-size: 11px; font-weight: 800; cursor: pointer;
transition: color .15s ease, background .15s ease, border-color .15s ease, box-shadow .15s ease; transition: color .15s ease, background .15s ease, border-color .15s ease, box-shadow .15s ease;
} }
.official-gift-categories button:hover { color: var(--brand); border-color: #9fc9c0; } .official-gift-categories button:hover { color: var(--brand); border-color: #9dc3f5; }
.official-gift-categories button.active { color: #ffffff; background: var(--brand); border-color: var(--brand); box-shadow: 0 4px 12px rgba(23, 109, 97, .17); } .official-gift-categories button.active { color: #ffffff; background: var(--brand); border-color: var(--brand); box-shadow: 0 4px 12px rgba(37, 99, 235, .17); }
.official-gift-categories button span { .official-gift-categories button span {
display: grid; min-width: 20px; height: 20px; padding: 0 5px; place-items: center; display: grid; min-width: 20px; height: 20px; padding: 0 5px; place-items: center;
color: inherit; background: rgba(255,255,255,.65); border-radius: 999px; font-size: 10px; color: inherit; background: rgba(255,255,255,.65); border-radius: 999px; font-size: 10px;
@ -298,20 +298,20 @@
.official-gift-list { .official-gift-list {
display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; max-height: 314px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; max-height: 314px;
min-height: 126px; padding: 8px; overflow: auto; border: 1px solid var(--line); border-radius: 14px; min-height: 126px; padding: 8px; overflow: auto; border: 1px solid var(--line); border-radius: 14px;
background: #f6f9f8; scrollbar-gutter: stable; background: #f5f8fd; scrollbar-gutter: stable;
} }
.official-gift-option { .official-gift-option {
display: grid; min-width: 0; gap: 8px; padding: 11px 12px; text-align: left; color: var(--text); display: grid; min-width: 0; gap: 8px; padding: 11px 12px; text-align: left; color: var(--text);
background: #ffffff; border: 1px solid #dce6e3; border-radius: 11px; cursor: pointer; background: #ffffff; border: 1px solid #dbe6f7; border-radius: 11px; cursor: pointer;
box-shadow: 0 1px 2px rgba(32, 54, 50, .03); box-shadow: 0 1px 2px rgba(30, 41, 82, .03);
transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease; transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
} }
.official-gift-option:hover { border-color: #9fc9c0; box-shadow: 0 5px 14px rgba(32, 76, 68, .08); transform: translateY(-1px); } .official-gift-option:hover { border-color: #9dc3f5; box-shadow: 0 5px 14px rgba(30, 64, 175, .08); transform: translateY(-1px); }
.official-gift-option.selected { border-color: var(--brand); box-shadow: 0 0 0 2px rgba(23, 109, 97, .12), 0 5px 14px rgba(32, 76, 68, .08); } .official-gift-option.selected { border-color: var(--brand); box-shadow: 0 0 0 2px rgba(37, 99, 235, .12), 0 5px 14px rgba(30, 64, 175, .08); }
.official-gift-option-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: baseline; } .official-gift-option-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: baseline; }
.official-gift-option-head strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; } .official-gift-option-head strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
.official-gift-option-head .mono { color: var(--muted); font-size: 9px; } .official-gift-option-head .mono { color: var(--muted); font-size: 9px; }
.official-gift-option-meta { display: flex; flex-wrap: wrap; gap: 10px; color: #667773; font-size: 10px; font-weight: 700; } .official-gift-option-meta { display: flex; flex-wrap: wrap; gap: 10px; color: #5b6b85; font-size: 10px; font-weight: 700; }
.official-gift-capabilities { display: flex; flex-wrap: wrap; gap: 5px; } .official-gift-capabilities { display: flex; flex-wrap: wrap; gap: 5px; }
.official-gift-capabilities > span { .official-gift-capabilities > span {
padding: 3px 7px; border: 1px solid transparent; border-radius: 999px; font-size: 9px; font-weight: 850; letter-spacing: .01em; padding: 3px 7px; border: 1px solid transparent; border-radius: 999px; font-size: 9px; font-weight: 850; letter-spacing: .01em;
@ -342,21 +342,21 @@
padding: 12px 14px; padding: 12px 14px;
color: var(--text); color: var(--text);
background: #ffffff; background: #ffffff;
border: 1px dashed #b7ccc8; border: 1px dashed #b7c9e8;
border-radius: 10px; border-radius: 10px;
cursor: pointer; cursor: pointer;
transition: border-color .16s ease, background .16s ease, box-shadow .16s ease; transition: border-color .16s ease, background .16s ease, box-shadow .16s ease;
} }
.gift-file-picker:hover, .gift-file-picker:hover,
.gift-file-picker.has-file { background: #f8fcfb; border-color: var(--brand); box-shadow: 0 0 0 2px rgba(23, 109, 97, .05); } .gift-file-picker.has-file { background: #f5f9ff; border-color: var(--brand); box-shadow: 0 0 0 2px rgba(37, 99, 235, .05); }
.gift-file-picker input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; } .gift-file-picker input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.gift-file-icon { width: 40px; height: 40px; border-radius: 9px; } .gift-file-icon { width: 40px; height: 40px; border-radius: 9px; }
.gift-file-copy { display: grid; min-width: 0; gap: 2px; } .gift-file-copy { display: grid; min-width: 0; gap: 2px; }
.gift-field-label { color: var(--muted); font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; } .gift-field-label { color: var(--muted); font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; }
.gift-file-copy strong { overflow: hidden; font-size: 13px; text-overflow: ellipsis; white-space: nowrap; } .gift-file-copy strong { overflow: hidden; font-size: 13px; text-overflow: ellipsis; white-space: nowrap; }
.gift-file-copy small { color: var(--muted); font-size: 11px; font-weight: 500; } .gift-file-copy small { color: var(--muted); font-size: 11px; font-weight: 500; }
.gift-file-action { padding: 7px 10px; color: var(--brand); background: #f0f8f6; border: 1px solid #c7e3dc; border-radius: 7px; font-size: 11px; font-weight: 800; } .gift-file-action { padding: 7px 10px; color: var(--brand); background: #eef4ff; border: 1px solid #c7dcf9; border-radius: 7px; font-size: 11px; font-weight: 800; }
.gift-fields-grid { .gift-fields-grid {
display: grid; display: grid;
@ -386,7 +386,7 @@
} }
.gift-fields-grid input:focus, .gift-fields-grid input:focus,
.gift-reason-field input:focus { border-color: #77b6aa; box-shadow: 0 0 0 3px rgba(23, 109, 97, .08); outline: none; } .gift-reason-field input:focus { border-color: #7bb4f0; box-shadow: 0 0 0 3px rgba(37, 99, 235, .08); outline: none; }
.gift-switch { display: inline-flex; align-items: center; gap: 9px; color: #344054; font-size: 12px; font-weight: 700; cursor: pointer; } .gift-switch { display: inline-flex; align-items: center; gap: 9px; color: #344054; font-size: 12px; font-weight: 700; cursor: pointer; }
.gift-switch input { position: absolute; width: 1px; height: 1px; opacity: 0; } .gift-switch input { position: absolute; width: 1px; height: 1px; opacity: 0; }
@ -394,14 +394,14 @@
.gift-switch-track span { width: 15px; height: 15px; background: #ffffff; border-radius: 50%; box-shadow: 0 1px 3px rgba(16, 24, 40, .22); transition: transform .16s ease; } .gift-switch-track span { width: 15px; height: 15px; background: #ffffff; border-radius: 50%; box-shadow: 0 1px 3px rgba(16, 24, 40, .22); transition: transform .16s ease; }
.gift-switch input:checked + .gift-switch-track { background: var(--brand); } .gift-switch input:checked + .gift-switch-track { background: var(--brand); }
.gift-switch input:checked + .gift-switch-track span { transform: translateX(15px); } .gift-switch input:checked + .gift-switch-track span { transform: translateX(15px); }
.gift-switch input:focus-visible + .gift-switch-track { outline: 3px solid rgba(23, 109, 97, .16); outline-offset: 2px; } .gift-switch input:focus-visible + .gift-switch-track { outline: 3px solid rgba(37, 99, 235, .16); outline-offset: 2px; }
.gift-validation { overflow: hidden; color: #d5fff5; background: #173631; border: 1px solid #24564e; border-radius: 9px; } .gift-validation { overflow: hidden; color: #d5fff5; background: #173631; border: 1px solid #24564e; border-radius: 9px; }
.gift-validation-head { display: flex; align-items: center; gap: 9px; padding: 10px 12px; color: #e3fff9; background: rgba(255, 255, 255, .035); border-bottom: 1px solid rgba(255, 255, 255, .09); } .gift-validation-head { display: flex; align-items: center; gap: 9px; padding: 10px 12px; color: #e3fff9; background: rgba(255, 255, 255, .035); border-bottom: 1px solid rgba(255, 255, 255, .09); }
.gift-validation-head div { display: grid; gap: 2px; } .gift-validation-head div { display: grid; gap: 2px; }
.gift-validation-head span { color: #99cfc4; font-size: 10px; } .gift-validation-head span { color: #99cfc4; font-size: 10px; }
.gift-validation pre { max-height: 180px; overflow: auto; margin: 0; padding: 11px 12px; color: #d5fff5; font-size: 11px; } .gift-validation pre { max-height: 180px; overflow: auto; margin: 0; padding: 11px 12px; color: #d5fff5; font-size: 11px; }
.gift-animation-shell { position: relative; display: grid; min-height: 210px; place-items: center; background: radial-gradient(circle, #f9f3ff, #eef8f5); } .gift-animation-shell { position: relative; display: grid; min-height: 210px; place-items: center; background: radial-gradient(circle, #f9f3ff, #eaf2fe); }
.gift-animation { width: 200px; height: 200px; } .gift-animation { width: 200px; height: 200px; }
.gift-animation canvas { width: 100% !important; height: 100% !important; } .gift-animation canvas { width: 100% !important; height: 100% !important; }
.gift-play { position: absolute; right: 8px; bottom: 8px; display: grid; width: 30px; height: 30px; place-items: center; color: var(--text); background: rgba(255,255,255,.9); border: 1px solid var(--line); border-radius: 50%; } .gift-play { position: absolute; right: 8px; bottom: 8px; display: grid; width: 30px; height: 30px; place-items: center; color: var(--text); background: rgba(255,255,255,.9); border: 1px solid var(--line); border-radius: 50%; }

View file

@ -90,7 +90,7 @@
.command-step.active { .command-step.active {
color: var(--brand); color: var(--brand);
border-color: #a9d8ce; border-color: #a9c8f7;
} }
.command-step.done { .command-step.done {
@ -201,8 +201,8 @@
align-items: center; align-items: center;
padding: 0 8px; padding: 0 8px;
color: var(--brand); color: var(--brand);
background: #edf7f4; background: #eaf2fd;
border: 1px solid #c9e2dc; border: 1px solid #c7dcf9;
border-radius: 999px; border-radius: 999px;
font-size: 12px; font-size: 12px;
} }

View file

@ -815,41 +815,41 @@ func run(logger *zap.Logger) error {
help.WithEmailSignupPhonePrefixes(cfg.EmailSignupPhonePrefixes), help.WithEmailSignupPhonePrefixes(cfg.EmailSignupPhonePrefixes),
help.WithAccountFreezeProvider(adminService), help.WithAccountFreezeProvider(adminService),
), ),
AccountFreeze: adminService, AccountFreeze: adminService,
AICompose: aiComposeService, AICompose: aiComposeService,
Ephemeral: ephemeralService, Ephemeral: ephemeralService,
EphemeralPush: ephemeralStore, EphemeralPush: ephemeralStore,
EphemeralReports: ephemeralReportStore, EphemeralReports: ephemeralReportStore,
Users: usersService, Users: usersService,
Updates: updatesService, Updates: updatesService,
BootstrapUpdates: bootstrapUpdateStore, BootstrapUpdates: bootstrapUpdateStore,
BotAPIUpdates: botAPIUpdateStore, BotAPIUpdates: botAPIUpdateStore,
BotCallbacks: botCallbackStore, BotCallbacks: botCallbackStore,
Contacts: contactsService, Contacts: contactsService,
Dialogs: dialogsService, Dialogs: dialogsService,
Chatlists: chatlistsService, Chatlists: chatlistsService,
Messages: messagesService, Messages: messagesService,
Translation: translationService, Translation: translationService,
Channels: channelsService, Channels: channelsService,
Communities: communitiesService, Communities: communitiesService,
Files: filesService, Files: filesService,
Bots: botsService, Bots: botsService,
Polls: pollsapp.NewService(pollStore), Polls: pollsapp.NewService(pollStore),
Stories: storiesapp.NewService(storyStore, storiesapp.WithChannelStoryAccess(channelsService)), Stories: storiesapp.NewService(storyStore, storiesapp.WithChannelStoryAccess(channelsService)),
Phone: phoneService, Phone: phoneService,
SecretChats: secretChatService, SecretChats: secretChatService,
Stars: starsService, Stars: starsService,
Gifts: giftsService, Gifts: giftsService,
Passkey: passkeyService, Passkey: passkeyService,
Themes: themeService, Themes: themeService,
GroupCalls: groupCallsService, GroupCalls: groupCallsService,
LiveStreams: liveStreamDep(liveStreamService), LiveStreams: liveStreamDep(liveStreamService),
SFU: sfuService, SFU: sfuService,
TURN: turnService, TURN: turnService,
LangPack: langPackService, LangPack: langPackService,
Sessions: activeSessions, Sessions: activeSessions,
Inline: inlineRegistryStore, Inline: inlineRegistryStore,
Limiter: rateLimiter, Limiter: rateLimiter,
}, logger.Named("rpc"), clock.System) }, logger.Named("rpc"), clock.System)
readModelListener := postgres.NewReadModelChangeListener(cfg.PostgresDSN, postgres.ReadModelCacheSet{ readModelListener := postgres.NewReadModelChangeListener(cfg.PostgresDSN, postgres.ReadModelCacheSet{
ReadModelVersions: readModelVersionStore, ReadModelVersions: readModelVersionStore,