web: account avatars, member /profile, framed admin panel

- an account can carry a picture: POST /api/auth/avatar (raw bytes,
  sniffed, replaces and unlinks the old file) and the public
  GET /api/users/:id/avatar. It rides wherever the account is named —
  the landing chip, the studio TopBar, the profile form.
- new /profile page for members, sharing one Profile form (picture,
  email, password) with the admin drawer.
- /admin is now one bordered frame whose left column is
  Profile / User account / Pictures / Close. Pictures lists every
  photo in the system with the slot that shows it; User account lists
  each account's name, email, picture and contribution count.
- account control opens a menu: Admin page + Log out for an admin,
  Profile + Log out for a member.
This commit is contained in:
2026-09-18 08:19:36 +07:00
parent 2917c034ed
commit 6bbf77860b
15 changed files with 908 additions and 79 deletions
+17 -1
View File
@@ -142,10 +142,26 @@ html { scroll-behavior: smooth; scroll-padding-top: 78px; }
.lp-theme-pop .chip { background: transparent; border-color: var(--lp-line); color: var(--lp-muted); }
.lp-theme-pop .chip:hover { color: var(--lp-text); }
.lp-theme-pop .chip.on { color: var(--lp-ink-amber); border-color: var(--lp-ink-amber); background: rgba(251, 191, 36, 0.12); }
/* The account chip: a face + a name, opening the two things that account can
do — its page (Admin / Profile) and log out. */
.lp-account { display: inline-flex; align-items: center; gap: 7px; }
.lp-account .avatar { border-color: var(--lp-line); background: rgba(255, 255, 255, 0.06); color: var(--lp-muted); }
.lp-acc-pop .hint { color: var(--lp-muted); }
.lp-acc-pop .btn {
display: block;
width: 100%;
margin-top: 6px;
text-align: left;
background: transparent;
border-color: var(--lp-line);
color: var(--lp-muted);
text-decoration: none;
}
.lp-acc-pop .btn:hover { color: var(--lp-text); border-color: rgba(251, 191, 36, 0.5); }
.lp-burger { display: none; }
@media (max-width: 1160px) {
.lp-nav-links, .lp-nav .lp-wrap > .lp-btn { display: none; }
.lp-nav-links, .lp-nav .lp-wrap > .lp-btn, .lp-nav .lp-account { display: none; }
.lp-burger {
display: inline-flex;
flex-direction: column;