diff --git a/backend/product/views.py b/backend/product/views.py
index ccc51ee..797b97e 100644
--- a/backend/product/views.py
+++ b/backend/product/views.py
@@ -12,6 +12,7 @@ from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiTypes
from rest_framework.permissions import AllowAny
from order.serializers import OrderItemSerailzier
from order.models import OrderModel
+from django.db.models import Min, Max
# class APIView(APIView):
# def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
@@ -177,15 +178,16 @@ class AllProductsView(APIView):
if search_query:
products = products.filter(Q(name__icontains=search_query) | Q(description__icontains=search_query))
- # # Price filters
+ # Price filters
price_gte = request.query_params.get('price_gte', None)
price_lte = request.query_params.get('price_lte', None)
-
- if price_gte:
- products = products.filter(variants__price__gte=price_gte)
- if price_lte:
- products = products.filter(variants__price__lte=price_lte)
+ products = products.annotate(min_price=Min('variants__price'), max_price=Max('variants__price'))
+
+ if price_gte:
+ products = products.filter(max_price__gte=price_gte)
+ if price_lte:
+ products = products.filter(min_price__lte=price_lte)
# Sorting
sort_by = request.query_params.get('sort', None)
if sort_by in ['name', '-name', 'created_at', '-created_at']:
diff --git a/frontend/assets/css/other.utils.css b/frontend/assets/css/other.utils.css
index 45c7fec..a34b0b2 100644
--- a/frontend/assets/css/other.utils.css
+++ b/frontend/assets/css/other.utils.css
@@ -1,7 +1,7 @@
@utility persian-number {
- -moz-font-feature-settings: "ss03";
- -webkit-font-feature-settings: "ss03";
- font-feature-settings: "ss03";
+ -moz-font-feature-settings: "ss02";
+ -webkit-font-feature-settings: "ss02";
+ font-feature-settings: "ss02";
}
@utility text-gradient {
diff --git a/frontend/components/global/BlogPost.vue b/frontend/components/global/BlogPost.vue
index 457a707..1e26aa7 100644
--- a/frontend/components/global/BlogPost.vue
+++ b/frontend/components/global/BlogPost.vue
@@ -39,7 +39,7 @@ const createdAt = usePersianTimeAgo(new Date(date.value));
{{ category.name }}
@@ -49,7 +49,7 @@ const createdAt = usePersianTimeAgo(new Date(date.value));
class="aspect-square w-full rounded-150 overflow-hidden relative"
>
{{ category.name }}
diff --git a/frontend/components/global/Header.vue b/frontend/components/global/Header.vue
index 9ae43bc..06097a3 100644
--- a/frontend/components/global/Header.vue
+++ b/frontend/components/global/Header.vue
@@ -123,7 +123,7 @@ const isHomePage = computed(() => route.path === "/");
diff --git a/frontend/components/global/LoadingOverlay.vue b/frontend/components/global/LoadingOverlay.vue
index 57494c6..fecd7bf 100644
--- a/frontend/components/global/LoadingOverlay.vue
+++ b/frontend/components/global/LoadingOverlay.vue
@@ -92,7 +92,7 @@ onMounted(() => {
src="/img/heymlz/heymlz-text-logo.png"
class="invert w-[250px]"
/>
-
+
{
:key="slide"
class="py-4"
>
-
+
+
+
diff --git a/frontend/components/global/product/ProductCard.vue b/frontend/components/global/product/ProductCard.vue
index 745cdb8..f96e0dc 100644
--- a/frontend/components/global/product/ProductCard.vue
+++ b/frontend/components/global/product/ProductCard.vue
@@ -22,11 +22,17 @@ type Props = {
// props
const props = defineProps
();
-const { id } = toRefs(props);
+const { id, colors } = toRefs(props);
// state
const { colorObject } = useImageColor(`#product-image-${id.value}`);
+
+// computed
+
+const limitedColors = computed(() => {
+ return colors.value.slice(0, 3);
+});
@@ -51,33 +57,26 @@ const { colorObject } = useImageColor(`#product-image-${id.value}`);
-
+
{{ tag }}
-
+
{{ title }}
-
-
+
+
-
+
{{ title }}
-
-
+
+
{{ price }}
diff --git a/frontend/components/product/ProductComments.vue b/frontend/components/product/ProductComments.vue
index 21eece2..e5d9730 100644
--- a/frontend/components/product/ProductComments.vue
+++ b/frontend/components/product/ProductComments.vue
@@ -98,7 +98,19 @@ const limitedComments = computed(() => {
:username="'منصور مرزبان'"
/>
-
+
+
+ هیچ نظری ثبت نشده است
+
+
{
selectedQuantity.value = 1;
selectedSlide.value = newValue.images[0].id;
+ },
+ {
+ immediate: true,
}
);
@@ -180,7 +183,7 @@ watch(
0 ? (selectedVariantId = variant.id) : undefined"
+ @click="selectedVariantId = variant.id"
v-for="variant in product!.variants.filter(p => p.color === selectedColor)"
:key="variant.id"
:variantDetail="variant"
@@ -190,57 +193,67 @@ watch(
-
-
+
+
+
+
+
+
+
-
-
-
+ اتمام موجودی
+
-
-
+
diff --git a/frontend/components/product/ProductVariant.vue b/frontend/components/product/ProductVariant.vue
index 3e16e09..e203e85 100644
--- a/frontend/components/product/ProductVariant.vue
+++ b/frontend/components/product/ProductVariant.vue
@@ -13,22 +13,12 @@ defineProps
();
@@ -38,27 +28,25 @@ defineProps
();
{{ variantDetail.price }}
-
-
-
- {{ variantDetail.discount }}
-
-
-
- اتمام موجودی
+
+
+ {{ variantDetail.discount }}
+
+
+
+ اتمام موجودی
-
+
diff --git a/frontend/pages/contact-us.vue b/frontend/pages/contact-us.vue
index 7f47c7c..dc7d036 100644
--- a/frontend/pages/contact-us.vue
+++ b/frontend/pages/contact-us.vue
@@ -168,7 +168,7 @@ const contactWays = ref([
diff --git a/frontend/pages/profile/index.vue b/frontend/pages/profile/index.vue
index 9378ec9..44ce1de 100644
--- a/frontend/pages/profile/index.vue
+++ b/frontend/pages/profile/index.vue
@@ -239,7 +239,7 @@ const handleSubmit = (withValidation: boolean) => {
{
const config = useRuntimeConfig();
const { token } = useAuth();
const axios = axiosOriginal.create({
- baseURL: config.public.API_BASE_URL
+ baseURL: config.public.API_BASE_URL,
});
axios.interceptors.request.use((config) => {
- if (
- !config.url?.includes(API_ENDPOINTS.auth.signin) &&
- !config.url?.includes(API_ENDPOINTS.account.send_otp)
- ) {
- config.headers.Authorization = token.value
- ? `Bearer ${token.value}`
- : undefined;
+ if (!config.url?.includes(API_ENDPOINTS.auth.signin) && !config.url?.includes(API_ENDPOINTS.account.send_otp)) {
+ config.headers.Authorization = token.value ? `Bearer ${token.value}` : undefined;
}
return config;
@@ -28,19 +22,14 @@ export default defineNuxtPlugin(() => {
(response) => {
return response;
},
- async function(error) {
-
- if (config.public.DEBUG === "true" && import.meta.server) {
- await Logger.axiosErrorLog(error);
- }
-
+ async function (error) {
return Promise.reject(error);
}
);
return {
provide: {
- axios
- }
+ axios,
+ },
};
});
diff --git a/frontend/plugins/error-handlers.ts b/frontend/plugins/error-handlers.ts
deleted file mode 100644
index a008af9..0000000
--- a/frontend/plugins/error-handlers.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export default defineNuxtPlugin((nuxtApp) => {
- // Also possible
- nuxtApp.hook('vue:error', (error, instance, info) => {
- // handle error, e.g. report to a service
- })
-})
\ No newline at end of file
diff --git a/frontend/public/icons/image-slash.svg b/frontend/public/icons/image-slash.svg
new file mode 100644
index 0000000..463b5c5
--- /dev/null
+++ b/frontend/public/icons/image-slash.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/img/heymlz/contact-us.gif b/frontend/public/img/heymlz/heymlz-contact-us.gif
similarity index 100%
rename from frontend/public/img/heymlz/contact-us.gif
rename to frontend/public/img/heymlz/heymlz-contact-us.gif
diff --git a/frontend/public/img/heymlz/heymlz-logomotion.gif b/frontend/public/img/heymlz/heymlz-logomotion.gif
new file mode 100644
index 0000000..5bbd0ad
Binary files /dev/null and b/frontend/public/img/heymlz/heymlz-logomotion.gif differ
diff --git a/frontend/public/logo/logo-row.png b/frontend/public/logo/logo-row.png
deleted file mode 100644
index 6483170..0000000
Binary files a/frontend/public/logo/logo-row.png and /dev/null differ
diff --git a/frontend/tools/logger.ts b/frontend/tools/logger.ts
deleted file mode 100644
index 7894536..0000000
--- a/frontend/tools/logger.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import fs from "fs/promises";
-import { ensureFileExists } from "~/utils";
-
-class Logger {
- public static async axiosErrorLog(error: any) {
- const errorJson = error.toJSON();
-
- const nowDate = new Date();
-
- const logData: AxiosLogType = {
- url: errorJson.config.url,
- code: errorJson.code!,
- status: errorJson.status!,
- method: errorJson.config.method,
- response: error?.response?.data,
- requestHeaders: errorJson.config.headers,
- // responseHeaders: error.response.headers,
- payload: errorJson.config.data ? JSON.parse(errorJson.config.data) : undefined,
- params: errorJson.config.params ?? undefined,
- date: nowDate.toString()
- };
-
- const logFilePath = ".logs/log.json";
-
- try {
- await ensureFileExists(logFilePath, "[]");
-
- const oldLogs = await fs.readFile(logFilePath, "utf-8");
- const oldLogsJson = JSON.parse(oldLogs) as Record[];
-
- oldLogsJson.push(logData);
-
- await fs.writeFile(logFilePath, JSON.stringify(oldLogsJson, null, 2));
- } catch (e) {
- console.error(e);
- }
- }
-}
-
-export default Logger;
\ No newline at end of file