aboutsummaryrefslogtreecommitdiff
path: root/front-end/src/views/Blog
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2024-01-30 15:23:06 -0500
committerLibravatar vnugent <public@vaughnnugent.com>2024-01-30 15:23:06 -0500
commit5abc489b9954111d66d1385aa62a3ea962fa0a55 (patch)
treeb1715e5c5e6316f33e3e33fb55397d93200ab518 /front-end/src/views/Blog
parente4dc63ded324c6e9678603296953bb1f7dea7569 (diff)
merge upstream. Add dynamic client-side support for optional oauth2 and social login methods
Diffstat (limited to 'front-end/src/views/Blog')
-rw-r--r--front-end/src/views/Blog/components/Posts.vue51
-rw-r--r--front-end/src/views/Blog/components/image-preview-dialog.vue54
-rw-r--r--front-end/src/views/Blog/index.vue66
3 files changed, 81 insertions, 90 deletions
diff --git a/front-end/src/views/Blog/components/Posts.vue b/front-end/src/views/Blog/components/Posts.vue
index 647e093..b89d263 100644
--- a/front-end/src/views/Blog/components/Posts.vue
+++ b/front-end/src/views/Blog/components/Posts.vue
@@ -1,24 +1,3 @@
-<template>
- <div id="post-editor" class="">
- <EditorTable title="Manage posts" :show-edit="showEdit" :pagination="pagination" @open-new="openNew">
- <template #table>
- <PostTable
- :items="items"
- @open-edit="openEdit"
- @delete="onDelete"
- />
- </template>
- <template #editor>
- <PostEditor
- @submit="onSubmit"
- @close="closeEdit(true)"
- @delete="onDelete"
- />
- </template>
- </EditorTable>
- </div>
-</template>
-
<script setup lang="ts">
import { computed, defineAsyncComponent } from 'vue';
import { isEmpty } from 'lodash-es';
@@ -49,7 +28,7 @@ const closeEdit = (update?: boolean) => {
//reload channels
if (update) {
//must refresh content and posts when a post is updated
- refresh();
+ refresh();
}
//Reset page to top
window.scrollTo(0, 0);
@@ -62,14 +41,14 @@ const openNew = () => {
window.scrollTo(0, 0)
}
-const onSubmit = async ({post, content } : { post: PostMeta, content: string }) => {
+const onSubmit = async ({ post, content }: { post: PostMeta, content: string }) => {
debugLog('submitting', post, content);
//Check for new channel, or updating old channel
if (store.posts.selectedId === 'new') {
//Exec create call
- await apiCall(async ({toaster}) => {
+ await apiCall(async ({ toaster }) => {
//endpoint returns the content
const newMeta = await store.posts.add(post);
@@ -86,9 +65,9 @@ const onSubmit = async ({post, content } : { post: PostMeta, content: string })
}
else if (!isEmpty(store.posts.selectedId)) {
//Exec update call
- await apiCall(async ( {toaster} ) => {
+ await apiCall(async ({ toaster }) => {
await store.posts.update(post);
-
+
//Publish the content
await store.content.updatePostContent(post, content)
@@ -129,6 +108,26 @@ const onDelete = async (post: PostMeta) => {
}
</script>
+<template>
+ <div id="post-editor" class="">
+ <EditorTable title="Manage posts" :show-edit="showEdit" :pagination="pagination" @open-new="openNew">
+ <template #table>
+ <PostTable
+ :items="items"
+ @open-edit="openEdit"
+ @delete="onDelete"
+ />
+ </template>
+ <template #editor>
+ <PostEditor
+ @submit="onSubmit"
+ @close="closeEdit(true)"
+ @delete="onDelete"
+ />
+ </template>
+ </EditorTable>
+ </div>
+</template>
<style lang="scss">
diff --git a/front-end/src/views/Blog/components/image-preview-dialog.vue b/front-end/src/views/Blog/components/image-preview-dialog.vue
index 5cfe552..b134d19 100644
--- a/front-end/src/views/Blog/components/image-preview-dialog.vue
+++ b/front-end/src/views/Blog/components/image-preview-dialog.vue
@@ -1,34 +1,14 @@
-<template>
- <div class="">
- <Dialog :open="isOpen" @close="onClose" class="relative z-50">
- <!-- The backdrop, rendered as a fixed sibling to the panel container -->
- <div class="fixed inset-0 bg-black/30" aria-hidden="true" />
-
- <!-- Full-screen container to center the panel -->
- <div class="fixed inset-0 flex items-center justify-center w-screen p-4">
- <!-- The actual dialog panel -->
- <DialogPanel class="p-2 bg-white rounded dark:bg-dark-700" ref="dialog">
- <DialogDescription>
- <img class="preview-image" :src="imgUrl" alt="preview" />
- </DialogDescription>
- <!-- ... -->
- </DialogPanel>
- </div>
- </Dialog>
- </div>
-</template>
-
<script setup lang="ts">
import { ref, computed, watch, toRefs } from 'vue'
import { Dialog, DialogDescription } from '@headlessui/vue'
-import { onClickOutside } from '@vueuse/core';
+import { onClickOutside, set } from '@vueuse/core';
import { useStore } from '../../../store';
import { ContentMeta } from '../../../../../lib/admin/dist';
import { isNil } from 'lodash-es';
import { apiCall } from '@vnuge/vnlib.browser';
const emit = defineEmits(['close'])
-const props = defineProps<{
+const props = defineProps<{
item: ContentMeta | undefined,
}>()
@@ -52,19 +32,33 @@ const downloadImage = (item: ContentMeta) => {
})
}
-//load the image when open
-watch(item, (item) => {
- if (isNil(item)) {
- imgUrl.value = undefined
- } else {
- downloadImage(item)
- }
-})
+//load the image when open or remove it if the item is undefined
+watch(item, (item) => isNil(item) ? set(imgUrl, undefined) : downloadImage(item))
//Close dialog when clicking outside
onClickOutside(dialog, onClose)
</script>
+
+<template>
+ <div class="">
+ <Dialog :open="isOpen" @close="onClose" class="relative z-50">
+ <!-- The backdrop, rendered as a fixed sibling to the panel container -->
+ <div class="fixed inset-0 bg-black/30" aria-hidden="true" />
+
+ <!-- Full-screen container to center the panel -->
+ <div class="fixed inset-0 flex items-center justify-center w-screen p-4">
+ <!-- The actual dialog panel -->
+ <DialogPanel class="p-2 bg-white rounded dark:bg-dark-700" ref="dialog">
+ <DialogDescription>
+ <img class="preview-image" :src="imgUrl" alt="preview" />
+ </DialogDescription>
+ <!-- ... -->
+ </DialogPanel>
+ </div>
+ </Dialog>
+ </div>
+</template>
<style lang="scss">
.preview-image {
diff --git a/front-end/src/views/Blog/index.vue b/front-end/src/views/Blog/index.vue
index de435ec..af6ab88 100644
--- a/front-end/src/views/Blog/index.vue
+++ b/front-end/src/views/Blog/index.vue
@@ -1,3 +1,35 @@
+<script setup lang="ts">
+import { computed } from 'vue';
+import { useRouteQuery } from '@vueuse/router';
+import { TabGroup, TabList, Tab, TabPanels, TabPanel, Switch } from '@headlessui/vue'
+import { defer, first } from 'lodash-es';
+import { useStore, SortType } from '../../store';
+import Channels from './components/Channels.vue';
+import Posts from './components/Posts.vue';
+import Content from './components/Content.vue';
+
+//Protect page
+const store = useStore()
+store.setPageTitle('Blog Admin')
+
+const firstLetter = computed(() => first(store.userName))
+const tabIdQ = useRouteQuery<string>('tabid', '', { mode: 'push' })
+
+//Map queries to their respective computed values
+const tabId = computed(() => tabIdQ.value ? parseInt(tabIdQ.value) : 0);
+const lastModified = computed({
+ get: () => store.queryState.sort === SortType.ModifiedTime,
+ set: (value: boolean) => {
+ store.queryState.sort = value ? SortType.ModifiedTime : SortType.CreatedTime
+ }
+})
+
+const onTabChange = (id: number) => tabIdQ.value = id.toString(10)
+
+//Load channels on page load
+defer(() => store.channels.refresh());
+
+</script>
<template>
<div class="container mx-auto mt-10 mb-[10rem]">
<div id="blog-admin-template" class="">
@@ -107,40 +139,6 @@
</div>
</template>
-<script setup lang="ts">
-import { computed } from 'vue';
-import { useRouteQuery } from '@vueuse/router';
-import { TabGroup, TabList, Tab, TabPanels, TabPanel, Switch } from '@headlessui/vue'
-import { defer, first } from 'lodash-es';
-import { useStore, SortType } from '../../store';
-import Channels from './components/Channels.vue';
-import Posts from './components/Posts.vue';
-import Content from './components/Content.vue';
-
-
-//Protect page
-const store = useStore()
-store.setPageTitle('Blog Admin')
-
-const firstLetter = computed(() => first(store.userName))
-const tabIdQ = useRouteQuery<string>('tabid', '', { mode: 'push' })
-
-//Map queries to their respective computed values
-const tabId = computed(() => tabIdQ.value ? parseInt(tabIdQ.value) : 0);
-const lastModified = computed({
- get :() => store.queryState.sort === SortType.ModifiedTime,
- set: (value:boolean) => {
- store.queryState.sort = value ? SortType.ModifiedTime : SortType.CreatedTime
- }
-})
-
-const onTabChange = (id:number) => tabIdQ.value = id.toString(10)
-
-//Load channels on page load
-defer(() => store.channels.refresh());
-
-</script>
-
<style lang="scss">
#blog-admin-template{