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
import { useQuery } from "@tanstack/vue-query";
import { useAppParams } from "~/composables/global/useAppParams";
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
// types
export type GetAllNotificationsResponse = ApiPaginated<Notification>;
export type GetAllNotificationsRequest = {
sort: string | undefined;
status: string | undefined;
page: string | string[];
};
const useGetAllNotifications = (params: ComputedRef<GetAllNotificationsRequest>) => {
const useGetAllNotifications = () => {
// state
const { $axios: axios } = useNuxtApp();
const { sort, status, page } = useAppParams();
// methods
const handleGetAllNotifications = async (params: GetAllNotificationsRequest) => {
const handleGetAllNotifications = async () => {
const { data } = await axios.get<GetAllNotificationsResponse>(API_ENDPOINTS.account.notifications.get_all, {
params: {
sort: params.sort,
filter: params.status,
offset: Number(params.page) * 10 - 10,
sort: sort.value ?? "created_at",
filter: status.value,
offset: Number(page.value) * 10 - 10,
limit: 10,
},
});
@@ -33,8 +30,8 @@ const useGetAllNotifications = (params: ComputedRef<GetAllNotificationsRequest>)
};
return useQuery({
queryKey: [QUERY_KEYS.notifications, params],
queryFn: () => handleGetAllNotifications(params.value),
queryKey: [QUERY_KEYS.notifications, sort, status, page],
queryFn: () => handleGetAllNotifications(),
});
};
@@ -1,6 +1,7 @@
// imports
import { useQuery } from "@tanstack/vue-query";
import { useAppParams } from "~/composables/global/useAppParams";
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
// types
@@ -13,32 +14,30 @@ export type GetAllOrdersRequest = {
page: string | string[];
};
const useGetAllOrders = (params: ComputedRef<GetAllOrdersRequest>) => {
const useGetAllOrders = () => {
// state
const { $axios: axios } = useNuxtApp();
const { sort, status, page } = useAppParams();
// methods
const handleGetAllOrders = async (params: GetAllOrdersRequest) => {
const { data } = await axios.get<GetAllOrdersResponse>(
API_ENDPOINTS.orders.get_all,
{
const handleGetAllOrders = async () => {
const { data } = await axios.get<GetAllOrdersResponse>(API_ENDPOINTS.orders.get_all, {
params: {
sort: params.sort,
filter: params.status,
offset: Number(params.page) * 7 - 7,
limit: 7,
sort: sort.value ?? "created_at",
filter: status.value,
offset: Number(page.value) * 10 - 10,
limit: 10,
},
}
);
});
return data;
};
return useQuery({
queryKey: [QUERY_KEYS.orders, params],
queryFn: () => handleGetAllOrders(params.value),
queryKey: [QUERY_KEYS.orders, sort, status, page],
queryFn: () => handleGetAllOrders(),
});
};
@@ -1,31 +1,32 @@
// imports
import { useQuery } from "@tanstack/vue-query";
import { useAppParams } from "~/composables/global/useAppParams";
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
// types
export type GetTransactionResponse = Transaction;
export type GetTransactionRequest = string;
const useGetTransaction = (params: ComputedRef<GetTransactionRequest>) => {
const useGetTransaction = () => {
// state
const { $axios: axios } = useNuxtApp();
const { tracking_code } = useAppParams();
// methods
const handleGetTransaction = async (tc: GetTransactionRequest) => {
const handleGetTransaction = async () => {
const { data } = await axios.get<GetTransactionResponse>(
`${API_ENDPOINTS.orders.checkout.transaction}/${tc}`
`${API_ENDPOINTS.orders.checkout.transaction}/${tracking_code.value}`
);
return data;
};
return useQuery({
queryKey: [QUERY_KEYS.transaction, params],
queryFn: () => handleGetTransaction(params.value),
queryKey: [QUERY_KEYS.transaction, tracking_code],
queryFn: () => handleGetTransaction(),
});
};
@@ -1,57 +1,105 @@
// imports
import { useQuery } from "@tanstack/vue-query";
import { useAppParams } from "~/composables/global/useAppParams";
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
// types
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
const useGetProducts = (params?: ComputedRef<GetProductsFilters>) => {
const useGetProducts = () => {
// 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
const handleGetProducts = async (params?: GetProductsFilters) => {
const { data } = await axios.get<GetProductsResponse>(
`${API_ENDPOINTS.products.get_all}`,
{
const handleGetProducts = async ({ signal }: { signal: AbortSignal }) => {
const { data } = await axios.get<GetProductsResponse>(`${API_ENDPOINTS.products.get_all}`, {
params: {
sort: params?.sort,
in_stock: params?.in_stock,
search: params?.search,
has_discount: params?.has_discount,
category: params?.category,
price_gte: params?.price_gte,
price_lte: params?.price_lte,
offset: Number(params?.page) * 15 - 15,
limit: 15
}
}
);
sort: sort.value || "newest",
in_stock: in_stock.value,
search: searchDebounced.value,
has_discount: has_discount.value,
category: products_category.value,
price_gte: price_gte.value,
price_lte: price_lte.value,
offset: Number(page.value) * 15 - 15,
limit: 15,
},
signal,
});
return data;
};
return useQuery({
staleTime: 60 * 1000,
queryKey: [QUERY_KEYS.products, params],
queryFn: () => handleGetProducts(params?.value)
queryKey: [
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
import { useQuery } from "@tanstack/vue-query";
import { useAppParams } from "~/composables/global/useAppParams";
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
// types
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
const useGetResellersProducts = (params?: ComputedRef<GetResellersProductsFilters>) => {
const useGetResellersProducts = () => {
// 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
const handleGetResellersProducts = async (params?: GetResellersProductsFilters) => {
const handleGetResellersProducts = async ({ signal }: { signal: AbortSignal }) => {
const { data } = await axios.get<GetResellersProductsResponse>(`${API_ENDPOINTS.resellers_products.get_all}`, {
params: {
sort: params?.sort,
in_stock: params?.in_stock,
search: params?.search,
has_discount: params?.has_discount,
category: params?.category,
price_gte: params?.price_gte,
price_lte: params?.price_lte,
offset: Number(params?.page) * 15 - 15,
sort: sort.value || "newest",
in_stock: in_stock.value,
search: searchDebounced.value,
has_discount: has_discount.value,
category: products_category.value,
price_gte: price_gte.value,
price_lte: price_lte.value,
offset: Number(page.value) * 15 - 15,
limit: 15,
},
signal,
});
return data;
@@ -47,8 +88,18 @@ const useGetResellersProducts = (params?: ComputedRef<GetResellersProductsFilter
return useQuery({
staleTime: 60 * 1000,
queryKey: [QUERY_KEYS.resellers_products, params],
queryFn: () => handleGetResellersProducts(params?.value),
queryKey: [
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
import { useQuery } from "@tanstack/vue-query";
import { useAppParams } from "~/composables/global/useAppParams";
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
// types
@@ -13,19 +14,21 @@ export type GetAllTicketsRequest = {
page: string | string[];
};
const useGetAllTickets = (params: ComputedRef<GetAllTicketsRequest>) => {
const useGetAllTickets = () => {
// state
const { $axios: axios } = useNuxtApp();
const { sort, status, page } = useAppParams();
// methods
const handleGetAllTickets = async (params: GetAllTicketsRequest) => {
const handleGetAllTickets = async () => {
const { data } = await axios.get<GetAllTicketsResponse>(API_ENDPOINTS.tickets.get_all, {
params: {
sort: params.sort,
filter: params.status,
offset: Number(params.page) * 7 - 7,
sort: sort.value ?? "created_at",
filter: status.value,
offset: Number(page.value) * 7 - 7,
limit: 7,
},
});
@@ -33,8 +36,8 @@ const useGetAllTickets = (params: ComputedRef<GetAllTicketsRequest>) => {
};
return useQuery({
queryKey: [QUERY_KEYS.tickets, params],
queryFn: () => handleGetAllTickets(params.value),
queryKey: [QUERY_KEYS.tickets, sort, status, page],
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,
};
};