@designbasekorea/figma-ui 0.7.0 → 0.7.1
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/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +14 -0
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.css.map +1 -1
- package/dist/index.esm.js +149 -37
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +148 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -52,12 +52,16 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
52
52
|
'form.submit': '제출',
|
|
53
53
|
'form.verifying': '확인 중...',
|
|
54
54
|
'license.youtube_membership': 'YouTube 멤버십',
|
|
55
|
+
'license.current_plan': '현재 플랜',
|
|
56
|
+
'license.pro_plan': '프로 플랜',
|
|
57
|
+
'license.membership': '멤버십',
|
|
55
58
|
'license.pro_account': '프로 계정',
|
|
56
59
|
'license.upgrade_to_pro': '프로로 업그레이드',
|
|
57
60
|
'license.all_features_available': '모든 기능을 사용할 수 있습니다.',
|
|
58
61
|
'license.youtube_membership_description': 'YouTube 멤버십에 가입하면 Designbase 플러그인을 무제한으로 사용할 수 있습니다.',
|
|
59
62
|
'license.purchase_for_unlimited': '디자인베이스 멤버십 또는 라이선스로 무제한 이용이 가능합니다.',
|
|
60
63
|
'license.usage_unlimited': '사용 횟수 제한 없음',
|
|
64
|
+
'license.active_until_expiry': '만료일까지 모든 기능을 제한 없이 사용할 수 있습니다.',
|
|
61
65
|
'license.usage_daily': '오늘 남은 횟수 {{remaining}}/{{limit}}',
|
|
62
66
|
'license.usage_weekly': '이번 주 남은 횟수 {{remaining}}/{{limit}}',
|
|
63
67
|
'license.usage_monthly': '이번 달 남은 횟수 {{remaining}}/{{limit}}',
|
|
@@ -67,6 +71,7 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
67
71
|
'license.spots_remaining': '자리 남음',
|
|
68
72
|
'license.deactivating': '비활성화 중...',
|
|
69
73
|
'license.deactivate': '라이선스 비활성화',
|
|
74
|
+
'license.deactivate_hint': '이 기기에서 라이선스 연결을 해제합니다.',
|
|
70
75
|
'license.designbase_account': '디자인베이스 계정',
|
|
71
76
|
'license.designbase_account_hint': 'WordPress 계정으로 로그인하거나 멤버십을 구매하면 플러그인이 자동으로 활성화됩니다.',
|
|
72
77
|
'license.authenticating': '인증 중...',
|
|
@@ -185,12 +190,16 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
185
190
|
'form.submit': 'Activate',
|
|
186
191
|
'form.verifying': 'Verifying...',
|
|
187
192
|
'license.youtube_membership': 'YouTube Membership',
|
|
193
|
+
'license.current_plan': 'Current plan',
|
|
194
|
+
'license.pro_plan': 'Pro plan',
|
|
195
|
+
'license.membership': 'Membership',
|
|
188
196
|
'license.pro_account': 'Pro account',
|
|
189
197
|
'license.upgrade_to_pro': 'Upgrade to Pro',
|
|
190
198
|
'license.all_features_available': 'All features are available.',
|
|
191
199
|
'license.youtube_membership_description': 'Join YouTube Membership to use Designbase plugins without limits.',
|
|
192
200
|
'license.purchase_for_unlimited': 'Get unlimited access with a Designbase membership or license.',
|
|
193
201
|
'license.usage_unlimited': 'Unlimited usage',
|
|
202
|
+
'license.active_until_expiry': 'All features remain available without limits until expiration.',
|
|
194
203
|
'license.usage_daily': '{{remaining}}/{{limit}} remaining today',
|
|
195
204
|
'license.usage_weekly': '{{remaining}}/{{limit}} remaining this week',
|
|
196
205
|
'license.usage_monthly': '{{remaining}}/{{limit}} remaining this month',
|
|
@@ -200,6 +209,7 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
200
209
|
'license.spots_remaining': 'spots remaining',
|
|
201
210
|
'license.deactivating': 'Deactivating...',
|
|
202
211
|
'license.deactivate': 'Deactivate license',
|
|
212
|
+
'license.deactivate_hint': 'Disconnects this license from the current device.',
|
|
203
213
|
'license.designbase_account': 'Designbase account',
|
|
204
214
|
'license.designbase_account_hint': 'Sign in with your WordPress account or purchase a membership to activate the plugin automatically.',
|
|
205
215
|
'license.authenticating': 'Authenticating...',
|
|
@@ -318,12 +328,16 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
318
328
|
'form.submit': '有効化',
|
|
319
329
|
'form.verifying': '確認中...',
|
|
320
330
|
'license.youtube_membership': 'YouTubeメンバーシップ',
|
|
331
|
+
'license.current_plan': '現在のプラン',
|
|
332
|
+
'license.pro_plan': 'Proプラン',
|
|
333
|
+
'license.membership': 'メンバーシップ',
|
|
321
334
|
'license.pro_account': 'Proアカウント',
|
|
322
335
|
'license.upgrade_to_pro': 'Proにアップグレード',
|
|
323
336
|
'license.all_features_available': 'すべての機能を使用できます。',
|
|
324
337
|
'license.youtube_membership_description': 'YouTubeメンバーシップに参加すると、Designbaseプラグインを無制限で使用できます。',
|
|
325
338
|
'license.purchase_for_unlimited': 'Designbaseのメンバーシップまたはライセンスで無制限に利用できます。',
|
|
326
339
|
'license.usage_unlimited': '使用回数の制限なし',
|
|
340
|
+
'license.active_until_expiry': '有効期限まで、すべての機能を制限なく使用できます。',
|
|
327
341
|
'license.usage_daily': '今日の残り {{remaining}}/{{limit}}回',
|
|
328
342
|
'license.usage_weekly': '今週の残り {{remaining}}/{{limit}}回',
|
|
329
343
|
'license.usage_monthly': '今月の残り {{remaining}}/{{limit}}回',
|
|
@@ -333,6 +347,7 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
333
347
|
'license.spots_remaining': '枠残り',
|
|
334
348
|
'license.deactivating': '無効化中...',
|
|
335
349
|
'license.deactivate': 'ライセンスを無効化',
|
|
350
|
+
'license.deactivate_hint': 'このデバイスからライセンスの接続を解除します。',
|
|
336
351
|
'license.designbase_account': 'Designbaseアカウント',
|
|
337
352
|
'license.designbase_account_hint': 'WordPressアカウントでサインインするか、メンバーシップを購入するとプラグインが自動的に有効化されます。',
|
|
338
353
|
'license.authenticating': '認証中...',
|
|
@@ -981,7 +996,7 @@ const fallbackText = (t, key, fallback) => {
|
|
|
981
996
|
const translated = t?.(key);
|
|
982
997
|
return translated && translated !== key ? translated : fallback;
|
|
983
998
|
};
|
|
984
|
-
const UsageStatusPopover = ({ paymentStatus, usageCount = 0, remainingUsage, maxDailyUsage = 20, showUsage = true, showPlan = true, isLoading = false, onLicensePageClick, t, locale, className, }) => {
|
|
999
|
+
const UsageStatusPopover = ({ paymentStatus, usageCount = 0, remainingUsage, maxDailyUsage = 20, showUsage = true, showPlan = true, isLoading = false, onLicensePageClick, licenseSource, accessScope, expiresAt, lastVerifiedAt, t, locale, className, }) => {
|
|
985
1000
|
const { t: translate } = useFigmaUiI18n(locale, t);
|
|
986
1001
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
987
1002
|
const rootRef = React.useRef(null);
|
|
@@ -1004,9 +1019,12 @@ const UsageStatusPopover = ({ paymentStatus, usageCount = 0, remainingUsage, max
|
|
|
1004
1019
|
: paymentStatus === 'TRIAL'
|
|
1005
1020
|
? fallbackText(translate, 'trialPlan', '체험판')
|
|
1006
1021
|
: fallbackText(translate, 'free', '무료');
|
|
1007
|
-
const
|
|
1022
|
+
const planSuffix = fallbackText(translate, 'planSuffix', '플랜');
|
|
1023
|
+
const normalizedPlanLabel = planLabel.toLocaleLowerCase();
|
|
1024
|
+
const normalizedPlanSuffix = planSuffix.toLocaleLowerCase();
|
|
1025
|
+
const planTitle = isBeta || normalizedPlanLabel.includes(normalizedPlanSuffix)
|
|
1008
1026
|
? planLabel
|
|
1009
|
-
: `${planLabel} ${
|
|
1027
|
+
: `${planLabel} ${planSuffix}`;
|
|
1010
1028
|
const triggerLabel = isPaid
|
|
1011
1029
|
? `${planLabel}, ${fallbackText(translate, 'unlimitedUsage', '무제한 사용 가능')}`
|
|
1012
1030
|
: isBeta
|
|
@@ -1017,6 +1035,41 @@ const UsageStatusPopover = ({ paymentStatus, usageCount = 0, remainingUsage, max
|
|
|
1017
1035
|
const upgradeLabel = isPaid
|
|
1018
1036
|
? fallbackText(translate, 'managePlan', '플랜 관리')
|
|
1019
1037
|
: fallbackText(translate, 'upgradePlan', '플랜 업그레이드');
|
|
1038
|
+
const resolvedLocale = locale || 'ko';
|
|
1039
|
+
const formatDate = (value) => {
|
|
1040
|
+
if (!value)
|
|
1041
|
+
return undefined;
|
|
1042
|
+
const date = new Date(value);
|
|
1043
|
+
if (Number.isNaN(date.getTime()))
|
|
1044
|
+
return value;
|
|
1045
|
+
return new Intl.DateTimeFormat(resolvedLocale, { dateStyle: 'medium' }).format(date);
|
|
1046
|
+
};
|
|
1047
|
+
const formattedSource = licenseSource === 'youtube_membership' || licenseSource === 'membership'
|
|
1048
|
+
? fallbackText(translate, 'license.source_youtube_membership', 'YouTube 멤버십')
|
|
1049
|
+
: licenseSource === 'lemonsqueezy'
|
|
1050
|
+
? fallbackText(translate, 'license.source_purchase', '구매 라이선스')
|
|
1051
|
+
: licenseSource;
|
|
1052
|
+
const formattedScope = accessScope === 'all-products' || accessScope === 'all_products'
|
|
1053
|
+
? fallbackText(translate, 'license.all_plugins', '모든 플러그인')
|
|
1054
|
+
: accessScope;
|
|
1055
|
+
const paidMetadata = [
|
|
1056
|
+
formattedSource && {
|
|
1057
|
+
label: fallbackText(translate, 'license.membership', '멤버십'),
|
|
1058
|
+
value: formattedSource,
|
|
1059
|
+
},
|
|
1060
|
+
expiresAt && {
|
|
1061
|
+
label: fallbackText(translate, 'license.expires', '만료일'),
|
|
1062
|
+
value: formatDate(expiresAt),
|
|
1063
|
+
},
|
|
1064
|
+
formattedScope && {
|
|
1065
|
+
label: fallbackText(translate, 'license.access', '접근 범위'),
|
|
1066
|
+
value: formattedScope,
|
|
1067
|
+
},
|
|
1068
|
+
lastVerifiedAt && {
|
|
1069
|
+
label: fallbackText(translate, 'license.last_checked', '최근 확인'),
|
|
1070
|
+
value: formatDate(lastVerifiedAt),
|
|
1071
|
+
},
|
|
1072
|
+
].filter(Boolean);
|
|
1020
1073
|
React.useEffect(() => {
|
|
1021
1074
|
if (!isOpen)
|
|
1022
1075
|
return undefined;
|
|
@@ -1051,7 +1104,10 @@ const UsageStatusPopover = ({ paymentStatus, usageCount = 0, remainingUsage, max
|
|
|
1051
1104
|
'designbase-figma-usage-status--loading': isLoading,
|
|
1052
1105
|
}, className) },
|
|
1053
1106
|
React.createElement("div", { className: "designbase-figma-usage-status__control" },
|
|
1054
|
-
showUsage && (React.createElement("button", { ref: triggerRef, type: "button", className: "designbase-figma-usage-status__trigger", "aria-expanded": isOpen, "aria-controls": popoverId, "aria-haspopup": "dialog", "aria-label": isLoading ? fallbackText(translate, 'loading', '불러오는 중') : triggerLabel, disabled: isLoading, onClick: togglePopover }, isLoading ? (React.createElement("span", { className: "designbase-figma-usage-status__skeleton", "aria-hidden": "true" })) : isPaid ? (React.createElement(
|
|
1107
|
+
showUsage && (React.createElement("button", { ref: triggerRef, type: "button", className: "designbase-figma-usage-status__trigger", "aria-expanded": isOpen, "aria-controls": popoverId, "aria-haspopup": "dialog", "aria-label": isLoading ? fallbackText(translate, 'loading', '불러오는 중') : triggerLabel, disabled: isLoading, onClick: togglePopover }, isLoading ? (React.createElement("span", { className: "designbase-figma-usage-status__skeleton", "aria-hidden": "true" })) : isPaid ? (React.createElement(React.Fragment, null,
|
|
1108
|
+
React.createElement("span", { className: "designbase-figma-usage-status__mini-progress", "aria-hidden": "true" },
|
|
1109
|
+
React.createElement("span", { style: { width: '100%' } })),
|
|
1110
|
+
React.createElement("span", { className: "designbase-figma-usage-status__unlimited-mark", "aria-hidden": "true" }, "\u221E"))) : hasDailyLimit ? (React.createElement(React.Fragment, null,
|
|
1055
1111
|
React.createElement("span", { className: "designbase-figma-usage-status__mini-progress", "aria-hidden": "true" },
|
|
1056
1112
|
React.createElement("span", { style: { width: `${remainingPercent}%` } })),
|
|
1057
1113
|
React.createElement("span", { className: "designbase-figma-usage-status__usage-value" },
|
|
@@ -1062,11 +1118,19 @@ const UsageStatusPopover = ({ paymentStatus, usageCount = 0, remainingUsage, max
|
|
|
1062
1118
|
showPlan && !isLoading && (React.createElement("button", { type: "button", className: "designbase-figma-usage-status__plan-badge", "aria-expanded": isOpen, "aria-controls": popoverId, "aria-haspopup": "dialog", "aria-label": planTitle, onClick: togglePopover }, planLabel))),
|
|
1063
1119
|
isOpen && (React.createElement("div", { id: popoverId, className: "designbase-figma-usage-status__popover", role: "dialog", "aria-label": fallbackText(translate, 'usageDetails', '사용량 상세') },
|
|
1064
1120
|
React.createElement("div", { className: "designbase-figma-usage-status__popover-header" },
|
|
1065
|
-
React.createElement("span", { className: "designbase-figma-usage-status__plan-
|
|
1121
|
+
React.createElement("span", { className: "designbase-figma-usage-status__plan-heading" },
|
|
1122
|
+
React.createElement("span", null, fallbackText(translate, 'license.current_plan', '현재 플랜')),
|
|
1123
|
+
React.createElement("strong", null, planTitle)),
|
|
1066
1124
|
!isBeta && (React.createElement(react.Button, { className: "designbase-figma-usage-status__upgrade", variant: isPaid ? 'secondary' : 'primary', size: "s", endIcon: "chevron-right", onPress: handleManageClick }, upgradeLabel))),
|
|
1067
|
-
isPaid ? (React.createElement(
|
|
1068
|
-
React.createElement("
|
|
1069
|
-
|
|
1125
|
+
isPaid ? (React.createElement(React.Fragment, null,
|
|
1126
|
+
React.createElement("div", { className: "designbase-figma-usage-status__unlimited-copy" },
|
|
1127
|
+
React.createElement("span", { className: "designbase-figma-usage-status__unlimited-mark", "aria-hidden": "true" }, "\u221E"),
|
|
1128
|
+
React.createElement("span", null,
|
|
1129
|
+
React.createElement("strong", null, fallbackText(translate, 'unlimitedUsage', '무제한 사용')),
|
|
1130
|
+
React.createElement("small", null, fallbackText(translate, 'unlimitedUsageTooltip', '모든 기능을 제한 없이 사용할 수 있습니다')))),
|
|
1131
|
+
paidMetadata.length > 0 && (React.createElement("dl", { className: "designbase-figma-usage-status__license-meta" }, paidMetadata.map((item) => (React.createElement("div", { key: item.label },
|
|
1132
|
+
React.createElement("dt", null, item.label),
|
|
1133
|
+
React.createElement("dd", null, item.value)))))))) : isBeta ? (React.createElement("p", { className: "designbase-figma-usage-status__note" }, fallbackText(translate, 'betaUsageDescription', '베타 기간에는 사용량 제한이 적용되지 않습니다'))) : hasDailyLimit ? (React.createElement("div", { className: "designbase-figma-usage-status__usage-detail" },
|
|
1070
1134
|
React.createElement("div", { className: "designbase-figma-usage-status__usage-summary" },
|
|
1071
1135
|
React.createElement("strong", { className: "designbase-figma-usage-status__usage-count" },
|
|
1072
1136
|
remaining,
|
|
@@ -1168,7 +1232,7 @@ FigmaToastProvider.displayName = 'FigmaToastProvider';
|
|
|
1168
1232
|
FigmaToast.displayName = 'FigmaToast';
|
|
1169
1233
|
|
|
1170
1234
|
const DEFAULT_LOW_USAGE_WARNING = { key: 'lowUsageWarning' };
|
|
1171
|
-
const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount = 0, remainingUsage, listenForUsageMessages = true, isLoading = false, showPaymentStatus = true, showUsageInfo = true, maxDailyUsage = 20, showLowUsageWarning = true, lowUsageThresholdPercent = 10, lowUsageWarningText = DEFAULT_LOW_USAGE_WARNING, onLowUsageWarning, showPaymentBadge = true, showDonation = true, donationUrl = 'https://buymeacoffee.com/designbase', donationText = { key: 'donation.buy_me_a_coffee' }, showDonationText = true, donationPromptText, showLanguageSelector = true, currentLanguage = 'ko', languages, onLanguageChange, logoSrc, logoAlt = 'DesignBase', logoType = 'designbase', logoSize = 'xs', logoLinks, className, t, children, }) => {
|
|
1235
|
+
const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount = 0, remainingUsage, listenForUsageMessages = true, isLoading = false, showPaymentStatus = true, showUsageInfo = true, maxDailyUsage = 20, licenseSource, accessScope, expiresAt, lastVerifiedAt, showLowUsageWarning = true, lowUsageThresholdPercent = 10, lowUsageWarningText = DEFAULT_LOW_USAGE_WARNING, onLowUsageWarning, showPaymentBadge = true, showDonation = true, donationUrl = 'https://buymeacoffee.com/designbase', donationText = { key: 'donation.buy_me_a_coffee' }, showDonationText = true, donationPromptText, showLanguageSelector = true, currentLanguage = 'ko', languages, onLanguageChange, logoSrc, logoAlt = 'DesignBase', logoType = 'designbase', logoSize = 'xs', logoLinks, className, t, children, }) => {
|
|
1172
1236
|
const { t: translate } = useFigmaUiI18n(currentLanguage, t);
|
|
1173
1237
|
const { showToast, toastComponent } = useFigmaToast();
|
|
1174
1238
|
const [liveUsage, setLiveUsage] = React.useState({});
|
|
@@ -1178,12 +1242,17 @@ const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount =
|
|
|
1178
1242
|
const effectiveUsageCount = liveUsage.usageCount ?? usageCount;
|
|
1179
1243
|
const effectiveRemainingUsage = liveUsage.remainingUsage ?? remainingUsage;
|
|
1180
1244
|
const effectiveMaxDailyUsage = liveUsage.maxDailyUsage ?? maxDailyUsage;
|
|
1245
|
+
const effectiveLicenseSource = liveUsage.licenseSource ?? licenseSource;
|
|
1246
|
+
const effectiveAccessScope = liveUsage.accessScope ?? accessScope;
|
|
1247
|
+
const effectiveExpiresAt = liveUsage.expiresAt ?? expiresAt;
|
|
1248
|
+
const effectiveLastVerifiedAt = liveUsage.lastVerifiedAt ?? lastVerifiedAt;
|
|
1181
1249
|
const limit = Math.max(1, Math.round(effectiveMaxDailyUsage));
|
|
1182
1250
|
const resolvedRemaining = typeof effectiveRemainingUsage === 'number' && Number.isFinite(effectiveRemainingUsage)
|
|
1183
1251
|
? Math.min(limit, Math.max(0, Math.round(effectiveRemainingUsage)))
|
|
1184
1252
|
: Math.max(0, limit - Math.min(limit, Math.max(0, Math.round(effectiveUsageCount))));
|
|
1185
1253
|
const remainingPercent = Math.round((resolvedRemaining / limit) * 100);
|
|
1186
|
-
const resolvedShowUsageInfo = showPaymentStatus
|
|
1254
|
+
const resolvedShowUsageInfo = showPaymentStatus
|
|
1255
|
+
&& (showUsageInfo || effectivePaymentStatus === 'FREE' || effectivePaymentStatus === 'PAID');
|
|
1187
1256
|
const resolvedShowPaymentBadge = showPaymentStatus && showPaymentBadge;
|
|
1188
1257
|
const resolvedLicensePageClick = effectivePaymentStatus === 'BETA' ? undefined : onLicensePageClick;
|
|
1189
1258
|
const hasChildren = React.Children.count(children) > 0;
|
|
@@ -1209,10 +1278,31 @@ const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount =
|
|
|
1209
1278
|
: message.paymentStatus === 'FREE' || message.paymentStatus === 'UNPAID'
|
|
1210
1279
|
? 'FREE'
|
|
1211
1280
|
: undefined;
|
|
1281
|
+
const nextLicenseSource = typeof message.licenseSource === 'string' ? message.licenseSource : undefined;
|
|
1282
|
+
const nextAccessScope = typeof message.accessScope === 'string' ? message.accessScope : undefined;
|
|
1283
|
+
const nextExpiresAt = typeof message.expiresAt === 'string' ? message.expiresAt : undefined;
|
|
1284
|
+
const rawLastVerifiedAt = message.lastVerifiedAt;
|
|
1285
|
+
const numericLastVerifiedAt = typeof rawLastVerifiedAt === 'number' && Number.isFinite(rawLastVerifiedAt)
|
|
1286
|
+
? rawLastVerifiedAt < 1000000000000
|
|
1287
|
+
? rawLastVerifiedAt * 1000
|
|
1288
|
+
: rawLastVerifiedAt
|
|
1289
|
+
: undefined;
|
|
1290
|
+
const parsedLastVerifiedAt = numericLastVerifiedAt === undefined
|
|
1291
|
+
? undefined
|
|
1292
|
+
: new Date(numericLastVerifiedAt);
|
|
1293
|
+
const nextLastVerifiedAt = typeof rawLastVerifiedAt === 'string'
|
|
1294
|
+
? rawLastVerifiedAt
|
|
1295
|
+
: parsedLastVerifiedAt && !Number.isNaN(parsedLastVerifiedAt.getTime())
|
|
1296
|
+
? parsedLastVerifiedAt.toISOString()
|
|
1297
|
+
: undefined;
|
|
1212
1298
|
if (nextPaymentStatus === undefined
|
|
1213
1299
|
&& nextLimit === undefined
|
|
1214
1300
|
&& nextUsed === undefined
|
|
1215
|
-
&& nextRemaining === undefined
|
|
1301
|
+
&& nextRemaining === undefined
|
|
1302
|
+
&& nextLicenseSource === undefined
|
|
1303
|
+
&& nextAccessScope === undefined
|
|
1304
|
+
&& nextExpiresAt === undefined
|
|
1305
|
+
&& nextLastVerifiedAt === undefined) {
|
|
1216
1306
|
return;
|
|
1217
1307
|
}
|
|
1218
1308
|
setLiveUsage((previous) => ({
|
|
@@ -1221,6 +1311,10 @@ const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount =
|
|
|
1221
1311
|
...(typeof nextLimit === 'number' ? { maxDailyUsage: nextLimit } : {}),
|
|
1222
1312
|
...(typeof nextUsed === 'number' ? { usageCount: nextUsed } : {}),
|
|
1223
1313
|
...(typeof nextRemaining === 'number' ? { remainingUsage: nextRemaining } : {}),
|
|
1314
|
+
...(nextLicenseSource ? { licenseSource: nextLicenseSource } : {}),
|
|
1315
|
+
...(nextAccessScope ? { accessScope: nextAccessScope } : {}),
|
|
1316
|
+
...(nextExpiresAt ? { expiresAt: nextExpiresAt } : {}),
|
|
1317
|
+
...(nextLastVerifiedAt ? { lastVerifiedAt: nextLastVerifiedAt } : {}),
|
|
1224
1318
|
}));
|
|
1225
1319
|
};
|
|
1226
1320
|
window.addEventListener('message', handleUsageMessage);
|
|
@@ -1279,7 +1373,7 @@ const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount =
|
|
|
1279
1373
|
React.createElement("div", { className: "designbase-figma-footer__left" },
|
|
1280
1374
|
React.createElement(LogoDropdown, { logoSrc: logoSrc, logoAlt: logoAlt, logoType: logoType, logoSize: logoSize, links: logoLinks, languages: languages, currentLanguage: currentLanguage, showLanguageSelector: showLanguageSelector, onLanguageChange: onLanguageChange, t: translate })),
|
|
1281
1375
|
React.createElement("div", { className: "designbase-figma-footer__right" },
|
|
1282
|
-
(resolvedShowUsageInfo || resolvedShowPaymentBadge) && (React.createElement(UsageStatusPopover, { paymentStatus: effectivePaymentStatus, usageCount: effectiveUsageCount, remainingUsage: effectiveRemainingUsage, maxDailyUsage: effectiveMaxDailyUsage, showUsage: resolvedShowUsageInfo, showPlan: resolvedShowPaymentBadge, isLoading: isLoading, onLicensePageClick: resolvedLicensePageClick, t: translate })),
|
|
1376
|
+
(resolvedShowUsageInfo || resolvedShowPaymentBadge) && (React.createElement(UsageStatusPopover, { paymentStatus: effectivePaymentStatus, usageCount: effectiveUsageCount, remainingUsage: effectiveRemainingUsage, maxDailyUsage: effectiveMaxDailyUsage, showUsage: resolvedShowUsageInfo, showPlan: resolvedShowPaymentBadge, isLoading: isLoading, onLicensePageClick: resolvedLicensePageClick, licenseSource: effectiveLicenseSource, accessScope: effectiveAccessScope, expiresAt: effectiveExpiresAt, lastVerifiedAt: effectiveLastVerifiedAt, locale: currentLanguage, t: translate })),
|
|
1283
1377
|
showDonation && (React.createElement(DonationBadge, { donationUrl: donationUrl, text: donationText, iconType: "heart", size: "s", iconOnly: true, showPrompt: false, t: translate })))),
|
|
1284
1378
|
children,
|
|
1285
1379
|
toastComponent));
|
|
@@ -1292,9 +1386,15 @@ const FormWithSubmit = ({ onLicenseSubmit, disabled = false, isSubmitting = fals
|
|
|
1292
1386
|
React.useEffect(() => {
|
|
1293
1387
|
setInputValue(value);
|
|
1294
1388
|
}, [value]);
|
|
1389
|
+
const submitLicense = async () => {
|
|
1390
|
+
const normalizedValue = inputValue.trim();
|
|
1391
|
+
if (!normalizedValue || disabled || isSubmitting)
|
|
1392
|
+
return;
|
|
1393
|
+
await onLicenseSubmit(normalizedValue);
|
|
1394
|
+
};
|
|
1295
1395
|
const handleSubmit = async (e) => {
|
|
1296
1396
|
e.preventDefault();
|
|
1297
|
-
await
|
|
1397
|
+
await submitLicense();
|
|
1298
1398
|
};
|
|
1299
1399
|
const handleChange = (value) => {
|
|
1300
1400
|
setInputValue(value);
|
|
@@ -1314,7 +1414,9 @@ const FormWithSubmit = ({ onLicenseSubmit, disabled = false, isSubmitting = fals
|
|
|
1314
1414
|
handleChange(value);
|
|
1315
1415
|
}
|
|
1316
1416
|
}, placeholder: displayPlaceholder, helperText: displayHelperText, disabled: disabled || isSubmitting, size: "m" })),
|
|
1317
|
-
React.createElement(react.Button, { type: "
|
|
1417
|
+
React.createElement(react.Button, { type: "button", variant: "primary", size: "m", loading: isSubmitting, disabled: !inputValue.trim() || isSubmitting || disabled, fullWidth: true, onPress: () => {
|
|
1418
|
+
void submitLicense();
|
|
1419
|
+
} }, isSubmitting ? displaySubmittingText : displaySubmitText)));
|
|
1318
1420
|
};
|
|
1319
1421
|
FormWithSubmit.displayName = 'FormWithSubmit';
|
|
1320
1422
|
|
|
@@ -1437,7 +1539,7 @@ function formatSource(value, t) {
|
|
|
1437
1539
|
}
|
|
1438
1540
|
return value;
|
|
1439
1541
|
}
|
|
1440
|
-
const LicenseStatusCard = ({ status, licenseKey = '', licenseStatus, licenseSource, accessScope, expiresAt, lastVerifiedAt, validationMessage, allowRevealKey = false, t, locale, className, }) => {
|
|
1542
|
+
const LicenseStatusCard = ({ status, licenseKey = '', licenseStatus, licenseSource, accessScope, expiresAt, lastVerifiedAt, validationMessage, showHeader = true, allowRevealKey = false, t, locale, className, }) => {
|
|
1441
1543
|
const { locale: resolvedLocale, t: translate } = useFigmaUiI18n(locale, t);
|
|
1442
1544
|
const [isKeyRevealed, setIsKeyRevealed] = React.useState(false);
|
|
1443
1545
|
const normalizedLicenseStatus = licenseStatus?.toLowerCase();
|
|
@@ -1448,13 +1550,15 @@ const LicenseStatusCard = ({ status, licenseKey = '', licenseStatus, licenseSour
|
|
|
1448
1550
|
: resolveText(translate, { key: 'license.status_inactive' }, 'License check failed');
|
|
1449
1551
|
const statusClass = isActive ? 'active' : 'inactive';
|
|
1450
1552
|
return (React.createElement("section", { className: `designbase-figma-license-status-card designbase-figma-license-status-card--${statusClass} ${className || ''}`, "aria-label": statusText },
|
|
1451
|
-
React.createElement("div", { className: "designbase-figma-license-status-card__header" },
|
|
1553
|
+
showHeader && (React.createElement("div", { className: "designbase-figma-license-status-card__header" },
|
|
1452
1554
|
React.createElement("div", null,
|
|
1453
1555
|
React.createElement("div", { className: "designbase-figma-license-status-card__eyebrow" }, isActive
|
|
1454
1556
|
? resolveText(translate, { key: 'license.activated' }, '라이선스 활성화됨')
|
|
1455
1557
|
: resolveText(translate, { key: 'license.status_label' }, '라이선스 상태')),
|
|
1456
1558
|
React.createElement("h3", null, statusText)),
|
|
1457
|
-
React.createElement("span", { className: "designbase-figma-license-status-card__badge" },
|
|
1559
|
+
React.createElement("span", { className: "designbase-figma-license-status-card__badge" }, isActive
|
|
1560
|
+
? resolveText(translate, { key: 'license.status_active' }, '활성')
|
|
1561
|
+
: resolveText(translate, { key: 'license.status_inactive' }, '비활성')))),
|
|
1458
1562
|
validationMessage && !isActive && (React.createElement("p", { className: "designbase-figma-license-status-card__message" }, validationMessage)),
|
|
1459
1563
|
licenseKey && (React.createElement("div", { className: "designbase-figma-license-status-card__key-row" },
|
|
1460
1564
|
React.createElement("span", null, resolveText(translate, { key: 'license.key_label' }, '라이선스 키')),
|
|
@@ -1849,7 +1953,7 @@ function formatUsageLabel(state, t) {
|
|
|
1849
1953
|
}
|
|
1850
1954
|
return resolveText(t, { key: 'license.usage_generic', values: { remaining, limit } }, `남은 횟수 ${remaining}/${limit}`) ?? `남은 횟수 ${remaining}/${limit}`;
|
|
1851
1955
|
}
|
|
1852
|
-
const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicenseKey = '', wordpressLinks, paymentPageUrl, mode = 'pricing', membershipUrl, enableAccountAuth = true, showLicenseKeyInput = true, pricingFeatures, pricing, paymentType = 'subscription', messageTypes, onStateChange, setPaymentStatus, setUsageCount, onLicenseSubmit, usageCount: initialUsageCount = 0, t, locale, className, }) => {
|
|
1956
|
+
const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicenseKey = '', licenseStatus: initialLicenseStatus, licenseSource: initialLicenseSource, accessScope: initialAccessScope, expiresAt: initialExpiresAt, lastVerifiedAt: initialLastVerifiedAt, wordpressLinks, paymentPageUrl, mode = 'pricing', membershipUrl, enableAccountAuth = true, showLicenseKeyInput = true, pricingFeatures, pricing, paymentType = 'subscription', messageTypes, onStateChange, setPaymentStatus, setUsageCount, onLicenseSubmit, usageCount: initialUsageCount = 0, t, locale, className, }) => {
|
|
1853
1957
|
const { t: translate } = useFigmaUiI18n(locale, t);
|
|
1854
1958
|
const links = React.useMemo(() => ({
|
|
1855
1959
|
purchaseUrl: wordpressLinks?.purchaseUrl ?? paymentPageUrl,
|
|
@@ -1862,13 +1966,21 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
|
|
|
1862
1966
|
initialState: {
|
|
1863
1967
|
paymentStatus: initialStatus,
|
|
1864
1968
|
licenseKey: initialLicenseKey,
|
|
1969
|
+
hasLicenseKey: Boolean(initialLicenseKey),
|
|
1970
|
+
isLicenseRegistered: initialStatus === 'PAID',
|
|
1971
|
+
planTier: initialStatus === 'PAID' ? 'PRO' : 'FREE',
|
|
1972
|
+
usageLimit: initialStatus === 'PAID' ? 'unlimited' : 0,
|
|
1973
|
+
licenseStatus: initialLicenseStatus,
|
|
1974
|
+
licenseSource: initialLicenseSource,
|
|
1975
|
+
accessScope: initialAccessScope,
|
|
1976
|
+
expiresAt: initialExpiresAt,
|
|
1977
|
+
lastVerifiedAt: initialLastVerifiedAt,
|
|
1865
1978
|
usageCount: initialUsageCount,
|
|
1866
1979
|
},
|
|
1867
1980
|
onStateChange,
|
|
1868
1981
|
onPaymentStatusChange: setPaymentStatus,
|
|
1869
1982
|
onUsageCountChange: setUsageCount,
|
|
1870
1983
|
});
|
|
1871
|
-
const [showDetails, setShowDetails] = React.useState(false);
|
|
1872
1984
|
const [licenseKeyDraft, setLicenseKeyDraft] = React.useState(initialLicenseKey);
|
|
1873
1985
|
const isPaid = state.isLicenseRegistered && state.paymentStatus === 'PAID';
|
|
1874
1986
|
const isMembershipMode = mode === 'youtube-membership';
|
|
@@ -1893,7 +2005,7 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
|
|
|
1893
2005
|
: isPaid
|
|
1894
2006
|
? resolveText(translate, { key: 'license.pro_account' }, '프로 계정')
|
|
1895
2007
|
: resolveText(translate, { key: 'license.upgrade_to_pro' }, '프로로 업그레이드')),
|
|
1896
|
-
|
|
2008
|
+
isPaid && (React.createElement("span", { className: "designbase-figma-page-license__tier" }, resolveText(translate, { key: 'license.pro_plan' }, '프로 플랜')))),
|
|
1897
2009
|
React.createElement("p", { className: "designbase-figma-page-license__description" }, isPaid
|
|
1898
2010
|
? resolveText(translate, { key: 'license.all_features_available' }, '모든 기능을 사용할 수 있습니다.')
|
|
1899
2011
|
: isMembershipMode
|
|
@@ -1901,16 +2013,16 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
|
|
|
1901
2013
|
: resolveText(translate, { key: 'license.purchase_for_unlimited' }, '디자인베이스 멤버십 또는 라이선스로 무제한 이용이 가능합니다.')),
|
|
1902
2014
|
!isPaid && !isMembershipMode && (React.createElement("p", { className: "designbase-figma-page-license__usage" }, usageLabel))),
|
|
1903
2015
|
!isMembershipMode && (React.createElement(PricingComparison, { features: pricingFeatures, pricing: pricing, paymentType: paymentType, t: translate })),
|
|
1904
|
-
state.lastMessage && !state.deactivateMessage && (React.createElement("p", { className: `designbase-figma-page-license__feedback ${state.lastErrorCode ? 'designbase-figma-page-license__feedback--error' : ''}`, "aria-live": "polite" }, state.lastMessage)),
|
|
1905
|
-
isPaid && (React.createElement("div", { className: "designbase-figma-page-
|
|
1906
|
-
React.createElement("div", { className: "designbase-figma-page-
|
|
1907
|
-
React.createElement("
|
|
1908
|
-
React.createElement(
|
|
1909
|
-
React.createElement(
|
|
1910
|
-
|
|
1911
|
-
React.createElement(
|
|
1912
|
-
|
|
1913
|
-
React.createElement("div", { className: "designbase-figma-page-license__activation-info" },
|
|
2016
|
+
state.lastMessage && state.lastErrorCode && !state.deactivateMessage && (React.createElement("p", { className: `designbase-figma-page-license__feedback ${state.lastErrorCode ? 'designbase-figma-page-license__feedback--error' : ''}`, "aria-live": "polite" }, state.lastMessage)),
|
|
2017
|
+
isPaid && (React.createElement("div", { className: "designbase-figma-page-license__paid-summary" },
|
|
2018
|
+
React.createElement("div", { className: "designbase-figma-page-license__paid-hero" },
|
|
2019
|
+
React.createElement("span", { "aria-hidden": "true" }, "\u221E"),
|
|
2020
|
+
React.createElement("div", null,
|
|
2021
|
+
React.createElement("strong", null, resolveText(translate, { key: 'license.usage_unlimited' }, '무제한 사용')),
|
|
2022
|
+
React.createElement("p", null, resolveText(translate, { key: 'license.active_until_expiry' }, '만료일까지 모든 기능을 제한 없이 사용할 수 있습니다.')))),
|
|
2023
|
+
React.createElement(LicenseStatusCard, { status: state.paymentStatus, licenseKey: state.licenseKey, licenseStatus: state.licenseStatus, licenseSource: state.licenseSource, accessScope: state.accessScope, expiresAt: state.expiresAt, lastVerifiedAt: state.lastVerifiedAt, validationMessage: state.validationMessage, allowRevealKey: false, showHeader: false, t: translate }),
|
|
2024
|
+
React.createElement("div", { className: "designbase-figma-page-license__paid-actions" },
|
|
2025
|
+
state.activationLimit > 0 && (React.createElement("div", { className: "designbase-figma-page-license__activation-info" },
|
|
1914
2026
|
React.createElement("div", { className: "designbase-figma-page-license__remaining" },
|
|
1915
2027
|
Math.max(0, state.activationLimit - state.activationUsage),
|
|
1916
2028
|
' ',
|
|
@@ -1920,12 +2032,12 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
|
|
|
1920
2032
|
React.createElement("div", { className: "designbase-figma-page-license__usage-count" },
|
|
1921
2033
|
state.activationUsage,
|
|
1922
2034
|
"/",
|
|
1923
|
-
state.activationLimit)),
|
|
1924
|
-
React.createElement(
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
2035
|
+
state.activationLimit))),
|
|
2036
|
+
React.createElement(react.Button, { onPress: deactivateLicense, variant: "secondary", size: "m", fullWidth: true, disabled: isDeactivating }, isDeactivating
|
|
2037
|
+
? resolveText(translate, { key: 'license.deactivating' }, '비활성화 중...')
|
|
2038
|
+
: resolveText(translate, { key: 'license.deactivate' }, '라이선스 비활성화')),
|
|
2039
|
+
state.deactivateMessage && state.deactivateErrorCode && (React.createElement("p", { className: `designbase-figma-page-license__action-feedback designbase-figma-page-license__action-feedback--${resolvePaymentFeedbackVariant(state.deactivateErrorCode)}`, role: "alert", "aria-live": "polite" }, state.deactivateMessage)),
|
|
2040
|
+
React.createElement("p", { className: "designbase-figma-page-license__deactivate-hint" }, resolveText(translate, { key: 'license.deactivate_hint' }, '이 기기에서 라이선스 연결을 해제합니다.'))))),
|
|
1929
2041
|
!isPaid && (React.createElement(React.Fragment, null,
|
|
1930
2042
|
isMembershipMode && (React.createElement(LicenseOffer, { joinUrl: links.membershipUrl || links.purchaseUrl, guideUrl: links.helpUrl || links.purchaseUrl, t: translate })),
|
|
1931
2043
|
!isMembershipMode && (enableAccountAuth || links.purchaseUrl || links.accountUrl) && (React.createElement("div", { className: "designbase-figma-page-license__section" },
|