@everymatrix/player-rglimits 1.28.3 → 1.28.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/player-rglimits.js +498 -480
- package/dist/player-rglimits.js.map +1 -1
- package/index.html +2 -2
- package/package.json +2 -2
- package/src/PlayerRglimits.svelte +451 -271
- package/src/images/arch-bg.svg +5 -0
- package/src/translations.js +100 -28
- package/tsconfig.json +2 -2
- package/types/general-animation-loading.d.ts +1 -0
- package/types/types.ts +57 -0
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
import { _, addNewMessages, setLocale } from './i18n';
|
|
5
5
|
import { TRANSLATIONS } from './translations.js';
|
|
6
6
|
import { onMount } from 'svelte';
|
|
7
|
+
import type { MonetaryLimitType, LimitDefinition, DisplayedLimit, ScheduleType, FormattedSchedule } from '../types/types';
|
|
7
8
|
|
|
8
9
|
import faCaretRightSvg from './images/fa-caret-right.svg';
|
|
9
10
|
import faDollarCircleSvg from './images/usd-circle.svg';
|
|
11
|
+
import archBgSvg from './images/arch-bg.svg';
|
|
12
|
+
|
|
10
13
|
import '@everymatrix/general-animation-loading'
|
|
11
14
|
|
|
12
15
|
export let session: string = '';
|
|
@@ -32,21 +35,21 @@
|
|
|
32
35
|
let isGaugeLoading: boolean = true;
|
|
33
36
|
let noLimitToDisplay:boolean;
|
|
34
37
|
|
|
35
|
-
let
|
|
36
|
-
|
|
38
|
+
let displayedLimit:DisplayedLimit = {
|
|
39
|
+
totalAmount: null,
|
|
37
40
|
spentAmount: '',
|
|
38
41
|
limitCurrency: 'EUR',
|
|
39
42
|
remainingAmount: '',
|
|
40
|
-
|
|
41
|
-
limitProducts:
|
|
43
|
+
limitPeriod: '',
|
|
44
|
+
limitProducts: ''
|
|
42
45
|
};
|
|
43
|
-
let limitPeriodList:Array<
|
|
46
|
+
let limitPeriodList:Array<string> = [];
|
|
47
|
+
let limitTypeList:Array<string> = [];
|
|
44
48
|
let selectedLimitPeriod:string = '';
|
|
45
|
-
let
|
|
49
|
+
let selectedLimitType:string = '';
|
|
50
|
+
let limitDefinitionList:Array<MonetaryLimitType> = [];
|
|
46
51
|
|
|
47
52
|
let gaugeValue:number = 0;
|
|
48
|
-
let gaugeNeedleValue:number = 0.750;
|
|
49
|
-
let totalSpentPerc:number = 0.00;
|
|
50
53
|
|
|
51
54
|
let errorMessage:string = '';
|
|
52
55
|
|
|
@@ -54,175 +57,271 @@
|
|
|
54
57
|
addNewMessages(item, TRANSLATIONS[item]);
|
|
55
58
|
});
|
|
56
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Sets the isMounted flag after a short delay when the component is first rendered.
|
|
62
|
+
*/
|
|
63
|
+
onMount(() => {
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
isMounted = true;
|
|
66
|
+
}, 50)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Sets the session information upon login.
|
|
71
|
+
*/
|
|
57
72
|
const setSession = ():void => {
|
|
58
73
|
isLoggedIn = true;
|
|
59
74
|
sessionID = session;
|
|
60
75
|
playerID = userid;
|
|
61
76
|
}
|
|
62
77
|
|
|
63
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Handles errors by updating the error message.
|
|
80
|
+
* @param error - The error message to be handled.
|
|
81
|
+
*/
|
|
82
|
+
const handleError = (error:string):void => {
|
|
64
83
|
errorMessage = error;
|
|
65
84
|
}
|
|
66
85
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
/**
|
|
87
|
+
* Retrieves the limit balance for a specific limit.
|
|
88
|
+
* @param limit - The financial transaction representing the limit.
|
|
89
|
+
*/
|
|
90
|
+
const getLimitBalanceById = async (limit: MonetaryLimitType): Promise<void> => {
|
|
91
|
+
try {
|
|
92
|
+
isLoading = true;
|
|
93
|
+
|
|
94
|
+
const url = new URL(`${endpoint}/v1/player/${playerID}/limits/monetary/balance`);
|
|
95
|
+
url.searchParams.append('limitDefinitionId', limit.id);
|
|
96
|
+
|
|
97
|
+
const options = {
|
|
98
|
+
method: 'GET',
|
|
99
|
+
headers: {
|
|
100
|
+
'X-SessionId': sessionID,
|
|
101
|
+
'X-Session-Type': sessiontype,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const response = await fetch(url, options);
|
|
106
|
+
if (!response.ok) {
|
|
107
|
+
throw new Error($_('fetchLimitBalanceError'));
|
|
85
108
|
}
|
|
109
|
+
|
|
110
|
+
const responseData = await response.json();
|
|
111
|
+
setCurrentLimit(responseData.limitBalances[0], limit);
|
|
112
|
+
} catch (err) {
|
|
113
|
+
handleError(err.message);
|
|
114
|
+
} finally {
|
|
115
|
+
isLoading = false;
|
|
116
|
+
}
|
|
86
117
|
}
|
|
87
118
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
'
|
|
96
|
-
|
|
97
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Get the widget translated title
|
|
121
|
+
* @param type - The type of limit
|
|
122
|
+
*/
|
|
123
|
+
const getWidgetTitle = (type: string) => {
|
|
124
|
+
switch ( type ) {
|
|
125
|
+
case 'Deposit':
|
|
126
|
+
return $_('depositLimitHeader');
|
|
127
|
+
case 'Loss':
|
|
128
|
+
return $_('lossLimitHeader');
|
|
129
|
+
case 'Wagering':
|
|
130
|
+
return $_('wageringLimitHeader');
|
|
131
|
+
default:
|
|
132
|
+
return '';
|
|
98
133
|
}
|
|
99
|
-
fetch(url, options)
|
|
100
|
-
.then((res:any) => res.json())
|
|
101
|
-
.then((res) => {
|
|
102
|
-
if (res && res.error) {
|
|
103
|
-
throw new Error(res.error);
|
|
104
|
-
}
|
|
105
|
-
setCurrentLimit(res.limitBalances[0], limit);
|
|
106
|
-
})
|
|
107
|
-
.catch((err) => {
|
|
108
|
-
handleError(err)
|
|
109
|
-
}).finally(() => {
|
|
110
|
-
isLoading = false;
|
|
111
|
-
})
|
|
112
134
|
}
|
|
113
135
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Retrieves the limit definitions for a player.
|
|
138
|
+
*
|
|
139
|
+
* @returns A promise that resolves to an array of limits.
|
|
140
|
+
*/
|
|
141
|
+
const getLimitDefinitions = async (): Promise<MonetaryLimitType[]> => {
|
|
142
|
+
try {
|
|
143
|
+
const url = new URL(`${endpoint}/v1/player/${playerID}/limits/monetary/`);
|
|
117
144
|
const options = {
|
|
118
145
|
method: 'GET',
|
|
119
146
|
headers: {
|
|
120
147
|
'X-SessionId': sessionID,
|
|
121
148
|
'X-Session-Type': sessiontype,
|
|
122
|
-
}
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const response = await fetch(url, options);
|
|
153
|
+
|
|
154
|
+
if (!response.ok) {
|
|
155
|
+
throw new Error($_('fetchLimitDefError'));
|
|
123
156
|
}
|
|
124
|
-
fetch(url, options)
|
|
125
|
-
.then((res:any) => res.json())
|
|
126
|
-
.then((res:any) => {
|
|
127
|
-
if (res && res.error) {
|
|
128
|
-
return reject(res.error);
|
|
129
|
-
}
|
|
130
|
-
return resolve(res.limits.length > 0 ? res.limits.filter((item:any) => item.type === 'Deposit') : []);
|
|
131
|
-
})
|
|
132
|
-
.catch((err) => {
|
|
133
|
-
return reject(err);
|
|
134
|
-
})
|
|
135
|
-
})
|
|
136
|
-
}
|
|
137
157
|
|
|
158
|
+
const res = await response.json();
|
|
159
|
+
|
|
160
|
+
const allowedLimitTypes = ['Deposit', 'Loss', 'Wagering'];
|
|
161
|
+
const limitTypes: string[] = res.limits.map((item: MonetaryLimitType) => item.type);
|
|
162
|
+
limitTypeList = Array.from(new Set(limitTypes)).filter( (type) => allowedLimitTypes.includes(type));
|
|
163
|
+
if (!selectedLimitType) {
|
|
164
|
+
selectedLimitType = limitTypeList[0];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const filteredLimits = res.limits.filter((item: MonetaryLimitType) => item.type === selectedLimitType);
|
|
168
|
+
return filteredLimits.length > 0 ? filteredLimits : [];
|
|
169
|
+
} catch (err) {
|
|
170
|
+
throw err;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Handles the change in the selected period.
|
|
176
|
+
*/
|
|
138
177
|
const handlePeriodChange = ():void => {
|
|
139
|
-
let selectedLimit = limitDefinitionList.find((limit) => `${limit.period} - ${limit.products[0]}` === selectedLimitPeriod)
|
|
178
|
+
let selectedLimit = limitDefinitionList.find((limit) => `${limit.period} - ${limit.products[0]}` === selectedLimitPeriod);
|
|
140
179
|
getLimitBalanceById(selectedLimit);
|
|
141
180
|
}
|
|
142
181
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
182
|
+
/**
|
|
183
|
+
* Retrieves and sets the limit balance based on available limit definitions.
|
|
184
|
+
* If no limit definitions are found, sets appropriate flags.
|
|
185
|
+
*/
|
|
186
|
+
const getLimitBalance = async (): Promise<void> => {
|
|
187
|
+
try {
|
|
188
|
+
limitDefinitionList = await getLimitDefinitions();
|
|
189
|
+
|
|
146
190
|
if (limitDefinitionList.length === 0) {
|
|
147
191
|
isLoading = false;
|
|
148
192
|
noLimitToDisplay = true;
|
|
149
193
|
return;
|
|
150
194
|
}
|
|
151
195
|
|
|
152
|
-
|
|
153
|
-
const timeMap = {
|
|
154
|
-
'Daily': 0,
|
|
155
|
-
'Weekly': 1,
|
|
156
|
-
'Monthly': 2
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
limitDefinitionList.forEach((limit) => {
|
|
160
|
-
if (limitPeriodList.indexOf(`${limit.period} - ${limit.products[0]}`) === -1) {
|
|
161
|
-
limitPeriodList.push(`${limit.period} - ${limit.products[0]}`)
|
|
162
|
-
}
|
|
163
|
-
})
|
|
196
|
+
limitPeriodList = [];
|
|
164
197
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
198
|
+
const timeMap = {
|
|
199
|
+
'Daily': 0,
|
|
200
|
+
'Weekly': 1,
|
|
201
|
+
'Monthly': 2
|
|
169
202
|
}
|
|
170
203
|
|
|
204
|
+
limitDefinitionList.forEach((limit) => {
|
|
205
|
+
if (limitPeriodList.indexOf(`${limit.period} - ${limit.products[0]}`) === -1) {
|
|
206
|
+
limitPeriodList.push(`${limit.period} - ${limit.products[0]}`)
|
|
207
|
+
}
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
limitPeriodList = limitPeriodList.sort((a, b) => {
|
|
211
|
+
return timeMap[a.split(' ')[0]] - timeMap[b.split(' ')[0]];
|
|
212
|
+
});
|
|
213
|
+
|
|
171
214
|
getLimitBalanceById(limitDefinitionList[0]);
|
|
172
|
-
}
|
|
215
|
+
} catch ( err ) {
|
|
173
216
|
isLoading = false;
|
|
174
|
-
handleError(err)
|
|
175
|
-
|
|
217
|
+
handleError(err.message);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
176
220
|
}
|
|
177
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Converts the date to a human-readable string
|
|
224
|
+
* @param date - Date to convert.
|
|
225
|
+
*/
|
|
178
226
|
const dateToReadableString = (date:string):string => {
|
|
179
227
|
return moment(date).utc(true).format(datetimeformat || `DD/MM/YYYY HH:mm:ss`);
|
|
180
228
|
}
|
|
181
229
|
|
|
182
|
-
|
|
230
|
+
/**
|
|
231
|
+
* Sets the current limit based on the provided limit balance and financial transaction.
|
|
232
|
+
* @param limitBalance - The limit balance information.
|
|
233
|
+
* @param limit - The financial transaction representing the limit.
|
|
234
|
+
*/
|
|
235
|
+
const setCurrentLimit = (limitBalance: LimitDefinition, limit: MonetaryLimitType): void => {
|
|
236
|
+
|
|
183
237
|
selectedLimitPeriod = `${limitBalance.limitPeriod} - ${limitBalance.limitProducts[0]}`;
|
|
238
|
+
|
|
184
239
|
const limitSchedule = formatScheduleData(limit.id, limit.schedules);
|
|
185
240
|
|
|
186
|
-
displayedLimit =
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
241
|
+
displayedLimit = {
|
|
242
|
+
totalAmount: limitBalance.limitAmount,
|
|
243
|
+
spentAmount: limitBalance.spentBalance.amount.toFixed(2),
|
|
244
|
+
limitCurrency: limitBalance.limitCurrency,
|
|
245
|
+
remainingAmount: (limitBalance.limitAmount - limitBalance.spentBalance.amount).toFixed(2),
|
|
246
|
+
limitPeriod: limitBalance.limitPeriod,
|
|
247
|
+
limitProducts: limitBalance.limitProducts[0],
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
if ( limitSchedule ) {
|
|
251
|
+
displayedLimit.formattedSchedule = limitSchedule;
|
|
252
|
+
}
|
|
195
253
|
|
|
196
254
|
setGauge(displayedLimit);
|
|
197
255
|
}
|
|
198
256
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
257
|
+
/**
|
|
258
|
+
* Sets the gauge value based on the provided limit information.
|
|
259
|
+
* @param limit - The limit information to calculate the gauge value.
|
|
260
|
+
*/
|
|
261
|
+
const setGauge = (limit:DisplayedLimit):void => {
|
|
262
|
+
const newGaugeValue = (180 / limit.totalAmount) * parseFloat(limit.spentAmount);
|
|
263
|
+
const step = 1.5; // Step size for increasing/decreasing gaugeValue
|
|
264
|
+
const interval = setInterval(() => {
|
|
265
|
+
if (Math.abs(gaugeValue - newGaugeValue) < step) {
|
|
266
|
+
gaugeValue = newGaugeValue;
|
|
267
|
+
clearInterval(interval);
|
|
268
|
+
} else {
|
|
269
|
+
gaugeValue += (gaugeValue < newGaugeValue) ? step : -step;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Boundary checks to ensure gaugeValue stays within [0, 180]
|
|
273
|
+
gaugeValue = Math.min(180, Math.max(0, gaugeValue));
|
|
274
|
+
|
|
275
|
+
if (gaugeValue === newGaugeValue) {
|
|
276
|
+
clearInterval(interval);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
|
|
211
280
|
isGaugeLoading = false;
|
|
212
281
|
}
|
|
213
282
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
283
|
+
/**
|
|
284
|
+
* Formats schedule data for a specific limit definition.
|
|
285
|
+
* @param limitDefinitionId - The ID of the limit definition.
|
|
286
|
+
* @param scheduleData - The schedule data to be formatted.
|
|
287
|
+
* @returns The formatted limit schedule.
|
|
288
|
+
*/
|
|
289
|
+
const formatScheduleData = (
|
|
290
|
+
limitDefinitionId: string,
|
|
291
|
+
scheduleData: ScheduleType[]
|
|
292
|
+
):FormattedSchedule => {
|
|
293
|
+
const limitSchedule = scheduleData.find(schedule => schedule.playerLimitId === limitDefinitionId);
|
|
294
|
+
return limitSchedule
|
|
295
|
+
? {
|
|
296
|
+
updateAmount: limitSchedule.updateAmount,
|
|
297
|
+
expires: limitSchedule.applyAt,
|
|
298
|
+
expiresString: dateToReadableString(limitSchedule.applyAt),
|
|
299
|
+
id: limitSchedule.id,
|
|
300
|
+
isRemoved: limitSchedule.updateAmount < 1,
|
|
301
|
+
isUpdated: limitSchedule.updateAmount > 0
|
|
302
|
+
}
|
|
303
|
+
: {
|
|
304
|
+
updateAmount: '',
|
|
305
|
+
expires: '',
|
|
306
|
+
expiresString: '',
|
|
307
|
+
id: '',
|
|
308
|
+
isRemoved: false,
|
|
309
|
+
isUpdated: false
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Sets client styling by appending a style element to the custom styling container.
|
|
315
|
+
*/
|
|
220
316
|
const setClientStyling = ():void => {
|
|
221
317
|
let sheet = document.createElement('style');
|
|
222
318
|
sheet.innerHTML = clientstyling;
|
|
223
319
|
customStylingContainer.appendChild(sheet);
|
|
224
320
|
}
|
|
225
321
|
|
|
322
|
+
/**
|
|
323
|
+
* Sets client styling URL by fetching the CSS file and appending a style element to the custom styling container.
|
|
324
|
+
*/
|
|
226
325
|
const setClientStylingURL = ():void => {
|
|
227
326
|
displayNone = true;
|
|
228
327
|
|
|
@@ -239,10 +338,16 @@
|
|
|
239
338
|
});
|
|
240
339
|
}
|
|
241
340
|
|
|
341
|
+
/**
|
|
342
|
+
* Sets the active language by updating the locale.
|
|
343
|
+
*/
|
|
242
344
|
const setActiveLanguage = ():void => {
|
|
243
345
|
setLocale(lang);
|
|
244
346
|
}
|
|
245
347
|
|
|
348
|
+
/**
|
|
349
|
+
* Sets translation URL by fetching translation data and updating messages.
|
|
350
|
+
*/
|
|
246
351
|
const setTranslationUrl = ():void => {
|
|
247
352
|
let url:URL = new URL(translationurl);
|
|
248
353
|
|
|
@@ -264,96 +369,116 @@
|
|
|
264
369
|
$: translationurl && setTranslationUrl();
|
|
265
370
|
</script>
|
|
266
371
|
|
|
267
|
-
|
|
268
|
-
<div class="LimitsContainer" bind:this={customStylingContainer}>
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
<
|
|
280
|
-
|
|
281
|
-
<
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
<div class="TextContainer">
|
|
289
|
-
<p><img class="TextIcon" alt="user" src="{faCaretRightSvg}" /> {displayedLimit.spentAmount} {displayedLimit.limitCurrency}</p>
|
|
290
|
-
<p><img class="TextIcon" alt="user" src="{faCaretRightSvg}" /> {displayedLimit.remainingAmount} {displayedLimit.limitCurrency}</p>
|
|
291
|
-
{#if displayedLimit.isUpdated === true}
|
|
292
|
-
<p><img class="TextIcon" alt="user" src="{faCaretRightSvg}" /> {displayedLimit.updateAmount} {displayedLimit.limitCurrency} </p>
|
|
293
|
-
{/if}
|
|
294
|
-
<p><img class="TextIcon" alt="user" src="{faCaretRightSvg}" /> {displayedLimit.limitPeriod}</p>
|
|
295
|
-
<p><img class="TextIcon" alt="user" src="{faCaretRightSvg}" /> {displayedLimit.limitProducts}</p>
|
|
296
|
-
</div>
|
|
297
|
-
{#if displayedLimit.isRemoved === true || displayedLimit.isUpdated === true }
|
|
298
|
-
<div class="ExtraInfoContainer">
|
|
299
|
-
{#if displayedLimit.isRemoved === true}
|
|
300
|
-
<span>{$_('limitRemoved')}: {displayedLimit.expiresString}</span>
|
|
301
|
-
{/if}
|
|
302
|
-
{#if displayedLimit.isUpdated === true}
|
|
303
|
-
<span>{$_('limitUpdated')}: {displayedLimit.expiresString}</span>
|
|
372
|
+
<div class={displayNone ? 'DisplayNone' : ''}>
|
|
373
|
+
<div class="LimitsContainer" bind:this={customStylingContainer}>
|
|
374
|
+
{#if noLimitToDisplay}
|
|
375
|
+
<div class="ContainerCenter">
|
|
376
|
+
<p>{$_('noLimitToDisplay')}</p>
|
|
377
|
+
</div>
|
|
378
|
+
{:else if errorMessage}
|
|
379
|
+
<div class="ContainerCenter">
|
|
380
|
+
<strong class="ErrorMessage">{errorMessage}</strong>
|
|
381
|
+
</div>
|
|
382
|
+
{:else}
|
|
383
|
+
<div class="ContentLeft">
|
|
384
|
+
<h2 class="LimitTypeHeader"><img class="HeaderIcon" alt="user" src="{faDollarCircleSvg}" />{getWidgetTitle(selectedLimitType)}</h2>
|
|
385
|
+
{#if isLoading}
|
|
386
|
+
<general-animation-loading clientstyling={clientstyling} clientstylingurl={clientstylingurl} />
|
|
387
|
+
{:else}
|
|
388
|
+
<div class="DetailsContainer Entries">
|
|
389
|
+
<span>{$_('spentAmount')}: </span>
|
|
390
|
+
<span>{$_('remainingAmount')}: </span>
|
|
391
|
+
{#if displayedLimit.formattedSchedule.isUpdated === true}
|
|
392
|
+
<span>{$_('futureAmount')}: </span>
|
|
304
393
|
{/if}
|
|
394
|
+
<span>{$_('limitPeriod')}: </span>
|
|
395
|
+
<span>{$_('displayedProduct')}: </span>
|
|
305
396
|
</div>
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
{#if
|
|
310
|
-
<
|
|
311
|
-
{:else if transactionspageurl}
|
|
312
|
-
<a href="{transactionspageurl}" target="_blank">{$_('additionalLink2')}</a>
|
|
397
|
+
<div class="TextContainer">
|
|
398
|
+
<p><img class="TextIcon" alt="user" src="{faCaretRightSvg}" /> {displayedLimit.spentAmount} {displayedLimit.limitCurrency}</p>
|
|
399
|
+
<p><img class="TextIcon" alt="user" src="{faCaretRightSvg}" /> {displayedLimit.remainingAmount} {displayedLimit.limitCurrency}</p>
|
|
400
|
+
{#if displayedLimit.formattedSchedule.isUpdated === true}
|
|
401
|
+
<p><img class="TextIcon" alt="user" src="{faCaretRightSvg}" /> {displayedLimit.formattedSchedule.updateAmount} {displayedLimit.limitCurrency} </p>
|
|
313
402
|
{/if}
|
|
403
|
+
<p><img class="TextIcon" alt="user" src="{faCaretRightSvg}" /> {displayedLimit.limitPeriod}</p>
|
|
404
|
+
<p><img class="TextIcon" alt="user" src="{faCaretRightSvg}" /> {displayedLimit.limitProducts}</p>
|
|
314
405
|
</div>
|
|
406
|
+
{#if displayedLimit.formattedSchedule.isRemoved === true || displayedLimit.formattedSchedule.isUpdated === true }
|
|
407
|
+
<div class="ExtraInfoContainer">
|
|
408
|
+
{#if displayedLimit.formattedSchedule.isRemoved === true}
|
|
409
|
+
<span>{$_('limitRemoved')}: {displayedLimit.formattedSchedule.expiresString}</span>
|
|
410
|
+
{/if}
|
|
411
|
+
{#if displayedLimit.formattedSchedule.isUpdated === true}
|
|
412
|
+
<span>{$_('limitUpdated')}: {displayedLimit.formattedSchedule.expiresString}</span>
|
|
413
|
+
{/if}
|
|
414
|
+
</div>
|
|
415
|
+
{/if}
|
|
416
|
+
{#if sessiontype === 'admin'}
|
|
417
|
+
<div class="UsefulLinksSection">
|
|
418
|
+
{#if transdetailsurl}
|
|
419
|
+
<a href="{transdetailsurl}" target="_blank">{$_('additionalLink1')}</a>
|
|
420
|
+
{:else if transactionspageurl}
|
|
421
|
+
<a href="{transactionspageurl}" target="_blank">{$_('additionalLink2')}</a>
|
|
422
|
+
{/if}
|
|
423
|
+
</div>
|
|
424
|
+
{/if}
|
|
315
425
|
{/if}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
426
|
+
<div class="WidgetFooterControls">
|
|
427
|
+
{#if limitPeriodList.length > 0}
|
|
428
|
+
<div class="ControlContainer">
|
|
429
|
+
<label for="LimitPeriod">{$_('changeLimitLabel')}: </label>
|
|
430
|
+
<select bind:value={selectedLimitPeriod} id="LimitPeriod" on:change={handlePeriodChange}>
|
|
431
|
+
{#each limitPeriodList as value}
|
|
432
|
+
<option {value}>
|
|
433
|
+
{value}
|
|
434
|
+
</option>
|
|
435
|
+
{/each}
|
|
436
|
+
</select>
|
|
437
|
+
</div>
|
|
438
|
+
{/if}
|
|
439
|
+
{#if limitTypeList.length > 0}
|
|
440
|
+
<div class="ControlContainer">
|
|
441
|
+
<label for="LimitType">{$_('limitTypeLabel')}: </label>
|
|
442
|
+
<select bind:value={selectedLimitType} id="LimitType" on:change={getLimitBalance}>
|
|
443
|
+
{#each limitTypeList as value}
|
|
444
|
+
<option {value}>
|
|
445
|
+
{value}
|
|
446
|
+
</option>
|
|
447
|
+
{/each}
|
|
448
|
+
</select>
|
|
449
|
+
</div>
|
|
450
|
+
{/if}
|
|
327
451
|
</div>
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
452
|
+
</div>
|
|
453
|
+
<div class="ContentRight">
|
|
454
|
+
{#if isGaugeLoading}
|
|
455
|
+
<general-animation-loading clientstyling={clientstyling} clientstylingurl={clientstylingurl} />
|
|
456
|
+
{:else}
|
|
457
|
+
<div class="AmountContainer">{displayedLimit.totalAmount} {displayedLimit.limitCurrency}</div>
|
|
458
|
+
<div class="Gauge">
|
|
459
|
+
<div class="GaugeBody">
|
|
460
|
+
<img class="Archbg" src="{archBgSvg}" alt="arch"/>
|
|
461
|
+
<div class="GaugeFill" style="--p:{gaugeValue}deg"></div>
|
|
462
|
+
<div class="GaugeCover">{displayedLimit.spentAmount} {displayedLimit.limitCurrency}</div>
|
|
463
|
+
<div class="GaugeNeedleCover"></div>
|
|
464
|
+
<div class="GaugeNeedle" style="--transform-needle-value: rotate({gaugeValue - 90}deg)"></div>
|
|
465
|
+
</div>
|
|
342
466
|
</div>
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
467
|
+
<div class="MinMaxContainer">
|
|
468
|
+
<div class="Min"> <strong class="MinContent">0</strong> <span class="MinContentCurrency">{displayedLimit.limitCurrency}</span></div>
|
|
469
|
+
<div class="Max"> <strong class="MaxContent">{displayedLimit.totalAmount}</strong> <span class="MaxContentCurrency">{displayedLimit.limitCurrency}</span></div>
|
|
470
|
+
</div>
|
|
471
|
+
{/if}
|
|
472
|
+
</div>
|
|
473
|
+
{/if}
|
|
474
|
+
</div>
|
|
351
475
|
</div>
|
|
352
476
|
|
|
353
477
|
|
|
354
478
|
<style lang="scss">
|
|
355
479
|
$primary-text-color: var(--emw--color-gray-150, #a9b6ce);
|
|
356
|
-
$primary-
|
|
480
|
+
$primary-color: var(--emw--color-primary, #D0046C);
|
|
481
|
+
$primary-gauge-fill-color: var(--emw--gauge-fill-bg, $primary-color);
|
|
357
482
|
$secondary-gauge-background-color: var(--emw--color-gray-100, #E6E6E6);
|
|
358
483
|
$primary-contrast-color: var(--emw--color-contrast, #07072A);
|
|
359
484
|
|
|
@@ -368,6 +493,18 @@
|
|
|
368
493
|
box-sizing: border-box;
|
|
369
494
|
}
|
|
370
495
|
|
|
496
|
+
.DisplayNone {
|
|
497
|
+
display: none;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
.ContainerCenter {
|
|
501
|
+
width: 100%;
|
|
502
|
+
display: flex;
|
|
503
|
+
justify-content: center;
|
|
504
|
+
align-items: center;
|
|
505
|
+
min-height: 219px;
|
|
506
|
+
}
|
|
507
|
+
|
|
371
508
|
.ErrorMessage {
|
|
372
509
|
margin: 0 15px;
|
|
373
510
|
font-size: 12px;
|
|
@@ -383,18 +520,47 @@
|
|
|
383
520
|
border-radius: 20px;
|
|
384
521
|
overflow: hidden;
|
|
385
522
|
box-shadow: 0.6em 0.6em 0.4em $primary-text-color;
|
|
523
|
+
}
|
|
386
524
|
|
|
387
|
-
|
|
388
|
-
|
|
525
|
+
.ContentLeft {
|
|
526
|
+
padding: 1rem;
|
|
527
|
+
width: 318px;
|
|
528
|
+
line-height: 20px;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
.LimitTypeHeader {
|
|
532
|
+
display: flex;
|
|
533
|
+
align-items: center;
|
|
534
|
+
color: $primary-text-color;
|
|
535
|
+
margin-bottom: 20px;
|
|
536
|
+
gap: 5px;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
.HeaderIcon {
|
|
540
|
+
height: 20px;
|
|
541
|
+
width: 20px;
|
|
542
|
+
color: $primary-text-color;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.DetailsContainer {
|
|
546
|
+
margin-bottom: 15px;
|
|
547
|
+
display: inline;
|
|
548
|
+
span {
|
|
549
|
+
float: left;
|
|
550
|
+
clear: both;
|
|
389
551
|
}
|
|
390
552
|
}
|
|
391
|
-
|
|
392
|
-
.
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
553
|
+
|
|
554
|
+
.ContentRight {
|
|
555
|
+
min-width: 300px;
|
|
556
|
+
padding: 1rem;
|
|
557
|
+
display: flex;
|
|
558
|
+
justify-content:
|
|
559
|
+
center;
|
|
560
|
+
flex-direction:
|
|
561
|
+
column;
|
|
396
562
|
}
|
|
397
|
-
|
|
563
|
+
|
|
398
564
|
.AmountContainer {
|
|
399
565
|
padding: 0.3rem;
|
|
400
566
|
font-size: xx-large;
|
|
@@ -404,91 +570,91 @@
|
|
|
404
570
|
box-shadow: 0.16em 0.16em 0.1em var(--emw--color-gray-150, #a9b6ce);
|
|
405
571
|
background-color: #F5F5F5;
|
|
406
572
|
}
|
|
407
|
-
|
|
408
|
-
|
|
573
|
+
|
|
574
|
+
.TextContainer {
|
|
575
|
+
display: inline-block;
|
|
576
|
+
padding-left: 5px;
|
|
577
|
+
p {
|
|
578
|
+
width: 100%;
|
|
579
|
+
display: block;
|
|
580
|
+
clear: both;
|
|
581
|
+
font-weight: bold;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
.ExtraInfoContainer {
|
|
586
|
+
padding: 1rem 0;
|
|
587
|
+
color: var(--emfe-w-color-red, #ed0909);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.UsefulLinksSection {
|
|
591
|
+
padding-top: 5px;
|
|
592
|
+
a {
|
|
593
|
+
float: left;
|
|
594
|
+
clear: both;
|
|
595
|
+
color: $primary-contrast-color;
|
|
596
|
+
}
|
|
409
597
|
}
|
|
410
|
-
|
|
411
|
-
.
|
|
412
|
-
|
|
598
|
+
|
|
599
|
+
.WidgetFooterControls {
|
|
600
|
+
display: flex;
|
|
413
601
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
602
|
+
|
|
603
|
+
.ControlContainer {
|
|
604
|
+
label {
|
|
605
|
+
display: inline-block;
|
|
606
|
+
width: 100%;
|
|
607
|
+
font-size: 12px;
|
|
608
|
+
font-weight: bold;
|
|
609
|
+
}
|
|
417
610
|
}
|
|
418
|
-
.TextIcon { color: $primary-
|
|
611
|
+
.TextIcon { color: $primary-color; }
|
|
419
612
|
|
|
420
613
|
.Gauge {
|
|
421
614
|
width: 100%;
|
|
422
615
|
font-family: 'Roboto', sans-serif;
|
|
423
616
|
font-size: 32px;
|
|
424
617
|
color: black;
|
|
425
|
-
margin
|
|
618
|
+
margin: 1rem 0;
|
|
426
619
|
}
|
|
427
620
|
|
|
428
621
|
.GaugeBody {
|
|
429
622
|
width: 100%;
|
|
430
|
-
height: 0;
|
|
431
|
-
padding-bottom: 50%;
|
|
432
|
-
background: $secondary-gauge-background-color;
|
|
433
623
|
position: relative;
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
.GaugeFill {
|
|
440
|
-
position: absolute;
|
|
441
|
-
top: 100%;
|
|
442
|
-
left: 0;
|
|
443
|
-
width: inherit;
|
|
444
|
-
height: 100%;
|
|
445
|
-
background: $primary-gauge-fill-color;
|
|
446
|
-
transform-origin: center top;
|
|
447
|
-
transform: var(--transform-value);
|
|
448
|
-
transition: transform 0.2s ease-out;
|
|
624
|
+
text-align: center;
|
|
625
|
+
padding: 23px;
|
|
626
|
+
padding-bottom: 0;
|
|
449
627
|
}
|
|
450
628
|
|
|
451
|
-
.
|
|
452
|
-
width: 75%;
|
|
453
|
-
height: 150%;
|
|
454
|
-
background: var(--emw--color-white, #FFFFFF);
|
|
629
|
+
.Archbg {
|
|
455
630
|
position: absolute;
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
left: 50%;
|
|
459
|
-
transform: translateX(-50%);
|
|
460
|
-
|
|
461
|
-
//Text
|
|
462
|
-
display: flex;
|
|
463
|
-
align-items: center;
|
|
464
|
-
justify-content: center;
|
|
465
|
-
padding-bottom: 47%;
|
|
466
|
-
box-sizing: border-box;
|
|
467
|
-
font-size: 20px;
|
|
631
|
+
right: 0;
|
|
632
|
+
bottom: 0;
|
|
468
633
|
}
|
|
469
634
|
|
|
470
|
-
.
|
|
471
|
-
|
|
472
|
-
|
|
635
|
+
.GaugeFill {
|
|
636
|
+
--p:0deg;
|
|
637
|
+
--b:25px;
|
|
638
|
+
border-radius:500px 500px 0 0;
|
|
473
639
|
background: $primary-gauge-fill-color;
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
640
|
+
mask: radial-gradient(farthest-side at bottom,transparent calc(100% - var(--b) - 1px),#fff calc(100% - var(--b))), linear-gradient(var(--p),#fff 50%,transparent 0) top/100% 200%;
|
|
641
|
+
-webkit-mask: radial-gradient(farthest-side at bottom,transparent calc(100% - var(--b) - 1px),#fff calc(100% - var(--b))), linear-gradient(var(--p),#fff 50%,transparent 0) top/100% 200%;
|
|
642
|
+
mask-composite:intersect;
|
|
643
|
+
-webkit-mask-composite:destination-in;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
.GaugeFill::before {
|
|
647
|
+
content:"";
|
|
648
|
+
display:block;
|
|
649
|
+
padding-top:50%;
|
|
479
650
|
}
|
|
480
651
|
|
|
481
|
-
.
|
|
482
|
-
width: 8%;
|
|
483
|
-
height: 16%;
|
|
484
|
-
background: var(--emw--color-black, #000000);
|
|
652
|
+
.GaugeCover {
|
|
485
653
|
position: absolute;
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
transform: translateX(-50%);
|
|
491
|
-
transition: transform 0.2s ease-out;
|
|
654
|
+
left: 0;
|
|
655
|
+
right: 0;
|
|
656
|
+
top: 50%;
|
|
657
|
+
font-size: 20px;
|
|
492
658
|
}
|
|
493
659
|
|
|
494
660
|
.GaugeNeedle {
|
|
@@ -498,13 +664,27 @@
|
|
|
498
664
|
display: inline-block;
|
|
499
665
|
left: 49.5%;
|
|
500
666
|
position: absolute;
|
|
501
|
-
bottom:
|
|
667
|
+
bottom: 0.1rem;
|
|
502
668
|
transform: var(--transform-needle-value);
|
|
503
669
|
transform-origin: bottom;
|
|
504
|
-
transition: transform 0.2s ease-out;
|
|
505
670
|
}
|
|
506
671
|
|
|
507
|
-
.
|
|
508
|
-
|
|
509
|
-
|
|
672
|
+
.GaugeNeedleCover {
|
|
673
|
+
width: 60px;
|
|
674
|
+
height: 30px;
|
|
675
|
+
border-radius: 150px 150px 0 0;
|
|
676
|
+
background: var(--emw--color-black, #000000);
|
|
677
|
+
background: radial-gradient(circle at 50% 100%, var(--emw--color-black, #000000) 0%, var(--emw--color-black, #000000) 25%, #fff 25%, #fff 40%, $primary-color 40%);
|
|
678
|
+
position: absolute;
|
|
679
|
+
bottom: 0;
|
|
680
|
+
left: 50%;
|
|
681
|
+
border: 4px solid var(--emw--color-white, #FFFFFF);
|
|
682
|
+
border-bottom: 0;
|
|
683
|
+
transform: translateX(-50%);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
.MinMaxContainer {
|
|
687
|
+
display: flex;
|
|
688
|
+
justify-content: space-between;
|
|
689
|
+
}
|
|
510
690
|
</style>
|