This commit is contained in:
Parsa Nazer
2025-03-26 11:03:11 +03:30
28 changed files with 107 additions and 71 deletions
@@ -27,7 +27,7 @@ const { isLoading: cartImageIsLoading } = useImage({
v-if="!cartImageIsLoading"
class="size-[3.5rem] shrink-0 rounded-100 border border-gray-300 overflow-hidden"
>
<img :src="image" alt="product" class="object-conver" />
<NuxtImg :src="image" alt="product" class="object-conver" />
</div>
<Skeleton
v-else
+1 -1
View File
@@ -121,7 +121,7 @@ watch(
v-if="!cartImageIsLoading"
class="size-[4rem] lg:size-[12rem] aspect-square shrink-0 rounded-xl border border-slate-200 overflow-hidden"
>
<img
<NuxtImg
:src="data.product.image"
class="object-cover size-full"
alt="product"
+1 -1
View File
@@ -36,7 +36,7 @@ const remaining = computed(() => items.value.length - max.value);
:class="index < 0 ? '' : ''"
:style="{ width: size, height: size, zIndex: index + 2 }"
>
<img
<NuxtImg
:src="item"
alt="avatar"
class="rounded-full object-cover w-full h-full"
+2 -2
View File
@@ -54,7 +54,7 @@ const createdAt = usePersianTimeAgo(new Date(date.value));
{{ category.name }}
</Tag>
<img
<NuxtImg
:src="image"
class="group-hover:scale-105 transition-transform duration-200 absolute size-full object-cover z-10"
alt=""
@@ -104,7 +104,7 @@ const createdAt = usePersianTimeAgo(new Date(date.value));
</div>
</div>
<img
<NuxtImg
v-if="variant === 'lg'"
:src="image"
class="group-hover:scale-105 transition-transform duration-200 absolute size-full object-cover z-10"
+1 -1
View File
@@ -25,7 +25,7 @@ const { colorObject } = useImageColor(`#category-image-${id.value}`);
<template>
<NuxtLink :to="`/products?category=${id}`">
<div class="group relative rounded-150 overflow-hidden w-full aspect-square bg-white brightness-[97%]">
<img
<NuxtImg
:id="`category-image-${id}`"
class="group-hover:scale-105 transition-transform duration-200 absolute object-contain size-full"
:src="picture"
+1 -1
View File
@@ -1,7 +1,7 @@
<template>
<div class="bg-black relative overflow-hidden">
<img src="/img/footer-bg.jpg" alt="" class="absolute z-10 object-cover opacity-45" />
<NuxtImg src="/img/footer-bg.jpg" alt="" class="absolute z-10 object-cover opacity-45" />
<div class="flex flex-col gap-4 items-center justify-center relative z-20">
@@ -55,7 +55,7 @@ onMounted(() => {
id="loading-overlay"
class="fixed inset-0 size-full z-9999 flex-center bg-black"
>
<img
<NuxtImg
id="loading-overlay-image"
src="/img/heymlz/heymlz-loading-1.gif"
class="opacity-0 scale-70 absolute z-20"
@@ -40,7 +40,7 @@ const highlights = ref<Highlight[]>([
>
<template v-for="(highlight, index) in highlights" :key="index">
<div class="flex flex-col-center gap-[.75rem] px-5">
<img
<NuxtImg
:src="highlight.icon"
class="size-[70px] md:size-[90px]"
alt=""
@@ -54,7 +54,7 @@ const changeSlide = (id: number) => {
class="bg-white brightness-[97%] w-full relative aspect-square overflow-hidden rounded-[12px] md:rounded-200"
>
<Transition name="zoom" mode="out-in">
<img
<NuxtImg
:key="selectedSlideDetail.id"
class="size-full absolute object-contain"
:src="selectedSlideDetail.image"
@@ -84,7 +84,7 @@ const changeSlide = (id: number) => {
"
class="active:scale-95 hover:border-slate-200 transition-all cursor-pointer brightness-[97%] bg-white aspect-square border-2 rounded-[12px] md:rounded-200 w-full overflow-hidden relative"
>
<img
<NuxtImg
class="absolute object-cover size-full"
:src="slide.image"
:alt="String(slide.id)"
@@ -36,7 +36,7 @@ const { colorObject } = useImageColor(`#product-image-${id.value}`);
<div
class="group relative size-full aspect-square rounded-xl @[280px]:rounded-2xl bg-white brightness-[98%] overflow-hidden p-6"
>
<img
<NuxtImg
:id="`product-image-${id}`"
:src="picture"
class="group-hover:scale-105 transition-transform duration-200 size-full object-contain absolute inset-0"
@@ -20,7 +20,7 @@ const { picture, price, title, color } = toRefs(props);
<div class="max-w-[500px] w-full h-[116px] flex items-center justify-between py-2 pe-6 ps-2 bg-white rounded-150">
<div class="flex items-center gap-4">
<div class="relative size-[100px] rounded-100 overflow-hidden border-[0.5px] border-slate-200">
<img :src="picture" :alt="title" class="object-cover absolute" />
<NuxtImg :src="picture" :alt="title" class="object-cover absolute" />
</div>
<div class="flex flex-col gap-1.5">
<span class="typo-sub-h-md text-black">{{ title }}</span>
+19 -7
View File
@@ -25,13 +25,13 @@ const onSwiper = (swiper: SwiperClass) => {
class="flex flex-col justify-center gap-4 bg-black h-[150svh] relative overflow-hidden"
>
<div class="w-full flex justify-center items-center relative z-10">
<span class="text-white typo-h-6 md:typo-h-5 lg:typo-h-4">
دسته بندی ها
</span>
</div>
<!-- <div class="w-full flex justify-center items-center relative z-10">-->
<!-- <span class="text-white typo-h-6 md:typo-h-5 lg:typo-h-4">-->
<!-- دسته بندی ها-->
<!-- </span>-->
<!-- </div>-->
<img
<NuxtImg
src="/img/categories-gradient.png"
class="animate-spin [animation-duration:16s] object-cover absolute size-full brightness-45 scale-115 aspect-square"
:style="{
@@ -41,6 +41,17 @@ const onSwiper = (swiper: SwiperClass) => {
/>
<div class="w-full my-20 relative">
<video
class="aspect-square w-[450px] translate-[-253px] absolute left-1/2 -translate-x-1/2 z-10"
:style="{
filter: 'drop-shadow(0px 0px 20px rgba(0, 0, 0, 0.4))',
}"
src="/video/heymlz/heymlz-seat-2.webm"
autoplay
playsinline
webkit-playsinline
muted
/>
<Swiper
:loop="true"
:centered-slides="true"
@@ -98,7 +109,8 @@ const onSwiper = (swiper: SwiperClass) => {
<div class="w-full flex justify-center items-center">
<NuxtLink to="/category">
<Button variant="solid" class="invert rounded-full max-xs:typo-label-sm !px-4 xs:!px-8" end-icon="ci:arrow-left">
<Button variant="solid" class="invert rounded-full max-xs:typo-label-sm !px-4 xs:!px-8"
end-icon="ci:arrow-left">
مشاهده همه دسته ها
</Button>
</NuxtLink>
+1 -1
View File
@@ -193,7 +193,7 @@ onUnmounted(() => {
/>
</template>
<img
<NuxtImg
v-else
class="absolute inset-0 size-full object-cover"
:src="slide.image!"
@@ -28,7 +28,7 @@ const onSwiper = (swiper: SwiperClass) => {
<template>
<div class="relative max-h-[700px] flex justify-center items-center h-svh w-full">
<img
<NuxtImg
class="absolute size-full object-cover"
src="/img/hero-bg.jpg"
alt=""
+20 -4
View File
@@ -59,7 +59,7 @@ watch(
class="rounded-200 overflow-hidden h-[70svh] md:h-[80svh] relative"
>
<Transition name="fade">
<img
<NuxtImg
v-if="activeSlideVideo !== 'right'"
:src="homeData!.difreance_section.image1"
class="select-none absolute size-full object-cover brightness-[95%]"
@@ -77,8 +77,9 @@ watch(
</Transition>
<div class="absolute size-full right-0 w-full">
<Transition name="fade">
<img
<NuxtImg
v-if="activeSlideVideo !== 'left'"
:src="homeData!.difreance_section.image2"
class="overlay-image select-none absolute object-cover size-full brightness-[95%]"
@@ -94,12 +95,27 @@ watch(
class="overlay-image select-none absolute object-cover size-full brightness-[95%]"
/>
</Transition>
<video
src="/video/heymlz/heymlz-pulling.webm"
autoplay
muted
playsinline
webkit-playsinline
class="size-[300px] absolute translate-x-[-100px] z-10 top-[32%] -translate-y-1/2"
:style="{
left: `${clipPathPercent}%`,
filter: 'drop-shadow(0px 0px 20px rgba(0, 0, 0, 0.3))'
}"
/>
<div
:style="{
left: `${clipPathPercent}%`,
}"
left: `${clipPathPercent}%`,
}"
class="select-none w-2 h-full bg-black absolute left-0 flex items-center justify-center"
>
<div
ref="draggableEl"
class="cursor-grab hover:scale-115 transition-transform rounded-full absolute bg-black size-11 flex items-center justify-center"
@@ -93,7 +93,7 @@ onUnmounted(() => {
class="showcase-slide origin-bottom absolute size-full bg-transparent flex items-center justify-center"
>
<img
<NuxtImg
class="w-[280px] xs:w-[350px] lg:w-[500px] xl:w-[650px] z-20 mb-30 sm:mb-20 lg:mb-30"
:src="slide.image"
:style="{
@@ -35,7 +35,7 @@ const { selectedVariant } = inject("productVariant") as ProductVariantProvideTyp
class="size-[6.25rem] rounded-full border-slate-200 bg-white flex-center"
>
<div class="size-11 relative">
<img
<NuxtImg
class="size-full absolute object-cover"
:src="inPackItem.cover"
:alt="inPackItem.item_title"
@@ -54,7 +54,7 @@ const username = computed(() => {
:class="is_user ? 'rounded-br-none' : 'rounded-bl-none'"
>
<div class="w-2/12 flex items-start justify-start">
<img :src="profile" class="size-16 rounded-full" />
<NuxtImg :src="profile" class="size-16 rounded-full" />
</div>
<div class="w-10/12 flex flex-col items-start pt-2">
+15 -18
View File
@@ -57,24 +57,17 @@ export default defineNuxtConfig({
]
},
modules: [
[
"@nuxtjs/google-fonts",
{
families: {
"DM Sans": "100..900",
Inter: "100..900",
download: true,
inject: false
}
modules: [[
"@nuxtjs/google-fonts",
{
families: {
"DM Sans": "100..900",
Inter: "100..900",
download: true,
inject: false
}
],
"@nuxt/icon",
"reka-ui/nuxt",
"@vueuse/nuxt",
"@formkit/auto-animate/nuxt",
"@vite-pwa/nuxt"
],
}
], "@nuxt/icon", "reka-ui/nuxt", "@vueuse/nuxt", "@formkit/auto-animate/nuxt", "@vite-pwa/nuxt", "@nuxt/image"],
pwa: {
strategies: "injectManifest",
@@ -109,10 +102,14 @@ export default defineNuxtConfig({
typeCheck: false
},
image: {
quality : 65
},
runtimeConfig: {
public: {
API_BASE_URL: process.env.API_BASE_URL,
DEBUG: process.env.DEBUG
}
}
});
});
+2
View File
@@ -17,6 +17,7 @@
"dependencies": {
"@formkit/auto-animate": "^0.8.2",
"@nuxt/icon": "^1.10.3",
"@nuxt/image": "^1.10.0",
"@nuxtjs/google-fonts": "^3.2.0",
"@tanstack/vue-query": "^5.62.2",
"@tanstack/vue-query-devtools": "^5.62.3",
@@ -51,6 +52,7 @@
"@tailwindcss/postcss": "^4.0.9",
"@types/node": "^22.13.11",
"@types/sanitize-html": "^2.13.0",
"@types/web-push": "^3.6.4",
"autoprefixer": "^10.4.20",
"postcss": "^8.5.3",
"tailwindcss": "^4.0.9",
+2 -2
View File
@@ -28,7 +28,7 @@ if (response.isError) {
<template>
<div class="container">
<div class="w-full h-[80svh] rounded-3xl relative overflow-hidden">
<img class="absolute object-cover size-full" :alt="article!.title" :src="article!.cover_image" />
<NuxtImg class="absolute object-cover size-full" :alt="article!.title" :src="article!.cover_image" />
<div class="absolute bg-linear-to-t from-black/75 to-transparent size-full" />
<div class="absolute pl-10 right-10 bottom-10 flex flex-col gap-6">
<h1 class="typo-h-4 text-white pl-8">
@@ -48,7 +48,7 @@ if (response.isError) {
class="w-fit pr-2 pl-5 h-[50px] rounded-full flex items-center justify-center gap-3 bg-white">
<div
class="relative flex items-center justify-center rounded-full overflow-hidden size-[35px]">
<img
<NuxtImg
class="size-full object-cover absolute"
:src="article!.author.profile_photo"
alt="article-author"
+1 -1
View File
@@ -76,7 +76,7 @@ const selectedGateway = ref<PaymentGateway>(paymentGateways.value[0]);
class="w-full p-5 border rounded-xl flex flex-col gap-4 transition-all cursor-pointer"
>
<div class="aspect-square flex-center">
<img :src="gateway.picture" class="object-cover" />
<NuxtImg :src="gateway.picture" class="object-cover" />
</div>
<span class="typo-label-sm text-black">
{{ gateway.title }}
+1 -1
View File
@@ -133,7 +133,7 @@ const contactWays = ref([
</div>
</div>
<div class="w-4/12 h-full bg-red-300">
<img src="/mlz.jpeg" class="-mt-16" />
<NuxtImg src="/mlz.jpeg" class="-mt-16" />
</div>
</div>
</div>
+9 -3
View File
@@ -159,10 +159,16 @@ const resetForm = () => {
}"
/>
<div class="flex items-center justify-center flex-col size-full translate-y-[-80px]">
<img
<video
class="aspect-square w-[450px] translate-y-[197px] animate-fade-in"
src="/img/heymlz/heymlz-seat-2.webp"
alt=""
src="/video/heymlz/heymlz-seat-2.webm"
:style="{
filter: 'drop-shadow(0px 4px 20px rgba(0, 0, 0, 0.15))'
}"
autoplay
playsinline
webkit-playsinline
muted
/>
<div
+19 -16
View File
@@ -3,7 +3,8 @@
// import
import hljs from "highlight.js";
import javascript from "highlight.js/lib/languages/javascript";
import json from "highlight.js/lib/languages/json";
import xml from "highlight.js/lib/languages/xml";
import "highlight.js/styles/atom-one-dark.css";
import LogDate from "~/components/server-logs/LogDate.vue";
import { useQuery } from "@tanstack/vue-query";
@@ -11,7 +12,7 @@ import { useQuery } from "@tanstack/vue-query";
// meta
definePageMeta({
middleware : "check-is-debug",
middleware: "check-is-debug",
layout: "none"
});
@@ -41,7 +42,9 @@ const logIcon = (status: number) => {
// lifecycle
onMounted(() => {
hljs.registerLanguage("json", javascript);
hljs.registerLanguage("json", json);
hljs.registerLanguage("xml", xml);
hljs.highlightAll();
});
@@ -103,40 +106,40 @@ onMounted(() => {
<summary class="cursor-pointer select-none">Details :</summary>
<div class="flex flex-col gap-2 mt-2 ml-4">
<details
v-if="log.response && typeof log.response === 'string' && log.response.includes('<!DOCTYPE html>')"
v-if="log.response && typeof log.response === 'string' && (log.response.startsWith('<!DOCTYPE html>') || log.response.startsWith('<html>'))"
class="text-white"
>
<summary class="cursor-pointer select-none">Preview :</summary>
<iframe class="w-full h-[500px]" :srcdoc="log.response"></iframe>
<iframe class="w-full h-[500px] bg-white" :srcdoc="log.response"></iframe>
</details>
<details v-if="log.response" class="text-white">
<summary class="cursor-pointer select-none">Response :</summary>
<pre>
<code class="language-json">
{{ log.response }}
<pre style="tab-size: 2">
<code class="whitespace-pre-wrap">
{{ String(log.response) }}
</code>
</pre>
</details>
<details class="text-white">
<summary class="cursor-pointer select-none">Req Headers :</summary>
<pre class="whitespace-pre-line">
<code class="language-json">
<pre style="tab-size: 2">
<code class="whitespace-pre-line">
{{ log.requestHeaders }}
</code>
</pre>
</details>
<details class="text-white">
<summary class="cursor-pointer select-none">Res Headers :</summary>
<pre>
<code class="language-json">
<pre style="tab-size: 2">
<code class="whitespace-pre-line">
{{ log.responseHeaders }}
</code>
</pre>
</details>
<details v-if="log.payload" class="text-white">
<summary class="cursor-pointer select-none">Payload :</summary>
<pre>
<code class="language-json">
<pre style="tab-size: 2">
<code class="whitespace-pre-line">
{{ log.payload }}
</code>
</pre>
@@ -158,11 +161,11 @@ onMounted(() => {
@keyframes log-fade-in {
from {
opacity : 0;
opacity: 0;
scale: 0.8;
}
to {
opacity : 1;
opacity: 1;
scale: 1;
}
}
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -30,7 +30,7 @@ class Logger {
oldLogsJson.push(logData);
await fs.writeFile(logFilePath, JSON.stringify(oldLogsJson));
await fs.writeFile(logFilePath, JSON.stringify(oldLogsJson, null, 2));
} catch (e) {
console.error(e);
}