From de278227ac1ff75c013ec1ec14f1cc8f35aae0a1 Mon Sep 17 00:00:00 2001 From: ruslan Date: Fri, 15 May 2026 21:30:03 +0300 Subject: [PATCH] Store picker in topbar, redesign cabinet, rename to WBfeed.ru MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - index.html: store dropdown in topbar (switch without leaving page) - cabinet.html: store-cards with Активировать/Проверить, edit hidden in
- Removed 'Используется' button, active shown as green card + label - next=index param to return to main page after store switch - Brand name changed to WBfeed.ru across all templates Co-Authored-By: Claude Sonnet 4.6 --- app.py | 7 ++ static/styles.css | 143 +++++++++++++++++++++++++++++++++++++++++ templates/admin.html | 2 +- templates/cabinet.html | 72 ++++++++++++--------- templates/index.html | 33 +++++++++- 5 files changed, 221 insertions(+), 36 deletions(-) diff --git a/app.py b/app.py index ee52e02..e625e39 100644 --- a/app.py +++ b/app.py @@ -1202,6 +1202,8 @@ def cabinet(): token_row = db.get_token(int(token_id)) if token_row and (user["is_admin"] or token_row["user_id"] == user["id"]): session["token_id"] = int(token_id) + if request.form.get("next") == "index": + return redirect(url_for("index")) return redirect(url_for("cabinet", status="selected")) error_message = "Не удалось выбрать токен." elif action == "check": @@ -1243,6 +1245,9 @@ def index(): status = request.args.get("status") api_cooldown_seconds_left = _get_api_cooldown_seconds_left() _, active_token_name = _get_active_token() + active_token_id = session.get("token_id") + raw_tokens = db.fetch_tokens_for_user(g.user["id"], bool(g.user["is_admin"])) + tokens = [{"id": r["id"], "name": r["name"]} for r in raw_tokens] error_message: Optional[str] = None success_message: Optional[str] = None if status == "reply_sent": @@ -1261,6 +1266,8 @@ def index(): error_message=error_message, success_message=success_message, active_token_name=active_token_name, + active_token_id=active_token_id, + tokens=tokens, auto_reply_enabled=is_auto_reply_enabled(), api_cooldown_seconds_left=api_cooldown_seconds_left, next_fetch_seconds_left=_next_fetch_seconds_left(), diff --git a/static/styles.css b/static/styles.css index 223bd53..6ed5f1a 100644 --- a/static/styles.css +++ b/static/styles.css @@ -1847,3 +1847,146 @@ fieldset:disabled .filter-pill { pointer-events: none; opacity: 0.5; } font-weight: 700; margin-right: 6px; } + +/* ── Store picker (topbar dropdown) ─────────────────────── */ +.store-picker { + position: relative; +} +.store-picker__btn { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 6px 12px; + border-radius: var(--r-sm); + background: var(--line); + border: 1.5px solid var(--line-strong); + color: var(--text); + font-size: 13px; + font-weight: 500; + cursor: pointer; + box-shadow: none; + transition: background var(--t); + white-space: nowrap; + max-width: 180px; + overflow: hidden; + text-overflow: ellipsis; +} +.store-picker__btn:hover { background: var(--line-strong); filter: none; transform: none; box-shadow: none; } +.store-picker__dropdown { + display: none; + position: absolute; + top: calc(100% + 6px); + right: 0; + min-width: 200px; + background: #fff; + border: 1.5px solid var(--line); + border-radius: var(--r); + box-shadow: var(--shadow-md); + z-index: 300; + overflow: hidden; + padding: 6px; +} +.store-picker.open .store-picker__dropdown { display: block; } +.store-picker__item { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + width: 100%; + padding: 9px 12px; + border-radius: var(--r-sm); + font-size: 13px; + font-weight: 500; + color: var(--text); + background: transparent; + border: none; + cursor: pointer; + text-decoration: none; + box-shadow: none; + transition: background var(--t); + text-align: left; +} +.store-picker__item:hover { background: var(--line); filter: none; transform: none; box-shadow: none; } +.store-picker__item--active { color: var(--green); font-weight: 600; } +.store-picker__sep { height: 1px; background: var(--line); margin: 4px 0; } + +/* ── Store cards (cabinet) ───────────────────────────────── */ +.store-list { + display: flex; + flex-direction: column; + gap: 12px; +} +.store-card { + border: 2px solid var(--line); + border-radius: var(--r); + padding: 18px 20px; + background: var(--card); + transition: border-color var(--t); +} +.store-card--active { + border-color: var(--green-line); + background: var(--green-bg); +} +.store-card__header { + display: flex; + align-items: center; + gap: 14px; +} +.store-card__icon { + width: 42px; + height: 42px; + border-radius: var(--r-sm); + background: var(--line); + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + color: var(--muted); +} +.store-card--active .store-card__icon { + background: var(--green-line); + color: var(--green); +} +.store-card__info { flex: 1; min-width: 0; } +.store-card__name { + font-size: 15px; + font-weight: 600; + color: var(--text); +} +.store-card__active-label { + font-size: 12px; + font-weight: 600; + color: var(--green); + margin-top: 2px; + display: block; +} +.store-card__actions { + display: flex; + gap: 8px; + flex-shrink: 0; +} +.btn-activate { + background: linear-gradient(180deg, #22C55E 0%, #16A34A 100%); + color: #fff; + padding: 8px 16px; + font-size: 13px; + box-shadow: 0 2px 8px rgba(34,197,94,0.3); +} +.btn-activate:hover { opacity: 0.88; box-shadow: 0 4px 12px rgba(34,197,94,0.4); filter: none; } +.store-card__edit { + margin-top: 14px; + padding-top: 14px; + border-top: 1px solid var(--line); +} +.store-card__edit summary { + font-size: 13px; + color: var(--muted); + cursor: pointer; + user-select: none; + list-style: none; +} +.store-card__edit summary:hover { color: var(--text); } +.store-card__edit summary::marker, +.store-card__edit summary::-webkit-details-marker { display: none; } +.store-card__edit summary::before { content: '▸ '; font-size: 11px; } +.store-card__edit[open] summary::before { content: '▾ '; } diff --git a/templates/admin.html b/templates/admin.html index 2189930..34e4962 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -12,7 +12,7 @@
WB - Feedback + WBfeed.ru
Отзывы diff --git a/templates/cabinet.html b/templates/cabinet.html index c813023..2dcdaeb 100644 --- a/templates/cabinet.html +++ b/templates/cabinet.html @@ -12,7 +12,7 @@
WB - Feedback + WBfeed.ru
Отзывы @@ -51,54 +51,62 @@
{% if tokens %} -
    +
    {% for token in tokens %} -
  • -
    -
    +
    +
    +
    + +
    +
    +
    {{ token.name }} {% if current_user["is_admin"] and token.owner %} ({{ token.owner }}) {% endif %} - {% if token.id == active_token_id %} - Активен - {% endif %}
    - -
    - - - - -
    - -
    -
    + {% if token.id == active_token_id %} + ● Активен + {% endif %}
    - -
    +
    + {% if token.id != active_token_id %}
    - +
    + {% endif %}
    - +
    -
  • +
    + + +
    + Изменить данные +
    + + + + +
    + +
    +
    +
    +
{% endfor %} - +
{% else %}
Пока нет сохранённых магазинов.
{% endif %} diff --git a/templates/index.html b/templates/index.html index ac1441b..a091fe8 100644 --- a/templates/index.html +++ b/templates/index.html @@ -12,7 +12,7 @@
WB - Feedback + WBfeed.ru
Отзывы @@ -23,8 +23,29 @@
{{ current_user["username"] }} - {% if active_token_name %} - {{ active_token_name }} + {% if tokens %} +
+ +
+ {% for t in tokens %} +
+ + + + +
+ {% endfor %} +
+ Управление магазинами → +
+
{% endif %} Выйти
@@ -399,6 +420,12 @@ initPools(); poll(); setInterval(poll, 10000); })(); +// ── Store picker close on outside click ─────────────────── +document.addEventListener('click', e => { + if (!e.target.closest('.store-picker')) { + document.querySelectorAll('.store-picker.open').forEach(el => el.classList.remove('open')); + } +});