Bundles feature WIP + fix request-access products cap (20 -> 200)

- app/main.py: raise products_raw[:20] cap to [:200] in /api/request-access
  and /api/request-more-access - was silently truncating access requests
  with more than 20 selected products
- accumulated bundles/product-page WIP (config, models, runtime, templates)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-29 13:58:09 +00:00
parent f5c53f01bf
commit 40de4d5a0f
12 changed files with 2407 additions and 457 deletions
+172 -1
View File
@@ -23,8 +23,179 @@
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/109119977" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->
<style>
:root{
--av-bg:#eef1f5; --av-panel:#fff; --av-raised:#fff;
--av-line:#d7dee6; --av-line-soft:#e3e8ee;
--av-fg:#16202c; --av-fg-dim:#5c6b7c; --av-fg-faint:#93a1b0;
--av-accent:#c96c14; --av-accent-dim:rgba(201,108,20,.10); --av-accent-ink:#2a1400;
--av-good:#1f9d63; --av-warn:#b5680a; --av-bad:#d3453f;
}
body.admin-page-v2{
background:var(--av-bg) !important; color:var(--av-fg);
font-family:"Ubuntu","IBM Plex Sans",system-ui,sans-serif;
}
body.admin-page-v2 *{ box-sizing:border-box; min-width:0; }
/* header */
body.admin-page-v2 .header{
background:var(--av-panel) !important; border-bottom:1px solid var(--av-line);
backdrop-filter:none;
}
body.admin-page-v2 .header-logo{ height:28px; }
body.admin-page-v2 .header > div > div{
font:600 13px/1 "Ubuntu Mono",monospace; color:var(--av-fg-dim); letter-spacing:.02em;
}
body.admin-page-v2 .btn-link.secondary{
background:transparent !important; border:1px solid var(--av-line); color:var(--av-fg-dim) !important;
font:600 13px/1 "Ubuntu",sans-serif; padding:9px 16px; border-radius:7px;
}
body.admin-page-v2 .btn-link.secondary:hover{ border-color:var(--av-accent); color:var(--av-fg) !important; }
/* layout / panels */
body.admin-page-v2 .admin-layout{ max-width:1500px; }
body.admin-page-v2 .panel{
background:var(--av-panel) !important; border:1px solid var(--av-line); box-shadow:none;
border-radius:12px;
}
body.admin-page-v2 .admin-intro{
background:var(--av-accent-dim) !important; border:1px solid var(--av-line);
border-left:3px solid var(--av-accent); color:var(--av-fg-dim) !important;
font:500 13px/1.55 "Ubuntu",sans-serif; letter-spacing:normal;
}
body.admin-page-v2 .admin-intro b{ color:var(--av-fg); }
/* tabs */
body.admin-page-v2 .tab-row{ gap:6px; padding-bottom:2px; }
body.admin-page-v2 .tab-btn{
background:transparent !important; color:var(--av-fg-dim) !important;
border:1px solid var(--av-line); border-radius:8px;
font:600 13px/1 "Ubuntu",sans-serif; padding:9px 16px;
}
body.admin-page-v2 .tab-btn:hover{ border-color:var(--av-fg-faint); color:var(--av-fg) !important; }
body.admin-page-v2 .tab-btn.active-tab{
background:var(--av-accent-dim) !important; border-color:var(--av-accent);
color:var(--av-fg) !important;
}
/* split / lists */
body.admin-page-v2 .split{ grid-template-columns:minmax(280px,340px) minmax(0,1fr); }
@media (max-width:900px){ body.admin-page-v2 .split{ grid-template-columns:minmax(0,1fr); } }
body.admin-page-v2 .list-title{
font:700 11px/1 "Ubuntu Mono",monospace; letter-spacing:.1em; text-transform:uppercase;
color:var(--av-fg-faint);
}
body.admin-page-v2 .list-box{
background:var(--av-raised) !important; border:1px solid var(--av-line); border-radius:10px;
}
body.admin-page-v2 .list-search{
background:var(--av-panel) !important; border:1px solid var(--av-line) !important;
color:var(--av-fg); border-radius:8px;
}
body.admin-page-v2 .list-search::placeholder{ color:var(--av-fg-faint); }
body.admin-page-v2 .list-item{
background:var(--av-panel) !important; border:1px solid var(--av-line) !important;
color:var(--av-fg) !important; border-radius:8px; transition:border-color .12s;
}
body.admin-page-v2 .list-item:hover{ border-color:var(--av-fg-faint) !important; }
body.admin-page-v2 .list-item.selected-item{
border-color:var(--av-accent) !important; background:var(--av-accent-dim) !important;
box-shadow:none !important;
}
body.admin-page-v2 .list-item small{ color:var(--av-fg-faint); }
body.admin-page-v2 .user-days{ color:var(--av-fg-faint) !important; }
/* forms */
body.admin-page-v2 input,
body.admin-page-v2 button,
body.admin-page-v2 textarea,
body.admin-page-v2 select{
background:var(--av-panel); border:1px solid var(--av-line); color:var(--av-fg);
border-radius:8px; font:400 13.5px/1.4 "Ubuntu",sans-serif;
}
body.admin-page-v2 input::placeholder,
body.admin-page-v2 textarea::placeholder{ color:var(--av-fg-faint); }
body.admin-page-v2 input:focus,
body.admin-page-v2 textarea:focus,
body.admin-page-v2 select:focus{ outline:none; border-color:var(--av-accent); }
body.admin-page-v2 input[readonly]{ opacity:.6; cursor:default; }
body.admin-page-v2 button{
background:var(--av-accent); color:var(--av-accent-ink); border:none;
font-weight:700; cursor:pointer; padding:8px 16px;
}
body.admin-page-v2 button:hover{ filter:brightness(1.06); }
body.admin-page-v2 .field-col > span{
font:600 11.5px/1 "Ubuntu",sans-serif; color:var(--av-fg-faint);
}
body.admin-page-v2 .field-help{ color:var(--av-fg-faint); }
body.admin-page-v2 .actions{ flex-wrap:wrap; }
/* acl / category grids */
body.admin-page-v2 .acl-grid label,
body.admin-page-v2 .compact-grid label{
display:flex; align-items:center; gap:8px; padding:6px 8px;
border:1px solid var(--av-line); border-radius:7px; background:var(--av-panel);
font:400 13px/1.3 "Ubuntu",sans-serif; color:var(--av-fg-dim);
}
body.admin-page-v2 .acl-grid input[type=checkbox],
body.admin-page-v2 .compact-grid input[type=checkbox]{ accent-color:var(--av-accent); }
body.admin-page-v2 .acl-owner{ color:var(--av-accent) !important; }
/* tables */
body.admin-page-v2 .admin-table{ color:var(--av-fg-dim); }
body.admin-page-v2 .admin-table th{
color:var(--av-fg-faint); font:700 10.5px/1 "Ubuntu Mono",monospace; letter-spacing:.06em;
text-transform:uppercase; border-bottom:1px solid var(--av-line) !important;
}
body.admin-page-v2 .admin-table td{ border-bottom:1px solid var(--av-line) !important; }
body.admin-page-v2 .container-table-wrap{
background:var(--av-panel) !important; border:1px solid var(--av-line) !important;
border-radius:10px;
}
/* summary strip */
body.admin-page-v2 .summary-card{
background:var(--av-panel) !important; border:1px solid var(--av-line);
border-radius:10px;
}
body.admin-page-v2 .summary-label{
color:var(--av-fg-faint) !important; font:600 10.5px/1 "Ubuntu Mono",monospace;
letter-spacing:.06em; text-transform:uppercase;
}
body.admin-page-v2 .summary-value{
color:var(--av-fg) !important; font:700 19px/1 "Ubuntu Mono",monospace; margin-top:6px;
font-variant-numeric:tabular-nums;
}
/* health / icon boxes */
body.admin-page-v2 .health-box,
body.admin-page-v2 .icon-box{
background:var(--av-raised) !important; border:1px solid var(--av-line) !important;
border-radius:10px;
}
body.admin-page-v2 .service-thumb,
body.admin-page-v2 .service-icon-preview{
background:var(--av-panel) !important; border:1px solid var(--av-line-soft) !important;
border-radius:9px;
}
body.admin-page-v2 .status-ok{ background:var(--av-good) !important; }
body.admin-page-v2 .status-degraded{ background:var(--av-warn) !important; }
body.admin-page-v2 .status-down{ background:var(--av-bad) !important; }
/* categories tab rows */
body.admin-page-v2 .category-item-row small{ color:var(--av-fg-faint); }
body.admin-page-v2 .category-item-row button{
background:transparent; border:1px solid var(--av-bad); color:var(--av-bad);
font-weight:600; padding:6px 12px;
}
body.admin-page-v2 .category-item-row button:hover{ background:rgba(255,107,107,.12); }
body.admin-page-v2 .muted{ color:var(--av-fg-faint) !important; }
body.admin-page-v2 hr{ border:none; border-top:1px solid var(--av-line); margin:1.2rem 0; }
</style>
</head>
<body>
<body class="admin-page-v2">
<header class="header">
<div style="display:flex; align-items:center; gap:0.6rem;">
<a href="https://4mont.ru"><img src="/static/logo.png?v=4" alt="MONT" class="header-logo" /></a>