Add image upload fields, media edit/delete, blog seeds
This commit is contained in:
@@ -57,6 +57,33 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card space-y-4">
|
||||
<h3 class="font-semibold text-slate-800">تصاویر Hero</h3>
|
||||
<ImageField v-model="hero.darkImageUrl" label="پسزمینه تم تیره" />
|
||||
<ImageField v-model="hero.lightImageUrl" label="پسزمینه تم روشن" />
|
||||
</section>
|
||||
|
||||
<section class="card space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="font-semibold text-slate-800">پیامرسانها</h3>
|
||||
<button type="button" class="btn-secondary text-xs" @click="addMessenger">افزودن</button>
|
||||
</div>
|
||||
<div v-for="(messenger, i) in messengers" :key="messenger.id || i" class="space-y-4 rounded-xl border border-slate-100 p-4">
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<div>
|
||||
<label class="label">نام</label>
|
||||
<input v-model="messenger.name" class="input" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="label">لینک</label>
|
||||
<input v-model="messenger.url" class="input" dir="ltr" />
|
||||
</div>
|
||||
</div>
|
||||
<ImageField v-model="messenger.iconUrl" :label="`آیکون ${messenger.name || 'پیامرسان'}`" preview-class="h-12 w-12 object-contain p-1" />
|
||||
<button type="button" class="text-sm text-red-500" @click="messengers.splice(i, 1)">حذف پیامرسان</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card space-y-4">
|
||||
<h3 class="font-semibold text-slate-800">سئو پیشفرض</h3>
|
||||
<div class="grid gap-4">
|
||||
@@ -92,6 +119,7 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { api, type NavItem, type SiteSettings } from '@/api/client'
|
||||
import ImageField from '@/components/ImageField.vue'
|
||||
|
||||
const loading = ref(true)
|
||||
const saving = ref(false)
|
||||
@@ -102,6 +130,8 @@ const error = ref('')
|
||||
const site = reactive<SiteSettings>({})
|
||||
const seo = reactive({ defaultTitle: '', defaultDescription: '' })
|
||||
const navigation = ref<NavItem[]>([])
|
||||
const hero = reactive({ darkImageUrl: '', lightImageUrl: '' })
|
||||
const messengers = ref<Array<{ id: string; name: string; url: string; iconUrl?: string }>>([])
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
@@ -110,6 +140,11 @@ onMounted(async () => {
|
||||
seo.defaultTitle = siteData.seo?.defaultTitle || ''
|
||||
seo.defaultDescription = siteData.seo?.defaultDescription || ''
|
||||
navigation.value = [...nav]
|
||||
hero.darkImageUrl = siteData.hero?.darkImageUrl || ''
|
||||
hero.lightImageUrl = siteData.hero?.lightImageUrl || ''
|
||||
messengers.value = siteData.messengers?.length
|
||||
? siteData.messengers.map((m) => ({ ...m }))
|
||||
: []
|
||||
} catch (e) {
|
||||
error.value = e instanceof Error ? e.message : 'خطا در بارگذاری'
|
||||
} finally {
|
||||
@@ -121,12 +156,23 @@ function addNavItem() {
|
||||
navigation.value.push({ label: '', to: '' })
|
||||
}
|
||||
|
||||
function addMessenger() {
|
||||
messengers.value.push({
|
||||
id: `messenger-${Date.now()}`,
|
||||
name: '',
|
||||
url: '',
|
||||
iconUrl: '',
|
||||
})
|
||||
}
|
||||
|
||||
async function save() {
|
||||
saving.value = true
|
||||
message.value = ''
|
||||
error.value = ''
|
||||
try {
|
||||
site.seo = { defaultTitle: seo.defaultTitle, defaultDescription: seo.defaultDescription }
|
||||
site.hero = { darkImageUrl: hero.darkImageUrl, lightImageUrl: hero.lightImageUrl }
|
||||
site.messengers = messengers.value
|
||||
await api.putSite({ ...site })
|
||||
message.value = 'تنظیمات سایت ذخیره شد.'
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user