Yuyuqt commited on
Commit
0cba109
·
1 Parent(s): 202c378

fix: balance backend

Browse files
Backend/Features/Users/UserService.cs CHANGED
@@ -167,8 +167,10 @@ namespace Backend.Features.Users
167
  CreatedAt = user.CreatedAt,
168
  UpdatedAt = user.UpdatedAt,
169
  BanStatus = user.BanStatus,
170
- SuspensionEndDate = user.SuspensionEndDate
 
171
  };
172
  }
 
173
  }
174
  }
 
167
  CreatedAt = user.CreatedAt,
168
  UpdatedAt = user.UpdatedAt,
169
  BanStatus = user.BanStatus,
170
+ SuspensionEndDate = user.SuspensionEndDate,
171
+ Balance = user.Balance
172
  };
173
  }
174
+
175
  }
176
  }
BlazorWebAssembly/Services/LibraryApiClient.cs CHANGED
@@ -1,18 +1,33 @@
1
  using System.Text.Json.Serialization;
2
  using System.Net.Http.Json;
3
  using System.Text.Json;
 
4
  using LibraryManagement.Shared.Models;
 
 
5
 
6
  namespace BlazorWebAssembly.Services
7
  {
8
  public class LibraryApiClient
9
  {
10
  private readonly HttpClient _httpClient;
11
- public LibraryApiClient(HttpClient httpClient)
 
 
12
  {
13
  _httpClient = httpClient;
 
 
 
 
 
 
 
 
 
14
  }
15
 
 
16
  #region Auth
17
  public async Task<AuthResponse?> LoginAsync(LoginRequest request)
18
  {
@@ -159,10 +174,12 @@ namespace BlazorWebAssembly.Services
159
 
160
  public async Task<SubscriptionDto?> AdminSubscribeAsync(AdminSubscribeRequest request)
161
  {
 
162
  var response = await _httpClient.PostAsJsonAsync("api/subscriptions/admin-subscribe", request);
163
  return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<SubscriptionDto>() : null;
164
  }
165
 
 
166
  public async Task<IEnumerable<SubscriptionDto>> GetAllSubscriptionsAsync()
167
  {
168
  return await _httpClient.GetFromJsonAsync<IEnumerable<SubscriptionDto>>("api/subscriptions/all") ?? Enumerable.Empty<SubscriptionDto>();
@@ -172,6 +189,7 @@ namespace BlazorWebAssembly.Services
172
  {
173
  try
174
  {
 
175
  return await _httpClient.GetFromJsonAsync<SubscriptionUpgradePreviewDto>($"api/subscriptions/preview-upgrade/{membershipId}");
176
  }
177
  catch { return null; }
@@ -179,6 +197,7 @@ namespace BlazorWebAssembly.Services
179
 
180
  public async Task<SubscriptionDto?> SubscribeWithWalletAsync(SubscribeRequest request)
181
  {
 
182
  var response = await _httpClient.PostAsJsonAsync("api/subscriptions/subscribe-wallet", request);
183
  return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<SubscriptionDto>() : null;
184
  }
@@ -189,6 +208,7 @@ namespace BlazorWebAssembly.Services
189
  {
190
  try
191
  {
 
192
  return await _httpClient.GetFromJsonAsync<decimal>("api/wallet/balance");
193
  }
194
  catch { return 0; }
@@ -198,19 +218,35 @@ namespace BlazorWebAssembly.Services
198
  {
199
  try
200
  {
 
201
  return await _httpClient.GetFromJsonAsync<IEnumerable<WalletTransactionDto>>("api/wallet/history") ?? Enumerable.Empty<WalletTransactionDto>();
202
  }
203
  catch { return Enumerable.Empty<WalletTransactionDto>(); }
204
  }
205
 
 
206
  public async Task<(bool Success, string Message)> TopUpWalletAsync(TopUpRequest request)
207
  {
 
208
  var response = await _httpClient.PostAsJsonAsync("api/wallet/topup", request);
 
209
  if (response.IsSuccessStatusCode) return (true, "Success");
210
 
211
- var error = await response.Content.ReadFromJsonAsync<JsonDocument>();
212
- var msg = error?.RootElement.TryGetProperty("message", out var m) == true ? m.GetString() : "Unknown error";
213
- return (false, msg ?? "Failed to top up");
 
 
 
 
 
 
 
 
 
 
 
 
214
  }
215
  #endregion
216
 
 
1
  using System.Text.Json.Serialization;
2
  using System.Net.Http.Json;
3
  using System.Text.Json;
4
+ using System.Net.Http.Headers;
5
  using LibraryManagement.Shared.Models;
6
+ using Blazored.LocalStorage;
7
+
8
 
9
  namespace BlazorWebAssembly.Services
10
  {
11
  public class LibraryApiClient
12
  {
13
  private readonly HttpClient _httpClient;
14
+ private readonly ILocalStorageService _localStorage;
15
+
16
+ public LibraryApiClient(HttpClient httpClient, ILocalStorageService localStorage)
17
  {
18
  _httpClient = httpClient;
19
+ _localStorage = localStorage;
20
+ }
21
+
22
+ /// <summary>Ensures the JWT token from localStorage is attached before every request.</summary>
23
+ private async Task EnsureAuthHeader()
24
+ {
25
+ var token = await _localStorage.GetItemAsync<string>("authToken");
26
+ if (!string.IsNullOrWhiteSpace(token))
27
+ _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
28
  }
29
 
30
+
31
  #region Auth
32
  public async Task<AuthResponse?> LoginAsync(LoginRequest request)
33
  {
 
174
 
175
  public async Task<SubscriptionDto?> AdminSubscribeAsync(AdminSubscribeRequest request)
176
  {
177
+ await EnsureAuthHeader();
178
  var response = await _httpClient.PostAsJsonAsync("api/subscriptions/admin-subscribe", request);
179
  return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<SubscriptionDto>() : null;
180
  }
181
 
182
+
183
  public async Task<IEnumerable<SubscriptionDto>> GetAllSubscriptionsAsync()
184
  {
185
  return await _httpClient.GetFromJsonAsync<IEnumerable<SubscriptionDto>>("api/subscriptions/all") ?? Enumerable.Empty<SubscriptionDto>();
 
189
  {
190
  try
191
  {
192
+ await EnsureAuthHeader();
193
  return await _httpClient.GetFromJsonAsync<SubscriptionUpgradePreviewDto>($"api/subscriptions/preview-upgrade/{membershipId}");
194
  }
195
  catch { return null; }
 
197
 
198
  public async Task<SubscriptionDto?> SubscribeWithWalletAsync(SubscribeRequest request)
199
  {
200
+ await EnsureAuthHeader();
201
  var response = await _httpClient.PostAsJsonAsync("api/subscriptions/subscribe-wallet", request);
202
  return response.IsSuccessStatusCode ? await response.Content.ReadFromJsonAsync<SubscriptionDto>() : null;
203
  }
 
208
  {
209
  try
210
  {
211
+ await EnsureAuthHeader();
212
  return await _httpClient.GetFromJsonAsync<decimal>("api/wallet/balance");
213
  }
214
  catch { return 0; }
 
218
  {
219
  try
220
  {
221
+ await EnsureAuthHeader();
222
  return await _httpClient.GetFromJsonAsync<IEnumerable<WalletTransactionDto>>("api/wallet/history") ?? Enumerable.Empty<WalletTransactionDto>();
223
  }
224
  catch { return Enumerable.Empty<WalletTransactionDto>(); }
225
  }
226
 
227
+
228
  public async Task<(bool Success, string Message)> TopUpWalletAsync(TopUpRequest request)
229
  {
230
+ await EnsureAuthHeader();
231
  var response = await _httpClient.PostAsJsonAsync("api/wallet/topup", request);
232
+
233
  if (response.IsSuccessStatusCode) return (true, "Success");
234
 
235
+ // Read as string first to avoid crash if response is not JSON (e.g. 401/403 with empty body)
236
+ var raw = await response.Content.ReadAsStringAsync();
237
+ if (string.IsNullOrWhiteSpace(raw))
238
+ return (false, $"HTTP {(int)response.StatusCode}: {response.StatusCode}");
239
+
240
+ try
241
+ {
242
+ var error = JsonSerializer.Deserialize<JsonDocument>(raw);
243
+ var msg = error?.RootElement.TryGetProperty("message", out var m) == true ? m.GetString() : raw;
244
+ return (false, msg ?? raw);
245
+ }
246
+ catch
247
+ {
248
+ return (false, raw);
249
+ }
250
  }
251
  #endregion
252