Skip to content

Commit 3c151cb

Browse files
committed
feat: big refactor for great UX
1 parent 7829c22 commit 3c151cb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+499
-557
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"exports": {
99
".": "./dist/module/module.mjs",
1010
"./app": {
11-
"types": "./dist/app/index.d.ts",
12-
"default": "./dist/app/index.js"
11+
"types": "./dist/app/main.d.ts",
12+
"default": "./dist/app/main.js"
1313
},
1414
"./app/utils": {
1515
"types": "./dist/app/utils.d.ts",

src/app/src/App.vue

Lines changed: 0 additions & 80 deletions
This file was deleted.

src/app/src/app.vue

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<script setup lang="ts">
2+
import { useStudio } from './composables/useStudio'
3+
import { watch, ref } from 'vue'
4+
import { StudioFeature } from './types'
5+
import { defineShortcuts } from '#imports'
6+
import { useRouter } from 'vue-router'
7+
8+
const { host, ui, isReady, documentTree } = useStudio()
9+
const router = useRouter()
10+
11+
defineShortcuts({
12+
'meta_.': () => {
13+
ui.toggle()
14+
},
15+
})
16+
17+
watch(ui.sidebar.sidebarWidth, () => {
18+
if (ui.isOpen.value) {
19+
host.ui.updateStyles()
20+
}
21+
})
22+
const activeDocuments = ref<{ id: string, title: string }[]>([])
23+
24+
function detectActiveDocuments() {
25+
activeDocuments.value = host.document.detectActives().map((content) => {
26+
return {
27+
id: content.id,
28+
title: content.title,
29+
}
30+
})
31+
}
32+
33+
async function editContentFile(id: string) {
34+
await documentTree.selectItemById(id)
35+
ui.open(StudioFeature.Content)
36+
}
37+
38+
const colorModeClass = ref(host.ui.colorMode)
39+
40+
host.on.colorModeChange((colorMode) => {
41+
colorModeClass.value = colorMode
42+
})
43+
44+
host.on.mounted(() => {
45+
detectActiveDocuments()
46+
host.on.routeChange(() => {
47+
setTimeout(() => {
48+
detectActiveDocuments()
49+
}, 100)
50+
})
51+
})
52+
53+
const direction = ref<'left' | 'right'>('left')
54+
const directionOrder = ['content', 'media']
55+
56+
router.beforeEach((to, from) => {
57+
direction.value = directionOrder.indexOf(from.name as string) > directionOrder.indexOf(to.name as string) ? 'left' : 'right'
58+
})
59+
</script>
60+
61+
<template>
62+
<div :class="colorModeClass">
63+
<UApp :toaster="{ portal: false }">
64+
<AppLayout :open="ui.isOpen.value">
65+
<RouterView v-slot="{ Component }">
66+
<Transition
67+
enter-active-class="transition-translate duration-200 absolute"
68+
:enter-from-class="direction === 'right' ? 'translate-x-full' : '-translate-x-full'"
69+
enter-to-class="translate-x-0"
70+
leave-active-class="transition-translate duration-200 absolute"
71+
leave-from-class="translate-x-0"
72+
:leave-to-class="direction === 'right' ? '-translate-x-full' : 'translate-x-full'"
73+
>
74+
<KeepAlive>
75+
<component
76+
:is="Component"
77+
class="w-full h-full"
78+
/>
79+
</KeepAlive>
80+
</Transition>
81+
</RouterView>
82+
</AppLayout>
83+
84+
<!-- Floating Files Panel Toggle -->
85+
<div
86+
class="fixed bottom-2 left-2 flex transition-all"
87+
:class="[isReady && !ui.isOpen.value ? 'opacity-100 duration-200 delay-300 translate-y-0' : 'duration-0 opacity-0 -translate-x-12 pointer-events-none']"
88+
>
89+
<UFieldGroup>
90+
<UTooltip
91+
text="Toggle Studio"
92+
:kbds="['meta', '.']"
93+
>
94+
<UButton
95+
icon="i-lucide-panel-left-open"
96+
size="sm"
97+
color="neutral"
98+
variant="outline"
99+
class="bg-transparent backdrop-blur-md"
100+
@click="ui.open()"
101+
/>
102+
</UTooltip>
103+
<UButton
104+
v-if="activeDocuments.length === 1"
105+
size="sm"
106+
color="neutral"
107+
variant="outline"
108+
class="bg-transparent backdrop-blur-md px-2"
109+
label="Edit this page"
110+
@click="editContentFile(activeDocuments[0].id)"
111+
/>
112+
</UFieldGroup>
113+
</div>
114+
</UApp>
115+
</div>
116+
</template>

src/app/src/assets/css/main.css

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@source inline('ring-red-200 hover:ring-red-300 hover:dark:ring-red-700');
1212
@source inline('ring-green-200 hover:ring-green-300 hover:dark:ring-green-700');
1313

14-
:root {
14+
:root, .light {
1515
--ui-primary: black;
1616
}
1717

@@ -20,11 +20,6 @@
2020
}
2121

2222
@theme static {
23-
--ui-sub-header-height: 45px;
24-
--ui-footer-height: 40px;
25-
26-
--font-sans: 'Public Sans', sans-serif;
27-
2823
--color-green-50: '#EFFDF5';
2924
--color-green-100: '#D9FBE8';
3025
--color-green-200: '#B3F5D1';
Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import { computed } from 'vue'
3-
import { useStudio } from '../../../composables/useStudio'
3+
import { useStudio } from '../composables/useStudio'
44
55
const { ui, host } = useStudio()
66
@@ -12,36 +12,35 @@ const userMenuItems = computed(() => [
1212
label: 'Sign out',
1313
icon: 'i-lucide-log-out',
1414
onClick: () => {
15-
alert('TODO: delete cookie manually')
15+
fetch('/__nuxt_content/studio/auth/session', { method: 'delete' }).then(() => {
16+
document.location.reload()
17+
})
1618
},
1719
},
1820
])
1921
</script>
2022

2123
<template>
22-
<UFooter
23-
class="h-var(--ui-footer-height) sticky bottom-0 bg-white"
24-
:ui="{ container: 'px-2 sm:px-2 lg:px-2', right: 'gap-0' }"
24+
<div
25+
class="bg-muted/50 border-default border-t-[0.5px] flex items-center justify-between gap-1.5 px-2 py-2"
2526
>
26-
<template #left>
27-
<UDropdownMenu
28-
:portal="false"
29-
:items="userMenuItems"
30-
:ui="{ content: 'w-full' }"
31-
size="xs"
32-
>
33-
<UButton
34-
color="neutral"
35-
variant="ghost"
36-
size="sm"
37-
:avatar="{ src: user?.avatar, alt: user?.name, size: '2xs' }"
38-
class="px-2 font-medium"
39-
:label="user?.name"
40-
/>
41-
</UDropdownMenu>
42-
</template>
27+
<UDropdownMenu
28+
:portal="false"
29+
:items="userMenuItems"
30+
:ui="{ content: 'w-full' }"
31+
size="xs"
32+
>
33+
<UButton
34+
color="neutral"
35+
variant="ghost"
36+
size="sm"
37+
:avatar="{ src: user?.avatar, alt: user?.name, size: '2xs' }"
38+
class="px-2 py-1 font-medium"
39+
:label="user?.name"
40+
/>
41+
</UDropdownMenu>
4342

44-
<template #right>
43+
<div class="flex items-center">
4544
<UTooltip
4645
:text="uiConfig.syncEditorAndRoute ? 'Unlink editor and preview' : 'Link editor and preview'"
4746
:delay-duration="0"
@@ -51,17 +50,15 @@ const userMenuItems = computed(() => [
5150
variant="ghost"
5251
:color="uiConfig.syncEditorAndRoute ? 'info' : 'neutral'"
5352
:class="!uiConfig.syncEditorAndRoute && 'opacity-50'"
54-
size="sm"
5553
@click="uiConfig.syncEditorAndRoute = !uiConfig.syncEditorAndRoute"
5654
/>
5755
</UTooltip>
5856
<UButton
5957
icon="i-lucide-panel-left-close"
6058
variant="ghost"
6159
color="neutral"
62-
size="sm"
63-
@click="ui.closePanels()"
60+
@click="ui.close()"
6461
/>
65-
</template>
66-
</UFooter>
62+
</div>
63+
</div>
6764
</template>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<script setup lang="ts">
2+
import type { TabsItem } from '@nuxt/ui'
3+
import { useRouter, useRoute } from 'vue-router'
4+
import { computed } from 'vue'
5+
6+
const router = useRouter()
7+
const route = useRoute()
8+
9+
const items: TabsItem[] = [
10+
{
11+
label: 'Content',
12+
value: 'content',
13+
},
14+
{
15+
label: 'Media',
16+
value: 'media',
17+
},
18+
]
19+
20+
const current = computed({
21+
get: () => route.name as string,
22+
set: (name: string) => router.push({ name }),
23+
})
24+
</script>
25+
26+
<template>
27+
<div
28+
class="bg-muted/50 border-default border-b-[0.5px] pr-4 gap-1.5 flex items-center justify-between"
29+
>
30+
<div class="flex-1">
31+
<UTabs
32+
v-model="current"
33+
:content="false"
34+
:items="items"
35+
class="w-full"
36+
variant="link"
37+
size="md"
38+
color="neutral"
39+
:ui="{ trigger: 'py-1 px-2', list: 'p-2' }"
40+
/>
41+
</div>
42+
43+
<div class="flex items-center gap-1">
44+
<UButton
45+
label="Publish"
46+
color="neutral"
47+
variant="solid"
48+
/>
49+
</div>
50+
</div>
51+
</template>

0 commit comments

Comments
 (0)