feat: complete UI/UX improvements, vuesax icons, media server, and section management
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { AnimatePresence, motion } from "motion-v";
|
||||
import { ArrowUp } from "lucide-vue-next";
|
||||
import VuesaxIcon from "~/components/ui/VuesaxIcon.vue";
|
||||
|
||||
const show = useScrolledPast(700);
|
||||
</script>
|
||||
@@ -16,7 +16,7 @@ const show = useScrolledPast(700);
|
||||
:exit="{ opacity: 0, y: 24 }"
|
||||
class="fixed bottom-6 left-6 z-[70] flex size-12 items-center justify-center rounded-full border border-line bg-panel/90 text-ink shadow-[0_10px_40px_rgba(0,0,0,0.5)] backdrop-blur transition-colors hover:border-accent hover:text-accent"
|
||||
>
|
||||
<ArrowUp class="size-5" />
|
||||
<VuesaxIcon name="arrow-up" class="size-5" />
|
||||
</motion.a>
|
||||
</AnimatePresence>
|
||||
</template>
|
||||
|
||||
@@ -1,45 +1,42 @@
|
||||
<script setup lang="ts">
|
||||
import type { SocialType } from "@imen/shared";
|
||||
import {
|
||||
AtSign,
|
||||
Globe,
|
||||
Instagram,
|
||||
Linkedin,
|
||||
MessageCircle,
|
||||
Phone,
|
||||
Send,
|
||||
Youtube,
|
||||
} from "lucide-vue-next";
|
||||
import type { Component } from "vue";
|
||||
import VuesaxIcon from "~/components/ui/VuesaxIcon.vue";
|
||||
import Logo from "~/components/ui/Logo.vue";
|
||||
|
||||
const QUICK_LINKS = [
|
||||
{ href: "/#home", label: "خانه" },
|
||||
{ href: "/#products", label: "محصولات" },
|
||||
{ href: "/#about", label: "درباره ما" },
|
||||
{ href: "/#services", label: "خدمات" },
|
||||
{ href: "/#standards", label: "استانداردها" },
|
||||
{ href: "/#industries", label: "صنایع" },
|
||||
];
|
||||
const ALL_QUICK_LINKS = [
|
||||
{ href: "/#home", label: "خانه", section: "hero" },
|
||||
{ href: "/#products", label: "محصولات", section: "productsIntro" },
|
||||
{ href: "/#about", label: "درباره ما", section: "about" },
|
||||
{ href: "/#services", label: "خدمات", section: "services" },
|
||||
{ href: "/#standards", label: "استانداردها", section: "standards" },
|
||||
{ href: "/#industries", label: "صنایع", section: "industries" },
|
||||
] as const;
|
||||
|
||||
const SOCIAL_META: Record<SocialType, { icon: Component; label: string }> = {
|
||||
website: { icon: Globe, label: "وبسایت" },
|
||||
telegram: { icon: Send, label: "تلگرام" },
|
||||
instagram: { icon: Instagram, label: "اینستاگرام" },
|
||||
linkedin: { icon: Linkedin, label: "لینکدین" },
|
||||
whatsapp: { icon: MessageCircle, label: "واتساپ" },
|
||||
bale: { icon: MessageCircle, label: "بله" },
|
||||
eitaa: { icon: MessageCircle, label: "ایتا" },
|
||||
aparat: { icon: Youtube, label: "آپارات" },
|
||||
youtube: { icon: Youtube, label: "یوتیوب" },
|
||||
email: { icon: AtSign, label: "ایمیل" },
|
||||
phone: { icon: Phone, label: "تماس" },
|
||||
const SOCIAL_META: Record<SocialType, { icon: string; label: string }> = {
|
||||
website: { icon: "global", label: "وبسایت" },
|
||||
telegram: { icon: "send-2", label: "تلگرام" },
|
||||
instagram: { icon: "instagram", label: "اینستاگرام" },
|
||||
linkedin: { icon: "link", label: "لینکدین" },
|
||||
whatsapp: { icon: "messages-2", label: "واتساپ" },
|
||||
bale: { icon: "messages-2", label: "بله" },
|
||||
eitaa: { icon: "messages-2", label: "ایتا" },
|
||||
aparat: { icon: "video-play", label: "آپارات" },
|
||||
youtube: { icon: "video-play", label: "یوتیوب" },
|
||||
email: { icon: "sms", label: "ایمیل" },
|
||||
phone: { icon: "call", label: "تماس" },
|
||||
};
|
||||
|
||||
const site = useSiteStore();
|
||||
const footer = computed(() => site.sections.footer);
|
||||
const settings = computed(() => site.settings);
|
||||
|
||||
const QUICK_LINKS = computed(() =>
|
||||
ALL_QUICK_LINKS.filter(
|
||||
(l) =>
|
||||
(site.sections as Record<string, { enabled?: boolean }>)?.[l.section]?.enabled !== false,
|
||||
),
|
||||
);
|
||||
|
||||
const PRODUCT_LINKS = computed(() =>
|
||||
site.categories.map((c) => ({ label: c.name, href: `/categories/${c.slug}` })),
|
||||
);
|
||||
@@ -75,7 +72,7 @@ const SOCIALS = computed(() =>
|
||||
:rel="s.external ? 'noopener' : undefined"
|
||||
class="flex size-10 items-center justify-center rounded-lg border border-line text-muted transition-all duration-300 hover:border-accent hover:bg-accent hover:text-bg"
|
||||
>
|
||||
<component :is="s.icon" class="size-4" />
|
||||
<VuesaxIcon :name="s.icon" class="size-4" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,20 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
import { AnimatePresence, motion } from "motion-v";
|
||||
import { Menu, Phone, X } from "lucide-vue-next";
|
||||
import VuesaxIcon from "~/components/ui/VuesaxIcon.vue";
|
||||
import Logo from "~/components/ui/Logo.vue";
|
||||
|
||||
const LINKS = [
|
||||
{ href: "/#home", label: "خانه" },
|
||||
{ href: "/#products", label: "محصولات" },
|
||||
{ href: "/#about", label: "درباره ما" },
|
||||
{ href: "/#services", label: "خدمات" },
|
||||
{ href: "/#standards", label: "استانداردها" },
|
||||
{ href: "/#industries", label: "صنایع" },
|
||||
{ href: "/#contact", label: "تماس" },
|
||||
];
|
||||
const ALL_LINKS = [
|
||||
{ href: "/#home", label: "خانه", section: "hero" },
|
||||
{ href: "/#products", label: "محصولات", section: "productsIntro" },
|
||||
{ href: "/#about", label: "درباره ما", section: "about" },
|
||||
{ href: "/#services", label: "خدمات", section: "services" },
|
||||
{ href: "/#standards", label: "استانداردها", section: "standards" },
|
||||
{ href: "/#industries", label: "صنایع", section: "industries" },
|
||||
{ href: "/#contact", label: "تماس", section: "contact" },
|
||||
] as const;
|
||||
|
||||
const ui = useUiStore();
|
||||
const settings = computed(() => useSiteStore().settings);
|
||||
const site = useSiteStore();
|
||||
const settings = computed(() => site.settings);
|
||||
const sections = computed(() => site.sections);
|
||||
|
||||
const LINKS = computed(() =>
|
||||
ALL_LINKS.filter(
|
||||
(l) =>
|
||||
(sections.value as Record<string, { enabled?: boolean }>)?.[l.section]?.enabled !== false,
|
||||
),
|
||||
);
|
||||
|
||||
const scrolled = useScrolledPast(40);
|
||||
const { time, shift } = useTehranClock();
|
||||
|
||||
@@ -69,7 +79,7 @@ onBeforeUnmount(() => {
|
||||
href="/#contact"
|
||||
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"
|
||||
>
|
||||
<Phone class="size-4" />
|
||||
<VuesaxIcon name="call" class="size-4" />
|
||||
درخواست مشاوره
|
||||
</a>
|
||||
|
||||
@@ -78,7 +88,7 @@ onBeforeUnmount(() => {
|
||||
class="flex size-11 items-center justify-center rounded-lg border border-line text-ink transition-colors hover:border-accent hover:text-accent lg:hidden"
|
||||
@click="ui.openMenu"
|
||||
>
|
||||
<Menu class="size-5" />
|
||||
<VuesaxIcon name="menu" class="size-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -100,7 +110,7 @@ onBeforeUnmount(() => {
|
||||
class="flex size-11 items-center justify-center rounded-lg border border-line transition-colors hover:border-accent hover:text-accent"
|
||||
@click="ui.closeMenu"
|
||||
>
|
||||
<X class="size-5" />
|
||||
<VuesaxIcon name="close-circle" class="size-5" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -126,7 +136,7 @@ onBeforeUnmount(() => {
|
||||
|
||||
<div class="flex items-center justify-between border-t border-line p-8 text-sm">
|
||||
<div class="flex items-center gap-3 text-muted">
|
||||
<Phone class="size-4 text-accent" />
|
||||
<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>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { motion } from "motion-v";
|
||||
import { ShieldCheck } from "lucide-vue-next";
|
||||
import VuesaxIcon from "~/components/ui/VuesaxIcon.vue";
|
||||
|
||||
const STEPS = [
|
||||
"بررسی سیستمهای ایمنی",
|
||||
@@ -51,7 +51,7 @@ const step = computed(
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="flex size-12 items-center justify-center rounded-xl bg-accent text-bg">
|
||||
<ShieldCheck class="size-7" />
|
||||
<VuesaxIcon name="shield-tick" class="size-7" />
|
||||
</span>
|
||||
<span class="font-mono text-xs tracking-[0.35em] text-muted">
|
||||
IMEN PISHGAMAN CO.
|
||||
|
||||
Reference in New Issue
Block a user