changed component folders
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import useGetAccount from "~/composables/api/account/useGetAccount";
|
||||
|
||||
export const useAuth = () => {
|
||||
|
||||
// state
|
||||
|
||||
const token = useCookie("token");
|
||||
|
||||
// method
|
||||
|
||||
const updateToken = (newToken: string) => {
|
||||
token.value = newToken;
|
||||
};
|
||||
|
||||
const logout = (reload ?: boolean) => {
|
||||
token.value = undefined;
|
||||
if (reload) window.location.reload();
|
||||
};
|
||||
|
||||
// watch
|
||||
|
||||
watch(() => token.value, (newValue) => {
|
||||
token.value = newValue;
|
||||
}, {
|
||||
immediate: true
|
||||
});
|
||||
|
||||
return { token, updateToken, logout };
|
||||
|
||||
};
|
||||
@@ -1,33 +0,0 @@
|
||||
// imports
|
||||
|
||||
import { useMutation } from "@tanstack/vue-query";
|
||||
import axios from "~/configs/axios.config";
|
||||
import { API_ENDPOINTS } from "~/constants";
|
||||
|
||||
// types
|
||||
|
||||
export type CreateBranchRequest = {
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
// methods
|
||||
|
||||
export const handleCreateBranch = async ({ name, description }: CreateBranchRequest) => {
|
||||
const payload: CreateBranchRequest = {
|
||||
name,
|
||||
description,
|
||||
};
|
||||
|
||||
await axios.post<CreateBranchRequest>(API_ENDPOINTS.branch.createBranch, payload);
|
||||
};
|
||||
|
||||
// composable
|
||||
|
||||
const useCreateBranch = () => {
|
||||
return useMutation({
|
||||
mutationFn: (data: CreateBranchRequest) => handleCreateBranch(data),
|
||||
});
|
||||
};
|
||||
|
||||
export default useCreateBranch;
|
||||
@@ -1,54 +0,0 @@
|
||||
// imports
|
||||
|
||||
import { useQuery } from "@tanstack/vue-query";
|
||||
import axios from "~/configs/axios.config";
|
||||
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
|
||||
import type { ComputedRef } from "vue";
|
||||
|
||||
// types
|
||||
|
||||
export type GetBranchResponse = Branch;
|
||||
|
||||
// methods
|
||||
|
||||
export const handleGetBranch = async (
|
||||
branchId: string,
|
||||
page: string | undefined,
|
||||
folderId: string | undefined,
|
||||
sort: string | undefined,
|
||||
signal: AbortSignal
|
||||
) => {
|
||||
|
||||
const { data } = await axios.get<GetBranchResponse>(`${API_ENDPOINTS.branch.get}/${branchId}`, {
|
||||
signal,
|
||||
params: {
|
||||
sort_by: sort,
|
||||
folder_id: folderId,
|
||||
offset: ((!!page ? Number(page) : 1) * 20) - 20,
|
||||
limit: 20
|
||||
}
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
// composable
|
||||
|
||||
const useGetBranch = (
|
||||
branchId: ComputedRef<string>,
|
||||
page: ComputedRef<string | undefined>,
|
||||
folderId: ComputedRef<string | undefined>,
|
||||
sort: ComputedRef<string | undefined>
|
||||
) => {
|
||||
return useQuery({
|
||||
queryKey: [QUERY_KEYS.branch, branchId, page, folderId, sort],
|
||||
queryFn: ({ signal }) => handleGetBranch(
|
||||
branchId.value,
|
||||
page.value,
|
||||
folderId.value,
|
||||
sort.value,
|
||||
signal
|
||||
)
|
||||
});
|
||||
};
|
||||
|
||||
export default useGetBranch;
|
||||
@@ -1,29 +0,0 @@
|
||||
// imports
|
||||
|
||||
import { useQuery } from "@tanstack/vue-query";
|
||||
import axios from "~/configs/axios.config";
|
||||
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
|
||||
|
||||
// types
|
||||
|
||||
export type GetBranchesResponse = Branch[];
|
||||
|
||||
// methods
|
||||
|
||||
export const handleGetBranches = async () => {
|
||||
const { data } = await axios.get<GetBranchesResponse>(`${API_ENDPOINTS.branch.getAll}`);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
// composable
|
||||
|
||||
const useGetBranches = () => {
|
||||
return useQuery({
|
||||
staleTime: 60 * 1000,
|
||||
queryKey: [QUERY_KEYS.branches],
|
||||
queryFn: () => handleGetBranches()
|
||||
});
|
||||
};
|
||||
|
||||
export default useGetBranches;
|
||||
@@ -1,31 +0,0 @@
|
||||
// imports
|
||||
|
||||
import { useQuery } from "@tanstack/vue-query";
|
||||
import axios from "~/configs/axios.config";
|
||||
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
|
||||
|
||||
// types
|
||||
|
||||
export type GetUserBranchesResponse = Branch[];
|
||||
|
||||
// methods
|
||||
|
||||
export const handleGetUserBranches = async () => {
|
||||
const { data } = await axios.get<GetUserBranchesResponse>(
|
||||
`${API_ENDPOINTS.branch.getUserBranches}`
|
||||
);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
// composable
|
||||
|
||||
const useGetUserBranches = () => {
|
||||
return useQuery({
|
||||
staleTime: 60 * 1000,
|
||||
queryKey: [QUERY_KEYS.userBranches],
|
||||
queryFn: () => handleGetUserBranches(),
|
||||
});
|
||||
};
|
||||
|
||||
export default useGetUserBranches;
|
||||
@@ -1,115 +0,0 @@
|
||||
// imports
|
||||
|
||||
import { QueryClient, useMutation } from "@tanstack/vue-query";
|
||||
import type { InfiniteData } from "@tanstack/vue-query";
|
||||
import { API_ENDPOINTS, MUTATION_KEYS, QUERY_KEYS } from "~/constants";
|
||||
|
||||
// types
|
||||
|
||||
export type CreateChatMessageRequest = {
|
||||
productId: string | number;
|
||||
new_message: string;
|
||||
};
|
||||
|
||||
export type CreateChatMessageResponse = Chat[]
|
||||
|
||||
const useCreateChatMessage = (queryClient: QueryClient) => {
|
||||
|
||||
// state
|
||||
|
||||
const { $axios: axios } = useNuxtApp();
|
||||
|
||||
// method
|
||||
|
||||
const handleCreateChatMessage = async (variables: CreateChatMessageRequest) => {
|
||||
|
||||
const { data } = await axios.post<CreateChatMessageResponse>(`${API_ENDPOINTS.chat.new_message}/${variables.productId}`, variables);
|
||||
return data;
|
||||
};
|
||||
|
||||
return useMutation({
|
||||
mutationKey: [MUTATION_KEYS.create_chat],
|
||||
mutationFn: (variables: CreateChatMessageRequest) => handleCreateChatMessage(variables),
|
||||
onMutate: (newMessage) => {
|
||||
const prevData = queryClient.getQueriesData({ queryKey: [QUERY_KEYS.chat] });
|
||||
|
||||
queryClient.setQueryData<InfiniteData<ApiPaginated<Chat>>>([QUERY_KEYS.chat], (oldData) => {
|
||||
const lastPage = oldData!.pages[oldData!.pages.length - 1];
|
||||
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
count: lastPage.count,
|
||||
next: lastPage.next,
|
||||
previous: lastPage.previous,
|
||||
results: [
|
||||
{
|
||||
id: Date.now(),
|
||||
content: newMessage.new_message,
|
||||
sender: "user"
|
||||
}
|
||||
]
|
||||
},
|
||||
...oldData!.pages
|
||||
],
|
||||
pageParams: [
|
||||
...oldData!.pageParams,
|
||||
{
|
||||
limit: 10,
|
||||
offset: 0
|
||||
}
|
||||
]
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
return { prevData: prevData ? prevData[0][1] : undefined };
|
||||
},
|
||||
onSuccess: (response) => {
|
||||
|
||||
queryClient.setQueryData<InfiniteData<ApiPaginated<Chat>>>([QUERY_KEYS.chat], (oldData) => {
|
||||
if (oldData) {
|
||||
const lastPage = oldData!.pages[oldData!.pages.length - 1];
|
||||
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
count: lastPage.count,
|
||||
next: lastPage.next,
|
||||
previous: lastPage.previous,
|
||||
results: {
|
||||
...response[0],
|
||||
id: Date.now()
|
||||
}
|
||||
},
|
||||
...oldData!.pages
|
||||
],
|
||||
pageParams: [
|
||||
...oldData!.pageParams,
|
||||
{
|
||||
limit: 10,
|
||||
offset: 0
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
return oldData;
|
||||
});
|
||||
|
||||
},
|
||||
onError: (err, newMessage, context) => {
|
||||
if (context) {
|
||||
queryClient.setQueryData(
|
||||
[QUERY_KEYS.chat],
|
||||
context.prevData
|
||||
);
|
||||
}
|
||||
},
|
||||
onSettled: (newMessage) => {
|
||||
queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.chat] });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default useCreateChatMessage;
|
||||
@@ -1,62 +0,0 @@
|
||||
// imports
|
||||
|
||||
import { useInfiniteQuery } from "@tanstack/vue-query";
|
||||
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
|
||||
|
||||
// types
|
||||
|
||||
export type GetBranchResponse = ApiPaginated<Chat>;
|
||||
|
||||
const useGetBranch = (
|
||||
productId: string | number,
|
||||
enabled: Ref<boolean>
|
||||
) => {
|
||||
|
||||
// state
|
||||
|
||||
const { $axios: axios } = useNuxtApp();
|
||||
|
||||
// method
|
||||
|
||||
const handleGetChat = async ({ productId, limit, offset }: {
|
||||
productId: number | string,
|
||||
limit: number,
|
||||
offset: number
|
||||
}) => {
|
||||
|
||||
const { data } = await axios.get<GetBranchResponse>(`${API_ENDPOINTS.chat.messages}/${productId}`, {
|
||||
params: {
|
||||
offset,
|
||||
limit
|
||||
},
|
||||
headers: {
|
||||
Authorization: `Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoyMTY3ODE2OTAwLCJpYXQiOjE3MzU4MTY5MDAsImp0aSI6ImQwN2E2Y2Y2NzgwZjRlNTE5NWIzOGQxMTAzYzU4NDQ3IiwidXNlcl9pZCI6NX0.slwd7ZSV7nUXEuDTYwwHUOo9ekCefwEEL4kVv2vSTFo`
|
||||
}
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
return useInfiniteQuery({
|
||||
enabled,
|
||||
queryKey: [QUERY_KEYS.chat],
|
||||
initialPageParam: {
|
||||
limit: 10,
|
||||
offset: 0
|
||||
},
|
||||
queryFn: ({ pageParam }) => handleGetChat({
|
||||
limit: pageParam.limit,
|
||||
offset: pageParam.offset,
|
||||
productId: productId
|
||||
}),
|
||||
getNextPageParam: (lastPage, pages) => {
|
||||
if (!lastPage.next) return undefined;
|
||||
|
||||
return {
|
||||
limit: 10,
|
||||
offset: pages.length * 10
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default useGetBranch;
|
||||
@@ -1,45 +0,0 @@
|
||||
// imports
|
||||
|
||||
import { useMutation } from "@tanstack/vue-query";
|
||||
import axios from "~/configs/axios.config";
|
||||
import { API_ENDPOINTS } from "~/constants";
|
||||
|
||||
// types
|
||||
|
||||
export type AddDocRequest = {
|
||||
name: string,
|
||||
parent?: string,
|
||||
branch: string | undefined,
|
||||
type: {
|
||||
title: "File" | "Folder",
|
||||
icon: "bi:folder" | "bi:file-earmark"
|
||||
},
|
||||
content: File | undefined
|
||||
};
|
||||
|
||||
// methods
|
||||
|
||||
export const handleAddDoc = async (variables: AddDocRequest & { updateUploadProgress: (p: number) => void }) => {
|
||||
const { data } = await axios.post<AddDocRequest>(`${API_ENDPOINTS.branch.getDoc}/`, {
|
||||
...variables,
|
||||
type: variables.type.title.toLocaleLowerCase()
|
||||
}, {
|
||||
onUploadProgress: (progressEvent) => {
|
||||
variables.updateUploadProgress(progressEvent.progress!);
|
||||
},
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data"
|
||||
}
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
// composable
|
||||
|
||||
const useAddDoc = () => {
|
||||
return useMutation({
|
||||
mutationFn: (variables: AddDocRequest & { updateUploadProgress: (p: number) => void }) => handleAddDoc(variables)
|
||||
});
|
||||
};
|
||||
|
||||
export default useAddDoc;
|
||||
@@ -1,27 +0,0 @@
|
||||
// imports
|
||||
|
||||
import { useMutation } from "@tanstack/vue-query";
|
||||
import axios from "~/configs/axios.config";
|
||||
import { API_ENDPOINTS } from "~/constants";
|
||||
|
||||
// types
|
||||
|
||||
export type DeleteDocRequest = {
|
||||
id: number
|
||||
};
|
||||
|
||||
// methods
|
||||
|
||||
export const handleDeleteDoc = async ({ id }: { id: string | undefined }) => {
|
||||
await axios.delete<DeleteDocRequest>(`${API_ENDPOINTS.branch.getDoc}/${id}`);
|
||||
};
|
||||
|
||||
// composable
|
||||
|
||||
const useDeleteDoc = (id: Ref<string | undefined>) => {
|
||||
return useMutation({
|
||||
mutationFn: () => handleDeleteDoc({ id: id.value })
|
||||
});
|
||||
};
|
||||
|
||||
export default useDeleteDoc;
|
||||
@@ -1,29 +0,0 @@
|
||||
// imports
|
||||
|
||||
import { useMutation } from "@tanstack/vue-query";
|
||||
import axios from "~/configs/axios.config";
|
||||
import { API_ENDPOINTS } from "~/constants";
|
||||
|
||||
// types
|
||||
|
||||
export type EditDocRequest = {
|
||||
id: number
|
||||
};
|
||||
|
||||
// methods
|
||||
|
||||
export const handleEditDoc = async ({ id, name }: { id: string | undefined, name: string | undefined }) => {
|
||||
await axios.patch<EditDocRequest>(`${API_ENDPOINTS.branch.getDoc}/${id}`, { name });
|
||||
};
|
||||
|
||||
// composable
|
||||
|
||||
const useEditDoc = (id: Ref<string | undefined>) => {
|
||||
return useMutation({
|
||||
mutationFn: ({ name }: { name: Ref<string | undefined> }) => {
|
||||
return handleEditDoc({ id: id.value, name: name.value });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default useEditDoc;
|
||||
@@ -1,33 +0,0 @@
|
||||
// imports
|
||||
|
||||
import { useQuery } from "@tanstack/vue-query";
|
||||
import axios from "~/configs/axios.config";
|
||||
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
|
||||
|
||||
// types
|
||||
|
||||
export type GetDocResponse = DocumentStructure;
|
||||
|
||||
// methods
|
||||
|
||||
export const handleGetDoc = async (id : string | undefined) => {
|
||||
const { data } = await axios.get<GetDocResponse>(`${API_ENDPOINTS.branch.getDoc}/${id}`);
|
||||
return data;
|
||||
};
|
||||
|
||||
// composable
|
||||
|
||||
const useGetDoc = (id: ComputedRef<string | undefined>) => {
|
||||
|
||||
const enabled = computed(() => {
|
||||
return !!id.value
|
||||
});
|
||||
|
||||
return useQuery({
|
||||
enabled,
|
||||
queryKey: [QUERY_KEYS.document, id],
|
||||
queryFn: () => handleGetDoc(id.value)
|
||||
});
|
||||
};
|
||||
|
||||
export default useGetDoc;
|
||||
@@ -1,32 +0,0 @@
|
||||
// imports
|
||||
|
||||
import { useMutation } from "@tanstack/vue-query";
|
||||
import axios from "~/configs/axios.config";
|
||||
import { API_ENDPOINTS } from "~/constants";
|
||||
|
||||
// types
|
||||
|
||||
export type MoveDocRequest = {
|
||||
itemsToMove: number[] | string[],
|
||||
parent: number | string
|
||||
};
|
||||
|
||||
// methods
|
||||
|
||||
export const handleMoveDoc = async ({ itemsToMove, parent }: MoveDocRequest) => {
|
||||
const apiUrl = `${API_ENDPOINTS.branch.moveDoc}?new_parent_id=${parent}&${itemsToMove.map(i => `patch_list=${i}&`)}`
|
||||
const splittedUrl = apiUrl.split("");
|
||||
splittedUrl.pop()
|
||||
|
||||
await axios.patch<MoveDocRequest>(splittedUrl.join("").replaceAll(",", ""));
|
||||
};
|
||||
|
||||
// composable
|
||||
|
||||
const useMoveDoc = () => {
|
||||
return useMutation({
|
||||
mutationFn: (variables: MoveDocRequest) => handleMoveDoc(variables)
|
||||
});
|
||||
};
|
||||
|
||||
export default useMoveDoc;
|
||||
@@ -1,40 +0,0 @@
|
||||
// imports
|
||||
|
||||
import { useMutation } from "@tanstack/vue-query";
|
||||
import axios from "~/configs/axios.config";
|
||||
import { API_ENDPOINTS } from "~/constants";
|
||||
|
||||
// types
|
||||
|
||||
export type ReplyDocRequest = {
|
||||
user_id: number;
|
||||
message: string;
|
||||
reply_id: number;
|
||||
};
|
||||
|
||||
export type ReplyDocResponse = {
|
||||
chat_id: number;
|
||||
};
|
||||
|
||||
// methods
|
||||
|
||||
export const handleReplyDoc = async ({ user_id, message, reply_id }: ReplyDocRequest) => {
|
||||
const payload = {
|
||||
user_id,
|
||||
message,
|
||||
item_id: reply_id,
|
||||
};
|
||||
|
||||
const { data } = await axios.post<ReplyDocResponse>(API_ENDPOINTS.branch.replyDoc, payload);
|
||||
return data;
|
||||
};
|
||||
|
||||
// composable
|
||||
|
||||
const useReplyDoc = () => {
|
||||
return useMutation({
|
||||
mutationFn: (data: ReplyDocRequest) => handleReplyDoc(data),
|
||||
});
|
||||
};
|
||||
|
||||
export default useReplyDoc;
|
||||
@@ -1,78 +0,0 @@
|
||||
// imports
|
||||
|
||||
import { useInfiniteQuery } from "@tanstack/vue-query";
|
||||
import axios from "~/configs/axios.config";
|
||||
import { API_ENDPOINTS, QUERY_KEYS } from "~/constants";
|
||||
import type { ComputedRef } from "vue";
|
||||
|
||||
// types
|
||||
|
||||
export type SearchFileResponse = Branch;
|
||||
|
||||
type HandlerProps = typeof initialPageParam & {
|
||||
signal: AbortSignal,
|
||||
search: string,
|
||||
id: number | undefined;
|
||||
sort: string | undefined;
|
||||
}
|
||||
|
||||
// state
|
||||
|
||||
const initialPageParam = {
|
||||
limit: 10,
|
||||
offset: 0
|
||||
};
|
||||
|
||||
// methods
|
||||
|
||||
export const handleSearchFile = async ({ search, offset, limit, id, signal, sort }: HandlerProps) => {
|
||||
const { data } = await axios.get<SearchFileResponse>(`${API_ENDPOINTS.branch.get}/${id}`, {
|
||||
params: {
|
||||
offset,
|
||||
limit,
|
||||
search,
|
||||
sort_by: sort
|
||||
},
|
||||
signal
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
// composable
|
||||
|
||||
const useSearchFile = (search: Ref<string>, id: Ref<number | undefined>, sort: ComputedRef<string | undefined>) => {
|
||||
|
||||
const enabled = computed(() => {
|
||||
return search.value.trim() != "" && !!id.value;
|
||||
});
|
||||
|
||||
return useInfiniteQuery({
|
||||
enabled,
|
||||
retry: false,
|
||||
refetchOnMount: false,
|
||||
refetchOnWindowFocus: false,
|
||||
queryKey: [QUERY_KEYS.searchFile, search, id, sort],
|
||||
queryFn: ({ pageParam, signal }) => handleSearchFile({
|
||||
...pageParam,
|
||||
signal,
|
||||
search: search.value,
|
||||
sort: sort.value,
|
||||
id: id.value
|
||||
}),
|
||||
initialPageParam,
|
||||
getNextPageParam: (lastPage, pages) => {
|
||||
const page = pages.length + 1;
|
||||
|
||||
const limit = initialPageParam.limit;
|
||||
|
||||
const nextPageParams = {
|
||||
offset: page * limit - limit,
|
||||
limit
|
||||
};
|
||||
|
||||
return lastPage?.structure.next ? nextPageParams : undefined;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default useSearchFile;
|
||||
@@ -0,0 +1,6 @@
|
||||
const useGetCustomers = () => {
|
||||
const config = useRuntimeConfig();
|
||||
return config.public.API_BASE_URL;
|
||||
};
|
||||
|
||||
export default useGetCustomers;
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { FastAverageColorResult } from "fast-average-color";
|
||||
import { FastAverageColor } from "fast-average-color";
|
||||
|
||||
export const useImageColor = (img: string) => {
|
||||
const fac = new FastAverageColor();
|
||||
const colorObject = ref<FastAverageColorResult>();
|
||||
const isPending = ref(false);
|
||||
|
||||
const extractImageColor = async () => {
|
||||
isPending.value = true;
|
||||
|
||||
const imageEl = document.querySelector(img) as HTMLImageElement;
|
||||
|
||||
try {
|
||||
const color = await fac.getColorAsync(imageEl);
|
||||
isPending.value = false;
|
||||
colorObject.value = color;
|
||||
} catch (e) {
|
||||
isPending.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
extractImageColor();
|
||||
});
|
||||
|
||||
return {
|
||||
colorObject,
|
||||
extractImageColor,
|
||||
isPending
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
type Props = {
|
||||
duration: number;
|
||||
callback?: () => void
|
||||
}
|
||||
|
||||
export function useTimer({ duration, callback }: Props) {
|
||||
const timeout = ref<NodeJS.Timeout | null>(null);
|
||||
const interval = ref<NodeJS.Timeout | null>(null);
|
||||
|
||||
const isPending = ref(false);
|
||||
const timer = ref(duration / 1000);
|
||||
|
||||
const reset = () => {
|
||||
if (timeout.value) clearTimeout(timeout.value);
|
||||
if (interval.value) clearInterval(interval.value);
|
||||
|
||||
isPending.value = false;
|
||||
timer.value = duration / 1000;
|
||||
};
|
||||
|
||||
const start = () => {
|
||||
isPending.value = true;
|
||||
|
||||
timeout.value = setTimeout(() => {
|
||||
if (interval.value) clearInterval(interval.value);
|
||||
if (callback) callback();
|
||||
isPending.value = false;
|
||||
timer.value = duration / 1000;
|
||||
}, duration);
|
||||
|
||||
interval.value = setInterval(() => {
|
||||
timer.value -= 1;
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
return {
|
||||
isPending,
|
||||
timer,
|
||||
reset,
|
||||
start
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
export type ToastOptions = {
|
||||
description?: string;
|
||||
duration?: number;
|
||||
status?: "success" | "error" | "info" | "warning",
|
||||
}
|
||||
|
||||
type Toast = {
|
||||
id: number;
|
||||
message: string;
|
||||
options?: ToastOptions
|
||||
}
|
||||
|
||||
const toasts = ref<Toast[]>([]);
|
||||
|
||||
export function useToast() {
|
||||
const addToast = ({ message, options = {} }: Omit<Toast, "id">) => {
|
||||
const id = Date.now();
|
||||
|
||||
toasts.value.push({ id, message, options });
|
||||
};
|
||||
|
||||
const destroyToast = (id: number) => {
|
||||
toasts.value = toasts.value.filter(toast => toast.id !== id);
|
||||
};
|
||||
|
||||
return {
|
||||
toasts,
|
||||
addToast,
|
||||
destroyToast
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user