This commit is contained in:
Vicente Ferrari Smith 2026-05-15 20:19:32 +02:00
parent 529bb6336e
commit 4855255373
4 changed files with 69 additions and 18 deletions

View File

@ -8,6 +8,11 @@ import (
) )
func (api *Api) Vote(w http.ResponseWriter, r *http.Request) { func (api *Api) Vote(w http.ResponseWriter, r *http.Request) {
if authHeader := r.Header.Get("Authorization"); authHeader != "" {
api.errorResponse(w, r, data.ErrAuthenticatedVoteRejected)
return
}
var input struct { var input struct {
IssueID int64 `json:"issue_id"` IssueID int64 `json:"issue_id"`
OptionID int64 `json:"option_id"` OptionID int64 `json:"option_id"`

View File

@ -78,6 +78,7 @@ var (
// 403 Forbidden // 403 Forbidden
ErrInactiveAccount = New(403, errCodeInactiveAccount, "your user account must be activated to access this resource") ErrInactiveAccount = New(403, errCodeInactiveAccount, "your user account must be activated to access this resource")
ErrNotPermitted = New(403, errCodeNotPermitted, "your user account doesn't have the necessary permissions to access this resource") ErrNotPermitted = New(403, errCodeNotPermitted, "your user account doesn't have the necessary permissions to access this resource")
ErrAuthenticatedVoteRejected = New(403, errCodeNotPermitted, "authenticated vote rejected")
// 404 Not Found // 404 Not Found
ErrRecordNotFound = New(404, 404, "record not found") ErrRecordNotFound = New(404, 404, "record not found")

View File

@ -3,25 +3,59 @@
{{define "title"}}Mein Profil{{end}} {{define "title"}}Mein Profil{{end}}
{{define "body"}} {{define "body"}}
<div class="page-header"> <div style="display:flex; flex-direction:column; align-items:center; padding-top:32px;">
<h1 class="page-title">Mein Profil</h1>
</div>
<div class="card" style="max-width:520px;"> <div style="width:88px; height:88px; border-radius:50%; background:var(--accent); display:flex; align-items:center; justify-content:center; font-family:'Montserrat',sans-serif; font-size:34px; font-weight:700; color:#1a1008; box-shadow:0 4px 18px rgba(200,150,26,0.35); margin-bottom:20px; flex-shrink:0;">
<div class="card-title">{{.User.Name}}{{if .User.AltName}} / {{.User.AltName}}{{end}}</div> {{slice .User.Name 0 1}}
<div style="margin-top:12px; display:flex; flex-direction:column; gap:8px; font-size:15px;">
<div><span style="color:var(--text-muted);">E-Mail</span> &nbsp; {{.User.Email}}</div>
<div><span style="color:var(--text-muted);">Telefon</span> &nbsp; {{.User.PhoneNumber}}</div>
<div><span style="color:var(--text-muted);">Land</span> &nbsp; {{.User.Country}}</div>
<div><span style="color:var(--text-muted);">Adresse</span> &nbsp; {{.User.Address}}</div>
<div><span style="color:var(--text-muted);">Geburtsdatum</span> &nbsp; {{.User.DateOfBirth.Format "02.01.2006"}}</div>
<div><span style="color:var(--text-muted);">Mitglied seit</span> &nbsp; {{.User.Created.Format "02.01.2006"}}</div>
</div> </div>
<div style="margin-top:20px; border-top:1px solid var(--border); padding-top:16px;"> <h1 style="font-family:'Montserrat',sans-serif; font-size:28px; font-weight:700; color:var(--dark); text-align:center; margin-bottom:4px;">
{{.User.Name}}{{if .User.AltName}} <span style="color:var(--text-muted); font-weight:600;">/ {{.User.AltName}}</span>{{end}}
</h1>
<p style="font-size:13px; font-weight:600; letter-spacing:0.09em; text-transform:uppercase; color:var(--accent); margin-bottom:36px;">Mitglied</p>
<div style="background:var(--bg-card); border:1px solid var(--border); border-radius:12px; box-shadow:0 6px 32px rgba(0,0,0,0.10); width:100%; max-width:620px; overflow:hidden;">
<div style="background:var(--dark); padding:16px 32px; border-bottom:3px solid var(--accent);">
<span style="font-family:'Montserrat',sans-serif; font-size:12px; font-weight:700; letter-spacing:0.1em; text-transform:uppercase; color:rgba(255,255,255,0.5);">Profildaten</span>
</div>
<div style="padding:0 32px;">
<div style="display:flex; align-items:baseline; gap:16px; padding:18px 0; border-bottom:1px solid var(--border);">
<span style="font-size:13px; font-weight:600; color:var(--text-muted); text-transform:uppercase; letter-spacing:0.06em; width:140px; flex-shrink:0;">E-Mail</span>
<span style="font-size:16px; color:var(--text);">{{.User.Email}}</span>
</div>
<div style="display:flex; align-items:baseline; gap:16px; padding:18px 0; border-bottom:1px solid var(--border);">
<span style="font-size:13px; font-weight:600; color:var(--text-muted); text-transform:uppercase; letter-spacing:0.06em; width:140px; flex-shrink:0;">Telefon</span>
<span style="font-size:16px; color:var(--text);">{{.User.PhoneNumber}}</span>
</div>
<div style="display:flex; align-items:baseline; gap:16px; padding:18px 0; border-bottom:1px solid var(--border);">
<span style="font-size:13px; font-weight:600; color:var(--text-muted); text-transform:uppercase; letter-spacing:0.06em; width:140px; flex-shrink:0;">Land</span>
<span style="font-size:16px; color:var(--text);">{{.User.Country}}</span>
</div>
<div style="display:flex; align-items:baseline; gap:16px; padding:18px 0; border-bottom:1px solid var(--border);">
<span style="font-size:13px; font-weight:600; color:var(--text-muted); text-transform:uppercase; letter-spacing:0.06em; width:140px; flex-shrink:0;">Adresse</span>
<span style="font-size:16px; color:var(--text);">{{.User.Address}}</span>
</div>
<div style="display:flex; align-items:baseline; gap:16px; padding:18px 0; border-bottom:1px solid var(--border);">
<span style="font-size:13px; font-weight:600; color:var(--text-muted); text-transform:uppercase; letter-spacing:0.06em; width:140px; flex-shrink:0;">Geburtsdatum</span>
<span style="font-size:16px; color:var(--text);">{{.User.DateOfBirth.Format "02.01.2006"}}</span>
</div>
<div style="display:flex; align-items:baseline; gap:16px; padding:18px 0;">
<span style="font-size:13px; font-weight:600; color:var(--text-muted); text-transform:uppercase; letter-spacing:0.06em; width:140px; flex-shrink:0;">Mitglied seit</span>
<span style="font-size:16px; color:var(--accent); font-weight:600;">{{.User.Created.Format "02.01.2006"}}</span>
</div>
</div>
<div style="border-top:1px solid var(--border); background:#fef2f2; padding:20px 32px; display:flex; align-items:center; justify-content:space-between;">
<div>
<div style="font-size:13px; font-weight:700; color:#991b1b; text-transform:uppercase; letter-spacing:0.06em; margin-bottom:2px;">Gefahrenzone</div>
<div style="font-size:13px; color:#b91c1c;">Diese Aktion kann nicht rückgängig gemacht werden.</div>
</div>
<button class="btn btn--danger" <button class="btn btn--danger"
hx-delete="/users/{{.User.ID}}" hx-delete="/users/{{.User.ID}}"
hx-confirm="Konto wirklich unwiderruflich löschen?">Konto löschen</button> hx-confirm="Konto wirklich unwiderruflich löschen?">Konto löschen</button>
</div> </div>
</div>
</div> </div>
{{end}} {{end}}

View File

@ -373,6 +373,17 @@ a:hover {
color: var(--text); color: var(--text);
} }
.btn--danger {
background: #dc2626;
color: #fff;
}
.btn--danger:hover {
background: #b91c1c;
color: #fff;
box-shadow: 0 2px 8px rgba(220,38,38,0.3);
}
.btn--full { .btn--full {
width: 100%; width: 100%;
margin-top: 4px; margin-top: 4px;