mirror of
https://github.com/Floriansylvain/RenewCMS.git
synced 2026-08-19 19:53:21 +02:00
Article creation overhaul
This commit is contained in:
@@ -65,7 +65,8 @@ a,
|
||||
input,
|
||||
label,
|
||||
button,
|
||||
span {
|
||||
span,
|
||||
li {
|
||||
font-family: 'Hind', sans-serif;
|
||||
color: var(--neutral-dark);
|
||||
}
|
||||
@@ -99,6 +100,26 @@ span {
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
.label-input .tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.label-input .tags li {
|
||||
background-color: var(--neutral-verylight);
|
||||
border-radius: var(--radius);
|
||||
|
||||
padding: 4px 16px;
|
||||
}
|
||||
|
||||
.label-input .tags li::marker {
|
||||
content: '';
|
||||
}
|
||||
|
||||
.label-input-error input {
|
||||
border: solid 1.75px var(--error);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { useAuthStore } from "@/stores/AuthStore"
|
||||
|
||||
export interface Article {
|
||||
idName: string,
|
||||
titleID: string,
|
||||
title: string,
|
||||
date: number,
|
||||
content: {
|
||||
html: string
|
||||
},
|
||||
pageId: string,
|
||||
tags: Array<string>,
|
||||
online: boolean
|
||||
}
|
||||
|
||||
@@ -24,7 +25,7 @@ export async function getArticle(id: string) : Promise<Article> {
|
||||
}
|
||||
|
||||
export async function postArticle(article: Article) : Promise<object> {
|
||||
return await fetch(`${baseURL}/articles/${article.idName}`, {
|
||||
return await fetch(`${baseURL}/articles/${article.titleID}`, {
|
||||
method: 'POST',
|
||||
headers: { "Authorization": `Bearer ${useAuthStore().token}` },
|
||||
body: JSON.stringify(article)
|
||||
|
||||
@@ -4,7 +4,7 @@ import Editor from '@tinymce/tinymce-vue';
|
||||
import { onMounted, ref, type Ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
let article: Ref<Article | void> = ref()
|
||||
const article: Ref<Article | void> = ref()
|
||||
const editorData: Ref<string> = ref('')
|
||||
|
||||
onMounted(async () => {
|
||||
|
||||
@@ -7,33 +7,42 @@ const router = useRouter()
|
||||
|
||||
const defaultData = `<h1>Bienvenue</h1><p>Vous êtes en mode <em>édition</em> d'article.</p><p>Celui-ci semble encore neuf ! Supprimez ces lignes et laissez libre cours à votre imagination :)</p><p>Pour plus d'infos, rendez-vous sur la <a title="Attention, rickroll incoming" href="https:/www.youtube.com/watch?v=dQw4w9WgXcQ" target="_blank" rel="noopener">page d'aide</a>.</p>`
|
||||
const title = ref('')
|
||||
const page = ref('')
|
||||
const rawTags = ref('')
|
||||
const tags: Ref<string[]> = ref([])
|
||||
|
||||
function isIdValid(): boolean {
|
||||
const regex = /^[a-zA-Z0-9]+$/
|
||||
return regex.test(title.value)
|
||||
const regexAccents = /[\u0300-\u036f]/g
|
||||
const regexSymbols = /([-!$%^&*()_+|~=`{}\[\]:";'<>?,.\/])+/g
|
||||
|
||||
function updateTags(): void {
|
||||
tags.value = rawTags.value.split(/[,\s]+/g)
|
||||
tags.value = tags.value.filter(x => x !== '')
|
||||
}
|
||||
|
||||
function generateTitleID(title: string): string {
|
||||
return title.toLowerCase().normalize('NFD')
|
||||
.replace(regexAccents, '')
|
||||
.replace(regexSymbols, '')
|
||||
.replace(/\s/g, '-')
|
||||
.replace(/-$/g, '')
|
||||
}
|
||||
|
||||
function isFormEmpty(): boolean {
|
||||
return title.value === '' || page.value === ''
|
||||
}
|
||||
|
||||
function isFormValid(): boolean {
|
||||
return isIdValid() && !isFormEmpty()
|
||||
return title.value === '' || rawTags.value === ''
|
||||
}
|
||||
|
||||
function createArticle() {
|
||||
const article: Article = {
|
||||
idName: title.value,
|
||||
titleID: generateTitleID(title.value),
|
||||
title: title.value,
|
||||
date: new Date().getTime(),
|
||||
content: {
|
||||
html: defaultData
|
||||
},
|
||||
online: false,
|
||||
pageId: page.value
|
||||
tags: tags.value
|
||||
}
|
||||
postArticle(article)
|
||||
router.push(`/articles/edit/${article.idName}`)
|
||||
router.push(`/articles/edit/${article.titleID}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -42,21 +51,23 @@ function createArticle() {
|
||||
<h2>Créer un nouvel article</h2>
|
||||
<form @submit.prevent="createArticle()">
|
||||
<div class="inputs-group">
|
||||
<div :class="`label-input${isIdValid() || title === '' ? '' : '-error'}`">
|
||||
<label for="title">Identifiant de l'article</label>
|
||||
<input id="title" name="title" placeholder="Identifiant de l'article" type="text" v-model="title">
|
||||
<p>⚠️ Doit être unique et composé de caractères alphanumériques, sans espaces !
|
||||
</p>
|
||||
<div class="label-input">
|
||||
<label for="title">Titre de l'article</label>
|
||||
<input id="title" name="title" placeholder="Titre de l'article" type="text" v-model="title">
|
||||
</div>
|
||||
<div class="label-input">
|
||||
<label for="page">Page</label>
|
||||
<input id="page" name="page" placeholder="Page" type="text" v-model="page">
|
||||
<label for="tags">Tags</label>
|
||||
<input id="tags" name="tags" placeholder="Tags" type="text" v-model="rawTags" @input="updateTags">
|
||||
<p>Spéparez les mots-clés par des virgules ou espaces.</p>
|
||||
<ul class="tags" v-if="tags.length !== 0">
|
||||
<li v-for="tag in tags">{{ tag }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="buttons-group">
|
||||
<RouterLink class="button-secondary" type="submit" to="/articles">Annuler</RouterLink>
|
||||
<button :class="`button-${!isFormValid() ? 'disabled' : 'primary'}`" type="submit"
|
||||
:disabled="!isFormValid()">Créer</button>
|
||||
<button :class="`button-${isFormEmpty() ? 'disabled' : 'primary'}`" type="submit"
|
||||
:disabled="isFormEmpty()">Créer</button>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
@@ -73,7 +84,7 @@ main {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
margin: 32px 0;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
.buttons-group a,
|
||||
|
||||
Reference in New Issue
Block a user