@shoppexio/storefront-react 0.2.1 → 0.3.0
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 +97 -0
- package/dist/account.js +1161 -195
- package/dist/account.js.map +1 -1
- package/dist/{chunk-ZEFZPUAW.js → chunk-NBOIS53R.js} +2 -1
- package/dist/chunk-NBOIS53R.js.map +1 -0
- package/dist/index.d.ts +151 -21
- package/dist/index.js +206 -61
- package/dist/index.js.map +1 -1
- package/eject/account/account-availability.ts +4 -1
- package/eject/account/account-referrals.ts +179 -6
- package/eject/account/dashboard.tsx +1 -0
- package/eject/account/messages/ar.json +40 -3
- package/eject/account/messages/de.json +40 -3
- package/eject/account/messages/en.json +40 -3
- package/eject/account/messages/es.json +40 -3
- package/eject/account/messages/fi.json +40 -3
- package/eject/account/messages/fr.json +40 -3
- package/eject/account/messages/hi.json +40 -3
- package/eject/account/messages/it.json +40 -3
- package/eject/account/messages/lt.json +40 -3
- package/eject/account/messages/nl.json +40 -3
- package/eject/account/messages/pl.json +40 -3
- package/eject/account/messages/pt.json +40 -3
- package/eject/account/messages/ru.json +40 -3
- package/eject/account/messages/tr.json +40 -3
- package/eject/account/messages/uk.json +40 -3
- package/eject/account/messages/zh.json +40 -3
- package/eject/account/orders.tsx +53 -0
- package/eject/account/referrals.tsx +399 -153
- package/eject/account/rewards.tsx +38 -6
- package/eject/account/settings.tsx +98 -2
- package/eject/account/shared.tsx +3 -2
- package/package.json +4 -1
- package/dist/chunk-ZEFZPUAW.js.map +0 -1
|
@@ -33,6 +33,7 @@ export interface AccountAvailabilitySource {
|
|
|
33
33
|
subscriptionsCount: number;
|
|
34
34
|
walletPresent: boolean;
|
|
35
35
|
affiliateState: string;
|
|
36
|
+
affiliateCanCreateLinks: boolean;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
export interface AccountAvailability {
|
|
@@ -88,7 +89,9 @@ export function accountAvailabilityFrom(
|
|
|
88
89
|
subscriptions: source.subscriptionsCount > 0,
|
|
89
90
|
wallet: source.walletPresent,
|
|
90
91
|
rewards: true,
|
|
91
|
-
|
|
92
|
+
// With auto-join off a `not_enrolled` buyer may still make the first link,
|
|
93
|
+
// which is how they join; the panel's control has to be reachable for it.
|
|
94
|
+
referrals: source.affiliateState !== 'not_enrolled' || source.affiliateCanCreateLinks,
|
|
92
95
|
favorites: true,
|
|
93
96
|
reseller: accountResellerAvailable(reseller),
|
|
94
97
|
};
|
|
@@ -3,12 +3,13 @@ import type { SdkCustomerAffiliateLink, SdkCustomerAffiliateSummary } from '@sho
|
|
|
3
3
|
/**
|
|
4
4
|
* The referrals panel's pure half.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* money
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* has been earned and says
|
|
6
|
+
* One write: a link with a code of the buyer's own, when the shop allows it.
|
|
7
|
+
* Converting a referral balance into store credit and requesting a payout both
|
|
8
|
+
* move money toward the buyer, and ADR-0064 keeps money paths off the account
|
|
9
|
+
* API for good — theme code shares the origin with the session cookie, so an
|
|
10
|
+
* allowlisted payout endpoint would be a transaction primitive sitting next to
|
|
11
|
+
* untrusted markup. The panel therefore shows what has been earned and says
|
|
12
|
+
* where the payout is arranged.
|
|
12
13
|
*
|
|
13
14
|
* Nothing here adds two balances together either. The server sends five
|
|
14
15
|
* figures; summing them into a friendlier one produces a number no other
|
|
@@ -27,6 +28,18 @@ export function isEnrolledInReferrals(summary: SdkCustomerAffiliateSummary): boo
|
|
|
27
28
|
return summary.state !== 'not_enrolled';
|
|
28
29
|
}
|
|
29
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Whether the links section has anything to offer.
|
|
33
|
+
*
|
|
34
|
+
* Enrollment and link creation are separate answers: with auto-join off the
|
|
35
|
+
* shop reports `not_enrolled` and still lets the buyer make their first link,
|
|
36
|
+
* which is what enrolls them. Only when it allows neither is there nothing
|
|
37
|
+
* but the state to say.
|
|
38
|
+
*/
|
|
39
|
+
export function offersReferralLinks(summary: SdkCustomerAffiliateSummary): boolean {
|
|
40
|
+
return isEnrolledInReferrals(summary) || summary.can_create_custom_links;
|
|
41
|
+
}
|
|
42
|
+
|
|
30
43
|
/**
|
|
31
44
|
* The link a buyer shares, or null when the server built none.
|
|
32
45
|
*
|
|
@@ -44,6 +57,16 @@ export function isAwaitingApproval(link: SdkCustomerAffiliateLink): boolean {
|
|
|
44
57
|
return link.status === 'pending';
|
|
45
58
|
}
|
|
46
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Whether the link may be handed out. Checkout resolves only an approved,
|
|
62
|
+
* active link (`CouponService.resolveAffiliateCodeAsCoupon`), so a pending,
|
|
63
|
+
* rejected or switched-off one would send buyers who get no discount and earn
|
|
64
|
+
* the affiliate nothing.
|
|
65
|
+
*/
|
|
66
|
+
export function isShareableLink(link: SdkCustomerAffiliateLink): boolean {
|
|
67
|
+
return link.status === 'active';
|
|
68
|
+
}
|
|
69
|
+
|
|
47
70
|
const CLAIM_TYPE_KEYS: Readonly<Record<string, string>> = {
|
|
48
71
|
STORE_CREDIT: 'referrals.claimStoreCredit',
|
|
49
72
|
CRYPTO_PAYOUT_REQUEST: 'referrals.claimCryptoPayout',
|
|
@@ -66,3 +89,153 @@ export function isForeignBalanceCurrency(
|
|
|
66
89
|
return summary.balance_currency.toUpperCase() !== shopCurrency.toUpperCase();
|
|
67
90
|
}
|
|
68
91
|
|
|
92
|
+
|
|
93
|
+
type AffiliateCommission = SdkCustomerAffiliateSummary['commissions'][number];
|
|
94
|
+
type CommissionLedgerStatus = AffiliateCommission['ledger_status'];
|
|
95
|
+
|
|
96
|
+
const LEDGER_STATUS_KEYS: Readonly<Record<CommissionLedgerStatus, string>> = {
|
|
97
|
+
waiting_payment: 'referrals.ledgerWaitingPayment',
|
|
98
|
+
earned: 'referrals.ledgerEarned',
|
|
99
|
+
in_payout_request: 'referrals.ledgerInPayoutRequest',
|
|
100
|
+
paid_out: 'referrals.ledgerPaidOut',
|
|
101
|
+
store_credit: 'referrals.ledgerStoreCredit',
|
|
102
|
+
split: 'referrals.ledgerSplit',
|
|
103
|
+
voided: 'referrals.ledgerVoided',
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/** The shared status word whose chip tone each ledger status borrows. */
|
|
107
|
+
const LEDGER_STATUS_TONES: Readonly<Record<CommissionLedgerStatus, string>> = {
|
|
108
|
+
waiting_payment: 'PENDING',
|
|
109
|
+
earned: 'APPROVED',
|
|
110
|
+
in_payout_request: 'REQUESTED',
|
|
111
|
+
paid_out: 'PAID',
|
|
112
|
+
store_credit: 'CONVERTED',
|
|
113
|
+
split: 'PAID',
|
|
114
|
+
voided: 'VOIDED',
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The label key for a commission's ledger status.
|
|
119
|
+
*
|
|
120
|
+
* `status` is the raw row state and stays APPROVED after the money has left
|
|
121
|
+
* the ledger; `ledger_status` says whether it was paid out, became store
|
|
122
|
+
* credit or went both ways (`split`), which is what the buyer asks.
|
|
123
|
+
*/
|
|
124
|
+
export function commissionLedgerKey(status: CommissionLedgerStatus): string {
|
|
125
|
+
return LEDGER_STATUS_KEYS[status];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function commissionLedgerTone(status: CommissionLedgerStatus): string {
|
|
129
|
+
return LEDGER_STATUS_TONES[status];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface CommissionAmounts {
|
|
133
|
+
/** The figure the row leads with. */
|
|
134
|
+
amount: string;
|
|
135
|
+
/** The original commission, or null when `amount` already is all of it. */
|
|
136
|
+
total: string | null;
|
|
137
|
+
/** The part paid out, or null when there is none or `amount` already is it. */
|
|
138
|
+
paidOut: string | null;
|
|
139
|
+
/** The part turned into store credit, or null when there is none or `amount` already is it. */
|
|
140
|
+
storeCredit: string | null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* What a commission row shows as money.
|
|
145
|
+
*
|
|
146
|
+
* `commission_amount` is what the sale earned in full. An earned row leads
|
|
147
|
+
* with what is still earned, a payout-request row with `requested_amount`,
|
|
148
|
+
* a paid-out row with `paid_amount`, a store-credit
|
|
149
|
+
* row with `store_credit_amount`. Every other destination part is named on its
|
|
150
|
+
* own: a split commission is "20 paid out, 5 store credit", never one settled
|
|
151
|
+
* sum.
|
|
152
|
+
*/
|
|
153
|
+
export function commissionAmounts(commission: AffiliateCommission): CommissionAmounts {
|
|
154
|
+
const status = commission.ledger_status;
|
|
155
|
+
const amount = status === 'earned'
|
|
156
|
+
? commission.earned_amount
|
|
157
|
+
: status === 'in_payout_request'
|
|
158
|
+
? commission.requested_amount
|
|
159
|
+
: status === 'paid_out'
|
|
160
|
+
? commission.paid_amount
|
|
161
|
+
: status === 'store_credit'
|
|
162
|
+
? commission.store_credit_amount
|
|
163
|
+
: commission.commission_amount;
|
|
164
|
+
return {
|
|
165
|
+
amount,
|
|
166
|
+
total: Number(amount) !== Number(commission.commission_amount) ? commission.commission_amount : null,
|
|
167
|
+
paidOut: status !== 'paid_out' && Number(commission.paid_amount) > 0 ? commission.paid_amount : null,
|
|
168
|
+
storeCredit: status !== 'store_credit' && Number(commission.store_credit_amount) > 0
|
|
169
|
+
? commission.store_credit_amount
|
|
170
|
+
: null,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* A rate the buyer asks for, read strictly.
|
|
176
|
+
*
|
|
177
|
+
* Empty is "the shop's own rate" and answers null. Anything else has to be a
|
|
178
|
+
* plain percentage between 0 and 100 with at most two decimals: `Number()`
|
|
179
|
+
* would take `1e2` for 100 and `0x10` for 16, and a rate the buyer did not mean
|
|
180
|
+
* to ask for is a link sitting in the shop's approval queue under the wrong
|
|
181
|
+
* terms. `undefined` is "not a rate".
|
|
182
|
+
*/
|
|
183
|
+
export function parseRequestedRate(raw: string): number | null | undefined {
|
|
184
|
+
const value = raw.trim();
|
|
185
|
+
if (value === '') return null;
|
|
186
|
+
// A decimal comma is how German or French keyboards type 12.5, so either
|
|
187
|
+
// separator is read as the decimal point. Only one may appear, with one or
|
|
188
|
+
// two digits after it: `1,234` or `1.234,5` could be a thousands group and is
|
|
189
|
+
// refused rather than guessed at.
|
|
190
|
+
if (!/^\d{1,3}([.,]\d{1,2})?$/.test(value)) return undefined;
|
|
191
|
+
const rate = Number(value.replace(',', '.'));
|
|
192
|
+
return rate <= 100 ? rate : undefined;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export interface ReferralLinkDraft {
|
|
196
|
+
label: string;
|
|
197
|
+
code: string;
|
|
198
|
+
commission: string;
|
|
199
|
+
discount: string;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export type ReferralLinkInputResult =
|
|
203
|
+
| {
|
|
204
|
+
ok: true;
|
|
205
|
+
input: {
|
|
206
|
+
label: string;
|
|
207
|
+
code: string;
|
|
208
|
+
requested_affiliate_revenue_percent?: number;
|
|
209
|
+
requested_affiliate_customer_discount_percent?: number;
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
| { ok: false; reason: 'required' | 'rate' };
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* What the new-link form sends, or why it sends nothing.
|
|
216
|
+
*
|
|
217
|
+
* The producer owns every rule about a code — its length, whether it is taken,
|
|
218
|
+
* how many links a buyer may hold — and answers with its own sentence. Two
|
|
219
|
+
* things are settled here first: both required fields carry something, and a
|
|
220
|
+
* requested rate is a rate. A rate left empty is left OUT: a present one puts
|
|
221
|
+
* the link in the shop's approval queue, an absent one is the shop's default.
|
|
222
|
+
*/
|
|
223
|
+
export function referralLinkInput(draft: ReferralLinkDraft): ReferralLinkInputResult {
|
|
224
|
+
const label = draft.label.trim();
|
|
225
|
+
const code = draft.code.trim();
|
|
226
|
+
if (label === '' || code === '') return { ok: false, reason: 'required' };
|
|
227
|
+
|
|
228
|
+
const commission = parseRequestedRate(draft.commission);
|
|
229
|
+
const discount = parseRequestedRate(draft.discount);
|
|
230
|
+
if (commission === undefined || discount === undefined) return { ok: false, reason: 'rate' };
|
|
231
|
+
|
|
232
|
+
return {
|
|
233
|
+
ok: true,
|
|
234
|
+
input: {
|
|
235
|
+
label,
|
|
236
|
+
code,
|
|
237
|
+
...(commission !== null ? { requested_affiliate_revenue_percent: commission } : {}),
|
|
238
|
+
...(discount !== null ? { requested_affiliate_customer_discount_percent: discount } : {}),
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
@@ -118,6 +118,7 @@ export function useAccountAvailability(reads: AccountShellReads): AccountAvailab
|
|
|
118
118
|
subscriptionsCount: dashboard.state.data.subscriptions.length,
|
|
119
119
|
walletPresent: dashboard.state.data.wallet !== null,
|
|
120
120
|
affiliateState: dashboard.state.data.affiliate.state,
|
|
121
|
+
affiliateCanCreateLinks: dashboard.state.data.affiliate.can_create_custom_links,
|
|
121
122
|
}
|
|
122
123
|
: null,
|
|
123
124
|
program?.ok ? program.data : null,
|
|
@@ -159,7 +159,10 @@
|
|
|
159
159
|
"warrantyClaimSending": "جارٍ الإرسال…",
|
|
160
160
|
"warrantyClaimDone": "وصل طلبك إلى المتجر. سيردّون عبر البريد الإلكتروني.",
|
|
161
161
|
"warrantyClaimFailed": "تعذّر إرسال طلبك.",
|
|
162
|
-
"warrantyClaimTooLong": "لا يمكن أن يتجاوز طلبك {max} حرف."
|
|
162
|
+
"warrantyClaimTooLong": "لا يمكن أن يتجاوز طلبك {max} حرف.",
|
|
163
|
+
"invoicePdf": "تنزيل الفاتورة (PDF)",
|
|
164
|
+
"invoicePdfLoading": "جارٍ التحضير…",
|
|
165
|
+
"invoicePdfFailed": "تعذّر تنزيل هذه الفاتورة. يُرجى المحاولة مرة أخرى."
|
|
163
166
|
},
|
|
164
167
|
"downloads": {
|
|
165
168
|
"loading": "جارٍ تحميل تنزيلاتك",
|
|
@@ -316,6 +319,16 @@
|
|
|
316
319
|
"commissionsEmptyTitle": "لا توجد عمولات بعد",
|
|
317
320
|
"commissionsEmptyBody": "تظهر هنا مبيعات الإحالة المعتمدة.",
|
|
318
321
|
"commissionFor": "الطلب {id}",
|
|
322
|
+
"ledgerWaitingPayment": "قيد الانتظار",
|
|
323
|
+
"ledgerEarned": "مكتسبة",
|
|
324
|
+
"ledgerInPayoutRequest": "في طلب صرف",
|
|
325
|
+
"ledgerPaidOut": "تم الدفع",
|
|
326
|
+
"ledgerStoreCredit": "رصيد المتجر",
|
|
327
|
+
"ledgerSplit": "مقسّم",
|
|
328
|
+
"ledgerVoided": "باطل",
|
|
329
|
+
"paidOutPart": "تم دفع {amount}",
|
|
330
|
+
"storeCreditPart": "{amount} رصيد المتجر",
|
|
331
|
+
"ofTotal": "من {total}",
|
|
319
332
|
"balanceTitle": "حركة الرصيد",
|
|
320
333
|
"balanceEmptyTitle": "لا توجد حركة رصيد بعد",
|
|
321
334
|
"balanceEmptyBody": "تظهر هنا التحويلات والدفعات.",
|
|
@@ -324,7 +337,23 @@
|
|
|
324
337
|
"claimAdjustment": "تسوية",
|
|
325
338
|
"differentCurrency": "رصيد إحالاتك محفوظ بعملة {currency}.",
|
|
326
339
|
"convertedLabel": "حُوِّل إلى رصيد المتجر",
|
|
327
|
-
"paidLabel": "تم الدفع"
|
|
340
|
+
"paidLabel": "تم الدفع",
|
|
341
|
+
"newLink": "رابط جديد",
|
|
342
|
+
"linkLabel": "الاسم",
|
|
343
|
+
"linkLabelPlaceholder": "حملة يوتيوب",
|
|
344
|
+
"linkCode": "الرمز",
|
|
345
|
+
"linkCommission": "العمولة المطلوبة (%)",
|
|
346
|
+
"linkDiscount": "خصم المشتري المطلوب (%)",
|
|
347
|
+
"linkRatePlaceholder": "افتراضي المتجر",
|
|
348
|
+
"linkRatesHint": "اترك النسبتين فارغتين لاستخدام نسب المتجر. الرابط الذي يطلب نسبًا خاصة ينتظر موافقة المتجر.",
|
|
349
|
+
"createLink": "إنشاء الرابط",
|
|
350
|
+
"creatingLink": "جارٍ الإنشاء…",
|
|
351
|
+
"linkCreated": "رابطك جاهز للمشاركة.",
|
|
352
|
+
"linkRequested": "رابطك بانتظار موافقة المتجر.",
|
|
353
|
+
"linkFailed": "تعذّر إنشاء رابطك. يُرجى المحاولة مرة أخرى.",
|
|
354
|
+
"linkRequired": "أدخل اسمًا ورمزًا لرابطك.",
|
|
355
|
+
"linkRateInvalid": "أدخل كل نسبة كقيمة مئوية بين 0 و100 بمنزلتين عشريتين على الأكثر، مثل 12.5.",
|
|
356
|
+
"linksEmptyCanCreate": "أنشئ رابطًا برمزك الخاص."
|
|
328
357
|
},
|
|
329
358
|
"support": {
|
|
330
359
|
"loading": "جارٍ تحميل تذاكرك",
|
|
@@ -393,7 +422,15 @@
|
|
|
393
422
|
"signOutOthersDone": "تم تسجيل الخروج من كل الأجهزة الأخرى.",
|
|
394
423
|
"devicesFailed": "تعذّر تحميل أجهزتك.",
|
|
395
424
|
"signOutDeviceFailed": "تعذّر تسجيل الخروج من هذا الجهاز. يُرجى المحاولة مرة أخرى.",
|
|
396
|
-
"deviceOn": "{browser} على {os}"
|
|
425
|
+
"deviceOn": "{browser} على {os}",
|
|
426
|
+
"orderEmailsTitle": "رسائل الطلبات",
|
|
427
|
+
"orderEmailsLoading": "جارٍ تحميل إعدادات رسائل الطلبات",
|
|
428
|
+
"orderCreated": "تأكيدات الطلبات",
|
|
429
|
+
"orderCreatedNote": "رسالة عند إتمام طلب.",
|
|
430
|
+
"orderCompleted": "إيصالات الطلبات",
|
|
431
|
+
"orderCompletedNote": "الإيصالات وإشعارات اكتمال الطلب. الرسالة التي تسلّم منتجاتك تُرسل دائمًا.",
|
|
432
|
+
"paymentIssue": "مشكلات الدفع",
|
|
433
|
+
"paymentIssueNote": "رسالة عندما تحتاج عملية دفع إلى انتباهك."
|
|
397
434
|
},
|
|
398
435
|
"walletTopup": {
|
|
399
436
|
"title": "إضافة رصيد المتجر",
|
|
@@ -159,7 +159,10 @@
|
|
|
159
159
|
"warrantyClaimSending": "Wird gesendet…",
|
|
160
160
|
"warrantyClaimDone": "Der Shop hat deinen Fall erhalten. Die Antwort kommt per E-Mail.",
|
|
161
161
|
"warrantyClaimFailed": "Dein Fall konnte nicht gesendet werden.",
|
|
162
|
-
"warrantyClaimTooLong": "Dein Fall darf höchstens {max} Zeichen lang sein."
|
|
162
|
+
"warrantyClaimTooLong": "Dein Fall darf höchstens {max} Zeichen lang sein.",
|
|
163
|
+
"invoicePdf": "Rechnung herunterladen (PDF)",
|
|
164
|
+
"invoicePdfLoading": "Wird vorbereitet…",
|
|
165
|
+
"invoicePdfFailed": "Wir konnten diese Rechnung nicht herunterladen. Bitte versuch es erneut."
|
|
163
166
|
},
|
|
164
167
|
"downloads": {
|
|
165
168
|
"loading": "Deine Downloads werden geladen",
|
|
@@ -316,6 +319,16 @@
|
|
|
316
319
|
"commissionsEmptyTitle": "Noch keine Provisionen",
|
|
317
320
|
"commissionsEmptyBody": "Freigegebene Empfehlungsverkäufe erscheinen hier.",
|
|
318
321
|
"commissionFor": "Bestellung {id}",
|
|
322
|
+
"ledgerWaitingPayment": "Ausstehend",
|
|
323
|
+
"ledgerEarned": "Verdient",
|
|
324
|
+
"ledgerInPayoutRequest": "In Auszahlungsanfrage",
|
|
325
|
+
"ledgerPaidOut": "Ausgezahlt",
|
|
326
|
+
"ledgerStoreCredit": "Shop-Guthaben",
|
|
327
|
+
"ledgerSplit": "Aufgeteilt",
|
|
328
|
+
"ledgerVoided": "Annulliert",
|
|
329
|
+
"paidOutPart": "{amount} ausgezahlt",
|
|
330
|
+
"storeCreditPart": "{amount} Shop-Guthaben",
|
|
331
|
+
"ofTotal": "von {total}",
|
|
319
332
|
"balanceTitle": "Guthabenbewegungen",
|
|
320
333
|
"balanceEmptyTitle": "Noch keine Guthabenbewegungen",
|
|
321
334
|
"balanceEmptyBody": "Umwandlungen und Auszahlungen erscheinen hier.",
|
|
@@ -324,7 +337,23 @@
|
|
|
324
337
|
"claimAdjustment": "Korrektur",
|
|
325
338
|
"differentCurrency": "Dein Empfehlungsguthaben wird in {currency} geführt.",
|
|
326
339
|
"convertedLabel": "In Shop-Guthaben umgewandelt",
|
|
327
|
-
"paidLabel": "Ausgezahlt"
|
|
340
|
+
"paidLabel": "Ausgezahlt",
|
|
341
|
+
"newLink": "Neuer Link",
|
|
342
|
+
"linkLabel": "Name",
|
|
343
|
+
"linkLabelPlaceholder": "YouTube-Kampagne",
|
|
344
|
+
"linkCode": "Code",
|
|
345
|
+
"linkCommission": "Gewünschte Provision (%)",
|
|
346
|
+
"linkDiscount": "Gewünschter Käuferrabatt (%)",
|
|
347
|
+
"linkRatePlaceholder": "Standard des Shops",
|
|
348
|
+
"linkRatesHint": "Lass beide Sätze leer, um die des Shops zu nutzen. Ein Link mit eigenen Sätzen wartet auf die Freigabe durch den Shop.",
|
|
349
|
+
"createLink": "Link erstellen",
|
|
350
|
+
"creatingLink": "Wird erstellt…",
|
|
351
|
+
"linkCreated": "Dein Link ist bereit zum Teilen.",
|
|
352
|
+
"linkRequested": "Dein Link wartet auf die Freigabe durch den Shop.",
|
|
353
|
+
"linkFailed": "Wir konnten deinen Link nicht erstellen. Bitte versuch es erneut.",
|
|
354
|
+
"linkRequired": "Gib einen Namen und einen Code für deinen Link ein.",
|
|
355
|
+
"linkRateInvalid": "Gib jeden Satz als Prozentwert zwischen 0 und 100 mit höchstens zwei Nachkommastellen ein, zum Beispiel 12,5.",
|
|
356
|
+
"linksEmptyCanCreate": "Erstell einen mit deinem eigenen Code."
|
|
328
357
|
},
|
|
329
358
|
"support": {
|
|
330
359
|
"loading": "Deine Anfragen werden geladen",
|
|
@@ -393,7 +422,15 @@
|
|
|
393
422
|
"signOutOthersDone": "Alle anderen Geräte wurden abgemeldet.",
|
|
394
423
|
"devicesFailed": "Deine Geräte konnten nicht geladen werden.",
|
|
395
424
|
"signOutDeviceFailed": "Dieses Gerät konnte nicht abgemeldet werden. Bitte versuche es noch einmal.",
|
|
396
|
-
"deviceOn": "{browser} auf {os}"
|
|
425
|
+
"deviceOn": "{browser} auf {os}",
|
|
426
|
+
"orderEmailsTitle": "Bestell-E-Mails",
|
|
427
|
+
"orderEmailsLoading": "Deine Bestell-E-Mails werden geladen",
|
|
428
|
+
"orderCreated": "Bestellbestätigungen",
|
|
429
|
+
"orderCreatedNote": "Eine E-Mail, wenn du eine Bestellung aufgibst.",
|
|
430
|
+
"orderCompleted": "Bestellbelege",
|
|
431
|
+
"orderCompletedNote": "Belege und Abschlussmeldungen. Die E-Mail, die deine Artikel liefert, wird immer gesendet.",
|
|
432
|
+
"paymentIssue": "Zahlungsprobleme",
|
|
433
|
+
"paymentIssueNote": "Eine E-Mail, wenn eine Zahlung deine Aufmerksamkeit braucht."
|
|
397
434
|
},
|
|
398
435
|
"walletTopup": {
|
|
399
436
|
"title": "Guthaben aufladen",
|
|
@@ -159,7 +159,10 @@
|
|
|
159
159
|
"warrantyClaimSending": "Sending…",
|
|
160
160
|
"warrantyClaimDone": "The store has your claim. They reply by email.",
|
|
161
161
|
"warrantyClaimFailed": "Your claim could not be sent.",
|
|
162
|
-
"warrantyClaimTooLong": "Your claim can be at most {max} characters."
|
|
162
|
+
"warrantyClaimTooLong": "Your claim can be at most {max} characters.",
|
|
163
|
+
"invoicePdf": "Download invoice (PDF)",
|
|
164
|
+
"invoicePdfLoading": "Preparing…",
|
|
165
|
+
"invoicePdfFailed": "We could not download this invoice. Please try again."
|
|
163
166
|
},
|
|
164
167
|
"downloads": {
|
|
165
168
|
"loading": "Loading your downloads",
|
|
@@ -316,6 +319,16 @@
|
|
|
316
319
|
"commissionsEmptyTitle": "No commissions yet",
|
|
317
320
|
"commissionsEmptyBody": "Approved referral sales appear here.",
|
|
318
321
|
"commissionFor": "Order {id}",
|
|
322
|
+
"ledgerWaitingPayment": "Pending",
|
|
323
|
+
"ledgerEarned": "Earned",
|
|
324
|
+
"ledgerInPayoutRequest": "In payout request",
|
|
325
|
+
"ledgerPaidOut": "Paid out",
|
|
326
|
+
"ledgerStoreCredit": "Store credit",
|
|
327
|
+
"ledgerSplit": "Split",
|
|
328
|
+
"ledgerVoided": "Voided",
|
|
329
|
+
"paidOutPart": "{amount} paid out",
|
|
330
|
+
"storeCreditPart": "{amount} store credit",
|
|
331
|
+
"ofTotal": "of {total}",
|
|
319
332
|
"balanceTitle": "Balance activity",
|
|
320
333
|
"balanceEmptyTitle": "No balance activity yet",
|
|
321
334
|
"balanceEmptyBody": "Conversions and payouts appear here.",
|
|
@@ -324,7 +337,23 @@
|
|
|
324
337
|
"claimAdjustment": "Adjustment",
|
|
325
338
|
"differentCurrency": "Your referral balance is held in {currency}.",
|
|
326
339
|
"convertedLabel": "Moved to store credit",
|
|
327
|
-
"paidLabel": "Paid out"
|
|
340
|
+
"paidLabel": "Paid out",
|
|
341
|
+
"newLink": "New link",
|
|
342
|
+
"linkLabel": "Name",
|
|
343
|
+
"linkLabelPlaceholder": "YouTube campaign",
|
|
344
|
+
"linkCode": "Code",
|
|
345
|
+
"linkCommission": "Commission you ask for (%)",
|
|
346
|
+
"linkDiscount": "Buyer discount you ask for (%)",
|
|
347
|
+
"linkRatePlaceholder": "Store default",
|
|
348
|
+
"linkRatesHint": "Leave both rates empty to use the store's own. A link that asks for its own rates waits for the store's approval.",
|
|
349
|
+
"createLink": "Create link",
|
|
350
|
+
"creatingLink": "Creating…",
|
|
351
|
+
"linkCreated": "Your link is ready to share.",
|
|
352
|
+
"linkRequested": "Your link is waiting for the store's approval.",
|
|
353
|
+
"linkFailed": "We could not create your link. Please try again.",
|
|
354
|
+
"linkRequired": "Enter a name and a code for your link.",
|
|
355
|
+
"linkRateInvalid": "Enter each rate as a percentage between 0 and 100 with at most two decimals, for example 12.5.",
|
|
356
|
+
"linksEmptyCanCreate": "Make one with a code of your own."
|
|
328
357
|
},
|
|
329
358
|
"support": {
|
|
330
359
|
"loading": "Loading your tickets",
|
|
@@ -393,7 +422,15 @@
|
|
|
393
422
|
"signOutOthersDone": "Every other device was signed out.",
|
|
394
423
|
"devicesFailed": "Your devices could not be loaded.",
|
|
395
424
|
"signOutDeviceFailed": "That device could not be signed out. Please try again.",
|
|
396
|
-
"deviceOn": "{browser} on {os}"
|
|
425
|
+
"deviceOn": "{browser} on {os}",
|
|
426
|
+
"orderEmailsTitle": "Order emails",
|
|
427
|
+
"orderEmailsLoading": "Loading your order emails",
|
|
428
|
+
"orderCreated": "Order confirmations",
|
|
429
|
+
"orderCreatedNote": "An email when you place an order.",
|
|
430
|
+
"orderCompleted": "Order receipts",
|
|
431
|
+
"orderCompletedNote": "Receipts and completion notices. The email that delivers your items is always sent.",
|
|
432
|
+
"paymentIssue": "Payment issues",
|
|
433
|
+
"paymentIssueNote": "An email when a payment needs your attention."
|
|
397
434
|
},
|
|
398
435
|
"walletTopup": {
|
|
399
436
|
"title": "Add store credit",
|
|
@@ -159,7 +159,10 @@
|
|
|
159
159
|
"warrantyClaimSending": "Enviando…",
|
|
160
160
|
"warrantyClaimDone": "La tienda ha recibido tu reclamación. Te responderán por correo.",
|
|
161
161
|
"warrantyClaimFailed": "No se ha podido enviar tu reclamación.",
|
|
162
|
-
"warrantyClaimTooLong": "Tu reclamación no puede superar los {max} caracteres."
|
|
162
|
+
"warrantyClaimTooLong": "Tu reclamación no puede superar los {max} caracteres.",
|
|
163
|
+
"invoicePdf": "Descargar factura (PDF)",
|
|
164
|
+
"invoicePdfLoading": "Preparando…",
|
|
165
|
+
"invoicePdfFailed": "No pudimos descargar esta factura. Inténtalo de nuevo."
|
|
163
166
|
},
|
|
164
167
|
"downloads": {
|
|
165
168
|
"loading": "Cargando tus descargas",
|
|
@@ -316,6 +319,16 @@
|
|
|
316
319
|
"commissionsEmptyTitle": "Aún no hay comisiones",
|
|
317
320
|
"commissionsEmptyBody": "Las ventas por referido aprobadas aparecen aquí.",
|
|
318
321
|
"commissionFor": "Pedido {id}",
|
|
322
|
+
"ledgerWaitingPayment": "Pendiente",
|
|
323
|
+
"ledgerEarned": "Ganado",
|
|
324
|
+
"ledgerInPayoutRequest": "En solicitud de pago",
|
|
325
|
+
"ledgerPaidOut": "Pagado",
|
|
326
|
+
"ledgerStoreCredit": "Saldo de la tienda",
|
|
327
|
+
"ledgerSplit": "Dividido",
|
|
328
|
+
"ledgerVoided": "Anulado",
|
|
329
|
+
"paidOutPart": "{amount} pagado",
|
|
330
|
+
"storeCreditPart": "{amount} en saldo de la tienda",
|
|
331
|
+
"ofTotal": "de {total}",
|
|
319
332
|
"balanceTitle": "Movimientos del saldo",
|
|
320
333
|
"balanceEmptyTitle": "Aún no hay movimientos de saldo",
|
|
321
334
|
"balanceEmptyBody": "Las conversiones y los pagos aparecen aquí.",
|
|
@@ -324,7 +337,23 @@
|
|
|
324
337
|
"claimAdjustment": "Ajuste",
|
|
325
338
|
"differentCurrency": "Tu saldo de referidos se lleva en {currency}.",
|
|
326
339
|
"convertedLabel": "Convertido en saldo",
|
|
327
|
-
"paidLabel": "Pagado"
|
|
340
|
+
"paidLabel": "Pagado",
|
|
341
|
+
"newLink": "Nuevo enlace",
|
|
342
|
+
"linkLabel": "Nombre",
|
|
343
|
+
"linkLabelPlaceholder": "Campaña de YouTube",
|
|
344
|
+
"linkCode": "Código",
|
|
345
|
+
"linkCommission": "Comisión que solicitas (%)",
|
|
346
|
+
"linkDiscount": "Descuento para compradores que solicitas (%)",
|
|
347
|
+
"linkRatePlaceholder": "Valor de la tienda",
|
|
348
|
+
"linkRatesHint": "Deja ambos porcentajes vacíos para usar los de la tienda. Un enlace que pide porcentajes propios espera la aprobación de la tienda.",
|
|
349
|
+
"createLink": "Crear enlace",
|
|
350
|
+
"creatingLink": "Creando…",
|
|
351
|
+
"linkCreated": "Tu enlace está listo para compartir.",
|
|
352
|
+
"linkRequested": "Tu enlace espera la aprobación de la tienda.",
|
|
353
|
+
"linkFailed": "No pudimos crear tu enlace. Inténtalo de nuevo.",
|
|
354
|
+
"linkRequired": "Escribe un nombre y un código para tu enlace.",
|
|
355
|
+
"linkRateInvalid": "Escribe cada porcentaje como un valor entre 0 y 100 con dos decimales como máximo, por ejemplo 12,5.",
|
|
356
|
+
"linksEmptyCanCreate": "Crea uno con tu propio código."
|
|
328
357
|
},
|
|
329
358
|
"support": {
|
|
330
359
|
"loading": "Cargando tus tickets",
|
|
@@ -393,7 +422,15 @@
|
|
|
393
422
|
"signOutOthersDone": "Se cerró la sesión en los demás dispositivos.",
|
|
394
423
|
"devicesFailed": "No se pudieron cargar tus dispositivos.",
|
|
395
424
|
"signOutDeviceFailed": "No se pudo cerrar la sesión de ese dispositivo. Inténtalo de nuevo.",
|
|
396
|
-
"deviceOn": "{browser} en {os}"
|
|
425
|
+
"deviceOn": "{browser} en {os}",
|
|
426
|
+
"orderEmailsTitle": "Correos de pedidos",
|
|
427
|
+
"orderEmailsLoading": "Cargando tus correos de pedidos",
|
|
428
|
+
"orderCreated": "Confirmaciones de pedido",
|
|
429
|
+
"orderCreatedNote": "Un correo cuando haces un pedido.",
|
|
430
|
+
"orderCompleted": "Recibos de pedido",
|
|
431
|
+
"orderCompletedNote": "Recibos y avisos de finalización. El correo que entrega tus artículos se envía siempre.",
|
|
432
|
+
"paymentIssue": "Problemas de pago",
|
|
433
|
+
"paymentIssueNote": "Un correo cuando un pago requiere tu atención."
|
|
397
434
|
},
|
|
398
435
|
"walletTopup": {
|
|
399
436
|
"title": "Añadir saldo",
|
|
@@ -159,7 +159,10 @@
|
|
|
159
159
|
"warrantyClaimSending": "Lähetetään…",
|
|
160
160
|
"warrantyClaimDone": "Kauppa sai vaatimuksesi. He vastaavat sähköpostitse.",
|
|
161
161
|
"warrantyClaimFailed": "Vaatimustasi ei voitu lähettää.",
|
|
162
|
-
"warrantyClaimTooLong": "Vaatimuksessa saa olla enintään {max} merkkiä."
|
|
162
|
+
"warrantyClaimTooLong": "Vaatimuksessa saa olla enintään {max} merkkiä.",
|
|
163
|
+
"invoicePdf": "Lataa lasku (PDF)",
|
|
164
|
+
"invoicePdfLoading": "Valmistellaan…",
|
|
165
|
+
"invoicePdfFailed": "Laskua ei voitu ladata. Yritä uudelleen."
|
|
163
166
|
},
|
|
164
167
|
"downloads": {
|
|
165
168
|
"loading": "Ladataan latauksiasi",
|
|
@@ -316,6 +319,16 @@
|
|
|
316
319
|
"commissionsEmptyTitle": "Ei vielä provisioita",
|
|
317
320
|
"commissionsEmptyBody": "Hyväksytyt suosittelumyynnit näkyvät täällä.",
|
|
318
321
|
"commissionFor": "Tilaus {id}",
|
|
322
|
+
"ledgerWaitingPayment": "Odottaa",
|
|
323
|
+
"ledgerEarned": "Ansaittu",
|
|
324
|
+
"ledgerInPayoutRequest": "Maksupyynnössä",
|
|
325
|
+
"ledgerPaidOut": "Maksettu ulos",
|
|
326
|
+
"ledgerStoreCredit": "Kaupan saldo",
|
|
327
|
+
"ledgerSplit": "Jaettu",
|
|
328
|
+
"ledgerVoided": "Mitätöity",
|
|
329
|
+
"paidOutPart": "{amount} maksettu ulos",
|
|
330
|
+
"storeCreditPart": "{amount} kaupan saldoa",
|
|
331
|
+
"ofTotal": "yhteensä {total}",
|
|
319
332
|
"balanceTitle": "Saldotapahtumat",
|
|
320
333
|
"balanceEmptyTitle": "Ei vielä saldotapahtumia",
|
|
321
334
|
"balanceEmptyBody": "Muunnot ja maksut näkyvät täällä.",
|
|
@@ -324,7 +337,23 @@
|
|
|
324
337
|
"claimAdjustment": "Oikaisu",
|
|
325
338
|
"differentCurrency": "Suosittelusaldosi säilytetään valuutassa {currency}.",
|
|
326
339
|
"convertedLabel": "Siirretty kaupan saldoon",
|
|
327
|
-
"paidLabel": "Maksettu ulos"
|
|
340
|
+
"paidLabel": "Maksettu ulos",
|
|
341
|
+
"newLink": "Uusi linkki",
|
|
342
|
+
"linkLabel": "Nimi",
|
|
343
|
+
"linkLabelPlaceholder": "YouTube-kampanja",
|
|
344
|
+
"linkCode": "Koodi",
|
|
345
|
+
"linkCommission": "Pyydetty komissio (%)",
|
|
346
|
+
"linkDiscount": "Pyydetty ostajan alennus (%)",
|
|
347
|
+
"linkRatePlaceholder": "Kaupan oletus",
|
|
348
|
+
"linkRatesHint": "Jätä molemmat prosentit tyhjiksi, niin käytetään kaupan omia. Omia prosentteja pyytävä linkki odottaa kaupan hyväksyntää.",
|
|
349
|
+
"createLink": "Luo linkki",
|
|
350
|
+
"creatingLink": "Luodaan…",
|
|
351
|
+
"linkCreated": "Linkkisi on valmis jaettavaksi.",
|
|
352
|
+
"linkRequested": "Linkkisi odottaa kaupan hyväksyntää.",
|
|
353
|
+
"linkFailed": "Linkkiäsi ei voitu luoda. Yritä uudelleen.",
|
|
354
|
+
"linkRequired": "Anna linkille nimi ja koodi.",
|
|
355
|
+
"linkRateInvalid": "Anna kumpikin prosentti väliltä 0–100 enintään kahdella desimaalilla, esimerkiksi 12,5.",
|
|
356
|
+
"linksEmptyCanCreate": "Luo linkki omalla koodillasi."
|
|
328
357
|
},
|
|
329
358
|
"support": {
|
|
330
359
|
"loading": "Ladataan tukipyyntöjäsi",
|
|
@@ -393,7 +422,15 @@
|
|
|
393
422
|
"signOutOthersDone": "Kaikki muut laitteet kirjattiin ulos.",
|
|
394
423
|
"devicesFailed": "Laitteitasi ei voitu ladata.",
|
|
395
424
|
"signOutDeviceFailed": "Tätä laitetta ei voitu kirjata ulos. Yritä uudelleen.",
|
|
396
|
-
"deviceOn": "{browser} järjestelmässä {os}"
|
|
425
|
+
"deviceOn": "{browser} järjestelmässä {os}",
|
|
426
|
+
"orderEmailsTitle": "Tilausviestit",
|
|
427
|
+
"orderEmailsLoading": "Ladataan tilausviestien asetuksia",
|
|
428
|
+
"orderCreated": "Tilausvahvistukset",
|
|
429
|
+
"orderCreatedNote": "Sähköposti, kun teet tilauksen.",
|
|
430
|
+
"orderCompleted": "Tilauskuitit",
|
|
431
|
+
"orderCompletedNote": "Kuitit ja valmistumisilmoitukset. Tuotteesi toimittava sähköposti lähetetään aina.",
|
|
432
|
+
"paymentIssue": "Maksuongelmat",
|
|
433
|
+
"paymentIssueNote": "Sähköposti, kun maksu vaatii huomiotasi."
|
|
397
434
|
},
|
|
398
435
|
"walletTopup": {
|
|
399
436
|
"title": "Lisää kauppasaldoa",
|