magic-editor-x 1.0.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.
Files changed (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +890 -0
  3. package/dist/_chunks/App-B1FgOsWa.mjs +2143 -0
  4. package/dist/_chunks/App-mtrlABtd.js +2146 -0
  5. package/dist/_chunks/LicensePage-BnyWSrWs.js +375 -0
  6. package/dist/_chunks/LicensePage-CWH-AFR-.mjs +373 -0
  7. package/dist/_chunks/LiveCollaborationPanel-DbDHwr2C.js +222 -0
  8. package/dist/_chunks/LiveCollaborationPanel-ryjcDAA7.mjs +220 -0
  9. package/dist/_chunks/Settings-Bk9bxJTy.js +440 -0
  10. package/dist/_chunks/Settings-D-V2MLVm.mjs +438 -0
  11. package/dist/_chunks/de-CSrHZWEb.mjs +295 -0
  12. package/dist/_chunks/de-CzSo1oD2.js +295 -0
  13. package/dist/_chunks/en-DuQun2v4.mjs +295 -0
  14. package/dist/_chunks/en-DxIkVPUh.js +295 -0
  15. package/dist/_chunks/es-DAQ_97zx.js +273 -0
  16. package/dist/_chunks/es-DEB0CA8S.mjs +273 -0
  17. package/dist/_chunks/fr-Bqkhvdx2.mjs +273 -0
  18. package/dist/_chunks/fr-ChPabvNP.js +273 -0
  19. package/dist/_chunks/getTranslation-C4uWR0DB.mjs +50985 -0
  20. package/dist/_chunks/getTranslation-D35vbDap.js +51001 -0
  21. package/dist/_chunks/index-B5MzUyo0.mjs +2541 -0
  22. package/dist/_chunks/index-BRVqbnOb.mjs +4450 -0
  23. package/dist/_chunks/index-BiLy_f7C.js +2540 -0
  24. package/dist/_chunks/index-CQx7-dFP.js +4472 -0
  25. package/dist/_chunks/pt-BMoYltav.mjs +273 -0
  26. package/dist/_chunks/pt-Cm74LpyZ.js +273 -0
  27. package/dist/_chunks/tools-CjnQJ9w2.mjs +2155 -0
  28. package/dist/_chunks/tools-DNt2tioN.js +2186 -0
  29. package/dist/admin/index.js +3 -0
  30. package/dist/admin/index.mjs +4 -0
  31. package/dist/server/index.js +2554 -0
  32. package/dist/server/index.mjs +2544 -0
  33. package/dist/style.css +164 -0
  34. package/package.json +122 -0
  35. package/pics/collab-magiceditorX.png +0 -0
  36. package/pics/editorX.png +0 -0
  37. package/pics/liveCollabwidget1.png +0 -0
@@ -0,0 +1,220 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useState, useEffect, useMemo } from "react";
3
+ import { u as useIntl, a as Flex, g as getTranslation } from "./getTranslation-C4uWR0DB.mjs";
4
+ import styled, { css, keyframes } from "styled-components";
5
+ const pulse = keyframes`
6
+ 0%, 100% {
7
+ box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.2);
8
+ transform: scale(1);
9
+ }
10
+ 50% {
11
+ box-shadow: 0 0 0 6px rgba(34, 197, 94, 0.1);
12
+ transform: scale(1.1);
13
+ }
14
+ `;
15
+ const StatusCard = styled.div`
16
+ background: ${(props) => props.theme.colors.neutral0};
17
+ border: 1px solid ${({ $status, theme }) => $status === "connected" ? "rgba(34, 197, 94, 0.3)" : $status === "denied" ? "rgba(239, 68, 68, 0.3)" : theme.colors.neutral200};
18
+ border-radius: 10px;
19
+ padding: 14px 16px;
20
+ display: flex;
21
+ align-items: center;
22
+ gap: 12px;
23
+ `;
24
+ const StatusDot = styled.div`
25
+ width: 12px;
26
+ height: 12px;
27
+ border-radius: 50%;
28
+ flex-shrink: 0;
29
+ background: ${({ $status }) => $status === "connected" ? "#22c55e" : $status === "connecting" || $status === "requesting" ? "#f59e0b" : $status === "denied" ? "#ef4444" : "#94a3b8"};
30
+
31
+ ${({ $status }) => $status === "connected" && css`
32
+ animation: ${pulse} 2s ease-in-out infinite;
33
+ `}
34
+ `;
35
+ const StatusText = styled.div`
36
+ display: flex;
37
+ flex-direction: column;
38
+ gap: 2px;
39
+ `;
40
+ const StatusLabel = styled.span`
41
+ font-size: 14px;
42
+ font-weight: 600;
43
+ color: ${({ $status, theme }) => $status === "connected" ? theme.colors.success600 : $status === "connecting" || $status === "requesting" ? theme.colors.warning600 : $status === "denied" ? theme.colors.danger600 : theme.colors.neutral600};
44
+ `;
45
+ const StatusSubtext = styled.span`
46
+ font-size: 12px;
47
+ color: ${(props) => props.theme.colors.neutral500};
48
+ `;
49
+ const SectionTitle = styled.div`
50
+ font-size: 11px;
51
+ font-weight: 600;
52
+ color: ${(props) => props.theme.colors.neutral600};
53
+ text-transform: uppercase;
54
+ letter-spacing: 0.5px;
55
+ margin-bottom: 10px;
56
+ `;
57
+ const PeerItem = styled.div`
58
+ display: flex;
59
+ align-items: center;
60
+ gap: 12px;
61
+ padding: 12px 14px;
62
+ background: ${(props) => props.theme.colors.neutral0};
63
+ border-radius: 10px;
64
+ border: 1px solid ${(props) => props.theme.colors.neutral150};
65
+ transition: all 0.2s ease;
66
+
67
+ &:hover {
68
+ border-color: ${(props) => props.theme.colors.primary200};
69
+ box-shadow: 0 2px 8px rgba(124, 58, 237, 0.08);
70
+ transform: translateY(-1px);
71
+ }
72
+ `;
73
+ const PEER_COLORS = [
74
+ "linear-gradient(135deg, #7C3AED 0%, #a855f7 100%)",
75
+ "linear-gradient(135deg, #3b82f6 0%, #60a5fa 100%)",
76
+ "linear-gradient(135deg, #10b981 0%, #34d399 100%)",
77
+ "linear-gradient(135deg, #f59e0b 0%, #fbbf24 100%)",
78
+ "linear-gradient(135deg, #ef4444 0%, #f87171 100%)",
79
+ "linear-gradient(135deg, #ec4899 0%, #f472b6 100%)"
80
+ ];
81
+ const PeerAvatar = styled.div`
82
+ width: 36px;
83
+ height: 36px;
84
+ border-radius: 50%;
85
+ background: ${({ $color }) => $color || PEER_COLORS[0]};
86
+ color: white;
87
+ font-size: 12px;
88
+ font-weight: 700;
89
+ display: flex;
90
+ align-items: center;
91
+ justify-content: center;
92
+ flex-shrink: 0;
93
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
94
+ `;
95
+ const PeerInfo = styled.div`
96
+ flex: 1;
97
+ min-width: 0;
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: 2px;
101
+ `;
102
+ const PeerName = styled.span`
103
+ font-size: 13px;
104
+ font-weight: 600;
105
+ color: ${(props) => props.theme.colors.neutral800};
106
+ white-space: nowrap;
107
+ overflow: hidden;
108
+ text-overflow: ellipsis;
109
+ `;
110
+ const PeerEmail = styled.span`
111
+ font-size: 11px;
112
+ color: ${(props) => props.theme.colors.neutral500};
113
+ white-space: nowrap;
114
+ overflow: hidden;
115
+ text-overflow: ellipsis;
116
+ `;
117
+ const OnlineBadge = styled.span`
118
+ font-size: 10px;
119
+ font-weight: 600;
120
+ color: #166534;
121
+ background: #dcfce7;
122
+ padding: 4px 8px;
123
+ border-radius: 12px;
124
+ flex-shrink: 0;
125
+ `;
126
+ const EmptyState = styled.div`
127
+ text-align: center;
128
+ padding: 16px;
129
+ background: ${(props) => props.theme.colors.neutral100};
130
+ border-radius: 10px;
131
+ border: 1px dashed ${(props) => props.theme.colors.neutral300};
132
+ `;
133
+ const EmptyText = styled.span`
134
+ font-size: 13px;
135
+ color: ${(props) => props.theme.colors.neutral500};
136
+ `;
137
+ const getPeerInitials = (user = {}) => {
138
+ const first = (user.firstname?.[0] || user.email?.[0] || "?").toUpperCase();
139
+ const last = (user.lastname?.[0] || "").toUpperCase();
140
+ return `${first}${last}`.trim();
141
+ };
142
+ const getPeerName = (user = {}, t) => {
143
+ if (user.firstname) {
144
+ return `${user.firstname} ${user.lastname || ""}`.trim();
145
+ }
146
+ return user.email || t("collab.unknown", "Unknown");
147
+ };
148
+ const LiveCollaborationPanel = ({ documentId, model, document }) => {
149
+ const { formatMessage } = useIntl();
150
+ const t = (id, defaultMessage, values) => formatMessage({ id: getTranslation(id), defaultMessage }, values);
151
+ const [collabState, setCollabState] = useState({
152
+ status: "disabled",
153
+ peers: [],
154
+ error: null
155
+ });
156
+ useEffect(() => {
157
+ const handleCollabUpdate = (event) => {
158
+ if (event.detail) {
159
+ setCollabState(event.detail);
160
+ }
161
+ };
162
+ window.addEventListener("magic-editor-collab-update", handleCollabUpdate);
163
+ if (window.__MAGIC_EDITOR_COLLAB_STATE__) {
164
+ setCollabState(window.__MAGIC_EDITOR_COLLAB_STATE__);
165
+ }
166
+ return () => {
167
+ window.removeEventListener("magic-editor-collab-update", handleCollabUpdate);
168
+ };
169
+ }, []);
170
+ const { status, peers, error } = collabState;
171
+ const statusLabel = useMemo(() => {
172
+ switch (status) {
173
+ case "connected":
174
+ return t("collab.live", "Live");
175
+ case "connecting":
176
+ return t("collab.connecting", "Connecting...");
177
+ case "requesting":
178
+ return t("collab.checkingPermission", "Checking permission");
179
+ case "denied":
180
+ return t("collab.noPermission", "No permission");
181
+ case "disconnected":
182
+ return t("collab.disconnected", "Disconnected");
183
+ case "disabled":
184
+ return t("collab.disabled", "Disabled");
185
+ default:
186
+ return t("collab.ready", "Ready");
187
+ }
188
+ }, [status, t]);
189
+ if (status === "disabled" || status === "idle") {
190
+ return null;
191
+ }
192
+ const isConnected = status === "connected";
193
+ return {
194
+ title: t("collab.title", "Live Collaboration"),
195
+ content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 4, alignItems: "stretch", style: { width: "100%" }, children: [
196
+ /* @__PURE__ */ jsxs(StatusCard, { $status: status, children: [
197
+ /* @__PURE__ */ jsx(StatusDot, { $status: status }),
198
+ /* @__PURE__ */ jsxs(StatusText, { children: [
199
+ /* @__PURE__ */ jsx(StatusLabel, { $status: status, children: statusLabel }),
200
+ /* @__PURE__ */ jsx(StatusSubtext, { children: isConnected ? t("collab.realtimeActive", "Realtime sync active") : error || t("collab.connectionEstablishing", "Connection is being established...") })
201
+ ] })
202
+ ] }),
203
+ isConnected && peers.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
204
+ /* @__PURE__ */ jsx(SectionTitle, { children: t("collab.activePeers", "Active Collaborators ({count})", { count: peers.length }) }),
205
+ /* @__PURE__ */ jsx(Flex, { direction: "column", gap: 2, alignItems: "stretch", children: peers.map((peer, idx) => /* @__PURE__ */ jsxs(PeerItem, { children: [
206
+ /* @__PURE__ */ jsx(PeerAvatar, { $color: PEER_COLORS[idx % PEER_COLORS.length], children: getPeerInitials(peer) }),
207
+ /* @__PURE__ */ jsxs(PeerInfo, { children: [
208
+ /* @__PURE__ */ jsx(PeerName, { children: getPeerName(peer, t) }),
209
+ peer.email && peer.firstname && /* @__PURE__ */ jsx(PeerEmail, { children: peer.email })
210
+ ] }),
211
+ /* @__PURE__ */ jsx(OnlineBadge, { children: t("collab.online", "Online") })
212
+ ] }, peer.id)) })
213
+ ] }),
214
+ isConnected && peers.length === 0 && /* @__PURE__ */ jsx(EmptyState, { children: /* @__PURE__ */ jsx(EmptyText, { children: t("collab.workingAlone", "You are working alone") }) })
215
+ ] })
216
+ };
217
+ };
218
+ export {
219
+ LiveCollaborationPanel as default
220
+ };
@@ -0,0 +1,440 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const React = require("react");
5
+ const getTranslation = require("./getTranslation-D35vbDap.js");
6
+ const admin = require("@strapi/strapi/admin");
7
+ const outline = require("@heroicons/react/24/outline");
8
+ const styled = require("styled-components");
9
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
10
+ const styled__default = /* @__PURE__ */ _interopDefault(styled);
11
+ const theme = {
12
+ borderRadius: { lg: "12px" }
13
+ };
14
+ const fadeIn = styled.keyframes`
15
+ from { opacity: 0; transform: translateY(10px); }
16
+ to { opacity: 1; transform: translateY(0); }
17
+ `;
18
+ const shimmer = styled.keyframes`
19
+ 0% { background-position: -200% 0; }
20
+ 100% { background-position: 200% 0; }
21
+ `;
22
+ const Container = styled__default.default(getTranslation.Box)`
23
+ ${styled.css`animation: ${fadeIn} 0.5s;`}
24
+ max-width: 1400px;
25
+ margin: 0 auto;
26
+ `;
27
+ const StickySaveBar = styled__default.default(getTranslation.Box)`
28
+ position: sticky;
29
+ top: 0;
30
+ z-index: 10;
31
+ background: ${(props) => props.theme.colors.neutral0};
32
+ border-bottom: 1px solid ${(props) => props.theme.colors.neutral200};
33
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
34
+ `;
35
+ const LicenseKeyBanner = styled__default.default(getTranslation.Box)`
36
+ background: linear-gradient(135deg, #7C3AED 0%, #6d28d9 100%);
37
+ border-radius: ${theme.borderRadius.lg};
38
+ padding: 28px 32px;
39
+ color: white;
40
+ position: relative;
41
+ overflow: hidden;
42
+ box-shadow: 0 4px 20px rgba(124, 58, 237, 0.25);
43
+ margin-bottom: 24px;
44
+
45
+ &::after {
46
+ content: '';
47
+ position: absolute;
48
+ top: -50%;
49
+ right: -50%;
50
+ width: 200%;
51
+ height: 200%;
52
+ background: linear-gradient(
53
+ 45deg,
54
+ transparent,
55
+ rgba(255, 255, 255, 0.08),
56
+ transparent
57
+ );
58
+ ${styled.css`animation: ${shimmer} 3s infinite;`}
59
+ pointer-events: none;
60
+ z-index: 0;
61
+ }
62
+
63
+ & > * {
64
+ position: relative;
65
+ z-index: 1;
66
+ }
67
+ `;
68
+ const LoaderContainer = styled__default.default(getTranslation.Flex)`
69
+ min-height: 400px;
70
+ align-items: center;
71
+ justify-content: center;
72
+ flex-direction: column;
73
+ gap: 16px;
74
+ `;
75
+ const Settings = () => {
76
+ const { formatMessage } = getTranslation.useIntl();
77
+ const t = (id, defaultMessage, values) => formatMessage({ id: getTranslation.getTranslation(id), defaultMessage }, values);
78
+ const { get } = admin.useFetchClient();
79
+ const { toggleNotification } = admin.useNotification();
80
+ const [loading, setLoading] = React.useState(true);
81
+ const [licenseData, setLicenseData] = React.useState(null);
82
+ const [limits, setLimits] = React.useState(null);
83
+ const [error, setError] = React.useState(null);
84
+ const fetchLicenseStatus = async () => {
85
+ setLoading(true);
86
+ setError(null);
87
+ try {
88
+ const [statusRes, limitsRes] = await Promise.all([
89
+ get("/magic-editor-x/license/status"),
90
+ get("/magic-editor-x/license/limits")
91
+ ]);
92
+ setLicenseData(statusRes.data);
93
+ setLimits(limitsRes.data);
94
+ } catch (err) {
95
+ console.error("[Magic Editor X] Error fetching license:", err);
96
+ setError("Failed to load license information");
97
+ } finally {
98
+ setLoading(false);
99
+ }
100
+ };
101
+ const handleCopyLicenseKey = async () => {
102
+ try {
103
+ await navigator.clipboard.writeText(licenseData?.data?.licenseKey || "");
104
+ toggleNotification({
105
+ type: "success",
106
+ message: t("license.copied", "License key copied to clipboard!")
107
+ });
108
+ } catch (err) {
109
+ toggleNotification({
110
+ type: "danger",
111
+ message: t("license.copyFailed", "Failed to copy license key")
112
+ });
113
+ }
114
+ };
115
+ const handleDownloadLicenseKey = () => {
116
+ try {
117
+ const data2 = licenseData?.data || {};
118
+ const licenseKey = data2.licenseKey || "";
119
+ const email = data2.email || "N/A";
120
+ const firstName = data2.firstName || "";
121
+ const lastName = data2.lastName || "";
122
+ const fullName = `${firstName} ${lastName}`.trim() || "N/A";
123
+ const tier2 = licenseData?.tier || "free";
124
+ const content = `Magic Editor X - License Key
125
+ ===================================
126
+
127
+ License Key: ${licenseKey}
128
+
129
+ License Holder Information:
130
+ ----------------------------------
131
+ Name: ${fullName}
132
+ Email: ${email}
133
+
134
+ License Status:
135
+ ----------------------------------
136
+ Status: ${data2.isActive ? "ACTIVE" : "INACTIVE"}
137
+ Tier: ${tier2.toUpperCase()}
138
+ Expires: ${data2.expiresAt ? new Date(data2.expiresAt).toLocaleDateString() : "Never"}
139
+
140
+ Features:
141
+ ----------------------------------
142
+ Premium: ${data2.features?.premium ? "Enabled" : "Disabled"}
143
+ Advanced: ${data2.features?.advanced ? "Enabled" : "Disabled"}
144
+ Enterprise: ${data2.features?.enterprise ? "Enabled" : "Disabled"}
145
+
146
+ ===================================
147
+ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
148
+ `;
149
+ const blob = new Blob([content], { type: "text/plain" });
150
+ const url = window.URL.createObjectURL(blob);
151
+ const link = document.createElement("a");
152
+ link.href = url;
153
+ link.download = `magic-editor-x-license-${licenseKey.substring(0, 8)}.txt`;
154
+ document.body.appendChild(link);
155
+ link.click();
156
+ document.body.removeChild(link);
157
+ window.URL.revokeObjectURL(url);
158
+ toggleNotification({
159
+ type: "success",
160
+ message: t("license.downloaded", "License key downloaded successfully!")
161
+ });
162
+ } catch (err) {
163
+ toggleNotification({
164
+ type: "danger",
165
+ message: t("license.downloadFailed", "Failed to download license key")
166
+ });
167
+ }
168
+ };
169
+ React.useEffect(() => {
170
+ fetchLicenseStatus();
171
+ }, []);
172
+ if (loading) {
173
+ return /* @__PURE__ */ jsxRuntime.jsx(Container, { children: /* @__PURE__ */ jsxRuntime.jsx(LoaderContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Loader, { children: t("license.loading", "Loading license information...") }) }) });
174
+ }
175
+ if (error) {
176
+ return /* @__PURE__ */ jsxRuntime.jsx(Container, { children: /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Box, { padding: 8, children: /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Alert, { variant: "danger", title: "Error", closeLabel: "Close", children: error }) }) });
177
+ }
178
+ const isValid = licenseData?.valid;
179
+ const isDemo = licenseData?.demo;
180
+ const tier = licenseData?.tier || "free";
181
+ const data = licenseData?.data || {};
182
+ const collaborators = limits?.limits?.collaborators || { current: 0, max: 2, unlimited: false };
183
+ return /* @__PURE__ */ jsxRuntime.jsxs(Container, { children: [
184
+ /* @__PURE__ */ jsxRuntime.jsx(StickySaveBar, { paddingTop: 5, paddingBottom: 5, paddingLeft: 6, paddingRight: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Flex, { justifyContent: "space-between", alignItems: "flex-start", children: [
185
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Flex, { direction: "column", gap: 1, alignItems: "flex-start", children: [
186
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "alpha", fontWeight: "bold", children: t("license.title", "License Management") }),
187
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "epsilon", textColor: "neutral600", children: t("license.subtitle", "View your Magic Editor X plugin license") })
188
+ ] }),
189
+ /* @__PURE__ */ jsxRuntime.jsx(
190
+ getTranslation.Button,
191
+ {
192
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(outline.ArrowPathIcon, { style: { width: 20, height: 20 } }),
193
+ onClick: fetchLicenseStatus,
194
+ size: "L",
195
+ style: {
196
+ background: "linear-gradient(135deg, #7C3AED 0%, #6d28d9 100%)",
197
+ color: "white",
198
+ fontWeight: "600",
199
+ border: "none"
200
+ },
201
+ children: t("license.refresh", "Refresh Status")
202
+ }
203
+ )
204
+ ] }) }),
205
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { paddingTop: 6, paddingLeft: 6, paddingRight: 6, paddingBottom: 10, children: [
206
+ isDemo ? /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Alert, { variant: "warning", title: t("license.alert.free", "FREE Mode"), closeLabel: "Close", children: t("license.alert.free.message", "You're using the FREE version with 2 collaborators. Upgrade for more features.") }) : isValid ? /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Alert, { variant: "success", title: t("license.alert.active", "License Active"), closeLabel: "Close", children: t("license.alert.active.message", "Your license is active and all features are unlocked.") }) : /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Alert, { variant: "danger", title: t("license.alert.issue", "License Issue"), closeLabel: "Close", children: t("license.alert.issue.message", "There's an issue with your license. Please check your license status.") }),
207
+ data.licenseKey && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Box, { marginTop: 6, children: /* @__PURE__ */ jsxRuntime.jsx(LicenseKeyBanner, { children: /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Flex, { justifyContent: "space-between", alignItems: "flex-start", children: [
208
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { style: { flex: 1 }, children: [
209
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "pi", style: { color: "rgba(255,255,255,0.8)", marginBottom: "12px", textTransform: "uppercase", fontSize: "11px", letterSpacing: "0.5px", display: "block" }, children: t("license.key", "License Key") }),
210
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { style: { color: "white", fontFamily: "monospace", fontSize: "28px", fontWeight: "bold", wordBreak: "break-all", marginBottom: "16px" }, children: data.licenseKey }),
211
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Flex, { gap: 2, children: [
212
+ /* @__PURE__ */ jsxRuntime.jsx(
213
+ getTranslation.Button,
214
+ {
215
+ onClick: handleCopyLicenseKey,
216
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(outline.DocumentDuplicateIcon, { style: { width: 16, height: 16 } }),
217
+ size: "S",
218
+ variant: "secondary",
219
+ style: {
220
+ backgroundColor: "rgba(255,255,255,0.2)",
221
+ color: "white",
222
+ border: "1px solid rgba(255,255,255,0.3)",
223
+ fontWeight: "600"
224
+ },
225
+ children: t("license.copyKey", "Copy Key")
226
+ }
227
+ ),
228
+ /* @__PURE__ */ jsxRuntime.jsx(
229
+ getTranslation.Button,
230
+ {
231
+ onClick: handleDownloadLicenseKey,
232
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(outline.ArrowDownTrayIcon, { style: { width: 16, height: 16 } }),
233
+ size: "S",
234
+ variant: "secondary",
235
+ style: {
236
+ backgroundColor: "rgba(255,255,255,0.2)",
237
+ color: "white",
238
+ border: "1px solid rgba(255,255,255,0.3)",
239
+ fontWeight: "600"
240
+ },
241
+ children: t("license.downloadTxt", "Download as TXT")
242
+ }
243
+ )
244
+ ] })
245
+ ] }),
246
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Flex, { direction: "column", gap: 2, alignItems: "flex-end", children: [
247
+ /* @__PURE__ */ jsxRuntime.jsx(
248
+ getTranslation.Badge,
249
+ {
250
+ backgroundColor: data.isActive ? "success100" : "danger100",
251
+ textColor: data.isActive ? "success700" : "danger700",
252
+ style: { fontSize: "11px", fontWeight: "700", padding: "6px 12px" },
253
+ children: data.isActive ? "ACTIVE" : "INACTIVE"
254
+ }
255
+ ),
256
+ /* @__PURE__ */ jsxRuntime.jsx(
257
+ getTranslation.Badge,
258
+ {
259
+ style: {
260
+ fontSize: "11px",
261
+ fontWeight: "700",
262
+ padding: "6px 12px",
263
+ background: tier === "free" ? "#6B7280" : "#7C3AED",
264
+ color: "white"
265
+ },
266
+ children: tier.toUpperCase()
267
+ }
268
+ )
269
+ ] })
270
+ ] }) }) }),
271
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Box, { marginTop: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Accordion.Root, { defaultValue: "account", collapsible: true, children: [
272
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Accordion.Item, { value: "account", children: [
273
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Trigger, { icon: () => /* @__PURE__ */ jsxRuntime.jsx(outline.UserIcon, { style: { width: 16, height: 16 } }), children: t("license.section.account", "Account Information") }) }),
274
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Box, { padding: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Flex, { gap: 8, wrap: "wrap", children: [
275
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { style: { flex: "1", minWidth: "200px" }, children: [
276
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: t("license.email", "Email Address") }),
277
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "omega", fontWeight: "semiBold", children: data.email || t("license.notProvided", "Not provided") })
278
+ ] }),
279
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { style: { flex: "1", minWidth: "200px" }, children: [
280
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: t("license.holder", "License Holder") }),
281
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "omega", fontWeight: "semiBold", children: data.firstName && data.lastName ? `${data.firstName} ${data.lastName}` : t("license.notSpecified", "Not specified") })
282
+ ] })
283
+ ] }) }) })
284
+ ] }),
285
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Accordion.Item, { value: "collaborators", children: [
286
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Trigger, { icon: () => /* @__PURE__ */ jsxRuntime.jsx(outline.UsersIcon, { style: { width: 16, height: 16 } }), children: t("license.section.collaborators", "Collaborator Limits") }) }),
287
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { padding: 6, children: [
288
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Flex, { gap: 8, wrap: "wrap", alignItems: "center", children: [
289
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { style: { flex: "1", minWidth: "200px" }, children: [
290
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: t("license.currentUsage", "Current Usage") }),
291
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "24px" }, children: [
292
+ collaborators.current,
293
+ " / ",
294
+ collaborators.unlimited ? t("license.unlimited", "Unlimited") : collaborators.max
295
+ ] })
296
+ ] }),
297
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { style: { flex: "1", minWidth: "200px" }, children: [
298
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: t("license.status", "Status") }),
299
+ /* @__PURE__ */ jsxRuntime.jsx(
300
+ getTranslation.Badge,
301
+ {
302
+ backgroundColor: collaborators.canAdd ? "success100" : "danger100",
303
+ textColor: collaborators.canAdd ? "success700" : "danger700",
304
+ style: { fontSize: "12px", fontWeight: "600", padding: "6px 12px" },
305
+ children: collaborators.canAdd ? t("license.canAddMore", "Can add more") : t("license.limitReached", "Limit reached")
306
+ }
307
+ )
308
+ ] })
309
+ ] }),
310
+ !collaborators.canAdd && !collaborators.unlimited && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Box, { marginTop: 4, padding: 4, background: "warning100", hasRadius: true, children: /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "omega", textColor: "warning700", children: t("license.upgradeMessage", "Upgrade your plan to add more collaborators. Visit https://store.magicdx.dev/") }) })
311
+ ] }) })
312
+ ] }),
313
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Accordion.Item, { value: "details", children: [
314
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Trigger, { icon: () => /* @__PURE__ */ jsxRuntime.jsx(outline.ShieldCheckIcon, { style: { width: 16, height: 16 } }), children: t("license.section.details", "License Details") }) }),
315
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Box, { padding: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Flex, { gap: 8, wrap: "wrap", children: [
316
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { style: { flex: "1", minWidth: "180px" }, children: [
317
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: data.isExpired ? t("license.expiredOn", "Expired On") : t("license.expiresOn", "Expires On") }),
318
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "omega", fontWeight: "semiBold", children: data.expiresAt ? new Date(data.expiresAt).toLocaleDateString("en-US", {
319
+ year: "numeric",
320
+ month: "long",
321
+ day: "numeric"
322
+ }) : t("license.never", "Never") })
323
+ ] }),
324
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { style: { flex: "1", minWidth: "180px" }, children: [
325
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: t("license.deviceName", "Device Name") }),
326
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "omega", fontWeight: "semiBold", children: data.deviceName || t("license.unknown", "Unknown") })
327
+ ] })
328
+ ] }) }) })
329
+ ] }),
330
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Accordion.Item, { value: "features", children: [
331
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Trigger, { icon: () => /* @__PURE__ */ jsxRuntime.jsx(outline.SparklesIcon, { style: { width: 16, height: 16 } }), children: t("license.section.features", "Features & Capabilities") }) }),
332
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { padding: 6, children: [
333
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Flex, { gap: 3, style: { marginBottom: "32px" }, children: [
334
+ /* @__PURE__ */ jsxRuntime.jsxs(
335
+ getTranslation.Badge,
336
+ {
337
+ backgroundColor: tier === "free" ? "success100" : "neutral100",
338
+ textColor: tier === "free" ? "success700" : "neutral600",
339
+ style: {
340
+ fontSize: "13px",
341
+ fontWeight: "700",
342
+ padding: "8px 16px",
343
+ border: tier === "free" ? "2px solid #dcfce7" : "2px solid #e5e7eb"
344
+ },
345
+ children: [
346
+ tier === "free" ? "[ACTIVE]" : "",
347
+ " FREE"
348
+ ]
349
+ }
350
+ ),
351
+ /* @__PURE__ */ jsxRuntime.jsxs(
352
+ getTranslation.Badge,
353
+ {
354
+ backgroundColor: tier === "premium" ? "primary100" : "neutral100",
355
+ textColor: tier === "premium" ? "primary700" : "neutral600",
356
+ style: {
357
+ fontSize: "13px",
358
+ fontWeight: "700",
359
+ padding: "8px 16px",
360
+ border: tier === "premium" ? "2px solid #ede9fe" : "2px solid #e5e7eb"
361
+ },
362
+ children: [
363
+ tier === "premium" ? "[ACTIVE]" : "",
364
+ " PREMIUM"
365
+ ]
366
+ }
367
+ ),
368
+ /* @__PURE__ */ jsxRuntime.jsxs(
369
+ getTranslation.Badge,
370
+ {
371
+ backgroundColor: tier === "advanced" || tier === "enterprise" ? "secondary100" : "neutral100",
372
+ textColor: tier === "advanced" || tier === "enterprise" ? "secondary700" : "neutral600",
373
+ style: {
374
+ fontSize: "13px",
375
+ fontWeight: "700",
376
+ padding: "8px 16px",
377
+ border: tier === "advanced" || tier === "enterprise" ? "2px solid #ddd6fe" : "2px solid #e5e7eb"
378
+ },
379
+ children: [
380
+ tier === "advanced" || tier === "enterprise" ? "[ACTIVE]" : "",
381
+ " ADVANCED"
382
+ ]
383
+ }
384
+ )
385
+ ] }),
386
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { padding: 5, background: "neutral100", hasRadius: true, children: [
387
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "delta", fontWeight: "bold", style: { marginBottom: "16px", display: "block" }, children: t("license.yourPlanIncludes", "Your Plan Includes:") }),
388
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Flex, { direction: "column", gap: 2, children: [
389
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Typography, { variant: "omega", style: { fontSize: "14px" }, children: [
390
+ "[OK] ",
391
+ t("license.feature.fullAccess", "Full Editor Access (all tools)")
392
+ ] }),
393
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Typography, { variant: "omega", style: { fontSize: "14px" }, children: [
394
+ "[OK] ",
395
+ t("license.feature.realtimeCollab", "Real-Time Collaboration")
396
+ ] }),
397
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Typography, { variant: "omega", style: { fontSize: "14px" }, children: [
398
+ "[OK] ",
399
+ collaborators.unlimited ? t("license.feature.collaboratorsUnlimited", "Unlimited Collaborators") : t("license.feature.collaborators", "{count} Collaborator(s)", { count: collaborators.max })
400
+ ] }),
401
+ (tier === "premium" || tier === "advanced" || tier === "enterprise") && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
402
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Typography, { variant: "omega", style: { fontSize: "14px" }, children: [
403
+ "[OK] ",
404
+ t("license.feature.aiAssistant", "AI Assistant (Usage-based)")
405
+ ] }),
406
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Typography, { variant: "omega", style: { fontSize: "14px" }, children: [
407
+ "[OK] ",
408
+ t("license.feature.versionHistory", "Version History")
409
+ ] }),
410
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Typography, { variant: "omega", style: { fontSize: "14px" }, children: [
411
+ "[OK] ",
412
+ t("license.feature.prioritySupport", "Priority Support")
413
+ ] })
414
+ ] })
415
+ ] })
416
+ ] })
417
+ ] }) })
418
+ ] }),
419
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Accordion.Item, { value: "status", children: [
420
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Trigger, { icon: () => /* @__PURE__ */ jsxRuntime.jsx(outline.ChartBarIcon, { style: { width: 16, height: 16 } }), children: t("license.section.status", "System Status") }) }),
421
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Box, { padding: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Flex, { gap: 8, wrap: "wrap", children: [
422
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { style: { flex: "1", minWidth: "150px" }, children: [
423
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: t("license.licenseStatus", "License Status") }),
424
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "omega", fontWeight: "semiBold", children: data.isActive ? t("license.active", "Active") : t("license.inactive", "Inactive") })
425
+ ] }),
426
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { style: { flex: "1", minWidth: "150px" }, children: [
427
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: t("license.connection", "Connection") }),
428
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "omega", fontWeight: "semiBold", children: data.isOnline ? t("license.online", "Online") : t("license.offline", "Offline") })
429
+ ] }),
430
+ /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Box, { style: { flex: "1", minWidth: "150px" }, children: [
431
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", style: { marginBottom: "8px", display: "block" }, children: t("license.lastSync", "Last Sync") }),
432
+ /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Typography, { variant: "omega", fontWeight: "semiBold", children: data.lastPingAt ? new Date(data.lastPingAt).toLocaleTimeString() : t("license.never", "Never") })
433
+ ] })
434
+ ] }) }) })
435
+ ] })
436
+ ] }) })
437
+ ] })
438
+ ] });
439
+ };
440
+ exports.default = Settings;