Skip to content

Commit 40c1b69

Browse files
authored
Fix user targeting variable and add User ID change functionality (#6)
Signed-off-by: André Silva <[email protected]>
1 parent d78e865 commit 40c1b69

File tree

4 files changed

+237
-87
lines changed

4 files changed

+237
-87
lines changed

Workshop.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ You'll see how feature flags can safely control major architectural decisions an
275275

276276
- Using the `EnableStatsHeader` flag, implement a simple A/B test
277277
- Use the `EvaluationContext` to differentiate between users, making sure to use the `_userId` property as the targetingKey
278-
- Change the localStorage value for `userId` to simulate different users
278+
- Use the "Change User ID" button on the homepage to simulate different users by changing your user ID
279279
- Observe how the tabs are displayed in the web application
280280

281281
2. Create a new configuration in flagd for `EnableTabs`

src/Garage.AppHost/flags/flagd.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
{
2525
"==": [
2626
{
27-
"var": "user"
27+
"var": "user_id"
2828
},
2929
"1"
3030
]
@@ -42,4 +42,4 @@
4242
"defaultVariant": "off"
4343
}
4444
}
45-
}
45+
}

src/Garage.Web/Components/Pages/Home.razor

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
</div>
3131
<div class="stat-item complete">
3232
<span class="stat-number">@(_winners.Count > 0
33-
? Math.Round((double)OwnedCount / _winners.Count * 100, 1)
34-
: 0)%</span>
33+
? Math.Round((double)OwnedCount / _winners.Count * 100, 1)
34+
: 0)%</span>
3535
<span class="stat-label">Complete</span>
3636
</div>
3737
</div>
@@ -41,34 +41,59 @@
4141

4242
<div class="collection-summary">
4343
<span class="collection-count">@_winners.Count of @_winners.Count cars</span>
44+
<button class="btn btn-secondary btn-sm" @onclick="ShowUserIdModal">Change User ID</button>
4445
</div>
4546

4647
<div class="collection-tabs">
4748
<button class="tab-btn @(_activeFilter == FilterType.All ? "active" : "")"
48-
@onclick="() => SetFilter(FilterType.All)">All Winners (@_winners.Count)
49+
@onclick="() => SetFilter(FilterType.All)">All Winners (@_winners.Count)
4950
</button>
5051
<button class="tab-btn @(_activeFilter == FilterType.Owned ? "active" : "")"
51-
@onclick="() => SetFilter(FilterType.Owned)">Owned (@OwnedCount)
52+
@onclick="() => SetFilter(FilterType.Owned)">Owned (@OwnedCount)
5253
</button>
5354
<button class="tab-btn @(_activeFilter == FilterType.NotOwned ? "active" : "")"
54-
@onclick="() => SetFilter(FilterType.NotOwned)">Not Owned (@(_winners.Count - OwnedCount))
55+
@onclick="() => SetFilter(FilterType.NotOwned)">Not Owned (@(_winners.Count - OwnedCount))
5556
</button>
5657
</div>
5758

5859
<div class="car-grid">
5960
@foreach (var winner in FilteredWinners)
6061
{
61-
<CarCard Car="@winner" OnOwnershipChanged="OnOwnershipChanged"/>
62+
<CarCard Car="@winner" OnOwnershipChanged="OnOwnershipChanged" />
6263
}
6364
</div>
6465

66+
<!-- User ID Change Modal -->
67+
@if (_showUserIdModal)
68+
{
69+
<div class="modal-backdrop" @onclick="HideUserIdModal">
70+
<div class="modal-content" @onclick:stopPropagation="true">
71+
<div class="modal-header">
72+
<h5>Change User ID</h5>
73+
<button type="button" class="btn-close" @onclick="HideUserIdModal">×</button>
74+
</div>
75+
<div class="modal-body">
76+
<p>Current User ID: <strong>@_userId</strong></p>
77+
<label for="newUserId">New User ID:</label>
78+
<input type="number" id="newUserId" @bind="_newUserId" class="form-control" min="1" />
79+
</div>
80+
<div class="modal-footer">
81+
<button type="button" class="btn btn-secondary" @onclick="HideUserIdModal">Cancel</button>
82+
<button type="button" class="btn btn-primary" @onclick="UpdateUserId">Update</button>
83+
</div>
84+
</div>
85+
</div>
86+
}
87+
6588
@code {
6689
private List<Winner> _winners = [];
6790
private FilterType _activeFilter = FilterType.All;
6891

6992
private int OwnedCount => _winners.Count(c => c.IsOwned);
7093
private bool ShowHeader => FeatureFlags.EnableStatsHeader;
7194
private int _userId;
95+
private bool _showUserIdModal;
96+
private int _newUserId;
7297

7398
private IEnumerable<Winner> FilteredWinners => _activeFilter switch
7499
{
@@ -103,8 +128,11 @@
103128
protected override async Task OnAfterRenderAsync(bool firstRender)
104129
{
105130
// Initialize user ID from local storage
106-
await GetUserId();
107-
StateHasChanged();
131+
if (firstRender)
132+
{
133+
await GetUserId();
134+
StateHasChanged();
135+
}
108136
}
109137

110138
private async Task GetUserId()
@@ -149,4 +177,29 @@
149177
StateHasChanged();
150178
}
151179

180+
private void ShowUserIdModal()
181+
{
182+
_newUserId = _userId; // Initialize with current value
183+
_showUserIdModal = true;
184+
StateHasChanged();
185+
}
186+
187+
private void HideUserIdModal()
188+
{
189+
_showUserIdModal = false;
190+
StateHasChanged();
191+
}
192+
193+
private async Task UpdateUserId()
194+
{
195+
if (_newUserId > 0)
196+
{
197+
_userId = _newUserId;
198+
await JsRuntime.InvokeVoidAsync("localStorage.setItem", "userId", _userId.ToString());
199+
Logger.LogInformation("Updated user ID to: {UserId}", _userId);
200+
_showUserIdModal = false;
201+
StateHasChanged();
202+
}
203+
}
204+
152205
}

0 commit comments

Comments
 (0)