connected to new url param

This commit is contained in:
Mamalizz
2025-10-03 21:40:42 +03:30
parent 20280b319b
commit 936958b434
7 changed files with 269 additions and 99 deletions
@@ -1,31 +1,28 @@
// imports // imports
import { useQuery } from "@tanstack/vue-query"; import { useQuery } from "@tanstack/vue-query";
import { useAppParams } from "~/composables/global/useAppParams";
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants"; import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
// types // types
export type GetAllNotificationsResponse = ApiPaginated<Notification>; export type GetAllNotificationsResponse = ApiPaginated<Notification>;
export type GetAllNotificationsRequest = { const useGetAllNotifications = () => {
sort: string | undefined;
status: string | undefined;
page: string | string[];
};
const useGetAllNotifications = (params: ComputedRef<GetAllNotificationsRequest>) => {
// state // state
const { $axios: axios } = useNuxtApp(); const { $axios: axios } = useNuxtApp();
const { sort, status, page } = useAppParams();
// methods // methods
const handleGetAllNotifications = async (params: GetAllNotificationsRequest) => { const handleGetAllNotifications = async () => {
const { data } = await axios.get<GetAllNotificationsResponse>(API_ENDPOINTS.account.notifications.get_all, { const { data } = await axios.get<GetAllNotificationsResponse>(API_ENDPOINTS.account.notifications.get_all, {
params: { params: {
sort: params.sort, sort: sort.value ?? "created_at",
filter: params.status, filter: status.value,
offset: Number(params.page) * 10 - 10, offset: Number(page.value) * 10 - 10,
limit: 10, limit: 10,
}, },
}); });
@@ -33,8 +30,8 @@ const useGetAllNotifications = (params: ComputedRef<GetAllNotificationsRequest>)
}; };
return useQuery({ return useQuery({
queryKey: [QUERY_KEYS.notifications, params], queryKey: [QUERY_KEYS.notifications, sort, status, page],
queryFn: () => handleGetAllNotifications(params.value), queryFn: () => handleGetAllNotifications(),
}); });
}; };
@@ -1,6 +1,7 @@
// imports // imports
import { useQuery } from "@tanstack/vue-query"; import { useQuery } from "@tanstack/vue-query";
import { useAppParams } from "~/composables/global/useAppParams";
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants"; import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
// types // types
@@ -13,32 +14,30 @@ export type GetAllOrdersRequest = {
page: string | string[]; page: string | string[];
}; };
const useGetAllOrders = (params: ComputedRef<GetAllOrdersRequest>) => { const useGetAllOrders = () => {
// state // state
const { $axios: axios } = useNuxtApp(); const { $axios: axios } = useNuxtApp();
const { sort, status, page } = useAppParams();
// methods // methods
const handleGetAllOrders = async (params: GetAllOrdersRequest) => { const handleGetAllOrders = async () => {
const { data } = await axios.get<GetAllOrdersResponse>( const { data } = await axios.get<GetAllOrdersResponse>(API_ENDPOINTS.orders.get_all, {
API_ENDPOINTS.orders.get_all,
{
params: { params: {
sort: params.sort, sort: sort.value ?? "created_at",
filter: params.status, filter: status.value,
offset: Number(params.page) * 7 - 7, offset: Number(page.value) * 10 - 10,
limit: 7, limit: 10,
}, },
} });
);
return data; return data;
}; };
return useQuery({ return useQuery({
queryKey: [QUERY_KEYS.orders, params], queryKey: [QUERY_KEYS.orders, sort, status, page],
queryFn: () => handleGetAllOrders(params.value), queryFn: () => handleGetAllOrders(),
}); });
}; };
@@ -1,31 +1,32 @@
// imports // imports
import { useQuery } from "@tanstack/vue-query"; import { useQuery } from "@tanstack/vue-query";
import { useAppParams } from "~/composables/global/useAppParams";
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants"; import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
// types // types
export type GetTransactionResponse = Transaction; export type GetTransactionResponse = Transaction;
export type GetTransactionRequest = string; const useGetTransaction = () => {
const useGetTransaction = (params: ComputedRef<GetTransactionRequest>) => {
// state // state
const { $axios: axios } = useNuxtApp(); const { $axios: axios } = useNuxtApp();
const { tracking_code } = useAppParams();
// methods // methods
const handleGetTransaction = async (tc: GetTransactionRequest) => { const handleGetTransaction = async () => {
const { data } = await axios.get<GetTransactionResponse>( const { data } = await axios.get<GetTransactionResponse>(
`${API_ENDPOINTS.orders.checkout.transaction}/${tc}` `${API_ENDPOINTS.orders.checkout.transaction}/${tracking_code.value}`
); );
return data; return data;
}; };
return useQuery({ return useQuery({
queryKey: [QUERY_KEYS.transaction, params], queryKey: [QUERY_KEYS.transaction, tracking_code],
queryFn: () => handleGetTransaction(params.value), queryFn: () => handleGetTransaction(),
}); });
}; };
@@ -1,57 +1,105 @@
// imports // imports
import { useQuery } from "@tanstack/vue-query"; import { useQuery } from "@tanstack/vue-query";
import { useAppParams } from "~/composables/global/useAppParams";
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants"; import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
// types // types
export type GetProductsResponse = ApiPaginated<ProductListItem>; export type GetProductsResponse = ApiPaginated<ProductListItem>;
export type GetProductsFilters = {
search?: string | undefined;
sort?: string | undefined;
category?: string | undefined;
price_gte: number;
price_lte: number;
has_discount?: boolean | undefined;
in_stock?: boolean | undefined;
page: number;
};
// composable // composable
const useGetProducts = (params?: ComputedRef<GetProductsFilters>) => { const useGetProducts = () => {
// state // state
const { $axios: axios } = useNuxtApp(); const { $axios: axios, $queryClient: queryClient } = useNuxtApp();
const { search, sort, in_stock, has_discount, slug, price_gte, price_lte, page } = useAppParams();
const searchDebounced = refDebounced(search, 500);
// computed
const products_category = computed(() => {
if (Array.isArray(slug.value) && slug.value.length >= 2) {
return slug.value[1];
}
return undefined;
});
const filters_clone = computed(() => {
return {
search,
sort,
in_stock,
has_discount,
slug,
price_gte,
price_lte,
};
});
// watch
watch(
() => filters_clone.value,
() => {
queryClient.cancelQueries({
queryKey: [
QUERY_KEYS.products,
searchDebounced,
sort,
in_stock,
has_discount,
products_category,
price_gte,
price_lte,
page,
],
});
page.value = 1;
},
{
deep: true,
}
);
// methods // methods
const handleGetProducts = async (params?: GetProductsFilters) => { const handleGetProducts = async ({ signal }: { signal: AbortSignal }) => {
const { data } = await axios.get<GetProductsResponse>( const { data } = await axios.get<GetProductsResponse>(`${API_ENDPOINTS.products.get_all}`, {
`${API_ENDPOINTS.products.get_all}`,
{
params: { params: {
sort: params?.sort, sort: sort.value || "newest",
in_stock: params?.in_stock, in_stock: in_stock.value,
search: params?.search, search: searchDebounced.value,
has_discount: params?.has_discount, has_discount: has_discount.value,
category: params?.category, category: products_category.value,
price_gte: params?.price_gte, price_gte: price_gte.value,
price_lte: params?.price_lte, price_lte: price_lte.value,
offset: Number(params?.page) * 15 - 15, offset: Number(page.value) * 15 - 15,
limit: 15 limit: 15,
} },
} signal,
); });
return data; return data;
}; };
return useQuery({ return useQuery({
staleTime: 60 * 1000, staleTime: 60 * 1000,
queryKey: [QUERY_KEYS.products, params], queryKey: [
queryFn: () => handleGetProducts(params?.value) QUERY_KEYS.products,
searchDebounced,
sort,
in_stock,
has_discount,
products_category,
price_gte,
price_lte,
page,
],
queryFn: ({ signal }) => handleGetProducts({ signal }),
}); });
}; };
@@ -1,45 +1,86 @@
// imports // imports
import { useQuery } from "@tanstack/vue-query"; import { useQuery } from "@tanstack/vue-query";
import { useAppParams } from "~/composables/global/useAppParams";
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants"; import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
// types // types
export type GetResellersProductsResponse = ApiPaginated<ProductListItem>; export type GetResellersProductsResponse = ApiPaginated<ProductListItem>;
export type GetResellersProductsFilters = {
search?: string | undefined;
sort?: string | undefined;
category?: string | undefined;
price_gte: number;
price_lte: number;
has_discount?: boolean | undefined;
in_stock?: boolean | undefined;
page: number;
};
// composable // composable
const useGetResellersProducts = (params?: ComputedRef<GetResellersProductsFilters>) => { const useGetResellersProducts = () => {
// state // state
const { $axios: axios } = useNuxtApp(); const { $axios: axios, $queryClient: queryClient } = useNuxtApp();
const { search, sort, in_stock, has_discount, slug, price_gte, price_lte, page } = useAppParams();
const searchDebounced = refDebounced(search, 500);
// computed
const products_category = computed(() => {
if (Array.isArray(slug.value) && slug.value.length >= 2) {
return slug.value[1];
}
return undefined;
});
const filters_clone = computed(() => {
return {
search,
sort,
in_stock,
has_discount,
slug,
price_gte,
price_lte,
};
});
// watch
watch(
() => filters_clone.value,
() => {
queryClient.cancelQueries({
queryKey: [
QUERY_KEYS.products,
searchDebounced,
sort,
in_stock,
has_discount,
products_category,
price_gte,
price_lte,
page,
],
});
page.value = 1;
},
{
deep: true,
}
);
// methods // methods
const handleGetResellersProducts = async (params?: GetResellersProductsFilters) => { const handleGetResellersProducts = async ({ signal }: { signal: AbortSignal }) => {
const { data } = await axios.get<GetResellersProductsResponse>(`${API_ENDPOINTS.resellers_products.get_all}`, { const { data } = await axios.get<GetResellersProductsResponse>(`${API_ENDPOINTS.resellers_products.get_all}`, {
params: { params: {
sort: params?.sort, sort: sort.value || "newest",
in_stock: params?.in_stock, in_stock: in_stock.value,
search: params?.search, search: searchDebounced.value,
has_discount: params?.has_discount, has_discount: has_discount.value,
category: params?.category, category: products_category.value,
price_gte: params?.price_gte, price_gte: price_gte.value,
price_lte: params?.price_lte, price_lte: price_lte.value,
offset: Number(params?.page) * 15 - 15, offset: Number(page.value) * 15 - 15,
limit: 15, limit: 15,
}, },
signal,
}); });
return data; return data;
@@ -47,8 +88,18 @@ const useGetResellersProducts = (params?: ComputedRef<GetResellersProductsFilter
return useQuery({ return useQuery({
staleTime: 60 * 1000, staleTime: 60 * 1000,
queryKey: [QUERY_KEYS.resellers_products, params], queryKey: [
queryFn: () => handleGetResellersProducts(params?.value), QUERY_KEYS.resellers_products,
searchDebounced,
sort,
in_stock,
has_discount,
products_category,
price_gte,
price_lte,
page,
],
queryFn: ({ signal }) => handleGetResellersProducts({ signal }),
}); });
}; };
@@ -1,6 +1,7 @@
// imports // imports
import { useQuery } from "@tanstack/vue-query"; import { useQuery } from "@tanstack/vue-query";
import { useAppParams } from "~/composables/global/useAppParams";
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants"; import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
// types // types
@@ -13,19 +14,21 @@ export type GetAllTicketsRequest = {
page: string | string[]; page: string | string[];
}; };
const useGetAllTickets = (params: ComputedRef<GetAllTicketsRequest>) => { const useGetAllTickets = () => {
// state // state
const { $axios: axios } = useNuxtApp(); const { $axios: axios } = useNuxtApp();
const { sort, status, page } = useAppParams();
// methods // methods
const handleGetAllTickets = async (params: GetAllTicketsRequest) => { const handleGetAllTickets = async () => {
const { data } = await axios.get<GetAllTicketsResponse>(API_ENDPOINTS.tickets.get_all, { const { data } = await axios.get<GetAllTicketsResponse>(API_ENDPOINTS.tickets.get_all, {
params: { params: {
sort: params.sort, sort: sort.value ?? "created_at",
filter: params.status, filter: status.value,
offset: Number(params.page) * 7 - 7, offset: Number(page.value) * 7 - 7,
limit: 7, limit: 7,
}, },
}); });
@@ -33,8 +36,8 @@ const useGetAllTickets = (params: ComputedRef<GetAllTicketsRequest>) => {
}; };
return useQuery({ return useQuery({
queryKey: [QUERY_KEYS.tickets, params], queryKey: [QUERY_KEYS.tickets, sort, status, page],
queryFn: () => handleGetAllTickets(params.value), queryFn: () => handleGetAllTickets(),
}); });
}; };
@@ -0,0 +1,71 @@
import { PRODUCT_RANGE } from "~/constants";
export const useAppParams = () => {
// state
const { y } = useWindowScroll({ behavior: "smooth" });
const slug = useRouteParams<string | undefined>("slug");
const sort = useRouteQuery<string | undefined>("sort", undefined, {
mode: "replace",
});
const search = useRouteQuery<string | undefined>("search", "", {
mode: "replace",
});
const page = useRouteQuery<number | undefined>("page", 1, {
mode: "push",
transform: (value) => (!!value ? +value : undefined),
});
const category = useRouteQuery<string | undefined>("category", "", {
mode: "replace",
});
const status = useRouteQuery<string | undefined>("status", undefined, {
mode: "replace",
});
const price_gte = useRouteQuery<number | undefined>("price_gte", PRODUCT_RANGE.min, {
mode: "replace",
});
const price_lte = useRouteQuery<number | undefined>("price_lte", PRODUCT_RANGE.max, {
mode: "replace",
});
const in_stock = useRouteQuery<string>("in_stock", "false", {
mode: "replace",
});
const has_discount = useRouteQuery<string>("has_discount", "false", {
mode: "replace",
});
const tracking_code = useRouteQuery<string>("tracking_code", "", {
mode: "replace",
});
watch(
() => page.value,
() => {
y.value = 0;
}
);
return {
slug,
sort,
search,
page,
category,
price_gte,
price_lte,
in_stock,
status,
has_discount,
tracking_code,
};
};