Files
gitea/templates/shared/user/profile_big_avatar.tmpl
Nicolas 4ba90207cf Add user badges (#36752)
Implemented #29798

This feature implements list badges, create new badges, view badge, edit
badge and assign badge to users.

- List all badges
![(screenshot)](https://github.com/user-attachments/assets/9dbf243e-c704-49f8-915a-73704e226da9)
- Create new badges
![(screenshot)](https://github.com/user-attachments/assets/8a3fff7e-fe6f-49b0-a7c5-bbba34478019)
- View badge
![(screenshot)](https://github.com/user-attachments/assets/dd7a882b-6e2c-47d2-93e0-05a2698a41e5)
![(screenshot)](https://private-user-images.githubusercontent.com/75789103/558982759-53536300-e189-406b-8b0e-824e1a768b92.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzQxOTMyMjUsIm5iZiI6MTc3NDE5MjkyNSwicGF0aCI6Ii83NTc4OTEwMy81NTg5ODI3NTktNTM1MzYzMDAtZTE4OS00MDZiLThiMGUtODI0ZTFhNzY4YjkyLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMjIlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzIyVDE1MjIwNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTUxNjQ5ZDUyMGVlNWRmODg1OGUyN2NiOWI3YTAxODhiMjRhM2U1OGQ1NWMwNjQ0MTBmNTRjNTBjYjIzN2ExMWEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.4aAfpFaziiXDG7W2HaNJop0B62-NR4f0Ni9YNjTZq0M)
- Edit badge
![(screenshot)](https://github.com/user-attachments/assets/7124671a-ed97-4c98-ac7d-34863377fa62)
- Add user to badge
![(screenshot)](https://github.com/user-attachments/assets/3438b492-0197-4acb-b9f2-2f9f7c80582e)
2026-03-22 15:49:45 +00:00

143 lines
5.8 KiB
Handlebars

<div id="profile-avatar-card" class="ui card">
<div id="profile-avatar" class="content tw-flex">
{{if eq .SignedUserID .ContextUser.ID}}
<a class="image" href="{{AppSubUrl}}/user/settings" data-tooltip-content="{{ctx.Locale.Tr "user.change_avatar"}}">
{{/* the size doesn't take affect (and no need to take affect), image size(width) should be controlled by the parent container since this is not a flex layout*/}}
{{ctx.AvatarUtils.Avatar .ContextUser 256}}
</a>
{{else}}
<span class="image">
{{ctx.AvatarUtils.Avatar .ContextUser 256}}
</span>
{{end}}
</div>
<div class="content tw-break-anywhere profile-avatar-name">
{{if .ContextUser.FullName}}<span class="header text center">{{.ContextUser.FullName}}</span>{{end}}
<span class="username text center">{{.ContextUser.Name}} {{if .IsAdmin}}
<a class="muted" href="{{AppSubUrl}}/-/admin/users/{{.ContextUser.ID}}" data-tooltip-content="{{ctx.Locale.Tr "admin.users.details"}}">
{{svg "octicon-gear" 18}}
</a>
{{end}}</span>
<div class="tw-mt-2">
<a class="muted" href="{{.ContextUser.HomeLink}}?tab=followers">{{svg "octicon-person" 18 "tw-mr-1"}}{{.NumFollowers}} {{ctx.Locale.Tr "user.followers"}}</a> · <a class="muted" href="{{.ContextUser.HomeLink}}?tab=following">{{.NumFollowing}} {{ctx.Locale.Tr "user.following"}}</a>
{{if .EnableFeed}}
<a href="{{.ContextUser.HomeLink}}.rss"><i class="ui tw-text-text-light tw-ml-2" data-tooltip-content="{{ctx.Locale.Tr "rss_feed"}}">{{svg "octicon-rss" 18}}</i></a>
{{end}}
</div>
</div>
<div class="extra content tw-break-anywhere">
<ul>
{{if .UserBlocking}}
<li class="tw-text-red">{{svg "octicon-circle-slash"}} {{ctx.Locale.Tr "user.block.blocked"}}</li>
{{if .UserBlocking.Note}}
<li class="tw-text-xs tw-text-red">{{ctx.Locale.Tr "user.block.note"}}: {{.UserBlocking.Note}}</li>
{{end}}
{{end}}
{{if .ContextUser.Location}}
<li>
{{svg "octicon-location"}}
<span class="tw-flex-1">{{.ContextUser.Location}}</span>
{{if .ContextUserLocationMapURL}}
<a href="{{.ContextUserLocationMapURL}}" data-tooltip-content="{{ctx.Locale.Tr "user.show_on_map"}}">
{{svg "octicon-link-external"}}
</a>
{{end}}
</li>
{{end}}
{{if (eq .SignedUserID .ContextUser.ID)}}
<li>
{{svg "octicon-mail"}}
<a class="tw-flex-1" href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
<a class="flex-text-inline" href="{{AppSubUrl}}/user/settings#privacy-user-settings" data-tooltip-content="{{ctx.Locale.Tr (Iif .ShowUserEmail "user.email_visibility.limited" "user.email_visibility.private")}}">
{{svg (Iif .ShowUserEmail "octicon-unlock" "octicon-lock")}}
</a>
</li>
{{else}}
{{if .ShowUserEmail}}
<li>
{{svg "octicon-mail"}}
<a href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
</li>
{{end}}
{{end}}
{{if .ContextUser.Website}}
<li>
{{svg "octicon-link"}}
<a target="_blank" rel="me" href="{{.ContextUser.Website}}">{{.ContextUser.Website}}</a>
</li>
{{end}}
{{if $.RenderedDescription}}
<li>
<div class="render-content markup">{{$.RenderedDescription}}</div>
</li>
{{end}}
{{range .OpenIDs}}
{{if .Show}}
<li>
{{svg "fontawesome-openid"}}
<a target="_blank" href="{{.URI}}">{{.URI}}</a>
</li>
{{end}}
{{end}}
<li>{{svg "octicon-calendar"}} <span>{{ctx.Locale.Tr "user.joined_on" (DateUtils.AbsoluteShort .ContextUser.CreatedUnix)}}</span></li>
{{if and .Orgs .HasOrgsVisible}}
<li>
<ul class="user-orgs">
{{range .Orgs}}
{{if (or .Visibility.IsPublic (and ($.SignedUser) (or .Visibility.IsLimited (and (.HasMemberWithUserID ctx $.SignedUserID) .Visibility.IsPrivate) ($.IsAdmin))))}}
<li>
<a href="{{.HomeLink}}" data-tooltip-content="{{.Name}}">
{{ctx.AvatarUtils.Avatar .}}
</a>
</li>
{{end}}
{{end}}
{{if .ShowMoreOrgs}}
<li><a class="tw-align-center" href="{{.ContextUser.HomeLink}}?tab=organizations" data-tooltip-content="{{ctx.Locale.Tr "user.show_more"}}">{{svg "octicon-kebab-horizontal" 28 "icon tw-p-1"}}</a></li>
{{end}}
</ul>
</li>
{{end}}
{{if .Badges}}
<li>
<div class="user-badges">
{{range .Badges}}
<span class="user-badge-item">
{{if .ImageURL}}
<img loading="lazy" width="64" height="64" src="{{.ImageURL}}" alt="{{.Description}}" data-tooltip-content="{{.Description}}">
{{else}}
<span class="ui label user-badge-chip" data-tooltip-content="{{if .Description}}{{.Description}}{{else}}{{.Slug}}{{end}}">{{.Slug}}</span>
{{end}}
</span>
{{end}}
</div>
</li>
{{end}}
{{if and .IsSigned (ne .SignedUserID .ContextUser.ID)}}
{{if not .UserBlocking}}
<li class="follow" hx-target="#profile-avatar-card" hx-indicator="#profile-avatar-card">
{{if $.IsFollowing}}
<button hx-post="{{.ContextUser.HomeLink}}?action=unfollow" class="ui basic red button">
{{svg "octicon-person"}} {{ctx.Locale.Tr "user.unfollow"}}
</button>
{{else}}
<button hx-post="{{.ContextUser.HomeLink}}?action=follow" class="ui basic primary button">
{{svg "octicon-person"}} {{ctx.Locale.Tr "user.follow"}}
</button>
{{end}}
</li>
{{end}}
<li>
{{if not .UserBlocking}}
<a class="muted show-modal" href="#" data-modal="#block-user-modal" data-modal-modal-blockee="{{.ContextUser.Name}}" data-modal-modal-blockee-name="{{.ContextUser.GetDisplayName}}" data-modal-modal-form.action="{{AppSubUrl}}/user/settings/blocked_users">{{ctx.Locale.Tr "user.block.block.user"}}</a>
{{else}}
<a class="muted" href="{{AppSubUrl}}/user/settings/blocked_users">{{ctx.Locale.Tr "user.block.unblock"}}</a>
{{end}}
</li>
{{end}}
</ul>
</div>
</div>
{{template "shared/user/block_user_dialog" .}}