Skip to content

Commit ab80622

Browse files
committed
- Adding new brand icons
- Reduced scope of user subscription events - Transitioning towards hexagon progress bars for experience items instead
1 parent cec44ab commit ab80622

17 files changed

+1147
-48
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
subscription UserBanned {
2+
userBanned {
3+
userId,
4+
banReason,
5+
isBanned
6+
}
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
subscription UserDeleted {
2+
userDeleted {
3+
userId,
4+
username
5+
}
6+
}

SocialCoder.Web/Client/GraphQL/UserUpdatedSubscription.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
userId,
44
username,
55
email,
6-
userRoles
6+
roles
77
}
88
}

SocialCoder.Web/Client/Pages/Account/Profile.razor

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,22 +79,23 @@
7979
<MudGrid Spacing="3" Class="mt-3">
8080
@foreach (var current in UserExperiences.OrderByDescending(x=>x.Experience))
8181
{
82-
var backgroundColor = $"background-color: {Theme.PaletteDark.Primary}; width: 100%";
83-
var iconColor = $"color: {Theme.GetSigmaColor(current.Experience)}";
84-
82+
var image = ExperiencePool.FirstOrDefault(x => x.Name == current.Name);
8583
<MudItem md="4" Style="display: flex;">
86-
<MudCard Style="@backgroundColor">
87-
<MudCardHeader>
88-
@current.Name
89-
<MudSpacer/>
90-
<MudIcon Icon="@Icons.Material.TwoTone.School" Style="@iconColor"/>
91-
</MudCardHeader>
92-
<MudCardContent>
84+
<HexagonProgress
85+
ImageUrl="@(image?.ImageUrl ?? string.Empty)"
86+
BadgeColor="@Color.Secondary"
87+
BadgeLineColor="Color.Success"
88+
UserLevel="@((int)current.Experience)"
89+
ProgressMin="0"
90+
ProgressMax="10"
91+
Progress="@((int)current.Experience)"
92+
>
93+
<CenterContent>
9394
<MudStack>
94-
<MudText>@current.Experience.GetSigmaYears()</MudText>
95-
</MudStack>
96-
</MudCardContent>
97-
</MudCard>
95+
<MudIcon Icon="@Icons.Material.Filled.School"/>
96+
</MudStack>
97+
</CenterContent>
98+
</HexagonProgress>
9899
</MudItem>
99100
}
100101
</MudGrid>

SocialCoder.Web/Client/Pages/Admin/AdminUserManagement.razor

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,15 @@
5555
</MudStack>
5656
</MudTd>
5757
<MudTd>
58-
<MudButton StartIcon="@Icons.Material.Filled.TimeToLeave"
59-
IconColor="Color.Warning"
60-
OnClick="@(async () => await BanUser(user.Data))">
61-
Ban
62-
</MudButton>
58+
@if (UserId != user.Data.UserId)
59+
{
60+
<MudButton StartIcon="@Icons.Material.Filled.TimeToLeave"
61+
IconColor="Color.Warning"
62+
OnClick="@(async () => await BanUser(user.Data))">
63+
Ban
64+
</MudButton>
65+
}
66+
6367
<MudButton StartIcon="@Icons.Material.TwoTone.Delete"
6468
IconColor="Color.Error"
6569
OnClick="@(() => Snack.Add("Not implement yet", Severity.Info))">

SocialCoder.Web/Client/Pages/Admin/AdminUserManagement.razor.cs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,38 @@ protected override async Task OnInitializedAsync()
111111
Cursor = x.Cursor
112112
}).ToList();
113113

114+
115+
this._onUserBannedSubscription = this.GraphQlClient.UserBanned.Watch().Subscribe(res =>
116+
{
117+
if (res.Data is not null)
118+
{
119+
var localUser = this._users.FirstOrDefault(x => x.Data.UserId == res.Data.UserBanned.UserId);
120+
121+
if (localUser is not null)
122+
{
123+
localUser.Data.IsBanned = res.Data.UserBanned.IsBanned;
124+
localUser.Data.BanReason = res.Data.UserBanned.BanReason;
125+
}
126+
}
127+
});
128+
129+
this._onUserDeletedSubscription = this.GraphQlClient.UserDeleted.Watch().Subscribe(res =>
130+
{
131+
if (res.Data is not null)
132+
{
133+
var localUser = this._users.FirstOrDefault(x => x.Data.UserId == res.Data.UserDeleted.UserId);
134+
135+
if (localUser is null)
136+
{
137+
return;
138+
}
139+
140+
this._users.RemoveAt(this._users.IndexOf(localUser));
141+
this.StateHasChanged();
142+
}
143+
});
144+
145+
// As users get updated, we'll update the local list of users
114146
this._onUserUpdatedSubscription = this.GraphQlClient.UserUpdated.Watch().Subscribe(res =>
115147
{
116148
if (res.Data is not null)
@@ -120,11 +152,11 @@ protected override async Task OnInitializedAsync()
120152

121153
if (localUser is not null)
122154
{
123-
localUser.Data.Roles = updatedUser.UserRoles.ToList();
155+
localUser.Data.Roles = updatedUser.Roles.ToList();
124156
}
125-
}
126157

127-
this.StateHasChanged();
158+
this.StateHasChanged();
159+
}
128160
});
129161
}
130162

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
@inject IJSRuntime JsRuntime
2+
3+
<div style="display: flex; justify-content: center;">
4+
<div style="display: inline">
5+
<div style="position: relative; max-width: @(Width)px">
6+
<div class="user-avatar-border">
7+
<div class="hexagon-progress" style="width: @(Width)px; height: @(Height)px; position: relative;"></div>
8+
</div>
9+
10+
<div class="user-avatar-content"
11+
style="position: absolute;
12+
top: @(Width * 0.16)px;
13+
left: @(Height * 0.17)px;">
14+
<div class="hexagon-image"
15+
style="width: @(Width * 0.683)px;
16+
height: @(Height * 0.683);
17+
position: relative;">
18+
@CenterContent
19+
</div>
20+
</div>
21+
22+
<div class="user-avatar-badge" style="display: flex;
23+
flex-wrap: wrap;
24+
align-items: center;
25+
justify-content: center;
26+
position: absolute;
27+
bottom: 25px;
28+
right: -3px;">
29+
30+
<div class="user-avatar-badge-border" style="
31+
display: inline-block;
32+
position: absolute;
33+
z-index: 1">
34+
<div class="hexagon-avatar-badge"
35+
style="width: 32px; height: 36px; position: absolute;"></div>
36+
</div>
37+
38+
<div class="user-avatar-badge-content"
39+
style="
40+
display: inline-block;
41+
z-index: 5;
42+
position: absolute;">
43+
<div class="hexagon-dark" style="width: 26px;
44+
height: 28px;
45+
position: relative;"></div>
46+
</div>
47+
<p class="user-avatar-badge-text" style="
48+
position: absolute;
49+
pointer-events: none;
50+
z-index: 6;
51+
display: inline-block;
52+
font-weight: 700;">
53+
@UserLevel
54+
</p>
55+
</div>
56+
</div>
57+
</div>
58+
</div>
59+
@code {
60+
61+
[Parameter]
62+
public string ImageUrl { get; set; } = string.Empty;
63+
64+
[Parameter]
65+
public int UserLevel { get; set; }
66+
67+
[Parameter]
68+
public int Progress { get; set; }
69+
70+
[Parameter]
71+
public int ProgressMin { get; set; } = 0;
72+
73+
[Parameter]
74+
public int ProgressMax { get; set; } = 100;
75+
76+
[Parameter]
77+
public int Width { get; set; } = 100;
78+
79+
[Parameter]
80+
public int Height { get; set; } = 100;
81+
82+
[Parameter]
83+
public int LineWidth { get; set; } = 8;
84+
85+
[Parameter]
86+
public Color ProgressColor { get; set; } = Color.Primary;
87+
88+
[Parameter]
89+
public RenderFragment? CenterContent { get; set; }
90+
91+
[Parameter]
92+
public Color BadgeLineColor { get; set; } = Color.Secondary;
93+
94+
[Parameter]
95+
public Color BadgeColor { get; set; } = Color.Tertiary;
96+
97+
readonly MudTheme _theme = new();
98+
99+
protected override async Task OnInitializedAsync()
100+
{
101+
await base.OnInitializedAsync();
102+
}
103+
104+
protected override async Task OnAfterRenderAsync(bool firstRender)
105+
{
106+
/*
107+
It is worth mentioning that
108+
109+
1. To have the line color appear -- you cannot use the gradient value
110+
2. To see the progress bar you cannot use the fill or clip value -- those are for images
111+
3. These methods are called AFTER render because we want to make sure our
112+
DOM elements are present before executing these scripts
113+
*/
114+
115+
await JsRuntime.InvokeVoidAsync("createHexagon", new
116+
{
117+
width = Width,
118+
height = Height,
119+
container = ".hexagon-progress",
120+
roundedCorners = true,
121+
lineWidth = LineWidth,
122+
lineColor = ColorUtil.GetCssValue(_theme, ProgressColor),
123+
scale = new { start = 0, end = 1, stop = MathUtil.GetNormalizedPercentage(Progress, ProgressMin, ProgressMax) }
124+
});
125+
126+
await JsRuntime.InvokeVoidAsync("createHexagon", new
127+
{
128+
width = 68,
129+
Height = 68,
130+
container = ".hexagon-image",
131+
roundedCorners = true,
132+
clip = true
133+
});
134+
135+
await JsRuntime.InvokeVoidAsync("createHexagon", new
136+
{
137+
container = ".hexagon-dark",
138+
width = 26,
139+
height = 28,
140+
roundedCorners = true,
141+
roundedCornerRadius = 1,
142+
lineColor = ColorUtil.GetCssValue(_theme, BadgeLineColor),
143+
fill = true
144+
});
145+
146+
await JsRuntime.InvokeVoidAsync("createHexagon", new
147+
{
148+
container = ".hexagon-avatar-badge",
149+
width = 32,
150+
height = 36,
151+
fill = true,
152+
roundedCorners = true,
153+
roundedCornerRadius = 1,
154+
lineColor = ColorUtil.GetCssValue(_theme, BadgeColor)
155+
});
156+
}
157+
158+
}

0 commit comments

Comments
 (0)