Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/apps/profiles/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

from api.serializers.profiles import UserSerializer, OrganizationDetailSerializer, OrganizationEditSerializer, \
UserNotificationSerializer
from api.serializers.competitions import CompetitionSerializerSimple
from .forms import SignUpForm, LoginForm, ActivationForm
from .models import User, DeletedUser, Organization, Membership
from oidc_configurations.models import Auth_Organization
Expand Down Expand Up @@ -67,7 +68,19 @@ class UserDetailView(LoginRequiredMixin, DetailView):

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['serialized_user'] = json.dumps(UserSerializer(self.get_object()).data)
user = self.get_object()
user_data = UserSerializer(user).data
# Fetch competitions organized by this user
organized_qs = (
Competition.objects
.filter(created_by=user, published=True)
.order_by("-created_when")
)
# Serialize into the same shape your public-list cards expect
user_data["competitions_organized"] = CompetitionSerializerSimple(
organized_qs, many=True, context={"request": self.request}
).data
context["serialized_user"] = json.dumps(user_data).replace("</", "<\\/")
return context


Expand Down
1 change: 0 additions & 1 deletion src/static/riot/competitions/public-list.tag
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@
self.update_competitions_list(1)
}


self.one("mount", function () {
const urlParams = new URLSearchParams(window.location.search)

Expand Down
2 changes: 1 addition & 1 deletion src/static/riot/profiles/organization_create.tag
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
</div>

<script>
self = this
var self = this
self.org_photo = null

self.one("mount", function () {
Expand Down
2 changes: 1 addition & 1 deletion src/static/riot/profiles/organization_edit.tag
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
</form>
</div>
<script>
self = this
var self = this
self.organization = organization
self.original_org_photo_name = typeof self.organization.photo !== 'undefined' ? null : self.organization.photo.replace(/\\/g, '/').replace(/.*\//, '')
self.original_org_photo = self.organization.photo
Expand Down
2 changes: 1 addition & 1 deletion src/static/riot/profiles/organization_invite.tag
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
</div>
</div>
<script>
self = this
var self = this
self.state = 'loading'
self.queryString = window.location.search
self.urlParams = new URLSearchParams(self.queryString)
Expand Down
2 changes: 1 addition & 1 deletion src/static/riot/profiles/profile_account.tag
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
</div>

<script>
self = this;
var self = this;
self.user = user;

self.isDeleteAccountSubmitButtonDisabled = true;
Expand Down
167 changes: 147 additions & 20 deletions src/static/riot/profiles/profile_detail.tag
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,64 @@
<!-- HTML -->
<div class="background">
<div id="profile_wrapper" class="ui two column doubling stackable grid container">

<!-- First Column -->
<div class="column">
<div if="{!selected_user.photo}"><img id="avatar" class="ui centered small rounded image" src="/static/img/user-avatar.png"></div>
<div if="{selected_user.photo}"><img id="avatar" class="ui centered small rounded image" src="{selected_user.photo}"></div>

<!-- Competition Divider -->
<div class="ui horizontal divider">Organizations</div>

<!-- Competition Cards -->
<div each="{org in selected_user.organizations}" class="ui fluid card">
<div class="comp_card center aligned image">
<div class="comp_header center aligned header content">
<div class="comp_name">{org.name}</div>
<img class="ui centered mini circular image"
src="{org.photo}">
<!-- Organizations -->
<div if="{selected_user.organizations && selected_user.organizations.length}">
<div class="ui horizontal divider">Organizations</div>

<div each="{org in selected_user.organizations}" class="ui fluid card">
<div class="comp_card center aligned image">
<div class="comp_header center aligned header content">
<div class="comp_name">{org.name}</div>
<img class="ui centered mini circular image"
src="{org.photo}">
</div>
</div>
</div>
<div class="content">
<div class="description">
<p>{ org.description.length > 225 ? org.description.substring(0, 222) + "..." : org.description}</p>
<div class="content">
<div class="description">
<p>{ org.description.length > 225 ? org.description.substring(0, 222) + "..." : org.description}</p>
</div>
</div>
<div class="right aligned extra content">
<a class="status" href="/profiles/organization/{org.id}/">
View Organization
<i class="angle right icon"></i>
</a>
</div>
</div>
<div class="right aligned extra content">
<a class="status" href="/profiles/organization/{org.id}/">
View Organization
<i class="angle right icon"></i>
</a>
</div>

<!-- Competitions Organized -->
<div if="{selected_user.competitions_organized && selected_user.competitions_organized.length}">
<div class="ui horizontal divider">Competitions Organized</div>

<div each="{competition in selected_user.competitions_organized}">
<!-- tile-wrapper from public-list.tag -->
<div class="tile-wrapper">
<div class="ui square tiny bordered image img-wrapper">
<img src="{competition.logo_icon ? competition.logo_icon : competition.logo}" loading="lazy">
</div>
<a class="link-no-deco" href="/competitions/{competition.id}">
<div class="comp-info">
<h4 class="heading">{competition.title}</h4>
<p class="comp-description">{ pretty_description(competition.description) }</p>
</div>
</a>
<div class="comp-stats">
{pretty_date(competition.created_when)}
<div if="{!competition.reward && ! competition.report}" class="ui divider"></div>
<div>
<span if="{competition.reward}"><img width="30" height="30" src="/static/img/trophy.png"></span>
<span if="{competition.report}"><a href="{competition.report}" target="_blank"><img width="30" height="30" src="/static/img/paper.png"></a></span>
</div>
<strong>{competition.participants_count}</strong> Participants
</div>
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -95,7 +127,6 @@
<!-- Empty About Message -->
<span if="{!selected_user.location && !selected_user.title}" class="text-placeholder">Update your profile to show your job title and location here.</span>



<!-- Section Bio -->
<div id="horiz-margin" class="ui horizontal divider">Bio</div>
Expand Down Expand Up @@ -156,8 +187,19 @@
</div>
</div>
</div>

<!-- Script -->
<script>
var self = this
self.selected_user = selected_user

self.pretty_date = function (date_string) {
return !!date_string ? luxon.DateTime.fromISO(date_string).toLocaleString(luxon.DateTime.DATE_FULL) : ''
}

self.pretty_description = function (description) {
return description.substring(0, 120) + (description.length > 120 ? '...' : '') || ''
}
</script>

<!-- CSS Styling -->
Expand Down Expand Up @@ -253,5 +295,90 @@
.value
font-size 15px
margin-left 10px

/* Competition cards (from public-list.tag) */
.link-no-deco
all unset
text-decoration none
cursor pointer
width 100%

.tile-wrapper
border solid 1px gainsboro
display inline-flex
background-color #fff
transition all 75ms ease-in-out
color #909090
width 100%
margin-bottom 6px

.tile-wrapper:hover
box-shadow 0 3px 4px -1px #cac9c9ff
transition all 75ms ease-in-out
background-color #e6edf2
border solid 1px #a5b7c5

.comp-stats
background-color #344d5e
transition background-color 75ms ease-in-out

.img-wrapper
padding 5px
align-self center

.img-wrapper img
max-height 60px !important
max-width 60px !important
margin 0 auto

.comp-info
flex 1
padding 0 10px

.comp-info .heading
text-align left
padding 5px
color #1b1b1b
margin-bottom 0

.comp-info .comp-description
text-align left
font-size 13px
line-height 1.15em
margin 0.35em

.organizer
font-size 13px
text-align left
margin 0.35em

.comp-stats
background #405e73
color #e8e8e8
padding 10px
text-align center
font-size 12px
width 140px

.loading-indicator
display flex
align-items center
padding 10px 0
width 100%
margin 0 auto

.spinner
border 4px solid rgba(0,0,0,.1)
width 28px
height 28px
border-radius 50%
border-top-color #3498db
animation spin 1s ease-in-out infinite

@keyframes spin
0%
transform rotate(0deg)
100%
transform rotate(360deg)
</style>
</profile-detail>
2 changes: 1 addition & 1 deletion src/static/riot/profiles/profile_edit.tag
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
</div>

<script>
self = this
var self = this
self.selected_user = selected_user
self.photo = self.selected_user.photo
delete self.selected_user.photo
Expand Down