@designbasekorea/figma-ui 0.7.0 → 0.7.2
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 +243 -59
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +242 -58
- package/dist/index.js.map +1 -1
- package/package.json +100 -100
package/dist/index.js
CHANGED
|
@@ -52,12 +52,30 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
52
52
|
'form.submit': '제출',
|
|
53
53
|
'form.verifying': '확인 중...',
|
|
54
54
|
'license.youtube_membership': 'YouTube 멤버십',
|
|
55
|
+
'license.unlock_unlimited': '무제한 사용 활성화',
|
|
56
|
+
'license.unlock_unlimited_description': '라이선스 키를 등록하면 모든 Designbase 플러그인의 프로 기능과 무제한 사용을 이용할 수 있습니다.',
|
|
57
|
+
'license.get_key_title': '라이선스 키 받기',
|
|
58
|
+
'license.get_key_description': '멤버십 회원에게 매월 새 라이선스 키가 제공됩니다.',
|
|
59
|
+
'license.get_key_step_1_title': '멤버십 가입',
|
|
60
|
+
'license.get_key_step_1_description': 'Designbase YouTube 채널에서 멤버십에 가입합니다.',
|
|
61
|
+
'license.get_key_step_2_title': '이번 달 키 복사',
|
|
62
|
+
'license.get_key_step_2_description': '멤버 전용 커뮤니티 게시글에서 키를 확인합니다.',
|
|
63
|
+
'license.get_key_step_3_title': '키 등록',
|
|
64
|
+
'license.get_key_step_3_description': '아래 입력창에 붙여 넣으면 프로 기능이 열립니다.',
|
|
65
|
+
'license.get_key_cta': '멤버십 가입하고 키 받기',
|
|
66
|
+
'license.activate_key_title': '라이선스 키 등록',
|
|
67
|
+
'license.activate_key_description': '이미 키가 있다면 아래에 붙여 넣어 프로 기능을 활성화하세요.',
|
|
68
|
+
'license.unlock_pro_features': '프로 기능 활성화',
|
|
69
|
+
'license.current_plan': '현재 플랜',
|
|
70
|
+
'license.pro_plan': '프로 플랜',
|
|
71
|
+
'license.membership': '멤버십',
|
|
55
72
|
'license.pro_account': '프로 계정',
|
|
56
73
|
'license.upgrade_to_pro': '프로로 업그레이드',
|
|
57
74
|
'license.all_features_available': '모든 기능을 사용할 수 있습니다.',
|
|
58
75
|
'license.youtube_membership_description': 'YouTube 멤버십에 가입하면 Designbase 플러그인을 무제한으로 사용할 수 있습니다.',
|
|
59
76
|
'license.purchase_for_unlimited': '디자인베이스 멤버십 또는 라이선스로 무제한 이용이 가능합니다.',
|
|
60
77
|
'license.usage_unlimited': '사용 횟수 제한 없음',
|
|
78
|
+
'license.active_until_expiry': '만료일까지 모든 기능을 제한 없이 사용할 수 있습니다.',
|
|
61
79
|
'license.usage_daily': '오늘 남은 횟수 {{remaining}}/{{limit}}',
|
|
62
80
|
'license.usage_weekly': '이번 주 남은 횟수 {{remaining}}/{{limit}}',
|
|
63
81
|
'license.usage_monthly': '이번 달 남은 횟수 {{remaining}}/{{limit}}',
|
|
@@ -67,6 +85,7 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
67
85
|
'license.spots_remaining': '자리 남음',
|
|
68
86
|
'license.deactivating': '비활성화 중...',
|
|
69
87
|
'license.deactivate': '라이선스 비활성화',
|
|
88
|
+
'license.deactivate_hint': '이 기기에서 라이선스 연결을 해제합니다.',
|
|
70
89
|
'license.designbase_account': '디자인베이스 계정',
|
|
71
90
|
'license.designbase_account_hint': 'WordPress 계정으로 로그인하거나 멤버십을 구매하면 플러그인이 자동으로 활성화됩니다.',
|
|
72
91
|
'license.authenticating': '인증 중...',
|
|
@@ -78,7 +97,7 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
78
97
|
'license.submit': '활성화',
|
|
79
98
|
'license.verifying': '확인 중...',
|
|
80
99
|
'license.enter_from_email': '이메일로 받은 라이선스 키를 입력하세요.',
|
|
81
|
-
'license.enter_from_youtube': '멤버 전용
|
|
100
|
+
'license.enter_from_youtube': '멤버 전용 게시글에서 복사한 이번 달 키를 입력하세요.',
|
|
82
101
|
'license.help_link': '라이선스·결제 도움말',
|
|
83
102
|
'license.youtube_membership_howto': '이용 방법',
|
|
84
103
|
'license.youtube_membership_step_1': 'Designbase YouTube 채널 멤버십에 가입합니다.',
|
|
@@ -185,12 +204,30 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
185
204
|
'form.submit': 'Activate',
|
|
186
205
|
'form.verifying': 'Verifying...',
|
|
187
206
|
'license.youtube_membership': 'YouTube Membership',
|
|
207
|
+
'license.unlock_unlimited': 'Unlock Unlimited Access',
|
|
208
|
+
'license.unlock_unlimited_description': 'Add a license key to unlock Pro features and unlimited use across Designbase plugins.',
|
|
209
|
+
'license.get_key_title': 'Get a license key',
|
|
210
|
+
'license.get_key_description': 'Members receive a new license key every month.',
|
|
211
|
+
'license.get_key_step_1_title': 'Join the membership',
|
|
212
|
+
'license.get_key_step_1_description': 'Join the Designbase YouTube channel membership.',
|
|
213
|
+
'license.get_key_step_2_title': 'Copy this month’s key',
|
|
214
|
+
'license.get_key_step_2_description': 'Find the key in the members-only community post.',
|
|
215
|
+
'license.get_key_step_3_title': 'Activate the key',
|
|
216
|
+
'license.get_key_step_3_description': 'Paste it below to unlock Pro features.',
|
|
217
|
+
'license.get_key_cta': 'Join and get a license key',
|
|
218
|
+
'license.activate_key_title': 'Activate your license key',
|
|
219
|
+
'license.activate_key_description': 'Already have a key? Paste it below to unlock Pro features.',
|
|
220
|
+
'license.unlock_pro_features': 'Unlock Pro features',
|
|
221
|
+
'license.current_plan': 'Current plan',
|
|
222
|
+
'license.pro_plan': 'Pro plan',
|
|
223
|
+
'license.membership': 'Membership',
|
|
188
224
|
'license.pro_account': 'Pro account',
|
|
189
225
|
'license.upgrade_to_pro': 'Upgrade to Pro',
|
|
190
226
|
'license.all_features_available': 'All features are available.',
|
|
191
227
|
'license.youtube_membership_description': 'Join YouTube Membership to use Designbase plugins without limits.',
|
|
192
228
|
'license.purchase_for_unlimited': 'Get unlimited access with a Designbase membership or license.',
|
|
193
229
|
'license.usage_unlimited': 'Unlimited usage',
|
|
230
|
+
'license.active_until_expiry': 'All features remain available without limits until expiration.',
|
|
194
231
|
'license.usage_daily': '{{remaining}}/{{limit}} remaining today',
|
|
195
232
|
'license.usage_weekly': '{{remaining}}/{{limit}} remaining this week',
|
|
196
233
|
'license.usage_monthly': '{{remaining}}/{{limit}} remaining this month',
|
|
@@ -200,6 +237,7 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
200
237
|
'license.spots_remaining': 'spots remaining',
|
|
201
238
|
'license.deactivating': 'Deactivating...',
|
|
202
239
|
'license.deactivate': 'Deactivate license',
|
|
240
|
+
'license.deactivate_hint': 'Disconnects this license from the current device.',
|
|
203
241
|
'license.designbase_account': 'Designbase account',
|
|
204
242
|
'license.designbase_account_hint': 'Sign in with your WordPress account or purchase a membership to activate the plugin automatically.',
|
|
205
243
|
'license.authenticating': 'Authenticating...',
|
|
@@ -211,7 +249,7 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
211
249
|
'license.submit': 'Activate',
|
|
212
250
|
'license.verifying': 'Verifying...',
|
|
213
251
|
'license.enter_from_email': 'Enter the license key you received by email.',
|
|
214
|
-
'license.enter_from_youtube': 'Enter
|
|
252
|
+
'license.enter_from_youtube': 'Enter this month’s key copied from the members-only post.',
|
|
215
253
|
'license.help_link': 'License · payment help',
|
|
216
254
|
'license.youtube_membership_howto': 'How to use',
|
|
217
255
|
'license.youtube_membership_step_1': 'Join the Designbase YouTube channel membership.',
|
|
@@ -318,12 +356,30 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
318
356
|
'form.submit': '有効化',
|
|
319
357
|
'form.verifying': '確認中...',
|
|
320
358
|
'license.youtube_membership': 'YouTubeメンバーシップ',
|
|
359
|
+
'license.unlock_unlimited': '無制限アクセスを有効化',
|
|
360
|
+
'license.unlock_unlimited_description': 'ライセンスキーを登録すると、DesignbaseプラグインのPro機能を無制限で利用できます。',
|
|
361
|
+
'license.get_key_title': 'ライセンスキーを取得',
|
|
362
|
+
'license.get_key_description': 'メンバーには毎月新しいライセンスキーが提供されます。',
|
|
363
|
+
'license.get_key_step_1_title': 'メンバーシップに参加',
|
|
364
|
+
'license.get_key_step_1_description': 'Designbase YouTubeチャンネルのメンバーシップに参加します。',
|
|
365
|
+
'license.get_key_step_2_title': '今月のキーをコピー',
|
|
366
|
+
'license.get_key_step_2_description': 'メンバー限定コミュニティの投稿でキーを確認します。',
|
|
367
|
+
'license.get_key_step_3_title': 'キーを登録',
|
|
368
|
+
'license.get_key_step_3_description': '下の入力欄に貼り付けるとPro機能が利用できます。',
|
|
369
|
+
'license.get_key_cta': '参加してライセンスキーを取得',
|
|
370
|
+
'license.activate_key_title': 'ライセンスキーを登録',
|
|
371
|
+
'license.activate_key_description': 'キーをお持ちの場合は、下に貼り付けてPro機能を有効化してください。',
|
|
372
|
+
'license.unlock_pro_features': 'Pro機能を有効化',
|
|
373
|
+
'license.current_plan': '現在のプラン',
|
|
374
|
+
'license.pro_plan': 'Proプラン',
|
|
375
|
+
'license.membership': 'メンバーシップ',
|
|
321
376
|
'license.pro_account': 'Proアカウント',
|
|
322
377
|
'license.upgrade_to_pro': 'Proにアップグレード',
|
|
323
378
|
'license.all_features_available': 'すべての機能を使用できます。',
|
|
324
379
|
'license.youtube_membership_description': 'YouTubeメンバーシップに参加すると、Designbaseプラグインを無制限で使用できます。',
|
|
325
380
|
'license.purchase_for_unlimited': 'Designbaseのメンバーシップまたはライセンスで無制限に利用できます。',
|
|
326
381
|
'license.usage_unlimited': '使用回数の制限なし',
|
|
382
|
+
'license.active_until_expiry': '有効期限まで、すべての機能を制限なく使用できます。',
|
|
327
383
|
'license.usage_daily': '今日の残り {{remaining}}/{{limit}}回',
|
|
328
384
|
'license.usage_weekly': '今週の残り {{remaining}}/{{limit}}回',
|
|
329
385
|
'license.usage_monthly': '今月の残り {{remaining}}/{{limit}}回',
|
|
@@ -333,6 +389,7 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
333
389
|
'license.spots_remaining': '枠残り',
|
|
334
390
|
'license.deactivating': '無効化中...',
|
|
335
391
|
'license.deactivate': 'ライセンスを無効化',
|
|
392
|
+
'license.deactivate_hint': 'このデバイスからライセンスの接続を解除します。',
|
|
336
393
|
'license.designbase_account': 'Designbaseアカウント',
|
|
337
394
|
'license.designbase_account_hint': 'WordPressアカウントでサインインするか、メンバーシップを購入するとプラグインが自動的に有効化されます。',
|
|
338
395
|
'license.authenticating': '認証中...',
|
|
@@ -344,7 +401,7 @@ const FIGMA_UI_TRANSLATIONS = {
|
|
|
344
401
|
'license.submit': '有効化',
|
|
345
402
|
'license.verifying': '確認中...',
|
|
346
403
|
'license.enter_from_email': 'メールで受け取ったライセンスキーを入力してください。',
|
|
347
|
-
'license.enter_from_youtube': '
|
|
404
|
+
'license.enter_from_youtube': 'メンバー限定投稿からコピーした今月のキーを入力してください。',
|
|
348
405
|
'license.help_link': 'ライセンス・支払いヘルプ',
|
|
349
406
|
'license.youtube_membership_howto': '利用方法',
|
|
350
407
|
'license.youtube_membership_step_1': 'Designbase YouTubeチャンネルのメンバーシップに参加します。',
|
|
@@ -981,7 +1038,7 @@ const fallbackText = (t, key, fallback) => {
|
|
|
981
1038
|
const translated = t?.(key);
|
|
982
1039
|
return translated && translated !== key ? translated : fallback;
|
|
983
1040
|
};
|
|
984
|
-
const UsageStatusPopover = ({ paymentStatus, usageCount = 0, remainingUsage, maxDailyUsage = 20, showUsage = true, showPlan = true, isLoading = false, onLicensePageClick, t, locale, className, }) => {
|
|
1041
|
+
const UsageStatusPopover = ({ paymentStatus, usageCount = 0, remainingUsage, maxDailyUsage = 20, showUsage = true, showPlan = true, isLoading = false, onLicensePageClick, licenseSource, accessScope, expiresAt, lastVerifiedAt, t, locale, className, }) => {
|
|
985
1042
|
const { t: translate } = useFigmaUiI18n(locale, t);
|
|
986
1043
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
987
1044
|
const rootRef = React.useRef(null);
|
|
@@ -1004,9 +1061,12 @@ const UsageStatusPopover = ({ paymentStatus, usageCount = 0, remainingUsage, max
|
|
|
1004
1061
|
: paymentStatus === 'TRIAL'
|
|
1005
1062
|
? fallbackText(translate, 'trialPlan', '체험판')
|
|
1006
1063
|
: fallbackText(translate, 'free', '무료');
|
|
1007
|
-
const
|
|
1064
|
+
const planSuffix = fallbackText(translate, 'planSuffix', '플랜');
|
|
1065
|
+
const normalizedPlanLabel = planLabel.toLocaleLowerCase();
|
|
1066
|
+
const normalizedPlanSuffix = planSuffix.toLocaleLowerCase();
|
|
1067
|
+
const planTitle = isBeta || normalizedPlanLabel.includes(normalizedPlanSuffix)
|
|
1008
1068
|
? planLabel
|
|
1009
|
-
: `${planLabel} ${
|
|
1069
|
+
: `${planLabel} ${planSuffix}`;
|
|
1010
1070
|
const triggerLabel = isPaid
|
|
1011
1071
|
? `${planLabel}, ${fallbackText(translate, 'unlimitedUsage', '무제한 사용 가능')}`
|
|
1012
1072
|
: isBeta
|
|
@@ -1017,6 +1077,41 @@ const UsageStatusPopover = ({ paymentStatus, usageCount = 0, remainingUsage, max
|
|
|
1017
1077
|
const upgradeLabel = isPaid
|
|
1018
1078
|
? fallbackText(translate, 'managePlan', '플랜 관리')
|
|
1019
1079
|
: fallbackText(translate, 'upgradePlan', '플랜 업그레이드');
|
|
1080
|
+
const resolvedLocale = locale || 'ko';
|
|
1081
|
+
const formatDate = (value) => {
|
|
1082
|
+
if (!value)
|
|
1083
|
+
return undefined;
|
|
1084
|
+
const date = new Date(value);
|
|
1085
|
+
if (Number.isNaN(date.getTime()))
|
|
1086
|
+
return value;
|
|
1087
|
+
return new Intl.DateTimeFormat(resolvedLocale, { dateStyle: 'medium' }).format(date);
|
|
1088
|
+
};
|
|
1089
|
+
const formattedSource = licenseSource === 'youtube_membership' || licenseSource === 'membership'
|
|
1090
|
+
? fallbackText(translate, 'license.source_youtube_membership', 'YouTube 멤버십')
|
|
1091
|
+
: licenseSource === 'lemonsqueezy'
|
|
1092
|
+
? fallbackText(translate, 'license.source_purchase', '구매 라이선스')
|
|
1093
|
+
: licenseSource;
|
|
1094
|
+
const formattedScope = accessScope === 'all-products' || accessScope === 'all_products'
|
|
1095
|
+
? fallbackText(translate, 'license.all_plugins', '모든 플러그인')
|
|
1096
|
+
: accessScope;
|
|
1097
|
+
const paidMetadata = [
|
|
1098
|
+
formattedSource && {
|
|
1099
|
+
label: fallbackText(translate, 'license.membership', '멤버십'),
|
|
1100
|
+
value: formattedSource,
|
|
1101
|
+
},
|
|
1102
|
+
expiresAt && {
|
|
1103
|
+
label: fallbackText(translate, 'license.expires', '만료일'),
|
|
1104
|
+
value: formatDate(expiresAt),
|
|
1105
|
+
},
|
|
1106
|
+
formattedScope && {
|
|
1107
|
+
label: fallbackText(translate, 'license.access', '접근 범위'),
|
|
1108
|
+
value: formattedScope,
|
|
1109
|
+
},
|
|
1110
|
+
lastVerifiedAt && {
|
|
1111
|
+
label: fallbackText(translate, 'license.last_checked', '최근 확인'),
|
|
1112
|
+
value: formatDate(lastVerifiedAt),
|
|
1113
|
+
},
|
|
1114
|
+
].filter(Boolean);
|
|
1020
1115
|
React.useEffect(() => {
|
|
1021
1116
|
if (!isOpen)
|
|
1022
1117
|
return undefined;
|
|
@@ -1051,7 +1146,10 @@ const UsageStatusPopover = ({ paymentStatus, usageCount = 0, remainingUsage, max
|
|
|
1051
1146
|
'designbase-figma-usage-status--loading': isLoading,
|
|
1052
1147
|
}, className) },
|
|
1053
1148
|
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(
|
|
1149
|
+
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,
|
|
1150
|
+
React.createElement("span", { className: "designbase-figma-usage-status__mini-progress", "aria-hidden": "true" },
|
|
1151
|
+
React.createElement("span", { style: { width: '100%' } })),
|
|
1152
|
+
React.createElement("span", { className: "designbase-figma-usage-status__unlimited-mark", "aria-hidden": "true" }, "\u221E"))) : hasDailyLimit ? (React.createElement(React.Fragment, null,
|
|
1055
1153
|
React.createElement("span", { className: "designbase-figma-usage-status__mini-progress", "aria-hidden": "true" },
|
|
1056
1154
|
React.createElement("span", { style: { width: `${remainingPercent}%` } })),
|
|
1057
1155
|
React.createElement("span", { className: "designbase-figma-usage-status__usage-value" },
|
|
@@ -1062,11 +1160,19 @@ const UsageStatusPopover = ({ paymentStatus, usageCount = 0, remainingUsage, max
|
|
|
1062
1160
|
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
1161
|
isOpen && (React.createElement("div", { id: popoverId, className: "designbase-figma-usage-status__popover", role: "dialog", "aria-label": fallbackText(translate, 'usageDetails', '사용량 상세') },
|
|
1064
1162
|
React.createElement("div", { className: "designbase-figma-usage-status__popover-header" },
|
|
1065
|
-
React.createElement("span", { className: "designbase-figma-usage-status__plan-
|
|
1163
|
+
React.createElement("span", { className: "designbase-figma-usage-status__plan-heading" },
|
|
1164
|
+
React.createElement("span", null, fallbackText(translate, 'license.current_plan', '현재 플랜')),
|
|
1165
|
+
React.createElement("strong", null, planTitle)),
|
|
1066
1166
|
!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
|
-
|
|
1167
|
+
isPaid ? (React.createElement(React.Fragment, null,
|
|
1168
|
+
React.createElement("div", { className: "designbase-figma-usage-status__unlimited-copy" },
|
|
1169
|
+
React.createElement("span", { className: "designbase-figma-usage-status__unlimited-mark", "aria-hidden": "true" }, "\u221E"),
|
|
1170
|
+
React.createElement("span", null,
|
|
1171
|
+
React.createElement("strong", null, fallbackText(translate, 'unlimitedUsage', '무제한 사용')),
|
|
1172
|
+
React.createElement("small", null, fallbackText(translate, 'unlimitedUsageTooltip', '모든 기능을 제한 없이 사용할 수 있습니다')))),
|
|
1173
|
+
paidMetadata.length > 0 && (React.createElement("dl", { className: "designbase-figma-usage-status__license-meta" }, paidMetadata.map((item) => (React.createElement("div", { key: item.label },
|
|
1174
|
+
React.createElement("dt", null, item.label),
|
|
1175
|
+
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
1176
|
React.createElement("div", { className: "designbase-figma-usage-status__usage-summary" },
|
|
1071
1177
|
React.createElement("strong", { className: "designbase-figma-usage-status__usage-count" },
|
|
1072
1178
|
remaining,
|
|
@@ -1168,7 +1274,7 @@ FigmaToastProvider.displayName = 'FigmaToastProvider';
|
|
|
1168
1274
|
FigmaToast.displayName = 'FigmaToast';
|
|
1169
1275
|
|
|
1170
1276
|
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, }) => {
|
|
1277
|
+
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
1278
|
const { t: translate } = useFigmaUiI18n(currentLanguage, t);
|
|
1173
1279
|
const { showToast, toastComponent } = useFigmaToast();
|
|
1174
1280
|
const [liveUsage, setLiveUsage] = React.useState({});
|
|
@@ -1178,12 +1284,17 @@ const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount =
|
|
|
1178
1284
|
const effectiveUsageCount = liveUsage.usageCount ?? usageCount;
|
|
1179
1285
|
const effectiveRemainingUsage = liveUsage.remainingUsage ?? remainingUsage;
|
|
1180
1286
|
const effectiveMaxDailyUsage = liveUsage.maxDailyUsage ?? maxDailyUsage;
|
|
1287
|
+
const effectiveLicenseSource = liveUsage.licenseSource ?? licenseSource;
|
|
1288
|
+
const effectiveAccessScope = liveUsage.accessScope ?? accessScope;
|
|
1289
|
+
const effectiveExpiresAt = liveUsage.expiresAt ?? expiresAt;
|
|
1290
|
+
const effectiveLastVerifiedAt = liveUsage.lastVerifiedAt ?? lastVerifiedAt;
|
|
1181
1291
|
const limit = Math.max(1, Math.round(effectiveMaxDailyUsage));
|
|
1182
1292
|
const resolvedRemaining = typeof effectiveRemainingUsage === 'number' && Number.isFinite(effectiveRemainingUsage)
|
|
1183
1293
|
? Math.min(limit, Math.max(0, Math.round(effectiveRemainingUsage)))
|
|
1184
1294
|
: Math.max(0, limit - Math.min(limit, Math.max(0, Math.round(effectiveUsageCount))));
|
|
1185
1295
|
const remainingPercent = Math.round((resolvedRemaining / limit) * 100);
|
|
1186
|
-
const resolvedShowUsageInfo = showPaymentStatus
|
|
1296
|
+
const resolvedShowUsageInfo = showPaymentStatus
|
|
1297
|
+
&& (showUsageInfo || effectivePaymentStatus === 'FREE' || effectivePaymentStatus === 'PAID');
|
|
1187
1298
|
const resolvedShowPaymentBadge = showPaymentStatus && showPaymentBadge;
|
|
1188
1299
|
const resolvedLicensePageClick = effectivePaymentStatus === 'BETA' ? undefined : onLicensePageClick;
|
|
1189
1300
|
const hasChildren = React.Children.count(children) > 0;
|
|
@@ -1209,10 +1320,31 @@ const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount =
|
|
|
1209
1320
|
: message.paymentStatus === 'FREE' || message.paymentStatus === 'UNPAID'
|
|
1210
1321
|
? 'FREE'
|
|
1211
1322
|
: undefined;
|
|
1323
|
+
const nextLicenseSource = typeof message.licenseSource === 'string' ? message.licenseSource : undefined;
|
|
1324
|
+
const nextAccessScope = typeof message.accessScope === 'string' ? message.accessScope : undefined;
|
|
1325
|
+
const nextExpiresAt = typeof message.expiresAt === 'string' ? message.expiresAt : undefined;
|
|
1326
|
+
const rawLastVerifiedAt = message.lastVerifiedAt;
|
|
1327
|
+
const numericLastVerifiedAt = typeof rawLastVerifiedAt === 'number' && Number.isFinite(rawLastVerifiedAt)
|
|
1328
|
+
? rawLastVerifiedAt < 1000000000000
|
|
1329
|
+
? rawLastVerifiedAt * 1000
|
|
1330
|
+
: rawLastVerifiedAt
|
|
1331
|
+
: undefined;
|
|
1332
|
+
const parsedLastVerifiedAt = numericLastVerifiedAt === undefined
|
|
1333
|
+
? undefined
|
|
1334
|
+
: new Date(numericLastVerifiedAt);
|
|
1335
|
+
const nextLastVerifiedAt = typeof rawLastVerifiedAt === 'string'
|
|
1336
|
+
? rawLastVerifiedAt
|
|
1337
|
+
: parsedLastVerifiedAt && !Number.isNaN(parsedLastVerifiedAt.getTime())
|
|
1338
|
+
? parsedLastVerifiedAt.toISOString()
|
|
1339
|
+
: undefined;
|
|
1212
1340
|
if (nextPaymentStatus === undefined
|
|
1213
1341
|
&& nextLimit === undefined
|
|
1214
1342
|
&& nextUsed === undefined
|
|
1215
|
-
&& nextRemaining === undefined
|
|
1343
|
+
&& nextRemaining === undefined
|
|
1344
|
+
&& nextLicenseSource === undefined
|
|
1345
|
+
&& nextAccessScope === undefined
|
|
1346
|
+
&& nextExpiresAt === undefined
|
|
1347
|
+
&& nextLastVerifiedAt === undefined) {
|
|
1216
1348
|
return;
|
|
1217
1349
|
}
|
|
1218
1350
|
setLiveUsage((previous) => ({
|
|
@@ -1221,6 +1353,10 @@ const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount =
|
|
|
1221
1353
|
...(typeof nextLimit === 'number' ? { maxDailyUsage: nextLimit } : {}),
|
|
1222
1354
|
...(typeof nextUsed === 'number' ? { usageCount: nextUsed } : {}),
|
|
1223
1355
|
...(typeof nextRemaining === 'number' ? { remainingUsage: nextRemaining } : {}),
|
|
1356
|
+
...(nextLicenseSource ? { licenseSource: nextLicenseSource } : {}),
|
|
1357
|
+
...(nextAccessScope ? { accessScope: nextAccessScope } : {}),
|
|
1358
|
+
...(nextExpiresAt ? { expiresAt: nextExpiresAt } : {}),
|
|
1359
|
+
...(nextLastVerifiedAt ? { lastVerifiedAt: nextLastVerifiedAt } : {}),
|
|
1224
1360
|
}));
|
|
1225
1361
|
};
|
|
1226
1362
|
window.addEventListener('message', handleUsageMessage);
|
|
@@ -1279,7 +1415,7 @@ const FigmaFooter = ({ onLicensePageClick, paymentStatus = 'FREE', usageCount =
|
|
|
1279
1415
|
React.createElement("div", { className: "designbase-figma-footer__left" },
|
|
1280
1416
|
React.createElement(LogoDropdown, { logoSrc: logoSrc, logoAlt: logoAlt, logoType: logoType, logoSize: logoSize, links: logoLinks, languages: languages, currentLanguage: currentLanguage, showLanguageSelector: showLanguageSelector, onLanguageChange: onLanguageChange, t: translate })),
|
|
1281
1417
|
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 })),
|
|
1418
|
+
(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
1419
|
showDonation && (React.createElement(DonationBadge, { donationUrl: donationUrl, text: donationText, iconType: "heart", size: "s", iconOnly: true, showPrompt: false, t: translate })))),
|
|
1284
1420
|
children,
|
|
1285
1421
|
toastComponent));
|
|
@@ -1292,9 +1428,15 @@ const FormWithSubmit = ({ onLicenseSubmit, disabled = false, isSubmitting = fals
|
|
|
1292
1428
|
React.useEffect(() => {
|
|
1293
1429
|
setInputValue(value);
|
|
1294
1430
|
}, [value]);
|
|
1431
|
+
const submitLicense = async () => {
|
|
1432
|
+
const normalizedValue = inputValue.trim();
|
|
1433
|
+
if (!normalizedValue || disabled || isSubmitting)
|
|
1434
|
+
return;
|
|
1435
|
+
await onLicenseSubmit(normalizedValue);
|
|
1436
|
+
};
|
|
1295
1437
|
const handleSubmit = async (e) => {
|
|
1296
1438
|
e.preventDefault();
|
|
1297
|
-
await
|
|
1439
|
+
await submitLicense();
|
|
1298
1440
|
};
|
|
1299
1441
|
const handleChange = (value) => {
|
|
1300
1442
|
setInputValue(value);
|
|
@@ -1314,7 +1456,9 @@ const FormWithSubmit = ({ onLicenseSubmit, disabled = false, isSubmitting = fals
|
|
|
1314
1456
|
handleChange(value);
|
|
1315
1457
|
}
|
|
1316
1458
|
}, placeholder: displayPlaceholder, helperText: displayHelperText, disabled: disabled || isSubmitting, size: "m" })),
|
|
1317
|
-
React.createElement(react.Button, { type: "
|
|
1459
|
+
React.createElement(react.Button, { type: "button", variant: "primary", size: "m", loading: isSubmitting, disabled: !inputValue.trim() || isSubmitting || disabled, fullWidth: true, onPress: () => {
|
|
1460
|
+
void submitLicense();
|
|
1461
|
+
} }, isSubmitting ? displaySubmittingText : displaySubmitText)));
|
|
1318
1462
|
};
|
|
1319
1463
|
FormWithSubmit.displayName = 'FormWithSubmit';
|
|
1320
1464
|
|
|
@@ -1386,19 +1530,34 @@ const LicenseOffer = ({ joinUrl, guideUrl, membershipUrl, t, locale, className,
|
|
|
1386
1530
|
const titleId = `designbase-license-offer-title-${React.useId().replace(/:/g, '')}`;
|
|
1387
1531
|
const resolvedJoinUrl = joinUrl || membershipUrl;
|
|
1388
1532
|
const steps = [
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1533
|
+
{
|
|
1534
|
+
title: resolveText(translate, { key: 'license.get_key_step_1_title' }, '멤버십 가입'),
|
|
1535
|
+
description: resolveText(translate, { key: 'license.get_key_step_1_description' }, 'Designbase YouTube 채널에서 멤버십에 가입합니다.'),
|
|
1536
|
+
},
|
|
1537
|
+
{
|
|
1538
|
+
title: resolveText(translate, { key: 'license.get_key_step_2_title' }, '이번 달 키 복사'),
|
|
1539
|
+
description: resolveText(translate, { key: 'license.get_key_step_2_description' }, '멤버 전용 커뮤니티 게시글에서 키를 확인합니다.'),
|
|
1540
|
+
},
|
|
1541
|
+
{
|
|
1542
|
+
title: resolveText(translate, { key: 'license.get_key_step_3_title' }, '키 등록'),
|
|
1543
|
+
description: resolveText(translate, { key: 'license.get_key_step_3_description' }, '아래 입력창에 붙여 넣으면 프로 기능이 열립니다.'),
|
|
1544
|
+
},
|
|
1392
1545
|
];
|
|
1393
1546
|
return (React.createElement("section", { className: `designbase-figma-license-offer ${className || ''}`, "aria-labelledby": titleId },
|
|
1394
|
-
React.createElement("
|
|
1547
|
+
React.createElement("header", { className: "designbase-figma-license-offer__header" },
|
|
1548
|
+
React.createElement("span", { className: "designbase-figma-license-offer__section-index", "aria-hidden": "true" }, "1"),
|
|
1549
|
+
React.createElement("div", null,
|
|
1550
|
+
React.createElement("h3", { id: titleId, className: "designbase-figma-license-offer__title" }, resolveText(translate, { key: 'license.get_key_title' }, '라이선스 키 받기')),
|
|
1551
|
+
React.createElement("p", { className: "designbase-figma-license-offer__description" }, resolveText(translate, { key: 'license.get_key_description' }, '멤버십 회원에게 매월 새 라이선스 키가 제공됩니다.')))),
|
|
1395
1552
|
React.createElement("ol", { className: "designbase-figma-license-offer__steps" }, steps.map((step, index) => (React.createElement("li", { key: index },
|
|
1396
|
-
React.createElement("span", { className: "designbase-figma-license-offer__step-index", "aria-hidden": "true" },
|
|
1397
|
-
|
|
1398
|
-
".
|
|
1399
|
-
|
|
1553
|
+
React.createElement("span", { className: "designbase-figma-license-offer__step-index", "aria-hidden": "true" }, index + 1),
|
|
1554
|
+
React.createElement("span", { className: "designbase-figma-license-offer__step-copy" },
|
|
1555
|
+
React.createElement("strong", null, step.title),
|
|
1556
|
+
React.createElement("span", null, step.description)))))),
|
|
1400
1557
|
(resolvedJoinUrl || guideUrl) && (React.createElement("div", { className: "designbase-figma-license-offer__actions" },
|
|
1401
|
-
resolvedJoinUrl && (React.createElement(react.Button, { onPress: () => openExternalUrl(resolvedJoinUrl), variant: "primary", size: "m", fullWidth: true },
|
|
1558
|
+
resolvedJoinUrl && (React.createElement(react.Button, { onPress: () => openExternalUrl(resolvedJoinUrl), variant: "primary", size: "m", fullWidth: true },
|
|
1559
|
+
React.createElement("span", null, resolveText(translate, { key: 'license.get_key_cta' }, '멤버십 가입하고 키 받기')),
|
|
1560
|
+
React.createElement(icons.ExternalLinkIcon, { size: 16, "aria-hidden": "true" }))),
|
|
1402
1561
|
guideUrl && (React.createElement(react.Button, { onPress: () => openExternalUrl(guideUrl), variant: "secondary", size: "m", fullWidth: true },
|
|
1403
1562
|
React.createElement("span", null, resolveText(translate, { key: 'license.youtube_membership_guide' }, '안내보기')),
|
|
1404
1563
|
React.createElement(icons.ExternalLinkIcon, { size: 16, "aria-hidden": "true" })))))));
|
|
@@ -1437,7 +1596,7 @@ function formatSource(value, t) {
|
|
|
1437
1596
|
}
|
|
1438
1597
|
return value;
|
|
1439
1598
|
}
|
|
1440
|
-
const LicenseStatusCard = ({ status, licenseKey = '', licenseStatus, licenseSource, accessScope, expiresAt, lastVerifiedAt, validationMessage, allowRevealKey = false, t, locale, className, }) => {
|
|
1599
|
+
const LicenseStatusCard = ({ status, licenseKey = '', licenseStatus, licenseSource, accessScope, expiresAt, lastVerifiedAt, validationMessage, showHeader = true, allowRevealKey = false, t, locale, className, }) => {
|
|
1441
1600
|
const { locale: resolvedLocale, t: translate } = useFigmaUiI18n(locale, t);
|
|
1442
1601
|
const [isKeyRevealed, setIsKeyRevealed] = React.useState(false);
|
|
1443
1602
|
const normalizedLicenseStatus = licenseStatus?.toLowerCase();
|
|
@@ -1448,13 +1607,15 @@ const LicenseStatusCard = ({ status, licenseKey = '', licenseStatus, licenseSour
|
|
|
1448
1607
|
: resolveText(translate, { key: 'license.status_inactive' }, 'License check failed');
|
|
1449
1608
|
const statusClass = isActive ? 'active' : 'inactive';
|
|
1450
1609
|
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" },
|
|
1610
|
+
showHeader && (React.createElement("div", { className: "designbase-figma-license-status-card__header" },
|
|
1452
1611
|
React.createElement("div", null,
|
|
1453
1612
|
React.createElement("div", { className: "designbase-figma-license-status-card__eyebrow" }, isActive
|
|
1454
1613
|
? resolveText(translate, { key: 'license.activated' }, '라이선스 활성화됨')
|
|
1455
1614
|
: resolveText(translate, { key: 'license.status_label' }, '라이선스 상태')),
|
|
1456
1615
|
React.createElement("h3", null, statusText)),
|
|
1457
|
-
React.createElement("span", { className: "designbase-figma-license-status-card__badge" },
|
|
1616
|
+
React.createElement("span", { className: "designbase-figma-license-status-card__badge" }, isActive
|
|
1617
|
+
? resolveText(translate, { key: 'license.status_active' }, '활성')
|
|
1618
|
+
: resolveText(translate, { key: 'license.status_inactive' }, '비활성')))),
|
|
1458
1619
|
validationMessage && !isActive && (React.createElement("p", { className: "designbase-figma-license-status-card__message" }, validationMessage)),
|
|
1459
1620
|
licenseKey && (React.createElement("div", { className: "designbase-figma-license-status-card__key-row" },
|
|
1460
1621
|
React.createElement("span", null, resolveText(translate, { key: 'license.key_label' }, '라이선스 키')),
|
|
@@ -1828,7 +1989,7 @@ function useFigmaLicenseBridge(options = {}) {
|
|
|
1828
1989
|
function formatUsageLabel(state, t) {
|
|
1829
1990
|
const { remainingUsage, usageUsed, usageLimit, usageReset } = state;
|
|
1830
1991
|
if (usageLimit === 'unlimited') {
|
|
1831
|
-
return resolveText(t, { key: 'license.usage_unlimited' }, '사용 횟수 제한 없음') ?? '사용 횟수 제한 없음';
|
|
1992
|
+
return (resolveText(t, { key: 'license.usage_unlimited' }, '사용 횟수 제한 없음') ?? '사용 횟수 제한 없음');
|
|
1832
1993
|
}
|
|
1833
1994
|
const limit = typeof usageLimit === 'number' ? usageLimit : remainingUsage + usageUsed;
|
|
1834
1995
|
const remaining = remainingUsage ?? Math.max(0, limit - usageUsed);
|
|
@@ -1847,9 +2008,9 @@ function formatUsageLabel(state, t) {
|
|
|
1847
2008
|
const translated = resolveText(t, { key: 'license.usage_weekly', values: { remaining, limit } }, fallback) ?? fallback;
|
|
1848
2009
|
return translated.includes(String(remaining)) ? translated : fallback;
|
|
1849
2010
|
}
|
|
1850
|
-
return resolveText(t, { key: 'license.usage_generic', values: { remaining, limit } }, `남은 횟수 ${remaining}/${limit}`) ?? `남은 횟수 ${remaining}/${limit}
|
|
2011
|
+
return (resolveText(t, { key: 'license.usage_generic', values: { remaining, limit } }, `남은 횟수 ${remaining}/${limit}`) ?? `남은 횟수 ${remaining}/${limit}`);
|
|
1851
2012
|
}
|
|
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, }) => {
|
|
2013
|
+
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
2014
|
const { t: translate } = useFigmaUiI18n(locale, t);
|
|
1854
2015
|
const links = React.useMemo(() => ({
|
|
1855
2016
|
purchaseUrl: wordpressLinks?.purchaseUrl ?? paymentPageUrl,
|
|
@@ -1862,13 +2023,21 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
|
|
|
1862
2023
|
initialState: {
|
|
1863
2024
|
paymentStatus: initialStatus,
|
|
1864
2025
|
licenseKey: initialLicenseKey,
|
|
2026
|
+
hasLicenseKey: Boolean(initialLicenseKey),
|
|
2027
|
+
isLicenseRegistered: initialStatus === 'PAID',
|
|
2028
|
+
planTier: initialStatus === 'PAID' ? 'PRO' : 'FREE',
|
|
2029
|
+
usageLimit: initialStatus === 'PAID' ? 'unlimited' : 0,
|
|
2030
|
+
licenseStatus: initialLicenseStatus,
|
|
2031
|
+
licenseSource: initialLicenseSource,
|
|
2032
|
+
accessScope: initialAccessScope,
|
|
2033
|
+
expiresAt: initialExpiresAt,
|
|
2034
|
+
lastVerifiedAt: initialLastVerifiedAt,
|
|
1865
2035
|
usageCount: initialUsageCount,
|
|
1866
2036
|
},
|
|
1867
2037
|
onStateChange,
|
|
1868
2038
|
onPaymentStatusChange: setPaymentStatus,
|
|
1869
2039
|
onUsageCountChange: setUsageCount,
|
|
1870
2040
|
});
|
|
1871
|
-
const [showDetails, setShowDetails] = React.useState(false);
|
|
1872
2041
|
const [licenseKeyDraft, setLicenseKeyDraft] = React.useState(initialLicenseKey);
|
|
1873
2042
|
const isPaid = state.isLicenseRegistered && state.paymentStatus === 'PAID';
|
|
1874
2043
|
const isMembershipMode = mode === 'youtube-membership';
|
|
@@ -1888,29 +2057,31 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
|
|
|
1888
2057
|
React.createElement("div", { className: "designbase-figma-page-license__content" },
|
|
1889
2058
|
React.createElement("div", { className: "designbase-figma-page-license__header" },
|
|
1890
2059
|
React.createElement("div", { className: "designbase-figma-page-license__title" },
|
|
1891
|
-
React.createElement("h2", null,
|
|
1892
|
-
? resolveText(translate, { key: 'license.
|
|
1893
|
-
:
|
|
1894
|
-
? resolveText(translate, { key: 'license.
|
|
2060
|
+
React.createElement("h2", null, isPaid
|
|
2061
|
+
? resolveText(translate, { key: 'license.pro_account' }, '프로 계정')
|
|
2062
|
+
: isMembershipMode
|
|
2063
|
+
? resolveText(translate, { key: 'license.unlock_unlimited' }, '무제한 사용 활성화')
|
|
1895
2064
|
: resolveText(translate, { key: 'license.upgrade_to_pro' }, '프로로 업그레이드')),
|
|
1896
|
-
|
|
2065
|
+
isPaid && (React.createElement("span", { className: "designbase-figma-page-license__tier" }, resolveText(translate, { key: 'license.pro_plan' }, '프로 플랜')))),
|
|
1897
2066
|
React.createElement("p", { className: "designbase-figma-page-license__description" }, isPaid
|
|
1898
2067
|
? resolveText(translate, { key: 'license.all_features_available' }, '모든 기능을 사용할 수 있습니다.')
|
|
1899
2068
|
: isMembershipMode
|
|
1900
|
-
? resolveText(translate, { key: 'license.
|
|
2069
|
+
? resolveText(translate, { key: 'license.unlock_unlimited_description' }, '라이선스 키를 등록하면 모든 Designbase 플러그인의 프로 기능과 무제한 사용을 이용할 수 있습니다.')
|
|
1901
2070
|
: resolveText(translate, { key: 'license.purchase_for_unlimited' }, '디자인베이스 멤버십 또는 라이선스로 무제한 이용이 가능합니다.')),
|
|
1902
2071
|
!isPaid && !isMembershipMode && (React.createElement("p", { className: "designbase-figma-page-license__usage" }, usageLabel))),
|
|
1903
2072
|
!isMembershipMode && (React.createElement(PricingComparison, { features: pricingFeatures, pricing: pricing, paymentType: paymentType, t: translate })),
|
|
1904
|
-
state.lastMessage &&
|
|
1905
|
-
|
|
1906
|
-
React.createElement("
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
2073
|
+
state.lastMessage &&
|
|
2074
|
+
state.lastErrorCode &&
|
|
2075
|
+
!state.deactivateMessage && (React.createElement("p", { className: `designbase-figma-page-license__feedback ${state.lastErrorCode ? 'designbase-figma-page-license__feedback--error' : ''}`, "aria-live": "polite" }, state.lastMessage)),
|
|
2076
|
+
isPaid && (React.createElement("div", { className: "designbase-figma-page-license__paid-summary" },
|
|
2077
|
+
React.createElement("div", { className: "designbase-figma-page-license__paid-hero" },
|
|
2078
|
+
React.createElement("span", { "aria-hidden": "true" }, "\u221E"),
|
|
2079
|
+
React.createElement("div", null,
|
|
2080
|
+
React.createElement("strong", null, resolveText(translate, { key: 'license.usage_unlimited' }, '무제한 사용')),
|
|
2081
|
+
React.createElement("p", null, resolveText(translate, { key: 'license.active_until_expiry' }, '만료일까지 모든 기능을 제한 없이 사용할 수 있습니다.')))),
|
|
2082
|
+
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 }),
|
|
2083
|
+
React.createElement("div", { className: "designbase-figma-page-license__paid-actions" },
|
|
2084
|
+
state.activationLimit > 0 && (React.createElement("div", { className: "designbase-figma-page-license__activation-info" },
|
|
1914
2085
|
React.createElement("div", { className: "designbase-figma-page-license__remaining" },
|
|
1915
2086
|
Math.max(0, state.activationLimit - state.activationUsage),
|
|
1916
2087
|
' ',
|
|
@@ -1920,15 +2091,16 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
|
|
|
1920
2091
|
React.createElement("div", { className: "designbase-figma-page-license__usage-count" },
|
|
1921
2092
|
state.activationUsage,
|
|
1922
2093
|
"/",
|
|
1923
|
-
state.activationLimit)),
|
|
1924
|
-
React.createElement(
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
2094
|
+
state.activationLimit))),
|
|
2095
|
+
React.createElement(react.Button, { onPress: deactivateLicense, variant: "secondary", size: "m", fullWidth: true, disabled: isDeactivating }, isDeactivating
|
|
2096
|
+
? resolveText(translate, { key: 'license.deactivating' }, '비활성화 중...')
|
|
2097
|
+
: resolveText(translate, { key: 'license.deactivate' }, '라이선스 비활성화')),
|
|
2098
|
+
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)),
|
|
2099
|
+
React.createElement("p", { className: "designbase-figma-page-license__deactivate-hint" }, resolveText(translate, { key: 'license.deactivate_hint' }, '이 기기에서 라이선스 연결을 해제합니다.'))))),
|
|
1929
2100
|
!isPaid && (React.createElement(React.Fragment, null,
|
|
1930
2101
|
isMembershipMode && (React.createElement(LicenseOffer, { joinUrl: links.membershipUrl || links.purchaseUrl, guideUrl: links.helpUrl || links.purchaseUrl, t: translate })),
|
|
1931
|
-
!isMembershipMode &&
|
|
2102
|
+
!isMembershipMode &&
|
|
2103
|
+
(enableAccountAuth || links.purchaseUrl || links.accountUrl) && (React.createElement("div", { className: "designbase-figma-page-license__section" },
|
|
1932
2104
|
React.createElement("div", { className: "designbase-figma-page-license__section-header" },
|
|
1933
2105
|
React.createElement("h3", null, resolveText(translate, { key: 'license.designbase_account' }, '디자인베이스 계정'))),
|
|
1934
2106
|
React.createElement("p", { className: "designbase-figma-page-license__hint" }, resolveText(translate, { key: 'license.designbase_account_hint' }, 'WordPress 계정으로 로그인하거나 멤버십을 구매하면 플러그인이 자동으로 활성화됩니다.')),
|
|
@@ -1946,8 +2118,20 @@ const PageLicense = ({ status: initialStatus, onClose, licenseKey: initialLicens
|
|
|
1946
2118
|
? 'designbase-figma-page-license__key-form'
|
|
1947
2119
|
: 'designbase-figma-page-license__section' },
|
|
1948
2120
|
React.createElement("div", { className: "designbase-figma-page-license__section-header" },
|
|
1949
|
-
React.createElement("
|
|
1950
|
-
|
|
2121
|
+
isMembershipMode && (React.createElement("span", { className: "designbase-figma-page-license__section-index", "aria-hidden": "true" }, "2")),
|
|
2122
|
+
React.createElement("h3", null, isMembershipMode
|
|
2123
|
+
? resolveText(translate, { key: 'license.activate_key_title' }, '라이선스 키 등록')
|
|
2124
|
+
: resolveText(translate, { key: 'license.enter_key' }, '라이선스 키 입력'))),
|
|
2125
|
+
isMembershipMode && (React.createElement("p", { className: "designbase-figma-page-license__hint" }, resolveText(translate, { key: 'license.activate_key_description' }, '이미 키가 있다면 아래에 붙여 넣어 프로 기능을 활성화하세요.'))),
|
|
2126
|
+
React.createElement(FormWithSubmit, { onLicenseSubmit: handleLicenseSubmit, disabled: false, isSubmitting: isVerifying, value: licenseKeyDraft, onValueChange: handleLicenseKeyChange, label: { key: 'license.key' }, submitText: {
|
|
2127
|
+
key: isMembershipMode
|
|
2128
|
+
? 'license.unlock_pro_features'
|
|
2129
|
+
: 'license.submit',
|
|
2130
|
+
}, submittingText: { key: 'license.verifying' }, helperText: {
|
|
2131
|
+
key: isMembershipMode
|
|
2132
|
+
? 'license.enter_from_youtube'
|
|
2133
|
+
: 'license.enter_from_email',
|
|
2134
|
+
}, t: translate }))))),
|
|
1951
2135
|
links.helpUrl && !isMembershipMode && (React.createElement("p", { className: "designbase-figma-page-license__disclaimer" },
|
|
1952
2136
|
React.createElement("button", { type: "button", className: "designbase-figma-page-license__link", onClick: () => openExternalUrl(links.helpUrl) }, resolveText(translate, { key: 'license.help_link' }, '라이선스·결제 도움말'))))),
|
|
1953
2137
|
React.createElement(react.Button, { className: "designbase-figma-page-license__close", onPress: onClose, variant: "tertiary", size: "s", iconOnly: true, "aria-label": translate('close') },
|