118 lines
2.6 KiB
Vue
118 lines
2.6 KiB
Vue
<script lang="ts" setup="">
|
|
|
|
import IconLogo from "~/components/icons/iconLogo.vue";
|
|
import {Button} from "~/components/ui/Buttons";
|
|
import {ButtonKind} from "~/components/ui/Buttons/constants.buttons";
|
|
import {EDITOR_KEY} from "~/shared/constants";
|
|
import type {Editor} from "@tiptap/vue-3";
|
|
import type {MaterialSendDto} from "~/stores/materials/types.materials";
|
|
import dayjs from "dayjs";
|
|
import {useMaterialsStore} from "~/stores/materials/useMaterialsStore";
|
|
|
|
const router = useRouter()
|
|
const route = useRoute()
|
|
const editor = inject<Ref<Editor | null>>(EDITOR_KEY)
|
|
|
|
const isLoadingSave = ref(false);
|
|
const materialsStore = useMaterialsStore()
|
|
|
|
const isntMaterialCreatePage = computed(() => route.name !== 'materials-create')
|
|
const getButtonKind = computed(() => {
|
|
if (route.name === 'materials-create') return ButtonKind.Send
|
|
|
|
return ButtonKind.CreateMaterial
|
|
})
|
|
|
|
const onClick = () => {
|
|
if (isntMaterialCreatePage.value) {
|
|
router.push({name: 'materials-create'})
|
|
return;
|
|
}
|
|
prepareEditorData()
|
|
}
|
|
|
|
const prepareEditorData = async() => {
|
|
const json = editor?.value?.getJSON()
|
|
const html = editor?.value?.getHTML()
|
|
if (!json || !html) return;
|
|
const title = json.content?.find(el => el.type === 'heading' && el.attrs?.level === 1)?.content?.[0]?.text
|
|
const shortDescription = json.content?.find(el => el.type === 'paragraph')?.content?.[0]?.text
|
|
const sendData: MaterialSendDto = {
|
|
title,
|
|
short_description: shortDescription,
|
|
datetime: dayjs().format('YYYY-MM-DDTHH:mm:ss.sssZ'),
|
|
description_json: json,
|
|
description_html: html
|
|
|
|
}
|
|
try {
|
|
isLoadingSave.value = true
|
|
const {data,error} = await useFetch('/api/save', {
|
|
method: 'POST',
|
|
body: sendData
|
|
})
|
|
if (data.value) {
|
|
router.push({name: 'materials-id', params: {id: data.value.id}})
|
|
}
|
|
} catch {
|
|
|
|
} finally {
|
|
isLoadingSave.value = false
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<div class="bg-header">
|
|
<div class="header">
|
|
<NuxtLink to="/" class="link">
|
|
<IconLogo class="icon" />
|
|
</NuxtLink>
|
|
<div>
|
|
<Button.ButtonDefault :kind="getButtonKind" @click="onClick" :loading="isLoadingSave" />
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.header {
|
|
max-width: 1224px;
|
|
margin: 0 auto;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: 20px 36px;
|
|
background: #fff;
|
|
align-items: center;
|
|
}
|
|
|
|
.icon {
|
|
height: 44px;
|
|
width: 115px;
|
|
color: var(--text-blue);
|
|
}
|
|
|
|
.bg-header {
|
|
background: #fff;
|
|
width: 100dvw;
|
|
}
|
|
|
|
.link {
|
|
line-height: 80%;
|
|
}
|
|
|
|
@media screen and (max-width: 768px) {
|
|
.header {
|
|
padding: 8px 16px;
|
|
}
|
|
.icon {
|
|
height: 36px;
|
|
width: 93px;
|
|
}
|
|
}
|
|
</style>
|