@kyro-cms/admin 0.9.5 → 0.9.6

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.
@@ -51,7 +51,7 @@ export const AccordionBlock: React.FC<{ block: Record<string, unknown>; index: n
51
51
  <button
52
52
  type="button"
53
53
  onClick={() => removeBlock(block.id)}
54
- className="p-1 hover:bg-red-50 rounded text-red-500"
54
+ className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
55
55
  title="Remove"
56
56
  >
57
57
  <X className="w-3 h-3" />
@@ -47,7 +47,7 @@ export const ArrayBlock: React.FC<{ block: Record<string, unknown>; index: numbe
47
47
  <button
48
48
  type="button"
49
49
  onClick={() => removeBlock(block.id)}
50
- className="p-1 hover:bg-red-50 rounded text-red-500"
50
+ className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
51
51
  title="Remove"
52
52
  >
53
53
  <X className="w-3 h-3" />
@@ -165,7 +165,7 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
165
165
  handleRemoveChild(child.id);
166
166
  setConfirmDeleteId(null);
167
167
  }}
168
- className="px-2 py-1 text-xs bg-red-500 text-white rounded hover:bg-red-600"
168
+ className="px-2 py-1 text-xs bg-[var(--kyro-danger)] text-white rounded"
169
169
  >
170
170
  Remove
171
171
  </button>
@@ -184,9 +184,9 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
184
184
  e.stopPropagation();
185
185
  setConfirmDeleteId(child.id);
186
186
  }}
187
- className="p-1.5 rounded-md transition-opacity cursor-pointer hover:bg-red-50"
187
+ className="p-1.5 rounded-md transition-opacity cursor-pointer hover:bg-[var(--kyro-danger-bg)]"
188
188
  >
189
- <X className="w-3.5 h-3.5 text-red-500 invisible group-hover/column:visible" />
189
+ <X className="w-3.5 h-3.5 text-[var(--kyro-danger)] invisible group-hover/column:visible" />
190
190
  </button>
191
191
  )}
192
192
  </div>
@@ -445,7 +445,7 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
445
445
  handleRemoveChild(child.id);
446
446
  setConfirmDeleteId(null);
447
447
  }}
448
- className="px-2 py-1 text-xs bg-red-500 text-white rounded hover:bg-red-600"
448
+ className="px-2 py-1 text-xs bg-[var(--kyro-danger)] text-white rounded"
449
449
  >
450
450
  Remove
451
451
  </button>
@@ -464,9 +464,9 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
464
464
  e.stopPropagation();
465
465
  setConfirmDeleteId(child.id);
466
466
  }}
467
- className="p-1.5 rounded-md invisible group-hover:visible transition-opacity cursor-pointer hover:bg-red-50"
467
+ className="p-1.5 rounded-md invisible group-hover:visible transition-opacity cursor-pointer hover:bg-[var(--kyro-danger-bg)]"
468
468
  >
469
- <X className="w-3.5 h-3.5 text-red-500" />
469
+ <X className="w-3.5 h-3.5 text-[var(--kyro-danger)]" />
470
470
  </button>
471
471
  )}
472
472
  </div>
@@ -47,7 +47,7 @@ export const CodeBlock: React.FC<{ block: Record<string, unknown>; index: number
47
47
  <button
48
48
  type="button"
49
49
  onClick={() => removeBlock(block.id)}
50
- className="p-1.5 hover:bg-red-500/10 rounded-lg transition-all text-[var(--kyro-text-muted)] hover:text-red-500"
50
+ className="p-1.5 hover:bg-[var(--kyro-danger-bg)] rounded-lg transition-all text-[var(--kyro-text-muted)] hover:text-[var(--kyro-danger)]"
51
51
  title="Remove"
52
52
  >
53
53
  <X className="w-4 h-4" />
@@ -45,7 +45,7 @@ export const FileBlock: React.FC<{ block: Record<string, unknown>; index: number
45
45
  <button
46
46
  type="button"
47
47
  onClick={() => removeBlock(block.id)}
48
- className="p-1 hover:bg-red-50 rounded text-red-500"
48
+ className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
49
49
  title="Remove"
50
50
  >
51
51
  <X className="w-3 h-3" />
@@ -50,7 +50,7 @@ export const HeroBlock: React.FC<{ block: Record<string, unknown>; index: number
50
50
  <button
51
51
  type="button"
52
52
  onClick={() => removeBlock(block.id)}
53
- className="p-1 hover:bg-red-50 rounded text-red-500"
53
+ className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
54
54
  title="Remove"
55
55
  >
56
56
  <X className="w-3 h-3" />
@@ -46,7 +46,7 @@ export const ListBlock: React.FC<{ block: Record<string, unknown>; index: number
46
46
  <button
47
47
  type="button"
48
48
  onClick={() => removeBlock(block.id)}
49
- className="p-1 hover:bg-red-50 rounded text-red-500"
49
+ className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
50
50
  title="Remove"
51
51
  >
52
52
  <X className="w-3 h-3" />
@@ -50,7 +50,7 @@ export const RelationshipBlock: React.FC<{ block: Record<string, unknown>; index
50
50
  <button
51
51
  type="button"
52
52
  onClick={() => removeBlock(block.id)}
53
- className="p-1 hover:bg-red-50 rounded text-red-500"
53
+ className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
54
54
  title="Remove"
55
55
  >
56
56
  <X className="w-3 h-3" />
@@ -48,7 +48,7 @@ export const RichTextBlock: React.FC<{ block: any; index: number }> = ({
48
48
  <button
49
49
  type="button"
50
50
  onClick={() => removeBlock(block.id)}
51
- className="p-1 hover:bg-red-50 rounded text-red-500"
51
+ className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
52
52
  title="Remove"
53
53
  >
54
54
  <X className="w-3 h-3" />
@@ -45,7 +45,7 @@ export const VideoBlock: React.FC<{ block: Record<string, unknown>; index: numbe
45
45
  <button
46
46
  type="button"
47
47
  onClick={() => removeBlock(block.id)}
48
- className="p-1 hover:bg-red-50 rounded text-red-500"
48
+ className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
49
49
  title="Remove"
50
50
  >
51
51
  <X className="w-3 h-3" />
@@ -138,7 +138,7 @@ const SortableBlockComponent = ({
138
138
  removeBlock(block.id as string);
139
139
  setShowDeleteConfirm(false);
140
140
  }}
141
- className="px-1.5 py-0.5 text-[9px] bg-red-500 hover:bg-red-600 text-white rounded font-semibold transition-colors"
141
+ className="px-1.5 py-0.5 text-[9px] bg-[var(--kyro-danger)] text-white rounded font-semibold transition-colors hover:brightness-90"
142
142
  >
143
143
  Remove
144
144
  </button>
@@ -169,7 +169,7 @@ const SortableBlockComponent = ({
169
169
  e.stopPropagation();
170
170
  setShowDeleteConfirm(true);
171
171
  }}
172
- className="p-0.5 hover:bg-red-50 hover:text-red-500 rounded text-[var(--kyro-text-muted)] transition-colors"
172
+ className="p-0.5 hover:bg-[var(--kyro-danger-bg)] hover:text-[var(--kyro-danger)] rounded text-[var(--kyro-text-muted)] transition-colors"
173
173
  title="Remove"
174
174
  >
175
175
  <X className="w-3 h-3" />
@@ -245,7 +245,7 @@ const SortableBlockComponent = ({
245
245
  removeBlock(block.id as string);
246
246
  setShowDeleteConfirm(false);
247
247
  }}
248
- className="px-2.5 py-1 text-[10px] bg-red-500 hover:bg-red-600 text-white rounded font-semibold transition-colors"
248
+ className="px-2.5 py-1 text-[10px] bg-[var(--kyro-danger)] text-white rounded font-semibold transition-colors hover:brightness-90"
249
249
  >
250
250
  Remove
251
251
  </button>
@@ -276,7 +276,7 @@ const SortableBlockComponent = ({
276
276
  e.stopPropagation();
277
277
  setShowDeleteConfirm(true);
278
278
  }}
279
- className="p-1 hover:bg-red-50 hover:text-red-500 rounded text-[var(--kyro-text-muted)] transition-colors"
279
+ className="p-1 hover:bg-[var(--kyro-danger-bg)] hover:text-[var(--kyro-danger)] rounded text-[var(--kyro-text-muted)] transition-colors"
280
280
  title="Remove Block"
281
281
  >
282
282
  <X className="w-3.5 h-3.5" />
@@ -526,7 +526,7 @@ export const BlocksField: React.FC<BlocksFieldProps> = ({
526
526
 
527
527
  // Render active drag overlay
528
528
  const activeBlock = activeDrag
529
- ? blockCategories
529
+ ? dynamicCategories
530
530
  .flatMap((cat) => cat.blocks)
531
531
  .find((b) => `drawer-${b.type}` === activeDrag.id) ||
532
532
  blocks.find((b) => b.id === activeDrag.id)
@@ -52,6 +52,7 @@ export function Toast({ type, message, onClose }: ToastProps) {
52
52
  onMouseEnter={() => setIsPaused(true)}
53
53
  onMouseLeave={() => setIsPaused(false)}
54
54
  >
55
+ <div className="kyro-toast-accent" />
55
56
  <div className="kyro-toast-icon-container">
56
57
  <Icon className="w-4 h-4" />
57
58
  </div>
@@ -60,7 +61,7 @@ export function Toast({ type, message, onClose }: ToastProps) {
60
61
  </div>
61
62
  <button
62
63
  type="button"
63
- className="kyro-toast-close"
64
+ className="kyro-toast-close group-hover:opacity-100 opacity-40 transition-opacity"
64
65
  onClick={onClose}
65
66
  >
66
67
  <X className="w-3.5 h-3.5" />
@@ -214,17 +214,19 @@ if (includeSiteName) {
214
214
  const toggleSidebar = () => {
215
215
  if (!sidebar) return;
216
216
  const isOpen = sidebar.classList.contains("translate-x-0");
217
+ const fab = document.getElementById("kyro-fab");
217
218
  if (isOpen) {
218
219
  sidebar.classList.remove("translate-x-0");
219
220
  sidebar.classList.add("-translate-x-full");
220
221
  backdrop?.classList.remove("opacity-100");
221
222
  setTimeout(() => backdrop?.classList.add("hidden"), 300);
223
+ fab?.classList.remove("fab-hidden");
222
224
  } else {
223
225
  sidebar.classList.remove("-translate-x-full");
224
226
  sidebar.classList.add("translate-x-0");
225
227
  backdrop?.classList.remove("hidden");
226
- // small delay to allow display:block to apply before opacity transition
227
228
  setTimeout(() => backdrop?.classList.add("opacity-100"), 10);
229
+ fab?.classList.add("fab-hidden");
228
230
  }
229
231
  };
230
232
 
@@ -291,6 +293,19 @@ if (includeSiteName) {
291
293
  <!-- Toast Notifications (React) -->
292
294
  <Toaster client:only="react" />
293
295
 
296
+ <!-- Floating Command Palette Trigger -->
297
+ <button
298
+ id="kyro-fab"
299
+ type="button"
300
+ onclick="window.openCommandPalette?.()"
301
+ class="fixed bottom-6 right-6 z-50 w-12 h-12 flex md:hidden items-center justify-center rounded-2xl bg-[var(--kyro-primary)] text-white shadow-lg shadow-[var(--kyro-primary)]/30 hover:shadow-xl hover:shadow-[var(--kyro-primary)]/40 hover:scale-110 active:scale-95 transition-all duration-200"
302
+ title="Open command palette (Cmd+K)"
303
+ >
304
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
305
+ <path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3" />
306
+ </svg>
307
+ </button>
308
+
294
309
  <!-- Theme UI Logic -->
295
310
  <script is:inline define:vars={{ adminPath, apiPath }}>
296
311
  const lightBtn = document.getElementById("theme-light-btn");
@@ -1,59 +1,15 @@
1
1
  ---
2
2
  import AdminLayout from "../layouts/AdminLayout.astro";
3
3
  import { GraphQLPlayground } from "../components/GraphQLPlayground";
4
-
5
- import { adminPath, apiPath } from "../lib/paths";
4
+ import { apiPath } from "../lib/paths";
6
5
  ---
7
6
 
8
7
  <AdminLayout title="GraphQL Explorer">
9
- <div class="flex-1 overflow-hidden">
10
- <!-- Header -->
11
- <div class="mb-6 surface-tile">
12
- <div class="flex items-center justify-between mb-4">
13
- <div>
14
- <h1
15
- class="text-xl font-bold tracking-tighter text-[var(--kyro-text-primary)]"
16
- >
17
- GraphQL Explorer
18
- </h1>
19
- <p
20
- class="text-[var(--kyro-text-secondary)] font-bold mt-2 text-sm tracking-wider"
21
- >
22
- Schema documentation and type explorer
23
- </p>
24
- </div>
25
- <div class="flex items-center gap-4">
26
- <a
27
- href={`${adminPath}/graphql`}
28
- class="flex items-center gap-2 px-4 py-2 bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-primary)] rounded-lg font-bold text-sm hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
29
- >
30
- <svg
31
- class="w-4 h-4"
32
- fill="none"
33
- stroke="currentColor"
34
- viewBox="0 0 24 24"
35
- >
36
- <path
37
- stroke-linecap="round"
38
- stroke-linejoin="round"
39
- stroke-width="2"
40
- d="M13 10V3L4 14h7v7l9-11h-7z"></path>
41
- </svg>
42
- Playground
43
- </a>
44
- </div>
45
- </div>
46
- </div>
47
-
48
- <!-- Explorer Container -->
49
- <div class="h-[calc(100vh-200px)] surface-tile overflow-hidden">
50
- <div class="surface-tile h-full overflow-hidden">
51
- <GraphQLPlayground
52
- client:load
53
- endpoint={`${apiPath}/graphql`}
54
- initialShowDocs={true}
55
- />
56
- </div>
57
- </div>
8
+ <div class="flex-1 overflow-hidden h-[calc(100vh-64px)] md:h-[calc(100vh-80px)]">
9
+ <GraphQLPlayground
10
+ client:load
11
+ endpoint={`${apiPath}/graphql`}
12
+ initialShowDocs={true}
13
+ />
58
14
  </div>
59
15
  </AdminLayout>
@@ -1,8 +1,7 @@
1
1
  ---
2
2
  import AdminLayout from "../layouts/AdminLayout.astro";
3
3
  import { GraphQLPlayground } from "../components/GraphQLPlayground";
4
-
5
- import { adminPath, apiPath } from "../lib/paths";
4
+ import { apiPath } from "../lib/paths";
6
5
 
7
6
  const url = Astro.request.url;
8
7
  const params = new URL(url).searchParams;
@@ -10,122 +9,11 @@ const initialQuery = params.get("query") || "";
10
9
  ---
11
10
 
12
11
  <AdminLayout title="GraphQL Playground">
13
- <div class="flex-1 overflow-hidden">
14
- <!-- Header -->
15
- <div class="mb-6 surface-tile">
16
- <div class="flex items-center justify-between mb-4">
17
- <div>
18
- <h1
19
- class="text-xl font-bold tracking-tighter text-[var(--kyro-text-primary)]"
20
- >
21
- GraphQL Playground
22
- </h1>
23
- <p
24
- class="text-[var(--kyro-text-secondary)] font-bold mt-2 text-sm tracking-wider"
25
- >
26
- Interactive GraphQL query editor and explorer
27
- </p>
28
- </div>
29
- <div class="flex items-center gap-4">
30
- <a
31
- href={`${adminPath}/graphql-explorer`}
32
- class="flex items-center gap-2 px-4 py-2 bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-primary)] rounded-lg font-bold text-sm hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
33
- >
34
- <svg
35
- class="w-4 h-4"
36
- fill="none"
37
- stroke="currentColor"
38
- viewBox="0 0 24 24"
39
- >
40
- <path
41
- stroke-linecap="round"
42
- stroke-linejoin="round"
43
- stroke-width="2"
44
- d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
45
- ></path>
46
- </svg>
47
- Explorer
48
- </a>
49
- <div
50
- class="flex items-center gap-2 px-4 py-2 bg-[var(--kyro-surface-accent)] rounded-lg border border-[var(--kyro-border)]"
51
- >
52
- <div class="w-2 h-2 rounded-full bg-green-500"></div>
53
- <span class="text-sm font-medium text-[var(--kyro-text-primary)]"
54
- >API Active</span
55
- >
56
- </div>
57
- <a
58
- href={`${apiPath}/graphql`}
59
- target="_blank"
60
- class="flex items-center gap-2 px-4 py-2 bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-primary)] rounded-lg font-bold text-sm hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
61
- >
62
- <svg
63
- class="w-4 h-4"
64
- fill="none"
65
- stroke="currentColor"
66
- viewBox="0 0 24 24"
67
- >
68
- <path
69
- stroke-linecap="round"
70
- stroke-linejoin="round"
71
- stroke-width="2"
72
- d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
73
- ></path>
74
- </svg>
75
- Open Endpoint
76
- </a>
77
- </div>
78
- </div>
79
-
80
- <!-- Quick Examples -->
81
- <div class="flex flex-wrap gap-2">
82
- <button
83
- onclick="copyToClipboard('{ __schema { types { name } } }')"
84
- class="px-3 py-1.5 text-xs font-bold text-[var(--kyro-text-secondary)] bg-[var(--kyro-surface-accent)] rounded-lg hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
85
- >
86
- Introspection
87
- </button>
88
- <button
89
- onclick="copyToClipboard('{ collections { slug name } }')"
90
- class="px-3 py-1.5 text-xs font-bold text-[var(--kyro-text-secondary)] bg-[var(--kyro-surface-accent)] rounded-lg hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
91
- >
92
- Collections
93
- </button>
94
- <button
95
- onclick="copyToClipboard('{ ping }')"
96
- class="px-3 py-1.5 text-xs font-bold text-[var(--kyro-text-secondary)] bg-[var(--kyro-surface-accent)] rounded-lg hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
97
- >
98
- Ping
99
- </button>
100
- <button
101
- onclick="copyToClipboard('{ posts(page: 1, limit: 10) { docs { id title slug } totalDocs } }')"
102
- class="px-3 py-1.5 text-xs font-bold text-[var(--kyro-text-secondary)] bg-[var(--kyro-surface-accent)] rounded-lg hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
103
- >
104
- Posts Query
105
- </button>
106
- </div>
107
- </div>
108
-
109
- <!-- GraphQL Playground Container -->
110
- <div class="h-[calc(100vh-280px)] overflow-hidden surface-tile">
111
- <GraphQLPlayground
112
- client:load
113
- endpoint={`${apiPath}/graphql`}
114
- initialQuery={initialQuery}
115
- />
116
- </div>
12
+ <div class="flex-1 overflow-hidden h-[calc(100vh-64px)] md:h-[calc(100vh-80px)]">
13
+ <GraphQLPlayground
14
+ client:load
15
+ endpoint={`${apiPath}/graphql`}
16
+ initialQuery={initialQuery}
17
+ />
117
18
  </div>
118
-
119
- <script is:inline>
120
- function copyToClipboard(text) {
121
- navigator.clipboard.writeText(text);
122
- }
123
- </script>
124
-
125
- <style is:global>
126
- /* Ensure proper styling for textarea editors */
127
- .graphiql-container textarea {
128
- font-family: var(--font-mono) !important;
129
- }
130
- </style>
131
19
  </AdminLayout>
@@ -13,7 +13,7 @@ const authItems = authCollections.map((slug) => ({
13
13
  ---
14
14
 
15
15
  <AdminLayout title="Dashboard">
16
- <div class="flex-1 overflow-y-auto space-y-8">
16
+ <div class="flex-1 overflow-y-auto space-y-8">
17
17
  <!-- Header -->
18
18
  <div class="surface-tile p-6 flex items-center justify-between gap-8">
19
19
  <div class="relative flex-1 max-w-2xl">
@@ -281,36 +281,7 @@ const authItems = authCollections.map((slug) => ({
281
281
  </p>
282
282
  </div>
283
283
  </div>
284
- <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
285
- <a
286
- href={`${adminPath}/api-explorer`}
287
- class="group p-4 bg-[var(--kyro-surface)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)]"
288
- >
289
- <div class="flex items-center gap-3 mb-2">
290
- <div
291
- class="w-8 h-8 rounded-lg bg-green-500/10 flex items-center justify-center text-green-500 group-hover:scale-110 transition-transform"
292
- >
293
- <svg
294
- class="w-4 h-4"
295
- fill="none"
296
- stroke="currentColor"
297
- viewBox="0 0 24 24"
298
- >
299
- <path
300
- stroke-linecap="round"
301
- stroke-linejoin="round"
302
- stroke-width="2"
303
- d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
304
- </svg>
305
- </div>
306
- <h4 class="font-medium text-[var(--kyro-text-primary)]">
307
- Explorer
308
- </h4>
309
- </div>
310
- <p class="text-xs text-[var(--kyro-text-secondary)]">
311
- Test endpoints interactively
312
- </p>
313
- </a>
284
+ <div class="grid grid-cols-1 gap-4">
314
285
  <a
315
286
  href={`${adminPath}/rest-playground`}
316
287
  class="group p-4 bg-[var(--kyro-surface)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)]"
@@ -394,7 +365,7 @@ const authItems = authCollections.map((slug) => ({
394
365
  </p>
395
366
  </div>
396
367
  </div>
397
- <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
368
+ <div class="grid grid-cols-1 gap-4">
398
369
  <a
399
370
  href={`${adminPath}/graphql`}
400
371
  class="group p-4 bg-[var(--kyro-surface)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)]"
@@ -422,42 +393,12 @@ const authItems = authCollections.map((slug) => ({
422
393
  d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
423
394
  </svg>
424
395
  </div>
425
- <h4 class="font-medium text-[var(--kyro-text-primary)]">
426
- Playground
427
- </h4>
428
- </div>
429
- <p class="text-xs text-[var(--kyro-text-secondary)]">
430
- Write & test queries
431
- </p>
432
- </a>
433
- <a
434
- href={`${adminPath}/graphql-explorer`}
435
- class="group p-4 bg-[var(--kyro-surface)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)]"
436
- >
437
- <div class="flex items-center gap-3 mb-2">
438
- <div
439
- class="w-8 h-8 rounded-lg bg-orange-500/10 flex items-center justify-center text-orange-500 group-hover:scale-110 transition-transform"
440
- >
441
- <svg
442
- class="w-4 h-4"
443
- fill="none"
444
- stroke="currentColor"
445
- viewBox="0 0 24 24"
446
- >
447
- <path
448
- stroke-linecap="round"
449
- stroke-linejoin="round"
450
- stroke-width="2"
451
- d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
452
- ></path>
453
- </svg>
454
- </div>
455
396
  <h4 class="font-medium text-[var(--kyro-text-primary)]">
456
397
  Explorer
457
398
  </h4>
458
399
  </div>
459
400
  <p class="text-xs text-[var(--kyro-text-secondary)]">
460
- Schema documentation
401
+ Write & test queries
461
402
  </p>
462
403
  </a>
463
404
  </div>
@@ -1,8 +1,7 @@
1
1
  ---
2
2
  import AdminLayout from "../layouts/AdminLayout.astro";
3
3
  import { RestPlayground } from "../components/RestPlayground";
4
-
5
- import { adminPath, apiPath } from "../lib/paths";
4
+ import { apiPath } from "../lib/paths";
6
5
 
7
6
  const collectionsResponse = await fetch(
8
7
  `${Astro.url.origin}${apiPath}/collections`,
@@ -12,32 +11,7 @@ const collections = collectionsData.collections || [];
12
11
  ---
13
12
 
14
13
  <AdminLayout title="REST Playground">
15
- <div class="flex-1 overflow-hidden">
16
- <!-- Header -->
17
- <div class="mb-6 surface-tile">
18
- <div class="flex items-center justify-between mb-4">
19
- <div>
20
- <h1
21
- class="text-xl font-bold tracking-tighter text-[var(--kyro-text-primary)]"
22
- >
23
- REST Playground
24
- </h1>
25
- <p
26
- class="text-[var(--kyro-text-secondary)] font-bold mt-2 text-sm tracking-wider"
27
- >
28
- Saved collections, history, and environment variables
29
- </p>
30
- </div>
31
- <div class="flex items-center gap-4">
32
- </div>
33
- </div>
34
- </div>
35
-
36
- <!-- Playground Container -->
37
- <div class="h-[calc(100vh-200px)] surface-tile overflow-hidden">
38
- <div class="surface-tile h-full overflow-hidden">
39
- <RestPlayground client:load collections={collections} />
40
- </div>
41
- </div>
14
+ <div class="flex-1 overflow-hidden h-[calc(100vh-64px)] md:h-[calc(100vh-80px)]">
15
+ <RestPlayground client:load collections={collections} />
42
16
  </div>
43
17
  </AdminLayout>