Dildo items, admin fixes, UI refactor

- Add 85 custom Dildo items (knife/skin pattern names, various rarities)
- Create Dildo Case config (hidden, items obtained via contracts)
- Fix admin user_detail.html nested script tag (Notify fallback removed)
- Fix admin cases.html embedded script tag
- Add notifications.js to admin base.html
- Fix admin users.html: use counts instead of relationship lists
- Replace old money format with |money filter across all templates
- Standardize nav partial (_nav.html) with active_page highlighting
- Fix RARITY_COLORS rename in activity sidebar
- Fix toast animation (forwards) and remove duplicate CSS
- Replace showToast() with Notify.* in upgrade page
- Add cs2_simulator.db and *.log to .gitignore
- Create remote-deploy.sh with DB exclusion
This commit is contained in:
root
2026-07-05 16:15:12 +00:00
parent 50535ec777
commit 3fe8a47e04
25 changed files with 2669 additions and 390 deletions
+69 -12
View File
@@ -58,6 +58,14 @@ app.include_router(admin_router)
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")
def money_filter(value):
try:
return "{:,.0f}".format(float(value)).replace(",", " ")
except (ValueError, TypeError):
return "0"
templates.env.filters["money"] = money_filter
# Создаем отдельный роутер для API оригинального симулятора
from backend import app as api_app
@@ -301,7 +309,8 @@ async def index(request: Request, user: Optional[User] = Depends(get_current_use
return templates.TemplateResponse("index.html", {
"request": request,
"user": None
"user": None,
"active_page": "home"
})
@app.get("/login", response_class=HTMLResponse)
@@ -312,7 +321,8 @@ async def login_page(request: Request, user: Optional[User] = Depends(get_curren
return templates.TemplateResponse("login.html", {
"request": request,
"user": None
"user": None,
"active_page": "login"
})
@app.get("/register", response_class=HTMLResponse)
@@ -323,7 +333,8 @@ async def register_page(request: Request, user: Optional[User] = Depends(get_cur
return templates.TemplateResponse("register.html", {
"request": request,
"user": None
"user": None,
"active_page": "register"
})
@app.get("/profile", response_class=HTMLResponse)
@@ -403,7 +414,8 @@ async def profile_page(
"types": sorted(types),
"rarity_order": RARITY_ORDER,
"is_public": False,
"profile_user": user
"profile_user": user,
"active_page": "profile"
})
# ═══════════════════════════════════════════════════════════════════════════════
@@ -436,9 +448,42 @@ async def public_profile_page(
inventory_items = db.query(InventoryItem).filter(
InventoryItem.user_id == profile_user.id
).all()
).order_by(desc(InventoryItem.obtained_at)).all()
rarity_order = {k: v for k, v in RARITY_ORDER.items()}
rarities = set()
types = set()
enriched_items = []
for item in inventory_items:
item_data = None
for idx, it in enumerate(ALL_ITEMS):
if it.get("_id", idx) == item.item_id:
item_data = it
break
if not item_data:
item_data = get_item(item.item_id)
image_url = ""
price_rub = 100
if item_data:
image_url = item_data.get("image_url", "")
price_rub = item_data.get("price_rub", 100)
enriched_items.append({
"id": item.id,
"item_id": item.item_id,
"name": item.market_hash_name,
"rarity": item.rarity,
"wear": item.wear,
"float": item.float_value,
"type": item.type,
"image_url": image_url,
"price_rub": price_rub
})
if item.rarity:
rarities.add(item.rarity)
if item.type:
types.add(item.type)
valuable_items = sorted(
inventory_items,
key=lambda x: rarity_order.get(x.rarity, 0),
@@ -455,7 +500,12 @@ async def public_profile_page(
"contracts_completed": contracts_completed,
"recent_openings": recent_openings,
"recent_contracts": recent_contracts,
"valuable_items": valuable_items
"valuable_items": valuable_items,
"inventory_items": enriched_items,
"rarities": sorted(rarities),
"types": sorted(types),
"rarity_order": RARITY_ORDER,
"active_page": "profile"
})
@@ -539,7 +589,8 @@ async def cases_page(
return templates.TemplateResponse("cases.html", {
"request": request,
"user": user,
"sections": sections
"sections": sections,
"active_page": "cases"
})
@@ -598,7 +649,8 @@ async def contracts_page(
"user": user,
"inventory_items": all_items + knife_items,
"has_contract": has_contract or has_knife_contract,
"knife_count": len(knife_items)
"knife_count": len(knife_items),
"active_page": "contracts"
})
@app.get("/inventory")
@@ -1432,7 +1484,8 @@ async def case_detail_page(
"items_by_rarity": items_by_rarity,
"sorted_rarities": sorted_rarities,
"rarities_count": rarities_count,
"case_items": case_items_json
"case_items": case_items_json,
"active_page": "cases"
})
@@ -2175,7 +2228,8 @@ async def upgrade_page(
"total_attempts": total_attempts,
"total_success": total_success,
"success_rate": round(success_rate, 1),
"recent_upgrades": recent_upgrades
"recent_upgrades": recent_upgrades,
"active_page": "upgrade"
})
@app.post("/web/api/upgrade/calculate")
@@ -2438,7 +2492,8 @@ async def achievements_page(
"user": user,
"achievements": achievements,
"total": total,
"unlocked": unlocked
"unlocked": unlocked,
"active_page": "achievements"
})
@@ -2479,7 +2534,8 @@ async def activity_page(
"created_at": a.created_at.isoformat()
}
for a in activities
]
],
"active_page": "activity"
})
@@ -2614,6 +2670,7 @@ async def crash_page(
return templates.TemplateResponse("crash.html", {
"request": request,
"user": user,
"active_page": "crash"
})