Skip to content

Commit 0aff235

Browse files
authored
fix: ecurrency issues (#733)
* fix: ecurrency issues * fix: add UTC label to messages * fix: edge case where finalContext is null
1 parent 61197fb commit 0aff235

4 files changed

Lines changed: 50 additions & 24 deletions

File tree

platforms/eCurrency-api/src/services/TransactionNotificationService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ Transaction for your ${accountText} has been processed.
257257
258258
${isSender ? 'sent amount' : 'received amount'}: ${formattedAmount}
259259
currency: ${currency.name} (${currency.ename})
260-
time: ${formattedTime}
260+
time: ${formattedTime} UTC
261261
${otherPartyLabel}: ${otherPartyName}`;
262262
}
263263

platforms/eCurrency-api/src/services/UserService.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,27 @@ export class UserService {
4848
}
4949

5050
async searchUsers(query: string, limit: number = 10): Promise<User[]> {
51+
const q = query.trim().toLowerCase();
52+
const patternPartial = `%${q}%`;
53+
const patternPrefix = `${q}%`;
54+
5155
return await this.userRepository
5256
.createQueryBuilder("user")
53-
.where("user.name ILIKE :query OR user.handle ILIKE :query", { query: `%${query}%` })
57+
.where("(user.name ILIKE :patternPartial OR user.handle ILIKE :patternPartial)", {
58+
patternPartial,
59+
})
60+
.addSelect(
61+
`CASE ` +
62+
`WHEN LOWER(COALESCE(user.name, '')) = :exact OR LOWER(COALESCE(user.handle, '')) = :exact THEN 0 ` +
63+
`WHEN LOWER(COALESCE(user.name, '')) LIKE :patternPrefix OR LOWER(COALESCE(user.handle, '')) LIKE :patternPrefix THEN 1 ` +
64+
`ELSE 2 ` +
65+
`END`,
66+
"relevance",
67+
)
68+
.setParameter("exact", q)
69+
.setParameter("patternPrefix", patternPrefix)
70+
.orderBy("relevance", "ASC")
71+
.addOrderBy("user.name", "ASC", "NULLS LAST")
5472
.limit(limit)
5573
.getMany();
5674
}

platforms/eCurrency/client/src/pages/currency-detail.tsx

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export default function CurrencyDetail() {
108108
if (!user) return;
109109

110110
const adminGroups = groups?.filter((g: any) => g.isAdmin) || [];
111-
111+
112112
// If no context is set, default to user account
113113
if (!accountContext) {
114114
const defaultContext = { type: "user" as const, id: user.id };
@@ -119,16 +119,18 @@ export default function CurrencyDetail() {
119119

120120
// Validate the saved context
121121
let isValid = false;
122-
122+
123123
if (accountContext.type === "user") {
124-
// User context must match current user ID
125124
isValid = accountContext.id === user.id;
126125
} else if (accountContext.type === "group") {
127-
// Group context must be in admin groups list
128-
isValid = adminGroups.some((g: any) => g.id === accountContext.id);
126+
// Do not reset group context while groups are still loading (preserves selection across refresh)
127+
if (groups === undefined) {
128+
isValid = true;
129+
} else {
130+
isValid = adminGroups.some((g: any) => g.id === accountContext.id);
131+
}
129132
}
130133

131-
// If invalid, reset to user account
132134
if (!isValid) {
133135
const defaultContext = { type: "user" as const, id: user.id };
134136
setAccountContext(defaultContext);
@@ -141,22 +143,26 @@ export default function CurrencyDetail() {
141143
// If null is passed, default to user account
142144
const finalContext = context || (user ? { type: "user" as const, id: user.id } : null);
143145

144-
// Check if context actually changed
145-
const contextChanged = !accountContext ||
146-
accountContext.type !== finalContext?.type ||
147-
accountContext.id !== finalContext?.id;
148-
146+
// Check if context actually changed (semantic comparison)
147+
const contextChanged =
148+
finalContext === null && accountContext === null
149+
? false
150+
: !accountContext ||
151+
!finalContext ||
152+
accountContext.type !== finalContext.type ||
153+
accountContext.id !== finalContext.id;
154+
155+
// Only update state and storage when context meaningfully changed (avoids clearing transaction history when re-selecting same account)
156+
if (!contextChanged) return;
157+
149158
setAccountContext(finalContext);
150159
if (finalContext) {
151160
localStorage.setItem("ecurrency_account_context", JSON.stringify(finalContext));
152161
} else {
153162
localStorage.removeItem("ecurrency_account_context");
154163
}
155-
156-
// Navigate to dashboard when context changes
157-
if (contextChanged) {
158-
setLocation("/");
159-
}
164+
165+
setLocation("/");
160166
};
161167

162168
const { data: totalSupplyData, isLoading: totalSupplyLoading } = useQuery({
@@ -423,9 +429,9 @@ export default function CurrencyDetail() {
423429

424430
{/* Transactions */}
425431
<div className="mb-6">
426-
<div className="flex justify-between items-center mb-4">
432+
<div className="flex flex-col sm:flex-row sm:justify-between sm:items-center gap-3 mb-4">
427433
<h2 className="text-xl font-semibold">Transactions</h2>
428-
<div className="flex gap-2">
434+
<div className="flex flex-wrap gap-2">
429435
{isAdminOfCurrency && accountContext?.type === "group" && accountContext.id === currency.groupId && (
430436
<>
431437
<button

platforms/eCurrency/client/src/pages/dashboard.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,16 @@ export default function Dashboard() {
6565
let isValid = false;
6666

6767
if (accountContext.type === "user") {
68-
// User context must match current user ID
6968
isValid = accountContext.id === user.id;
7069
} else if (accountContext.type === "group") {
71-
// Group context must be in admin groups list
72-
isValid = adminGroups.some((g: any) => g.id === accountContext.id);
70+
// Do not reset group context while groups are still loading (preserves selection across refresh)
71+
if (groups === undefined) {
72+
isValid = true;
73+
} else {
74+
isValid = adminGroups.some((g: any) => g.id === accountContext.id);
75+
}
7376
}
7477

75-
// If invalid, reset to user account
7678
if (!isValid) {
7779
const defaultContext = { type: "user" as const, id: user.id };
7880
setAccountContext(defaultContext);

0 commit comments

Comments
 (0)