feat(admin): editable contact fields in sections and larger logos

Allow address, phone, map, and related site chrome to be edited from contact/settings for all editors, and enlarge brand marks on login, header, and preloader.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
S. Esmaeili
2026-11-12 18:42:59 +03:30
co-authored by Cursor
parent cad1a8652e
commit 9ad88af20f
26 changed files with 285 additions and 108 deletions
+12 -3
View File
@@ -79,7 +79,7 @@ const SOCIALS = computed(() =>
<!-- quick links -->
<div class="md:col-span-2">
<div class="font-mono text-xs tracking-[0.25em] text-accent">// دسترسی</div>
<div class="font-mono text-xs tracking-[0.25em] text-accent">// {{ footer.linksTitle }}</div>
<ul class="mt-5 space-y-3">
<li v-for="l in QUICK_LINKS" :key="l.href">
<a :href="l.href" class="text-sm text-muted transition-colors hover:text-ink">
@@ -91,7 +91,7 @@ const SOCIALS = computed(() =>
<!-- products -->
<div class="md:col-span-2">
<div class="font-mono text-xs tracking-[0.25em] text-accent">// محصولات</div>
<div class="font-mono text-xs tracking-[0.25em] text-accent">// {{ footer.productsTitle }}</div>
<ul class="mt-5 space-y-3">
<li v-for="p in PRODUCT_LINKS" :key="p.href">
<NuxtLink :to="p.href" class="text-sm text-muted transition-colors hover:text-ink">
@@ -103,10 +103,19 @@ const SOCIALS = computed(() =>
<!-- contact -->
<div class="md:col-span-3">
<div class="font-mono text-xs tracking-[0.25em] text-accent">// ارتباط</div>
<div class="font-mono text-xs tracking-[0.25em] text-accent">// {{ footer.contactTitle }}</div>
<address class="mt-5 space-y-3 text-sm text-muted not-italic">
<p class="leading-7">
{{ settings.address.locality }}، {{ settings.address.street }}
<a
v-if="settings.mapUrl"
:href="settings.mapUrl"
target="_blank"
rel="noopener"
class="ms-2 text-accent transition-colors hover:text-ink"
>
نقشه
</a>
</p>
<p class="font-mono tracking-wider" dir="ltr">
<a :href="`tel:${settings.phone}`" class="transition-colors hover:text-ink">{{ settings.phoneDisplay }}</a>
+4 -4
View File
@@ -72,15 +72,15 @@ onBeforeUnmount(() => {
<span class="size-1.5 animate-pulse rounded-full bg-emerald-400" />
<span class="font-mono">{{ time }}</span>
<span class="text-muted/50">|</span>
<span>تهران — شیفت {{ shift }}</span>
<span>{{ settings.address.locality }} — شیفت {{ shift }}</span>
</div>
<a
href="/#contact"
:href="settings.headerCta.href"
class="hidden items-center gap-2 rounded-full bg-accent px-5 py-2.5 text-sm font-bold text-bg transition-all duration-300 hover:bg-accent-soft hover:shadow-[0_0_30px_rgba(255,90,0,0.4)] md:flex"
>
<VuesaxIcon name="call" class="size-4" />
درخواست مشاوره
{{ settings.headerCta.label }}
</a>
<button
@@ -139,7 +139,7 @@ onBeforeUnmount(() => {
<VuesaxIcon name="call" class="size-4 text-accent" />
<a :href="`tel:${settings.phone}`" class="font-mono" dir="ltr">{{ settings.phoneDisplay }}</a>
</div>
<div class="text-xs text-muted">تهران — شیفت {{ shift }}، {{ time }}</div>
<div class="text-xs text-muted">{{ settings.address.locality }} — شیفت {{ shift }}، {{ time }}</div>
</div>
</motion.div>
</AnimatePresence>
+4 -4
View File
@@ -50,14 +50,14 @@ const step = computed(
<div class="flex items-center gap-4">
<span
class="flex size-12 items-center justify-center rounded-xl bg-white shadow-[0_0_28px_rgba(255,90,0,0.3)] ring-1 ring-white/10"
class="flex size-20 items-center justify-center overflow-hidden rounded-2xl bg-white shadow-[0_0_28px_rgba(255,90,0,0.3)] ring-1 ring-white/10"
>
<img
src="/images/logo.png"
alt="ایمن پیشگامان"
width="32"
height="32"
class="size-8 object-contain"
width="80"
height="80"
class="size-full scale-110 object-contain object-center"
/>
</span>
<span class="font-mono text-xs tracking-[0.35em] text-muted">
+11 -3
View File
@@ -12,7 +12,13 @@ const content = computed(() => site.sections.contact);
const INFO = computed(() => {
const s = site.settings;
return [
{ icon: "location", label: "نشانی", value: `${s.address.locality}، ${s.address.street}` },
{
icon: "location",
label: "نشانی",
value: `${s.address.locality}، ${s.address.street}`,
href: s.mapUrl || undefined,
external: Boolean(s.mapUrl),
},
{ icon: "call", label: "تلفن تماس", value: s.phoneDisplay, ltr: true, href: `tel:${s.phone}` },
{ icon: "sms", label: "ایمیل", value: s.email, ltr: true, href: `mailto:${s.email}` },
{ icon: "clock", label: "ساعات کاری", value: s.workingHours },
@@ -59,6 +65,8 @@ const contact = useContactStore();
<component
:is="item.href ? 'a' : 'div'"
:href="item.href"
:target="item.external ? '_blank' : undefined"
:rel="item.external ? 'noopener' : undefined"
:class="`mt-1 block text-sm font-medium ${item.ltr ? 'font-mono tracking-wider' : ''}`"
:dir="item.ltr ? 'ltr' : 'rtl'"
>
@@ -106,7 +114,7 @@ const contact = useContactStore();
class="mt-7 rounded-full border border-line px-7 py-3 text-sm transition-colors hover:border-accent hover:text-accent"
@click="contact.reset"
>
ثبت درخواست جدید
{{ content.resetLabel }}
</button>
</div>
@@ -172,7 +180,7 @@ const contact = useContactStore();
</template>
<template v-else>
<VuesaxIcon name="send-2" class="size-5" />
ارسال درخواست مشاوره
{{ content.submitLabel }}
</template>
</AButton>
</div>
+9 -8
View File
@@ -1,23 +1,24 @@
<script setup lang="ts">
const settings = computed(() => useSiteStore().settings);
</script>
<template>
<NuxtLink to="/" class="flex items-center gap-3" aria-label="ایمن پیشگامان">
<NuxtLink to="/" class="flex items-center gap-3" :aria-label="settings.name">
<span
class="flex size-10 items-center justify-center rounded-xl bg-white shadow-[0_0_28px_rgba(10,30,92,0.45)]"
class="flex size-11 items-center justify-center overflow-hidden rounded-xl bg-white p-0.5 shadow-[0_0_28px_rgba(10,30,92,0.45)] sm:size-12"
>
<img
src="/images/logo.png"
alt="ایمن پیشگامان"
width="28"
height="28"
class="size-7 object-contain"
:alt="settings.name"
width="48"
height="48"
class="size-full object-contain object-center"
/>
</span>
<span class="leading-tight">
<span class="block text-lg font-black">ایمن پیشگامان</span>
<span class="block text-lg font-black">{{ settings.name }}</span>
<span class="block font-mono text-[9px] tracking-[0.32em] text-muted">
IMEN PISHGAMAN CO.
{{ settings.nameEn }}
</span>
</span>
</NuxtLink>