@structcms/admin 0.1.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.
@@ -0,0 +1,736 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { AuthUser, AuthSession } from '@structcms/api';
3
+ import * as React from 'react';
4
+ import React__default, { ReactNode } from 'react';
5
+ import { Registry, FieldType, SectionData, NavigationItem } from '@structcms/core';
6
+ import * as class_variance_authority_types from 'class-variance-authority/types';
7
+ import { VariantProps } from 'class-variance-authority';
8
+ import { DefaultValues } from 'react-hook-form';
9
+ import { z } from 'zod';
10
+ import { ClassValue } from 'clsx';
11
+
12
+ interface AuthContextValue {
13
+ user: AuthUser | null;
14
+ session: AuthSession | null;
15
+ isLoading: boolean;
16
+ isAuthenticated: boolean;
17
+ signIn: (email: string, password: string) => Promise<void>;
18
+ signOut: () => Promise<void>;
19
+ refreshSession: () => Promise<void>;
20
+ }
21
+ interface AuthProviderProps {
22
+ children: React__default.ReactNode;
23
+ apiBaseUrl: string;
24
+ onAuthStateChange?: (user: AuthUser | null) => void;
25
+ }
26
+ declare function AuthProvider({ children, apiBaseUrl, onAuthStateChange }: AuthProviderProps): react_jsx_runtime.JSX.Element;
27
+ declare function useAuth(): AuthContextValue;
28
+
29
+ interface SidebarNavItem {
30
+ label: string;
31
+ path: string;
32
+ }
33
+ interface AdminLayoutProps {
34
+ children: React.ReactNode;
35
+ title?: string;
36
+ navItems?: SidebarNavItem[];
37
+ activePath?: string;
38
+ onNavigate: (path: string) => void;
39
+ className?: string;
40
+ }
41
+ /**
42
+ * Admin layout with sidebar navigation, header, and content area.
43
+ *
44
+ * @example
45
+ * ```tsx
46
+ * <AdminLayout
47
+ * title="My CMS"
48
+ * onNavigate={(path) => router.push(path)}
49
+ * activePath="/pages"
50
+ * >
51
+ * <PageList ... />
52
+ * </AdminLayout>
53
+ * ```
54
+ */
55
+ declare function AdminLayout({ children, title, navItems, activePath, onNavigate, className, }: AdminLayoutProps): react_jsx_runtime.JSX.Element;
56
+ declare namespace AdminLayout {
57
+ var displayName: string;
58
+ }
59
+
60
+ interface StructCMSAdminAppProps {
61
+ registry: Registry;
62
+ apiBaseUrl?: string;
63
+ className?: string;
64
+ customNavItems?: SidebarNavItem[];
65
+ renderView?: (view: View) => React__default.ReactNode | null;
66
+ /**
67
+ * If true, wraps the app in AuthProvider. When enabled, you should provide login/auth handling.
68
+ * @default false
69
+ */
70
+ enableAuth?: boolean;
71
+ /**
72
+ * Callback when user authentication state changes
73
+ */
74
+ onAuthStateChange?: (user: AuthContextValue['user']) => void;
75
+ }
76
+ type View = {
77
+ type: 'dashboard';
78
+ } | {
79
+ type: 'pages';
80
+ } | {
81
+ type: 'page-editor';
82
+ pageId?: string;
83
+ } | {
84
+ type: 'media';
85
+ } | {
86
+ type: 'navigation';
87
+ } | {
88
+ type: 'custom';
89
+ path: string;
90
+ };
91
+ declare function StructCMSAdminApp({ registry, apiBaseUrl, className, customNavItems, renderView: customRenderView, enableAuth, onAuthStateChange, }: StructCMSAdminAppProps): react_jsx_runtime.JSX.Element;
92
+
93
+ /**
94
+ * Configuration for the Admin context
95
+ */
96
+ interface AdminContextValue {
97
+ registry: Registry;
98
+ apiBaseUrl: string;
99
+ }
100
+ /**
101
+ * Props for the AdminProvider component
102
+ */
103
+ interface AdminProviderProps {
104
+ children: ReactNode;
105
+ registry: Registry;
106
+ apiBaseUrl?: string;
107
+ }
108
+ /**
109
+ * Provider component that makes registry and API configuration available to all admin components.
110
+ *
111
+ * @example
112
+ * ```tsx
113
+ * import { AdminProvider } from '@structcms/admin';
114
+ * import { registry } from './registry';
115
+ *
116
+ * export default function AdminLayout({ children }) {
117
+ * return (
118
+ * <AdminProvider registry={registry} apiBaseUrl="/api/cms">
119
+ * {children}
120
+ * </AdminProvider>
121
+ * );
122
+ * }
123
+ * ```
124
+ */
125
+ declare function AdminProvider({ children, registry, apiBaseUrl, }: AdminProviderProps): react_jsx_runtime.JSX.Element;
126
+
127
+ /**
128
+ * Hook to access the Admin context.
129
+ * Must be used within an AdminProvider.
130
+ *
131
+ * @returns The admin context containing registry and apiBaseUrl
132
+ * @throws Error if used outside of AdminProvider
133
+ *
134
+ * @example
135
+ * ```tsx
136
+ * function MyComponent() {
137
+ * const { registry, apiBaseUrl } = useAdmin();
138
+ * const sections = registry.getAllSections();
139
+ * // ...
140
+ * }
141
+ * ```
142
+ */
143
+ declare function useAdmin(): AdminContextValue;
144
+
145
+ /**
146
+ * API response wrapper
147
+ */
148
+ interface ApiResponse<T> {
149
+ data: T | null;
150
+ error: ApiError | null;
151
+ }
152
+ /**
153
+ * API error structure
154
+ */
155
+ interface ApiError {
156
+ message: string;
157
+ code?: string;
158
+ status: number;
159
+ }
160
+ /**
161
+ * API client interface for making requests to the CMS API
162
+ */
163
+ interface ApiClient {
164
+ get<T>(path: string): Promise<ApiResponse<T>>;
165
+ post<T>(path: string, body: unknown): Promise<ApiResponse<T>>;
166
+ put<T>(path: string, body: unknown): Promise<ApiResponse<T>>;
167
+ delete<T>(path: string): Promise<ApiResponse<T>>;
168
+ upload<T>(path: string, body: FormData): Promise<ApiResponse<T>>;
169
+ }
170
+ /**
171
+ * Hook to get an API client configured with the base URL from AdminProvider.
172
+ * Must be used within an AdminProvider.
173
+ *
174
+ * @returns An API client with get, post, put, delete methods
175
+ *
176
+ * @example
177
+ * ```tsx
178
+ * function PageList() {
179
+ * const api = useApiClient();
180
+ *
181
+ * async function loadPages() {
182
+ * const { data, error } = await api.get<Page[]>('/pages');
183
+ * if (error) {
184
+ * console.error(error.message);
185
+ * return;
186
+ * }
187
+ * setPages(data);
188
+ * }
189
+ * }
190
+ * ```
191
+ */
192
+ declare function useApiClient(): ApiClient;
193
+
194
+ interface StringInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {
195
+ label: string;
196
+ error?: string;
197
+ }
198
+ /**
199
+ * Text input component for string fields with label, placeholder, and validation error display.
200
+ *
201
+ * @example
202
+ * ```tsx
203
+ * <StringInput
204
+ * label="Title"
205
+ * placeholder="Enter title..."
206
+ * required
207
+ * {...register('title')}
208
+ * error={errors.title?.message}
209
+ * />
210
+ * ```
211
+ */
212
+ declare const StringInput: React.ForwardRefExoticComponent<StringInputProps & React.RefAttributes<HTMLInputElement>>;
213
+
214
+ interface TextInputProps extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'rows'> {
215
+ label: string;
216
+ error?: string;
217
+ rows?: number;
218
+ }
219
+ /**
220
+ * Textarea component for long text fields with label, placeholder, and validation error display.
221
+ *
222
+ * @example
223
+ * ```tsx
224
+ * <TextInput
225
+ * label="Description"
226
+ * placeholder="Enter description..."
227
+ * rows={5}
228
+ * required
229
+ * {...register('description')}
230
+ * error={errors.description?.message}
231
+ * />
232
+ * ```
233
+ */
234
+ declare const TextInput: React.ForwardRefExoticComponent<TextInputProps & React.RefAttributes<HTMLTextAreaElement>>;
235
+
236
+ interface RichTextEditorProps {
237
+ label: string;
238
+ value?: string;
239
+ onChange?: (value: string) => void;
240
+ error?: string;
241
+ required?: boolean;
242
+ placeholder?: string;
243
+ className?: string;
244
+ id?: string;
245
+ name?: string;
246
+ }
247
+ /**
248
+ * WYSIWYG editor for richtext fields using TipTap.
249
+ *
250
+ * @example
251
+ * ```tsx
252
+ * <RichTextEditor
253
+ * label="Content"
254
+ * value={content}
255
+ * onChange={setContent}
256
+ * required
257
+ * error={errors.content?.message}
258
+ * />
259
+ * ```
260
+ */
261
+ declare function RichTextEditor({ label, value, onChange, error, required, placeholder, className, id, name, }: RichTextEditorProps): react_jsx_runtime.JSX.Element | null;
262
+ declare namespace RichTextEditor {
263
+ var displayName: string;
264
+ }
265
+
266
+ interface LoginFormProps {
267
+ onSuccess?: () => void;
268
+ onError?: (error: Error) => void;
269
+ }
270
+ declare function LoginForm({ onSuccess, onError }: LoginFormProps): react_jsx_runtime.JSX.Element;
271
+
272
+ interface ProtectedRouteProps {
273
+ children: React__default.ReactNode;
274
+ fallback?: React__default.ReactNode;
275
+ loadingFallback?: React__default.ReactNode;
276
+ }
277
+ declare function ProtectedRoute({ children, fallback, loadingFallback }: ProtectedRouteProps): react_jsx_runtime.JSX.Element;
278
+
279
+ interface OAuthButtonProps {
280
+ provider: 'google' | 'github' | 'gitlab' | 'azure' | 'bitbucket';
281
+ apiBaseUrl: string;
282
+ redirectTo?: string;
283
+ children?: React__default.ReactNode;
284
+ className?: string;
285
+ }
286
+ declare function OAuthButton({ provider, apiBaseUrl, redirectTo, children, className, }: OAuthButtonProps): react_jsx_runtime.JSX.Element;
287
+
288
+ interface ImagePickerProps {
289
+ label: string;
290
+ value?: string;
291
+ onChange?: (value: string) => void;
292
+ onBrowse?: () => void;
293
+ error?: string;
294
+ required?: boolean;
295
+ className?: string;
296
+ id?: string;
297
+ name?: string;
298
+ }
299
+ /**
300
+ * Component for image fields that opens MediaBrowser for selection.
301
+ *
302
+ * @example
303
+ * ```tsx
304
+ * <ImagePicker
305
+ * label="Hero Image"
306
+ * value={imageUrl}
307
+ * onChange={setImageUrl}
308
+ * onBrowse={() => setMediaBrowserOpen(true)}
309
+ * required
310
+ * error={errors.image?.message}
311
+ * />
312
+ * ```
313
+ */
314
+ declare function ImagePicker({ label, value, onChange, onBrowse, error, required, className, id, name, }: ImagePickerProps): react_jsx_runtime.JSX.Element;
315
+ declare namespace ImagePicker {
316
+ var displayName: string;
317
+ }
318
+
319
+ interface ArrayFieldProps<T> {
320
+ label: string;
321
+ value: T[];
322
+ onChange: (value: T[]) => void;
323
+ renderItem: (item: T, index: number, onChange: (item: T) => void) => React.ReactNode;
324
+ createDefaultItem: () => T;
325
+ error?: string;
326
+ required?: boolean;
327
+ className?: string;
328
+ id?: string;
329
+ name?: string;
330
+ }
331
+ declare const ArrayField: <T>(props: ArrayFieldProps<T> & {
332
+ ref?: React.ForwardedRef<HTMLDivElement>;
333
+ }) => React.ReactElement;
334
+
335
+ interface ObjectFieldProps {
336
+ label: string;
337
+ children: React.ReactNode;
338
+ error?: string;
339
+ required?: boolean;
340
+ className?: string;
341
+ id?: string;
342
+ name?: string;
343
+ }
344
+ /**
345
+ * Component for nested object fields, rendering sub-form with visual grouping.
346
+ *
347
+ * @example
348
+ * ```tsx
349
+ * <ObjectField label="Address" required>
350
+ * <StringInput label="Street" {...register('address.street')} />
351
+ * <StringInput label="City" {...register('address.city')} />
352
+ * <StringInput label="Zip" {...register('address.zip')} />
353
+ * </ObjectField>
354
+ * ```
355
+ */
356
+ declare function ObjectField({ label, children, error, required, className, id, name }: ObjectFieldProps): react_jsx_runtime.JSX.Element;
357
+ declare namespace ObjectField {
358
+ var displayName: string;
359
+ }
360
+
361
+ interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
362
+ }
363
+ declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
364
+
365
+ interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
366
+ }
367
+ declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
368
+
369
+ declare const labelVariants: (props?: class_variance_authority_types.ClassProp | undefined) => string;
370
+ interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement>, VariantProps<typeof labelVariants> {
371
+ }
372
+ declare const Label: React.ForwardRefExoticComponent<LabelProps & React.RefAttributes<HTMLLabelElement>>;
373
+
374
+ declare const buttonVariants: (props?: ({
375
+ variant?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
376
+ size?: "default" | "sm" | "lg" | "icon" | null | undefined;
377
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
378
+ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
379
+ }
380
+ declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
381
+
382
+ /**
383
+ * Resolves the FieldType from a Zod schema by unwrapping wrappers first
384
+ */
385
+ declare function resolveFieldType(schema: z.ZodTypeAny): FieldType | null;
386
+ /**
387
+ * Converts a camelCase or snake_case field name to a human-readable label
388
+ */
389
+ declare function fieldNameToLabel(name: string): string;
390
+ interface FormGeneratorProps<T extends z.ZodObject<z.ZodRawShape>> {
391
+ schema: T;
392
+ onSubmit: (data: z.infer<T>) => void;
393
+ onChange?: (data: z.infer<T>) => void;
394
+ defaultValues?: DefaultValues<z.infer<T>>;
395
+ submitLabel?: string;
396
+ className?: string;
397
+ }
398
+ /**
399
+ * Generates a React Hook Form from a Zod schema, mapping field types to input components.
400
+ *
401
+ * @example
402
+ * ```tsx
403
+ * const schema = z.object({
404
+ * title: fields.string().min(1),
405
+ * description: fields.text(),
406
+ * content: fields.richtext(),
407
+ * });
408
+ *
409
+ * <FormGenerator
410
+ * schema={schema}
411
+ * onSubmit={(data) => console.log(data)}
412
+ * submitLabel="Save"
413
+ * />
414
+ * ```
415
+ */
416
+ declare function FormGenerator<T extends z.ZodObject<z.ZodRawShape>>({ schema, onSubmit, onChange, defaultValues, submitLabel, className, }: FormGeneratorProps<T>): react_jsx_runtime.JSX.Element;
417
+ declare namespace FormGenerator {
418
+ var displayName: string;
419
+ }
420
+
421
+ interface SectionEditorProps {
422
+ sectionType: string;
423
+ data?: Record<string, unknown>;
424
+ onChange: (data: Record<string, unknown>) => void;
425
+ submitLabel?: string;
426
+ className?: string;
427
+ }
428
+ /**
429
+ * Component that renders a form for a section based on its schema from the registry.
430
+ *
431
+ * @example
432
+ * ```tsx
433
+ * <AdminProvider registry={registry} apiBaseUrl="/api/cms">
434
+ * <SectionEditor
435
+ * sectionType="hero"
436
+ * data={{ title: 'Hello', subtitle: 'World' }}
437
+ * onChange={(data) => console.log(data)}
438
+ * />
439
+ * </AdminProvider>
440
+ * ```
441
+ */
442
+ declare function SectionEditor({ sectionType, data, onChange, submitLabel, className, }: SectionEditorProps): react_jsx_runtime.JSX.Element;
443
+ declare namespace SectionEditor {
444
+ var displayName: string;
445
+ }
446
+
447
+ interface PageEditorProps {
448
+ sections: SectionData[];
449
+ allowedSections: string[];
450
+ onSave: (sections: SectionData[]) => void;
451
+ className?: string;
452
+ }
453
+ /**
454
+ * Full page editor with multiple sections, add/remove/reorder sections.
455
+ *
456
+ * @example
457
+ * ```tsx
458
+ * <AdminProvider registry={registry} apiBaseUrl="/api/cms">
459
+ * <PageEditor
460
+ * sections={page.sections}
461
+ * allowedSections={['hero', 'content', 'cta']}
462
+ * onSave={(sections) => savePage({ ...page, sections })}
463
+ * />
464
+ * </AdminProvider>
465
+ * ```
466
+ */
467
+ declare function PageEditor({ sections: initialSections, allowedSections, onSave, className, }: PageEditorProps): react_jsx_runtime.JSX.Element;
468
+ declare namespace PageEditor {
469
+ var displayName: string;
470
+ }
471
+
472
+ interface PageSummary {
473
+ id: string;
474
+ title: string;
475
+ slug: string;
476
+ pageType: string;
477
+ updatedAt?: string;
478
+ }
479
+ interface PageListProps {
480
+ onSelectPage: (page: PageSummary) => void;
481
+ onCreatePage: () => void;
482
+ className?: string;
483
+ }
484
+ /**
485
+ * List all pages with filter/search, link to edit each page.
486
+ *
487
+ * @example
488
+ * ```tsx
489
+ * <AdminProvider registry={registry} apiBaseUrl="/api/cms">
490
+ * <PageList
491
+ * onSelectPage={(page) => router.push(`/admin/pages/${page.id}`)}
492
+ * onCreatePage={() => router.push('/admin/pages/new')}
493
+ * />
494
+ * </AdminProvider>
495
+ * ```
496
+ */
497
+ declare function PageList({ onSelectPage, onCreatePage, className }: PageListProps): react_jsx_runtime.JSX.Element;
498
+ declare namespace PageList {
499
+ var displayName: string;
500
+ }
501
+
502
+ interface NavigationEditorProps {
503
+ items: NavigationItem[];
504
+ onSave: (items: NavigationItem[]) => void;
505
+ className?: string;
506
+ }
507
+ /**
508
+ * Editor for navigation items with nested structure support (one level).
509
+ *
510
+ * @example
511
+ * ```tsx
512
+ * <NavigationEditor
513
+ * items={navigation.items}
514
+ * onSave={(items) => saveNavigation({ ...navigation, items })}
515
+ * />
516
+ * ```
517
+ */
518
+ declare function NavigationEditor({ items: initialItems, onSave, className }: NavigationEditorProps): react_jsx_runtime.JSX.Element;
519
+ declare namespace NavigationEditor {
520
+ var displayName: string;
521
+ }
522
+
523
+ interface MediaItem {
524
+ id: string;
525
+ url: string;
526
+ filename: string;
527
+ mimeType?: string;
528
+ createdAt?: string;
529
+ }
530
+ interface MediaBrowserProps {
531
+ onSelect?: (item: MediaItem) => void;
532
+ className?: string;
533
+ pageSize?: number;
534
+ }
535
+ /**
536
+ * Browse, upload, and select media files.
537
+ *
538
+ * @example
539
+ * ```tsx
540
+ * <AdminProvider registry={registry} apiBaseUrl="/api/cms">
541
+ * <MediaBrowser onSelect={(item) => setImageUrl(item.url)} />
542
+ * </AdminProvider>
543
+ * ```
544
+ */
545
+ declare function MediaBrowser({ onSelect, className, pageSize }: MediaBrowserProps): react_jsx_runtime.JSX.Element;
546
+ declare namespace MediaBrowser {
547
+ var displayName: string;
548
+ }
549
+
550
+ interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
551
+ width?: string | number;
552
+ height?: string | number;
553
+ }
554
+ /**
555
+ * Skeleton loading placeholder with pulse animation.
556
+ *
557
+ * @example
558
+ * ```tsx
559
+ * <Skeleton className="h-4 w-48" />
560
+ * <Skeleton width={200} height={20} />
561
+ * ```
562
+ */
563
+ declare function Skeleton({ className, width, height, style, ...props }: SkeletonProps): react_jsx_runtime.JSX.Element;
564
+ declare namespace Skeleton {
565
+ var displayName: string;
566
+ }
567
+
568
+ type ToastVariant = 'default' | 'success' | 'error';
569
+ interface Toast {
570
+ id: string;
571
+ message: string;
572
+ variant?: ToastVariant;
573
+ }
574
+ interface ToastProviderProps {
575
+ children: React.ReactNode;
576
+ autoDismissMs?: number;
577
+ }
578
+ /**
579
+ * Provider for toast notifications. Wrap your app with this to enable useToast().
580
+ *
581
+ * @example
582
+ * ```tsx
583
+ * <ToastProvider>
584
+ * <App />
585
+ * </ToastProvider>
586
+ * ```
587
+ */
588
+ declare function ToastProvider({ children, autoDismissMs }: ToastProviderProps): react_jsx_runtime.JSX.Element;
589
+ declare namespace ToastProvider {
590
+ var displayName: string;
591
+ }
592
+ /**
593
+ * Hook to trigger toast notifications. Must be used within a ToastProvider.
594
+ *
595
+ * @example
596
+ * ```tsx
597
+ * const { toast } = useToast();
598
+ * toast('Page saved!', 'success');
599
+ * toast('Something went wrong', 'error');
600
+ * ```
601
+ */
602
+ declare function useToast(): {
603
+ toast: (message: string, variant?: ToastVariant) => void;
604
+ dismiss: (id: string) => void;
605
+ toasts: Toast[];
606
+ };
607
+
608
+ interface ErrorBoundaryProps {
609
+ children: React.ReactNode;
610
+ fallback?: React.ReactNode;
611
+ onReset?: () => void;
612
+ className?: string;
613
+ }
614
+ interface ErrorBoundaryState {
615
+ hasError: boolean;
616
+ error: Error | null;
617
+ }
618
+ /**
619
+ * Error boundary for catching component-level render errors.
620
+ *
621
+ * @example
622
+ * ```tsx
623
+ * <ErrorBoundary fallback={<p>Something went wrong</p>}>
624
+ * <MyComponent />
625
+ * </ErrorBoundary>
626
+ * ```
627
+ */
628
+ declare class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
629
+ constructor(props: ErrorBoundaryProps);
630
+ static getDerivedStateFromError(error: Error): ErrorBoundaryState;
631
+ handleReset: () => void;
632
+ render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;
633
+ }
634
+
635
+ interface DialogProps {
636
+ open: boolean;
637
+ onClose: () => void;
638
+ children: React.ReactNode;
639
+ className?: string;
640
+ title?: string;
641
+ }
642
+ /**
643
+ * Minimal dialog component using React Portal.
644
+ * Renders a modal overlay with backdrop that closes on outside click or Escape key.
645
+ *
646
+ * @example
647
+ * ```tsx
648
+ * <Dialog open={isOpen} onClose={() => setIsOpen(false)} title="Select Media">
649
+ * <MediaBrowser onSelect={handleSelect} />
650
+ * </Dialog>
651
+ * ```
652
+ */
653
+ declare function Dialog({ open, onClose, children, className, title }: DialogProps): React.ReactPortal | null;
654
+ declare namespace Dialog {
655
+ var displayName: string;
656
+ }
657
+
658
+ interface DashboardPageProps {
659
+ onSelectPage: (page: PageSummary) => void;
660
+ onCreatePage: () => void;
661
+ onUploadMedia: () => void;
662
+ className?: string;
663
+ }
664
+ /**
665
+ * Main dashboard page composing KPI cards, recent pages, and quick actions.
666
+ * This is the default admin entry point.
667
+ *
668
+ * @example
669
+ * ```tsx
670
+ * <AdminProvider registry={registry} apiBaseUrl="/api/cms">
671
+ * <DashboardPage
672
+ * onSelectPage={(page) => router.push(`/admin/pages/${page.id}`)}
673
+ * onCreatePage={() => router.push('/admin/pages/new')}
674
+ * onUploadMedia={() => router.push('/admin/media')}
675
+ * />
676
+ * </AdminProvider>
677
+ * ```
678
+ */
679
+ declare function DashboardPage({ onSelectPage, onCreatePage, onUploadMedia, className, }: DashboardPageProps): react_jsx_runtime.JSX.Element;
680
+ declare namespace DashboardPage {
681
+ var displayName: string;
682
+ }
683
+
684
+ interface QuickActionsProps {
685
+ onCreatePage: () => void;
686
+ onUploadMedia: () => void;
687
+ className?: string;
688
+ }
689
+ declare function QuickActions({ onCreatePage, onUploadMedia, className }: QuickActionsProps): react_jsx_runtime.JSX.Element;
690
+
691
+ interface KpiCardsProps {
692
+ className?: string;
693
+ }
694
+ /**
695
+ * Dashboard KPI cards displaying content metrics.
696
+ *
697
+ * Fetches pages, media, and navigation counts from the API in parallel.
698
+ * Sections count is derived synchronously from the registry.
699
+ *
700
+ * @example
701
+ * ```tsx
702
+ * <AdminProvider registry={registry} apiBaseUrl="/api/cms">
703
+ * <KpiCards />
704
+ * </AdminProvider>
705
+ * ```
706
+ */
707
+ declare function KpiCards({ className }: KpiCardsProps): react_jsx_runtime.JSX.Element;
708
+ declare namespace KpiCards {
709
+ var displayName: string;
710
+ }
711
+
712
+ interface RecentPagesProps {
713
+ onSelectPage: (page: PageSummary) => void;
714
+ className?: string;
715
+ }
716
+ /**
717
+ * Displays a list of recently updated pages (max 10, sorted by updatedAt DESC).
718
+ *
719
+ * @example
720
+ * ```tsx
721
+ * <AdminProvider registry={registry} apiBaseUrl="/api/cms">
722
+ * <RecentPages onSelectPage={(page) => router.push(`/admin/pages/${page.id}`)} />
723
+ * </AdminProvider>
724
+ * ```
725
+ */
726
+ declare function RecentPages({ onSelectPage, className }: RecentPagesProps): react_jsx_runtime.JSX.Element;
727
+ declare namespace RecentPages {
728
+ var displayName: string;
729
+ }
730
+
731
+ /**
732
+ * Utility function to merge Tailwind CSS classes with clsx
733
+ */
734
+ declare function cn(...inputs: ClassValue[]): string;
735
+
736
+ export { type AdminContextValue, AdminLayout, type AdminLayoutProps, AdminProvider, type AdminProviderProps, type ApiClient, type ApiError, type ApiResponse, ArrayField, type ArrayFieldProps, type AuthContextValue, AuthProvider, type AuthProviderProps, Button, type ButtonProps, DashboardPage, type DashboardPageProps, Dialog, type DialogProps, ErrorBoundary, type ErrorBoundaryProps, FormGenerator, type FormGeneratorProps, ImagePicker, type ImagePickerProps, Input, type InputProps, KpiCards, type KpiCardsProps, Label, type LabelProps, LoginForm, type LoginFormProps, MediaBrowser, type MediaBrowserProps, type MediaItem, NavigationEditor, type NavigationEditorProps, OAuthButton, type OAuthButtonProps, ObjectField, type ObjectFieldProps, PageEditor, type PageEditorProps, PageList, type PageListProps, type PageSummary, ProtectedRoute, type ProtectedRouteProps, QuickActions, type QuickActionsProps, RecentPages, type RecentPagesProps, RichTextEditor, type RichTextEditorProps, SectionEditor, type SectionEditorProps, type SidebarNavItem, Skeleton, type SkeletonProps, StringInput, type StringInputProps, StructCMSAdminApp, type StructCMSAdminAppProps, TextInput, type TextInputProps, Textarea, type TextareaProps, type Toast, ToastProvider, type ToastProviderProps, type ToastVariant, type View, buttonVariants, cn, fieldNameToLabel, resolveFieldType, useAdmin, useApiClient, useAuth, useToast };