@serve.zone/catalog 1.0.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.
Files changed (122) hide show
  1. package/dist_ts_web/00_commitinfo_data.d.ts +8 -0
  2. package/dist_ts_web/00_commitinfo_data.js +9 -0
  3. package/dist_ts_web/elements/index.d.ts +33 -0
  4. package/dist_ts_web/elements/index.js +45 -0
  5. package/dist_ts_web/elements/sz-certificates-card.d.ts +14 -0
  6. package/dist_ts_web/elements/sz-certificates-card.js +210 -0
  7. package/dist_ts_web/elements/sz-dashboard-view.d.ts +33 -0
  8. package/dist_ts_web/elements/sz-dashboard-view.js +242 -0
  9. package/dist_ts_web/elements/sz-demo-view-dashboard.d.ts +18 -0
  10. package/dist_ts_web/elements/sz-demo-view-dashboard.js +184 -0
  11. package/dist_ts_web/elements/sz-demo-view-network.d.ts +32 -0
  12. package/dist_ts_web/elements/sz-demo-view-network.js +384 -0
  13. package/dist_ts_web/elements/sz-demo-view-registries.d.ts +22 -0
  14. package/dist_ts_web/elements/sz-demo-view-registries.js +240 -0
  15. package/dist_ts_web/elements/sz-demo-view-services.d.ts +32 -0
  16. package/dist_ts_web/elements/sz-demo-view-services.js +468 -0
  17. package/dist_ts_web/elements/sz-demo-view-settings.d.ts +19 -0
  18. package/dist_ts_web/elements/sz-demo-view-settings.js +151 -0
  19. package/dist_ts_web/elements/sz-demo-view-tokens.d.ts +20 -0
  20. package/dist_ts_web/elements/sz-demo-view-tokens.js +141 -0
  21. package/dist_ts_web/elements/sz-dns-ssl-card.d.ts +13 -0
  22. package/dist_ts_web/elements/sz-dns-ssl-card.js +180 -0
  23. package/dist_ts_web/elements/sz-domain-detail-view.d.ts +48 -0
  24. package/dist_ts_web/elements/sz-domain-detail-view.js +789 -0
  25. package/dist_ts_web/elements/sz-login-view.d.ts +18 -0
  26. package/dist_ts_web/elements/sz-login-view.js +384 -0
  27. package/dist_ts_web/elements/sz-network-dns-view.d.ts +20 -0
  28. package/dist_ts_web/elements/sz-network-dns-view.js +244 -0
  29. package/dist_ts_web/elements/sz-network-domains-view.d.ts +28 -0
  30. package/dist_ts_web/elements/sz-network-domains-view.js +312 -0
  31. package/dist_ts_web/elements/sz-network-proxy-view.d.ts +39 -0
  32. package/dist_ts_web/elements/sz-network-proxy-view.js +510 -0
  33. package/dist_ts_web/elements/sz-platform-service-detail-view.d.ts +49 -0
  34. package/dist_ts_web/elements/sz-platform-service-detail-view.js +733 -0
  35. package/dist_ts_web/elements/sz-platform-services-card.d.ts +19 -0
  36. package/dist_ts_web/elements/sz-platform-services-card.js +196 -0
  37. package/dist_ts_web/elements/sz-quick-actions-card.d.ts +19 -0
  38. package/dist_ts_web/elements/sz-quick-actions-card.js +194 -0
  39. package/dist_ts_web/elements/sz-registry-external-view.d.ts +22 -0
  40. package/dist_ts_web/elements/sz-registry-external-view.js +313 -0
  41. package/dist_ts_web/elements/sz-registry-onebox-view.d.ts +14 -0
  42. package/dist_ts_web/elements/sz-registry-onebox-view.js +307 -0
  43. package/dist_ts_web/elements/sz-resource-usage-card.d.ts +25 -0
  44. package/dist_ts_web/elements/sz-resource-usage-card.js +323 -0
  45. package/dist_ts_web/elements/sz-reverse-proxy-card.d.ts +16 -0
  46. package/dist_ts_web/elements/sz-reverse-proxy-card.js +216 -0
  47. package/dist_ts_web/elements/sz-service-create-view.d.ts +67 -0
  48. package/dist_ts_web/elements/sz-service-create-view.js +828 -0
  49. package/dist_ts_web/elements/sz-service-detail-view.d.ts +57 -0
  50. package/dist_ts_web/elements/sz-service-detail-view.js +728 -0
  51. package/dist_ts_web/elements/sz-services-backups-view.d.ts +37 -0
  52. package/dist_ts_web/elements/sz-services-backups-view.js +413 -0
  53. package/dist_ts_web/elements/sz-services-list-view.d.ts +20 -0
  54. package/dist_ts_web/elements/sz-services-list-view.js +272 -0
  55. package/dist_ts_web/elements/sz-settings-view.d.ts +30 -0
  56. package/dist_ts_web/elements/sz-settings-view.js +448 -0
  57. package/dist_ts_web/elements/sz-stat-card.d.ts +17 -0
  58. package/dist_ts_web/elements/sz-stat-card.js +249 -0
  59. package/dist_ts_web/elements/sz-status-grid-cluster.d.ts +19 -0
  60. package/dist_ts_web/elements/sz-status-grid-cluster.js +142 -0
  61. package/dist_ts_web/elements/sz-status-grid-infra.d.ts +17 -0
  62. package/dist_ts_web/elements/sz-status-grid-infra.js +140 -0
  63. package/dist_ts_web/elements/sz-status-grid-network.d.ts +30 -0
  64. package/dist_ts_web/elements/sz-status-grid-network.js +190 -0
  65. package/dist_ts_web/elements/sz-status-grid-services.d.ts +17 -0
  66. package/dist_ts_web/elements/sz-status-grid-services.js +145 -0
  67. package/dist_ts_web/elements/sz-tokens-view.d.ts +26 -0
  68. package/dist_ts_web/elements/sz-tokens-view.js +344 -0
  69. package/dist_ts_web/elements/sz-traffic-card.d.ts +24 -0
  70. package/dist_ts_web/elements/sz-traffic-card.js +255 -0
  71. package/dist_ts_web/index.d.ts +2 -0
  72. package/dist_ts_web/index.js +3 -0
  73. package/dist_ts_web/pages/index.d.ts +3 -0
  74. package/dist_ts_web/pages/index.js +4 -0
  75. package/dist_ts_web/pages/mainpage.d.ts +1 -0
  76. package/dist_ts_web/pages/mainpage.js +46 -0
  77. package/dist_ts_web/pages/sz-demo-app-shell.d.ts +13 -0
  78. package/dist_ts_web/pages/sz-demo-app-shell.js +212 -0
  79. package/dist_ts_web/pages/sz-demo-app.d.ts +2 -0
  80. package/dist_ts_web/pages/sz-demo-app.js +20 -0
  81. package/npmextra.json +24 -0
  82. package/package.json +45 -0
  83. package/ts_web/00_commitinfo_data.ts +8 -0
  84. package/ts_web/elements/index.ts +54 -0
  85. package/ts_web/elements/sz-certificates-card.ts +155 -0
  86. package/ts_web/elements/sz-dashboard-view.ts +217 -0
  87. package/ts_web/elements/sz-demo-view-dashboard.ts +150 -0
  88. package/ts_web/elements/sz-demo-view-network.ts +354 -0
  89. package/ts_web/elements/sz-demo-view-registries.ts +206 -0
  90. package/ts_web/elements/sz-demo-view-services.ts +434 -0
  91. package/ts_web/elements/sz-demo-view-settings.ts +118 -0
  92. package/ts_web/elements/sz-demo-view-tokens.ts +109 -0
  93. package/ts_web/elements/sz-dns-ssl-card.ts +130 -0
  94. package/ts_web/elements/sz-domain-detail-view.ts +766 -0
  95. package/ts_web/elements/sz-login-view.ts +329 -0
  96. package/ts_web/elements/sz-network-dns-view.ts +208 -0
  97. package/ts_web/elements/sz-network-domains-view.ts +273 -0
  98. package/ts_web/elements/sz-network-proxy-view.ts +456 -0
  99. package/ts_web/elements/sz-platform-service-detail-view.ts +714 -0
  100. package/ts_web/elements/sz-platform-services-card.ts +163 -0
  101. package/ts_web/elements/sz-quick-actions-card.ts +161 -0
  102. package/ts_web/elements/sz-registry-external-view.ts +279 -0
  103. package/ts_web/elements/sz-registry-onebox-view.ts +258 -0
  104. package/ts_web/elements/sz-resource-usage-card.ts +284 -0
  105. package/ts_web/elements/sz-reverse-proxy-card.ts +151 -0
  106. package/ts_web/elements/sz-service-create-view.ts +773 -0
  107. package/ts_web/elements/sz-service-detail-view.ts +710 -0
  108. package/ts_web/elements/sz-services-backups-view.ts +390 -0
  109. package/ts_web/elements/sz-services-list-view.ts +237 -0
  110. package/ts_web/elements/sz-settings-view.ts +417 -0
  111. package/ts_web/elements/sz-stat-card.ts +187 -0
  112. package/ts_web/elements/sz-status-grid-cluster.ts +105 -0
  113. package/ts_web/elements/sz-status-grid-infra.ts +88 -0
  114. package/ts_web/elements/sz-status-grid-network.ts +152 -0
  115. package/ts_web/elements/sz-status-grid-services.ts +99 -0
  116. package/ts_web/elements/sz-tokens-view.ts +308 -0
  117. package/ts_web/elements/sz-traffic-card.ts +222 -0
  118. package/ts_web/index.ts +2 -0
  119. package/ts_web/pages/index.ts +3 -0
  120. package/ts_web/pages/mainpage.ts +46 -0
  121. package/ts_web/pages/sz-demo-app-shell.ts +179 -0
  122. package/ts_web/pages/sz-demo-app.ts +20 -0
@@ -0,0 +1,329 @@
1
+ import {
2
+ DeesElement,
3
+ customElement,
4
+ html,
5
+ css,
6
+ cssManager,
7
+ property,
8
+ type TemplateResult,
9
+ } from '@design.estate/dees-element';
10
+
11
+ declare global {
12
+ interface HTMLElementTagNameMap {
13
+ 'sz-login-view': SzLoginView;
14
+ }
15
+ }
16
+
17
+ @customElement('sz-login-view')
18
+ export class SzLoginView extends DeesElement {
19
+ public static demo = () => html`
20
+ <div style="height: 600px; display: flex; align-items: center; justify-content: center; background: #09090b;">
21
+ <sz-login-view></sz-login-view>
22
+ </div>
23
+ `;
24
+
25
+ @property({ type: Boolean })
26
+ public accessor loading: boolean = false;
27
+
28
+ @property({ type: String })
29
+ public accessor error: string = '';
30
+
31
+ @property({ type: String })
32
+ public accessor title: string = 'serve.zone';
33
+
34
+ @property({ type: String })
35
+ public accessor subtitle: string = 'Sign in to your onebox';
36
+
37
+ public static styles = [
38
+ cssManager.defaultStyles,
39
+ css`
40
+ :host {
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ min-height: 100vh;
45
+ width: 100%;
46
+ background: ${cssManager.bdTheme('#f4f4f5', '#09090b')};
47
+ }
48
+
49
+ .login-container {
50
+ width: 100%;
51
+ max-width: 400px;
52
+ padding: 24px;
53
+ }
54
+
55
+ .login-card {
56
+ background: ${cssManager.bdTheme('#ffffff', '#18181b')};
57
+ border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
58
+ border-radius: 12px;
59
+ padding: 32px;
60
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
61
+ }
62
+
63
+ .logo-section {
64
+ text-align: center;
65
+ margin-bottom: 32px;
66
+ }
67
+
68
+ .logo {
69
+ width: 64px;
70
+ height: 64px;
71
+ background: ${cssManager.bdTheme('#18181b', '#fafafa')};
72
+ border-radius: 12px;
73
+ display: flex;
74
+ align-items: center;
75
+ justify-content: center;
76
+ margin: 0 auto 16px;
77
+ }
78
+
79
+ .logo svg {
80
+ width: 36px;
81
+ height: 36px;
82
+ color: ${cssManager.bdTheme('#fafafa', '#18181b')};
83
+ }
84
+
85
+ .title {
86
+ font-size: 24px;
87
+ font-weight: 700;
88
+ color: ${cssManager.bdTheme('#18181b', '#fafafa')};
89
+ margin-bottom: 4px;
90
+ }
91
+
92
+ .subtitle {
93
+ font-size: 14px;
94
+ color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
95
+ }
96
+
97
+ .form {
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: 20px;
101
+ }
102
+
103
+ .form-group {
104
+ display: flex;
105
+ flex-direction: column;
106
+ gap: 6px;
107
+ }
108
+
109
+ .form-label {
110
+ font-size: 14px;
111
+ font-weight: 500;
112
+ color: ${cssManager.bdTheme('#18181b', '#fafafa')};
113
+ }
114
+
115
+ .form-input {
116
+ width: 100%;
117
+ padding: 12px 14px;
118
+ background: ${cssManager.bdTheme('#ffffff', '#09090b')};
119
+ border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
120
+ border-radius: 8px;
121
+ font-size: 14px;
122
+ color: ${cssManager.bdTheme('#18181b', '#fafafa')};
123
+ outline: none;
124
+ transition: border-color 200ms ease, box-shadow 200ms ease;
125
+ box-sizing: border-box;
126
+ }
127
+
128
+ .form-input:focus {
129
+ border-color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')};
130
+ box-shadow: 0 0 0 3px ${cssManager.bdTheme('rgba(59, 130, 246, 0.1)', 'rgba(96, 165, 250, 0.1)')};
131
+ }
132
+
133
+ .form-input::placeholder {
134
+ color: ${cssManager.bdTheme('#a1a1aa', '#52525b')};
135
+ }
136
+
137
+ .form-input.error {
138
+ border-color: ${cssManager.bdTheme('#ef4444', '#f87171')};
139
+ }
140
+
141
+ .error-message {
142
+ display: flex;
143
+ align-items: center;
144
+ gap: 8px;
145
+ padding: 12px 14px;
146
+ background: ${cssManager.bdTheme('#fef2f2', 'rgba(239, 68, 68, 0.1)')};
147
+ border: 1px solid ${cssManager.bdTheme('#fecaca', 'rgba(239, 68, 68, 0.2)')};
148
+ border-radius: 8px;
149
+ font-size: 14px;
150
+ color: ${cssManager.bdTheme('#dc2626', '#f87171')};
151
+ }
152
+
153
+ .error-message svg {
154
+ width: 18px;
155
+ height: 18px;
156
+ flex-shrink: 0;
157
+ }
158
+
159
+ .submit-button {
160
+ width: 100%;
161
+ padding: 12px 20px;
162
+ background: ${cssManager.bdTheme('#18181b', '#fafafa')};
163
+ border: none;
164
+ border-radius: 8px;
165
+ font-size: 14px;
166
+ font-weight: 600;
167
+ color: ${cssManager.bdTheme('#fafafa', '#18181b')};
168
+ cursor: pointer;
169
+ transition: opacity 200ms ease, transform 200ms ease;
170
+ display: flex;
171
+ align-items: center;
172
+ justify-content: center;
173
+ gap: 8px;
174
+ }
175
+
176
+ .submit-button:hover:not(:disabled) {
177
+ opacity: 0.9;
178
+ }
179
+
180
+ .submit-button:active:not(:disabled) {
181
+ transform: scale(0.98);
182
+ }
183
+
184
+ .submit-button:disabled {
185
+ opacity: 0.6;
186
+ cursor: not-allowed;
187
+ }
188
+
189
+ .spinner {
190
+ width: 18px;
191
+ height: 18px;
192
+ border: 2px solid transparent;
193
+ border-top-color: currentColor;
194
+ border-radius: 50%;
195
+ animation: spin 0.8s linear infinite;
196
+ }
197
+
198
+ @keyframes spin {
199
+ to {
200
+ transform: rotate(360deg);
201
+ }
202
+ }
203
+
204
+ .footer {
205
+ margin-top: 24px;
206
+ text-align: center;
207
+ font-size: 13px;
208
+ color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
209
+ }
210
+
211
+ .footer a {
212
+ color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')};
213
+ text-decoration: none;
214
+ }
215
+
216
+ .footer a:hover {
217
+ text-decoration: underline;
218
+ }
219
+ `,
220
+ ];
221
+
222
+ public render(): TemplateResult {
223
+ return html`
224
+ <div class="login-container">
225
+ <div class="login-card">
226
+ <div class="logo-section">
227
+ <div class="logo">
228
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
229
+ <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path>
230
+ <polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline>
231
+ <line x1="12" y1="22.08" x2="12" y2="12"></line>
232
+ </svg>
233
+ </div>
234
+ <div class="title">${this.title}</div>
235
+ <div class="subtitle">${this.subtitle}</div>
236
+ </div>
237
+
238
+ <form class="form" @submit=${this.handleSubmit}>
239
+ ${this.error ? html`
240
+ <div class="error-message">
241
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
242
+ <circle cx="12" cy="12" r="10"></circle>
243
+ <line x1="12" y1="8" x2="12" y2="12"></line>
244
+ <line x1="12" y1="16" x2="12.01" y2="16"></line>
245
+ </svg>
246
+ ${this.error}
247
+ </div>
248
+ ` : ''}
249
+
250
+ <div class="form-group">
251
+ <label class="form-label" for="username">Username</label>
252
+ <input
253
+ type="text"
254
+ id="username"
255
+ class="form-input ${this.error ? 'error' : ''}"
256
+ placeholder="Enter your username"
257
+ autocomplete="username"
258
+ ?disabled=${this.loading}
259
+ required
260
+ >
261
+ </div>
262
+
263
+ <div class="form-group">
264
+ <label class="form-label" for="password">Password</label>
265
+ <input
266
+ type="password"
267
+ id="password"
268
+ class="form-input ${this.error ? 'error' : ''}"
269
+ placeholder="Enter your password"
270
+ autocomplete="current-password"
271
+ ?disabled=${this.loading}
272
+ required
273
+ >
274
+ </div>
275
+
276
+ <button type="submit" class="submit-button" ?disabled=${this.loading}>
277
+ ${this.loading ? html`
278
+ <div class="spinner"></div>
279
+ Signing in...
280
+ ` : 'Sign in'}
281
+ </button>
282
+ </form>
283
+
284
+ <div class="footer">
285
+ Powered by <a href="https://serve.zone" target="_blank">serve.zone</a>
286
+ </div>
287
+ </div>
288
+ </div>
289
+ `;
290
+ }
291
+
292
+ private handleSubmit(e: Event) {
293
+ e.preventDefault();
294
+
295
+ const usernameInput = this.shadowRoot?.getElementById('username') as HTMLInputElement;
296
+ const passwordInput = this.shadowRoot?.getElementById('password') as HTMLInputElement;
297
+
298
+ if (!usernameInput || !passwordInput) return;
299
+
300
+ const username = usernameInput.value.trim();
301
+ const password = passwordInput.value;
302
+
303
+ if (!username || !password) {
304
+ this.error = 'Please enter both username and password';
305
+ return;
306
+ }
307
+
308
+ this.error = '';
309
+ this.dispatchEvent(new CustomEvent('login', {
310
+ detail: { username, password },
311
+ bubbles: true,
312
+ composed: true,
313
+ }));
314
+ }
315
+
316
+ public clearForm() {
317
+ const usernameInput = this.shadowRoot?.getElementById('username') as HTMLInputElement;
318
+ const passwordInput = this.shadowRoot?.getElementById('password') as HTMLInputElement;
319
+
320
+ if (usernameInput) usernameInput.value = '';
321
+ if (passwordInput) passwordInput.value = '';
322
+ this.error = '';
323
+ }
324
+
325
+ public focusUsername() {
326
+ const usernameInput = this.shadowRoot?.getElementById('username') as HTMLInputElement;
327
+ if (usernameInput) usernameInput.focus();
328
+ }
329
+ }
@@ -0,0 +1,208 @@
1
+ import {
2
+ DeesElement,
3
+ customElement,
4
+ html,
5
+ css,
6
+ cssManager,
7
+ property,
8
+ type TemplateResult,
9
+ } from '@design.estate/dees-element';
10
+
11
+ declare global {
12
+ interface HTMLElementTagNameMap {
13
+ 'sz-network-dns-view': SzNetworkDnsView;
14
+ }
15
+ }
16
+
17
+ export interface IDnsRecord {
18
+ domain: string;
19
+ type: 'A' | 'AAAA' | 'CNAME' | 'MX' | 'TXT';
20
+ value: string;
21
+ id?: string;
22
+ }
23
+
24
+ @customElement('sz-network-dns-view')
25
+ export class SzNetworkDnsView extends DeesElement {
26
+ public static demo = () => html`
27
+ <div style="padding: 24px; max-width: 1000px;">
28
+ <sz-network-dns-view
29
+ .records=${[
30
+ { domain: 'pr.task.vc', type: 'A', value: '195.201.98.232' },
31
+ { domain: 'outline.task.vc', type: 'A', value: '195.201.98.232' },
32
+ { domain: 'ns1.task.vc', type: 'A', value: '212.95.99.130' },
33
+ { domain: 'bleu.de', type: 'A', value: '212.95.99.130' },
34
+ { domain: 'mail.bleu.de', type: 'MX', value: '10 mail.bleu.de' },
35
+ ]}
36
+ ></sz-network-dns-view>
37
+ </div>
38
+ `;
39
+
40
+ @property({ type: Array })
41
+ public accessor records: IDnsRecord[] = [];
42
+
43
+ public static styles = [
44
+ cssManager.defaultStyles,
45
+ css`
46
+ :host {
47
+ display: block;
48
+ }
49
+
50
+ .header {
51
+ display: flex;
52
+ justify-content: space-between;
53
+ align-items: center;
54
+ margin-bottom: 16px;
55
+ }
56
+
57
+ .description {
58
+ font-size: 14px;
59
+ color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
60
+ }
61
+
62
+ .sync-button {
63
+ display: inline-flex;
64
+ align-items: center;
65
+ gap: 8px;
66
+ padding: 8px 16px;
67
+ background: ${cssManager.bdTheme('#ffffff', '#09090b')};
68
+ border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
69
+ border-radius: 6px;
70
+ font-size: 14px;
71
+ font-weight: 500;
72
+ color: ${cssManager.bdTheme('#18181b', '#fafafa')};
73
+ cursor: pointer;
74
+ transition: all 200ms ease;
75
+ }
76
+
77
+ .sync-button:hover {
78
+ background: ${cssManager.bdTheme('#f4f4f5', '#18181b')};
79
+ border-color: ${cssManager.bdTheme('#d4d4d8', '#3f3f46')};
80
+ }
81
+
82
+ .table-container {
83
+ background: ${cssManager.bdTheme('#ffffff', '#09090b')};
84
+ border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
85
+ border-radius: 8px;
86
+ overflow: hidden;
87
+ }
88
+
89
+ .table-header {
90
+ display: grid;
91
+ grid-template-columns: 2fr 80px 2fr 100px;
92
+ gap: 16px;
93
+ padding: 12px 16px;
94
+ background: ${cssManager.bdTheme('#f4f4f5', '#18181b')};
95
+ border-bottom: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')};
96
+ font-size: 12px;
97
+ font-weight: 600;
98
+ text-transform: uppercase;
99
+ letter-spacing: 0.05em;
100
+ color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
101
+ }
102
+
103
+ .table-row {
104
+ display: grid;
105
+ grid-template-columns: 2fr 80px 2fr 100px;
106
+ gap: 16px;
107
+ padding: 12px 16px;
108
+ border-bottom: 1px solid ${cssManager.bdTheme('#f4f4f5', '#27272a')};
109
+ font-size: 14px;
110
+ color: ${cssManager.bdTheme('#18181b', '#fafafa')};
111
+ transition: background 200ms ease;
112
+ }
113
+
114
+ .table-row:last-child {
115
+ border-bottom: none;
116
+ }
117
+
118
+ .table-row:hover {
119
+ background: ${cssManager.bdTheme('#f4f4f5', '#18181b')};
120
+ }
121
+
122
+ .domain {
123
+ font-weight: 500;
124
+ }
125
+
126
+ .type-badge {
127
+ display: inline-flex;
128
+ align-items: center;
129
+ justify-content: center;
130
+ padding: 2px 8px;
131
+ background: ${cssManager.bdTheme('#dbeafe', 'rgba(59, 130, 246, 0.2)')};
132
+ color: ${cssManager.bdTheme('#2563eb', '#60a5fa')};
133
+ border-radius: 4px;
134
+ font-size: 12px;
135
+ font-weight: 600;
136
+ }
137
+
138
+ .value {
139
+ font-family: monospace;
140
+ color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
141
+ }
142
+
143
+ .delete-button {
144
+ padding: 6px 12px;
145
+ background: transparent;
146
+ border: 1px solid ${cssManager.bdTheme('#fee2e2', 'rgba(239, 68, 68, 0.3)')};
147
+ border-radius: 4px;
148
+ font-size: 13px;
149
+ color: ${cssManager.bdTheme('#dc2626', '#ef4444')};
150
+ cursor: pointer;
151
+ transition: all 200ms ease;
152
+ }
153
+
154
+ .delete-button:hover {
155
+ background: ${cssManager.bdTheme('#fee2e2', 'rgba(239, 68, 68, 0.2)')};
156
+ }
157
+
158
+ .empty-state {
159
+ padding: 48px 24px;
160
+ text-align: center;
161
+ color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
162
+ }
163
+ `,
164
+ ];
165
+
166
+ public render(): TemplateResult {
167
+ return html`
168
+ <div class="header">
169
+ <span class="description">Manage DNS records synced with Cloudflare</span>
170
+ <button class="sync-button" @click=${() => this.handleSync()}>
171
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
172
+ <path d="M21 12a9 9 0 0 1-9 9m9-9a9 9 0 0 0-9-9m9 9H3m9 9a9 9 0 0 1-9-9m9 9c1.66 0 3-4.03 3-9s-1.34-9-3-9m0 18c-1.66 0-3-4.03-3-9s1.34-9 3-9"/>
173
+ </svg>
174
+ Sync Cloudflare
175
+ </button>
176
+ </div>
177
+
178
+ <div class="table-container">
179
+ <div class="table-header">
180
+ <span>Domain</span>
181
+ <span>Type</span>
182
+ <span>Value</span>
183
+ <span>Actions</span>
184
+ </div>
185
+ ${this.records.length > 0 ? this.records.map(record => html`
186
+ <div class="table-row">
187
+ <span class="domain">${record.domain}</span>
188
+ <span><span class="type-badge">${record.type}</span></span>
189
+ <span class="value">${record.value}</span>
190
+ <span>
191
+ <button class="delete-button" @click=${() => this.handleDelete(record)}>Delete</button>
192
+ </span>
193
+ </div>
194
+ `) : html`
195
+ <div class="empty-state">No DNS records found</div>
196
+ `}
197
+ </div>
198
+ `;
199
+ }
200
+
201
+ private handleSync() {
202
+ this.dispatchEvent(new CustomEvent('sync', { bubbles: true, composed: true }));
203
+ }
204
+
205
+ private handleDelete(record: IDnsRecord) {
206
+ this.dispatchEvent(new CustomEvent('delete', { detail: record, bubbles: true, composed: true }));
207
+ }
208
+ }