From 1417eed7ef9fd66b2f750e62b7a6350d0ed005c7 Mon Sep 17 00:00:00 2001 From: marzban-dev Date: Wed, 29 Jan 2025 22:44:15 +0330 Subject: [PATCH 01/16] Remove timer --- frontend/composables/api/product/useGetCategories.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/composables/api/product/useGetCategories.ts b/frontend/composables/api/product/useGetCategories.ts index 10b34aa..47f3a2e 100644 --- a/frontend/composables/api/product/useGetCategories.ts +++ b/frontend/composables/api/product/useGetCategories.ts @@ -17,7 +17,6 @@ const useGetCategories = () => { const handleGetCategories = async () => { const { data } = await axios.get(`${API_ENDPOINTS.products.categories}`); - await new Promise(resolve => setTimeout(resolve, 5000)); return data; }; From 3ca94f7ca086eb553a4615773f55b66765dcf3a0 Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Wed, 29 Jan 2025 23:54:40 +0330 Subject: [PATCH 02/16] a --- backend/product/views.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/backend/product/views.py b/backend/product/views.py index 260beb7..7f6754a 100644 --- a/backend/product/views.py +++ b/backend/product/views.py @@ -171,9 +171,7 @@ class AllProductsView(APIView): # Price filters price_gte = request.query_params.get('price_gte', None) price_lte = request.query_params.get('price_lte', None) - - if type(price_gte) != int or type(price_lte) != int: - return Response({'detail': 'value error price_gte and price_lte should be a number'}, status=status.HTTP_400_BAD_REQUEST) + if price_gte: products = products.filter(price__gte=price_gte) if price_lte: From 07263a4de8146b13fe9c6e7d619144b354db1402 Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Thu, 30 Jan 2025 00:06:44 +0330 Subject: [PATCH 03/16] add auth class --- backend/blog/views.py | 3 ++- backend/home/views.py | 1 + backend/product/views.py | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/backend/blog/views.py b/backend/blog/views.py index 5bd3628..48dcfa7 100644 --- a/backend/blog/views.py +++ b/backend/blog/views.py @@ -12,6 +12,7 @@ from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiTypes class AllBlogView(APIView): serializer_class = AllBlogSerilizer pagination_class = StructurePagination + authentication_classes = [] @extend_schema( parameters=[ OpenApiParameter( @@ -43,7 +44,7 @@ class AllBlogView(APIView): class BlogView(APIView): serializer_class = BlogSerilizer - + authentication_classes = [] def get_client_ip(self, request): """Helper function to get the client IP from request headers.""" x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') diff --git a/backend/home/views.py b/backend/home/views.py index 815a2e4..8d78300 100644 --- a/backend/home/views.py +++ b/backend/home/views.py @@ -8,6 +8,7 @@ from rest_framework import status class HomeView(APIView): + authentication_classes = [] def get(self, request): dollor_object, _ = DollorModel.objects.get_or_create(unique_filed='unique') diff --git a/backend/product/views.py b/backend/product/views.py index 7f6754a..e0e8f2b 100644 --- a/backend/product/views.py +++ b/backend/product/views.py @@ -24,6 +24,7 @@ from rest_framework.permissions import AllowAny class AllCategories(APIView): serializer_class = MainCategorySerializer + authentication_classes = [] @extend_schema( # parameters=[ # OpenApiParameter( @@ -50,6 +51,7 @@ class AllCategories(APIView): class ProductView(APIView): serializer_class = ProductSerializer permission_classes = [AllowAny] + authentication_classes = [] def get(self, request, pk): product = get_object_or_404(ProductModel, id=pk) dollor_object, _ = DollorModel.objects.get_or_create(unique_filed='unique') @@ -61,7 +63,7 @@ class ProductView(APIView): class AllProductsView(APIView): serializer_class = ProductSerializer pagination_class = StructurePagination - + authentication_classes = [] @extend_schema( parameters=[ OpenApiParameter( From 0ca6ecbea0fe8a3a3825b08d80b25a8241330e55 Mon Sep 17 00:00:00 2001 From: marzban-dev Date: Thu, 30 Jan 2025 01:08:37 +0330 Subject: [PATCH 04/16] Update types --- frontend/types/global.d.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/frontend/types/global.d.ts b/frontend/types/global.d.ts index ee75637..e28b8ce 100644 --- a/frontend/types/global.d.ts +++ b/frontend/types/global.d.ts @@ -43,6 +43,15 @@ declare global { meta_rating: number | null; }; + type UserComment = { + "id": number, + "content": string, + "timestamp": string, + "show": boolean, + "product": number, + "user": number + } + type Category = { id: number; name: string; @@ -57,7 +66,7 @@ declare global { "name": string, "slug": string, "icon": string, - "image" : string, + "image": string, "product_count": string, "parent": string, "show": boolean From 10e5f4a5d5901527bab7ef86f4527ad208362754 Mon Sep 17 00:00:00 2001 From: marzban-dev Date: Thu, 30 Jan 2025 01:08:51 +0330 Subject: [PATCH 05/16] Update axios bearer token condition --- frontend/plugins/axios.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/plugins/axios.ts b/frontend/plugins/axios.ts index 04e524b..296a285 100644 --- a/frontend/plugins/axios.ts +++ b/frontend/plugins/axios.ts @@ -16,7 +16,7 @@ export default defineNuxtPlugin(() => { !config.url?.includes(API_ENDPOINTS.auth.signin) && !config.url?.includes(API_ENDPOINTS.account.send_otp) ) { - config.headers.Authorization = `Bearer ${token.value}`; + config.headers.Authorization = token.value ? `Bearer ${token.value}` : undefined; } return config; From 3c83e057d5ab41be88985794a22b20b2106e1c82 Mon Sep 17 00:00:00 2001 From: marzban-dev Date: Thu, 30 Jan 2025 01:09:08 +0330 Subject: [PATCH 06/16] Get comments on ssr --- frontend/pages/product/[id].vue | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/frontend/pages/product/[id].vue b/frontend/pages/product/[id].vue index 6ac127b..52e32e3 100644 --- a/frontend/pages/product/[id].vue +++ b/frontend/pages/product/[id].vue @@ -2,23 +2,27 @@ import ChatButton from "~/components/product/ChatBox/ChatButton.vue"; import useGetProduct from "~/composables/api/product/useGetProduct"; +import useGetComments from "~/composables/api/product/useGetComments"; const route = useRoute(); const id = route.params.id as string | undefined; +const page = ref(1); -const { suspense } = useGetProduct(id); +const { suspense : suspenseProduct } = useGetProduct(id); +const { suspense : suspenseComments} = useGetComments(id, page); // ssr await useAsyncData(async () => { - const response = await suspense(); + const productResponse = await suspenseProduct(); + const commentsResponse = await suspenseComments(); - if (response.isError) { + if (productResponse.isError || commentsResponse.isError) { throw createError({ statusCode: 404, - statusMessage: `error : ${response.error.message}`, - }) + statusMessage: `error : product ${id} prefetch error` + }); } }); @@ -30,7 +34,7 @@ await useAsyncData(async () => { - + From 4d96254a376ac09d5b5ff498b14e93e958ecd47d Mon Sep 17 00:00:00 2001 From: marzban-dev Date: Thu, 30 Jan 2025 01:09:13 +0330 Subject: [PATCH 07/16] Updated --- frontend/constants/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/constants/index.ts b/frontend/constants/index.ts index 7f1e2c4..bfad022 100644 --- a/frontend/constants/index.ts +++ b/frontend/constants/index.ts @@ -5,6 +5,8 @@ export const API_ENDPOINTS = { send_otp: "/accounts/send_otp" }, product: { + comments: "/products/comments", + create_comment: "/products/comments", get: "/products" }, auth: { @@ -24,6 +26,7 @@ export const API_ENDPOINTS = { }; export const QUERY_KEYS = { + comments: "comments", home: "home", chat: "chat", product: "product", From 81e0a54e5805e659fb152fee3ce6481eea42479f Mon Sep 17 00:00:00 2001 From: marzban-dev Date: Thu, 30 Jan 2025 01:09:28 +0330 Subject: [PATCH 08/16] Create hooks for comment api --- .../api/product/useCreateComment.ts | 30 +++++++++++++++++++ .../composables/api/product/useGetComments.ts | 29 ++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 frontend/composables/api/product/useCreateComment.ts create mode 100644 frontend/composables/api/product/useGetComments.ts diff --git a/frontend/composables/api/product/useCreateComment.ts b/frontend/composables/api/product/useCreateComment.ts new file mode 100644 index 0000000..9443850 --- /dev/null +++ b/frontend/composables/api/product/useCreateComment.ts @@ -0,0 +1,30 @@ +// imports + +import { useMutation } from "@tanstack/vue-query"; +import { API_ENDPOINTS } from "~/constants"; + +// types + +export type CreateCommentRequest = { + content: string +}; + +const useCreateComment = (id: number | string | undefined) => { + + // state + + const { $axios: axios } = useNuxtApp(); + + // method + + const handleCreateComment = async (variables: CreateCommentRequest) => { + const { data } = await axios.post(`${API_ENDPOINTS.product.create_comment}/${id}`, variables); + return data; + }; + + return useMutation({ + mutationFn: (variables: CreateCommentRequest) => handleCreateComment(variables) + }); +}; + +export default useCreateComment; diff --git a/frontend/composables/api/product/useGetComments.ts b/frontend/composables/api/product/useGetComments.ts new file mode 100644 index 0000000..ad74c20 --- /dev/null +++ b/frontend/composables/api/product/useGetComments.ts @@ -0,0 +1,29 @@ +// imports + +import { useQuery } from "@tanstack/vue-query"; +import { API_ENDPOINTS, QUERY_KEYS } from "~/constants"; + +// types + +export type GetCommentsResponse = ApiPaginated; + +const useGetComments = (id: string | number | undefined, page: Ref) => { + + // state + + const { $axios: axios } = useNuxtApp(); + + // methods + + const handleGetComments = async () => { + const { data } = await axios.get(`${API_ENDPOINTS.product.comments}/${id}`); + return data; + }; + + return useQuery({ + queryKey: [QUERY_KEYS.comments, id, page], + queryFn: () => handleGetComments() + }); +}; + +export default useGetComments; From c1842b2de892bddd24de398c11a5ba1f854b7188 Mon Sep 17 00:00:00 2001 From: marzban-dev Date: Thu, 30 Jan 2025 01:09:37 +0330 Subject: [PATCH 09/16] Update comments section --- .../components/product/ProductComments.vue | 89 ++++++++++++++++--- 1 file changed, 78 insertions(+), 11 deletions(-) diff --git a/frontend/components/product/ProductComments.vue b/frontend/components/product/ProductComments.vue index 4bc9a08..2d38b65 100644 --- a/frontend/components/product/ProductComments.vue +++ b/frontend/components/product/ProductComments.vue @@ -1,29 +1,96 @@