@plutocms/supabase 0.0.1-alpha.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 (99) hide show
  1. package/.agents/skills/nuxt/GENERATION.md +5 -0
  2. package/.agents/skills/nuxt/SKILL.md +55 -0
  3. package/.agents/skills/nuxt/references/advanced-hooks.md +289 -0
  4. package/.agents/skills/nuxt/references/advanced-layers.md +299 -0
  5. package/.agents/skills/nuxt/references/advanced-module-authoring.md +554 -0
  6. package/.agents/skills/nuxt/references/best-practices-data-fetching.md +357 -0
  7. package/.agents/skills/nuxt/references/best-practices-ssr.md +355 -0
  8. package/.agents/skills/nuxt/references/core-cli.md +263 -0
  9. package/.agents/skills/nuxt/references/core-config.md +162 -0
  10. package/.agents/skills/nuxt/references/core-data-fetching.md +236 -0
  11. package/.agents/skills/nuxt/references/core-deployment.md +224 -0
  12. package/.agents/skills/nuxt/references/core-directory-structure.md +269 -0
  13. package/.agents/skills/nuxt/references/core-modules.md +292 -0
  14. package/.agents/skills/nuxt/references/core-routing.md +226 -0
  15. package/.agents/skills/nuxt/references/features-components-autoimport.md +328 -0
  16. package/.agents/skills/nuxt/references/features-components.md +264 -0
  17. package/.agents/skills/nuxt/references/features-composables.md +276 -0
  18. package/.agents/skills/nuxt/references/features-server.md +265 -0
  19. package/.agents/skills/nuxt/references/features-state.md +194 -0
  20. package/.agents/skills/nuxt/references/rendering-modes.md +237 -0
  21. package/.agents/skills/nuxt-ui/SKILL.md +334 -0
  22. package/.agents/skills/nuxt-ui/references/components.md +377 -0
  23. package/.agents/skills/nuxt-ui/references/composables.md +127 -0
  24. package/.agents/skills/nuxt-ui/references/layouts/chat.md +195 -0
  25. package/.agents/skills/nuxt-ui/references/layouts/dashboard.md +220 -0
  26. package/.agents/skills/nuxt-ui/references/layouts/docs.md +141 -0
  27. package/.agents/skills/nuxt-ui/references/layouts/editor.md +167 -0
  28. package/.agents/skills/nuxt-ui/references/layouts/page.md +260 -0
  29. package/.agents/skills/nuxt-ui/references/theming.md +427 -0
  30. package/.agents/skills/supabase-postgres-best-practices/AGENTS.md +68 -0
  31. package/.agents/skills/supabase-postgres-best-practices/CLAUDE.md +1 -0
  32. package/.agents/skills/supabase-postgres-best-practices/README.md +116 -0
  33. package/.agents/skills/supabase-postgres-best-practices/SKILL.md +64 -0
  34. package/.agents/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
  35. package/.agents/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
  36. package/.agents/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
  37. package/.agents/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
  38. package/.agents/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
  39. package/.agents/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
  40. package/.agents/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
  41. package/.agents/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
  42. package/.agents/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
  43. package/.agents/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
  44. package/.agents/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
  45. package/.agents/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
  46. package/.agents/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
  47. package/.agents/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
  48. package/.agents/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
  49. package/.agents/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
  50. package/.agents/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
  51. package/.agents/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
  52. package/.agents/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
  53. package/.agents/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
  54. package/.agents/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
  55. package/.agents/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
  56. package/.agents/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
  57. package/.agents/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
  58. package/.agents/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
  59. package/.agents/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
  60. package/.agents/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
  61. package/.agents/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
  62. package/.agents/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
  63. package/.agents/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
  64. package/.agents/skills/supabase-postgres-best-practices/references/security-rls-performance.md +57 -0
  65. package/.editorconfig +12 -0
  66. package/.env.example +2 -0
  67. package/.eslintignore +1 -0
  68. package/.prettierrc +9 -0
  69. package/.vscode/extensions.json +10 -0
  70. package/.vscode/settings.json +61 -0
  71. package/README.md +62 -0
  72. package/app/components/navbar/NavbarAdmin.vue +169 -0
  73. package/app/composables/auth.ts +81 -0
  74. package/app/layouts/setup.vue +13 -0
  75. package/app/middleware/auth.ts +27 -0
  76. package/app/middleware/setup-check.ts +25 -0
  77. package/app/pages/admin/(auth)/login.vue +84 -0
  78. package/app/pages/admin/(auth)/signup.vue +128 -0
  79. package/app/pages/admin/settings.vue +116 -0
  80. package/app/pages/admin/setup.vue +300 -0
  81. package/app/pages/admin.vue +38 -0
  82. package/bun.lock +2685 -0
  83. package/eslint.config.mjs +88 -0
  84. package/nuxt.config.ts +55 -0
  85. package/package.json +44 -0
  86. package/public/schema.sql +103 -0
  87. package/scripts/supabase-typegen.ts +36 -0
  88. package/server/api/category/list.get.ts +9 -0
  89. package/server/api/category/new.post.ts +31 -0
  90. package/server/api/settings/first_setup.get.ts +39 -0
  91. package/server/api/settings/index.get.ts +27 -0
  92. package/server/api/settings/update.post.ts +36 -0
  93. package/server/api/setup/create.post.ts +58 -0
  94. package/server/api/signup.post.ts +28 -0
  95. package/server/api/users/[id].get.ts +21 -0
  96. package/server/api/users/index.get.ts +16 -0
  97. package/shared/types/supabase.ts +406 -0
  98. package/skills-lock.json +20 -0
  99. package/tsconfig.json +18 -0
@@ -0,0 +1,220 @@
1
+ # Dashboard Layout
2
+
3
+ Build admin interfaces with resizable sidebars, multi-panel layouts, and toolbars.
4
+
5
+ ## Component tree
6
+
7
+ ```
8
+ UApp
9
+ └── NuxtLayout (dashboard)
10
+ └── UDashboardGroup
11
+ ├── UDashboardSidebar
12
+ │ ├── #header (logo, search button)
13
+ │ ├── #default (navigation) — receives { collapsed } slot prop
14
+ │ └── #footer (user menu)
15
+ └── NuxtPage
16
+ └── UDashboardPanel
17
+ ├── #header → UDashboardNavbar + UDashboardToolbar
18
+ ├── #body (scrollable content)
19
+ └── #footer (optional)
20
+ ```
21
+
22
+ ## Layout
23
+
24
+ ```vue [layouts/dashboard.vue]
25
+ <script setup lang="ts">
26
+ import type { NavigationMenuItem } from '@nuxt/ui'
27
+
28
+ const items = computed<NavigationMenuItem[]>(() => [{
29
+ label: 'Home',
30
+ icon: 'i-lucide-house',
31
+ to: '/dashboard'
32
+ }, {
33
+ label: 'Inbox',
34
+ icon: 'i-lucide-inbox',
35
+ to: '/dashboard/inbox'
36
+ }, {
37
+ label: 'Users',
38
+ icon: 'i-lucide-users',
39
+ to: '/dashboard/users'
40
+ }, {
41
+ label: 'Settings',
42
+ icon: 'i-lucide-settings',
43
+ to: '/dashboard/settings'
44
+ }])
45
+ </script>
46
+
47
+ <template>
48
+ <UDashboardGroup>
49
+ <UDashboardSidebar collapsible resizable>
50
+ <template #header="{ collapsed }">
51
+ <UDashboardSearchButton :collapsed="collapsed" />
52
+ </template>
53
+
54
+ <template #default="{ collapsed }">
55
+ <UNavigationMenu
56
+ :items="items"
57
+ orientation="vertical"
58
+ :ui="{ link: collapsed ? 'justify-center' : undefined }"
59
+ />
60
+ </template>
61
+
62
+ <template #footer="{ collapsed }">
63
+ <UButton
64
+ :icon="collapsed ? 'i-lucide-log-out' : undefined"
65
+ :label="collapsed ? undefined : 'Sign out'"
66
+ color="neutral"
67
+ variant="ghost"
68
+ block
69
+ />
70
+ </template>
71
+ </UDashboardSidebar>
72
+
73
+ <slot />
74
+ </UDashboardGroup>
75
+ </template>
76
+ ```
77
+
78
+ ## Page
79
+
80
+ ```vue [pages/dashboard/index.vue]
81
+ <script setup lang="ts">
82
+ definePageMeta({ layout: 'dashboard' })
83
+ </script>
84
+
85
+ <template>
86
+ <UDashboardPanel>
87
+ <template #header>
88
+ <UDashboardNavbar title="Home">
89
+ <template #right>
90
+ <UButton icon="i-lucide-plus" label="New" />
91
+ </template>
92
+ </UDashboardNavbar>
93
+ </template>
94
+
95
+ <template #body>
96
+ <!-- Page content -->
97
+ </template>
98
+ </UDashboardPanel>
99
+ </template>
100
+ ```
101
+
102
+ ## Key components
103
+
104
+ ### DashboardGroup
105
+
106
+ Root layout wrapper. Manages sidebar state and persistence.
107
+
108
+ | Prop | Default | Description |
109
+ |---|---|---|
110
+ | `storage` | `'cookie'` | State persistence: `'cookie'`, `'localStorage'`, `false` |
111
+ | `storage-key` | `'dashboard'` | Storage key name |
112
+ | `unit` | `'percentages'` | Size unit: `'percentages'` or `'pixels'` |
113
+
114
+ ### DashboardSidebar
115
+
116
+ Resizable, collapsible sidebar. Must be inside `DashboardGroup`.
117
+
118
+ | Prop | Default | Description |
119
+ |---|---|---|
120
+ | `resizable` | `false` | Enable resize by dragging |
121
+ | `collapsible` | `false` | Enable collapse when dragged to edge |
122
+ | `side` | `'left'` | `'left'` or `'right'` |
123
+ | `mode` | `'slideover'` | Mobile menu mode: `'modal'`, `'slideover'`, `'drawer'` |
124
+
125
+ Slots receive `{ collapsed }` prop. Control state: `v-model:collapsed`, `v-model:open` (mobile).
126
+
127
+ ### DashboardPanel
128
+
129
+ Content panel with `#header`, `#body` (scrollable), `#footer`, and `#default` (raw) slots.
130
+
131
+ | Prop | Default | Description |
132
+ |---|---|---|
133
+ | `id` | `—` | Unique ID (required for multi-panel) |
134
+ | `resizable` | `false` | Enable resize by dragging |
135
+
136
+ ### DashboardNavbar / DashboardToolbar
137
+
138
+ Navbar has `#left`, `#default`, `#right` slots and a `title` prop. Toolbar has the same slots for filters/actions below the navbar.
139
+
140
+ ## Multi-panel (list-detail)
141
+
142
+ ```vue [pages/dashboard/inbox.vue]
143
+ <script setup lang="ts">
144
+ definePageMeta({ layout: 'dashboard' })
145
+ </script>
146
+
147
+ <template>
148
+ <UDashboardPanel id="inbox-list" resizable>
149
+ <template #header>
150
+ <UDashboardNavbar title="Inbox" />
151
+ </template>
152
+ <template #body>
153
+ <!-- Email list -->
154
+ </template>
155
+ </UDashboardPanel>
156
+
157
+ <UDashboardPanel id="inbox-detail" class="hidden lg:flex">
158
+ <template #header>
159
+ <UDashboardNavbar title="Message" />
160
+ </template>
161
+ <template #body>
162
+ <!-- Email content -->
163
+ </template>
164
+ </UDashboardPanel>
165
+ </template>
166
+ ```
167
+
168
+ ## With toolbar
169
+
170
+ ```vue
171
+ <UDashboardPanel>
172
+ <template #header>
173
+ <UDashboardNavbar title="Users" />
174
+
175
+ <UDashboardToolbar>
176
+ <template #left>
177
+ <UInput icon="i-lucide-search" placeholder="Search..." />
178
+ </template>
179
+ <template #right>
180
+ <USelect :items="['All', 'Active', 'Inactive']" />
181
+ </template>
182
+ </UDashboardToolbar>
183
+ </template>
184
+ </UDashboardPanel>
185
+ ```
186
+
187
+ ## With search
188
+
189
+ ```vue [layouts/dashboard.vue]
190
+ <template>
191
+ <UDashboardGroup>
192
+ <UDashboardSidebar>
193
+ <template #header>
194
+ <UDashboardSearchButton />
195
+ </template>
196
+ <!-- ... -->
197
+ </UDashboardSidebar>
198
+
199
+ <slot />
200
+
201
+ <UDashboardSearch :groups="searchGroups" />
202
+ </UDashboardGroup>
203
+ </template>
204
+ ```
205
+
206
+ ## Right sidebar
207
+
208
+ ```vue
209
+ <UDashboardGroup>
210
+ <UDashboardSidebar collapsible resizable>
211
+ <!-- Left sidebar -->
212
+ </UDashboardSidebar>
213
+
214
+ <slot />
215
+
216
+ <UDashboardSidebar side="right" resizable>
217
+ <!-- Right sidebar -->
218
+ </UDashboardSidebar>
219
+ </UDashboardGroup>
220
+ ```
@@ -0,0 +1,141 @@
1
+ # Docs Layout
2
+
3
+ Build documentation sites with sidebar navigation, table of contents, and surround links.
4
+
5
+ > Requires `@nuxt/content` module for navigation, search, and TOC.
6
+
7
+ ## Component tree
8
+
9
+ ```
10
+ UApp
11
+ ├── UHeader
12
+ ├── UMain
13
+ │ └── NuxtLayout (docs)
14
+ │ └── UPage
15
+ │ ├── #left → UPageAside → UContentNavigation
16
+ │ └── NuxtPage
17
+ │ ├── UPageHeader
18
+ │ ├── UPageBody → ContentRenderer + UContentSurround
19
+ │ └── #right → UContentToc
20
+ └── UFooter
21
+ ```
22
+
23
+ ## App shell
24
+
25
+ ```vue [app.vue]
26
+ <script setup lang="ts">
27
+ import type { NavigationMenuItem } from '@nuxt/ui'
28
+
29
+ const route = useRoute()
30
+
31
+ const { data: navigation } = await useAsyncData('navigation', () => queryCollectionNavigation('docs'))
32
+
33
+ provide('navigation', navigation)
34
+
35
+ const items = computed<NavigationMenuItem[]>(() => [{
36
+ label: 'Docs',
37
+ to: '/docs/getting-started',
38
+ active: route.path.startsWith('/docs')
39
+ }])
40
+ </script>
41
+
42
+ <template>
43
+ <UApp>
44
+ <UHeader>
45
+ <template #title>
46
+ <Logo class="h-6 w-auto" />
47
+ </template>
48
+
49
+ <UNavigationMenu :items="items" />
50
+
51
+ <template #right>
52
+ <UContentSearchButton />
53
+ <UColorModeButton />
54
+ </template>
55
+ </UHeader>
56
+
57
+ <UMain>
58
+ <NuxtLayout>
59
+ <NuxtPage />
60
+ </NuxtLayout>
61
+ </UMain>
62
+
63
+ <UFooter />
64
+
65
+ <UContentSearch :navigation="navigation" />
66
+ </UApp>
67
+ </template>
68
+ ```
69
+
70
+ ## Layout
71
+
72
+ ```vue [layouts/docs.vue]
73
+ <script setup lang="ts">
74
+ import type { ContentNavigationItem } from '@nuxt/content'
75
+
76
+ const navigation = inject<Ref<ContentNavigationItem[]>>('navigation')
77
+ </script>
78
+
79
+ <template>
80
+ <UPage>
81
+ <template #left>
82
+ <UPageAside>
83
+ <UContentNavigation :navigation="navigation" />
84
+ </UPageAside>
85
+ </template>
86
+
87
+ <slot />
88
+ </UPage>
89
+ </template>
90
+ ```
91
+
92
+ ## Page
93
+
94
+ ```vue [pages/docs/[...slug].vue]
95
+ <script setup lang="ts">
96
+ const route = useRoute()
97
+
98
+ definePageMeta({ layout: 'docs' })
99
+
100
+ const { data: page } = await useAsyncData(route.path, () => {
101
+ return queryCollection('docs').path(route.path).first()
102
+ })
103
+
104
+ const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
105
+ return queryCollectionItemSurroundings('docs', route.path)
106
+ })
107
+ </script>
108
+
109
+ <template>
110
+ <UPage>
111
+ <UPageHeader :title="page.title" :description="page.description" />
112
+
113
+ <UPageBody>
114
+ <ContentRenderer :value="page" />
115
+
116
+ <USeparator />
117
+
118
+ <UContentSurround :surround="surround" />
119
+ </UPageBody>
120
+
121
+ <template #right>
122
+ <UContentToc :links="page.body.toc.links" />
123
+ </template>
124
+ </UPage>
125
+ </template>
126
+ ```
127
+
128
+ > The outer `UPage` in the layout handles the left sidebar. The inner `UPage` in the page handles the right sidebar. They nest correctly.
129
+
130
+ ## Key components
131
+
132
+ - `UPage` — Multi-column grid layout with `#left`, `#default`, `#right` slots
133
+ - `UPageAside` — Sticky sidebar wrapper (visible from `lg` breakpoint)
134
+ - `UPageHeader` — Page title and description
135
+ - `UPageBody` — Main content area
136
+ - `UContentNavigation` — Sidebar navigation tree
137
+ - `UContentToc` — Table of contents
138
+ - `UContentSurround` — Prev/next links
139
+ - `UContentSearch` / `UContentSearchButton` — Search command palette
140
+ - `UPageAnchors` — Simpler alternative to full TOC
141
+ - `UPageLinks` — Related resource links
@@ -0,0 +1,167 @@
1
+ # Editor Layout
2
+
3
+ Build a rich text editor with toolbars, slash commands, mentions, and drag-and-drop.
4
+
5
+ ## Component tree
6
+
7
+ ```
8
+ UApp
9
+ ├── UHeader
10
+ ├── UMain
11
+ │ └── NuxtPage
12
+ │ └── UContainer
13
+ │ └── UEditor
14
+ │ ├── UEditorToolbar (fixed / bubble / floating)
15
+ │ ├── UEditorDragHandle
16
+ │ ├── UEditorSuggestionMenu
17
+ │ ├── UEditorMentionMenu
18
+ │ └── UEditorEmojiMenu
19
+ └── UFooter
20
+ ```
21
+
22
+ ## Page
23
+
24
+ ```vue [pages/editor.vue]
25
+ <script setup lang="ts">
26
+ const content = ref({
27
+ type: 'doc',
28
+ content: [
29
+ {
30
+ type: 'heading',
31
+ attrs: { level: 1 },
32
+ content: [{ type: 'text', text: 'Hello World' }]
33
+ },
34
+ {
35
+ type: 'paragraph',
36
+ content: [{ type: 'text', text: 'Start writing...' }]
37
+ }
38
+ ]
39
+ })
40
+ </script>
41
+
42
+ <template>
43
+ <UPage>
44
+ <UPageHeader title="Editor">
45
+ <template #actions>
46
+ <UButton label="Save" icon="i-lucide-save" />
47
+ </template>
48
+ </UPageHeader>
49
+
50
+ <UPageBody>
51
+ <UEditor v-model="content">
52
+ <UEditorToolbar />
53
+ <UEditorDragHandle />
54
+ <UEditorSuggestionMenu />
55
+ <UEditorMentionMenu
56
+ :items="[
57
+ { label: 'Benjamin', avatar: { src: 'https://github.com/benjamincanac.png' } },
58
+ { label: 'Sébastien', avatar: { src: 'https://github.com/atinux.png' } }
59
+ ]"
60
+ />
61
+ <UEditorEmojiMenu />
62
+ </UEditor>
63
+ </UPageBody>
64
+ </UPage>
65
+ </template>
66
+ ```
67
+
68
+ > If you encounter prosemirror-related errors, add prosemirror packages to `vite.optimizeDeps.include` in `nuxt.config.ts`.
69
+
70
+ ## Key components
71
+
72
+ - `UEditor` — Rich text editor (`v-model` accepts JSON, HTML, or markdown via `content-type` prop)
73
+ - `UEditorToolbar` — Toolbar with `layout`: `'fixed'` (default), `'bubble'` (on selection), `'floating'` (on empty lines)
74
+ - `UEditorDragHandle` — Block drag-and-drop handle
75
+ - `UEditorSuggestionMenu` — Slash command menu
76
+ - `UEditorMentionMenu` — @ mention menu
77
+ - `UEditorEmojiMenu` — Emoji picker
78
+
79
+ ## Toolbar modes
80
+
81
+ ```vue
82
+ <!-- Fixed (default) -->
83
+ <UEditor v-model="content">
84
+ <UEditorToolbar />
85
+ </UEditor>
86
+
87
+ <!-- Bubble (appears on text selection) -->
88
+ <UEditor v-model="content">
89
+ <UEditorToolbar layout="bubble" />
90
+ </UEditor>
91
+
92
+ <!-- Floating (appears on empty lines) -->
93
+ <UEditor v-model="content">
94
+ <UEditorToolbar layout="floating" />
95
+ </UEditor>
96
+ ```
97
+
98
+ ## Content types
99
+
100
+ ```vue
101
+ <!-- JSON (default) -->
102
+ <UEditor v-model="jsonContent" />
103
+
104
+ <!-- HTML -->
105
+ <UEditor v-model="htmlContent" content-type="html" />
106
+
107
+ <!-- Markdown -->
108
+ <UEditor v-model="markdownContent" content-type="markdown" />
109
+ ```
110
+
111
+ ## With document sidebar
112
+
113
+ Combine with Dashboard components for a multi-document editor with a sidebar.
114
+
115
+ ```vue [layouts/editor.vue]
116
+ <template>
117
+ <UDashboardGroup>
118
+ <UDashboardSidebar collapsible resizable>
119
+ <template #header>
120
+ <UButton icon="i-lucide-plus" label="New document" block />
121
+ </template>
122
+
123
+ <template #default>
124
+ <UNavigationMenu
125
+ :items="documents.map(doc => ({
126
+ label: doc.title,
127
+ to: `/editor/${doc.id}`,
128
+ icon: 'i-lucide-file-text'
129
+ }))"
130
+ orientation="vertical"
131
+ />
132
+ </template>
133
+ </UDashboardSidebar>
134
+
135
+ <slot />
136
+ </UDashboardGroup>
137
+ </template>
138
+ ```
139
+
140
+ ```vue [pages/editor/[id].vue]
141
+ <script setup lang="ts">
142
+ definePageMeta({ layout: 'editor' })
143
+
144
+ const content = ref({ type: 'doc', content: [] })
145
+ </script>
146
+
147
+ <template>
148
+ <UDashboardPanel>
149
+ <template #header>
150
+ <UDashboardNavbar title="Editor">
151
+ <template #right>
152
+ <UButton label="Save" icon="i-lucide-save" />
153
+ </template>
154
+ </UDashboardNavbar>
155
+ </template>
156
+
157
+ <UContainer class="py-8">
158
+ <UEditor v-model="content">
159
+ <UEditorToolbar />
160
+ <UEditorDragHandle />
161
+ <UEditorSuggestionMenu />
162
+ <UEditorEmojiMenu />
163
+ </UEditor>
164
+ </UContainer>
165
+ </UDashboardPanel>
166
+ </template>
167
+ ```