diff --git a/package.json b/package.json index 8c770b5..c5d20a6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@frontend/kitui", - "version": "1.0.4", + "version": "1.0.5", "description": "test", "main": "index.js", "types": "index.d.ts", @@ -16,17 +16,19 @@ }, "peerDependencies": { "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "zustand": "^4.3.8", + "axios": "^1.4.0" }, "devDependencies": { "@types/node": "^20.2.5", "@types/react": "^18.2.7", "react": "^18.2.0", "react-dom": "^18.2.0", - "typescript": "^5.0.4" + "typescript": "^5.0.4", + "zustand": "^4.3.8" }, "dependencies": { - "axios": "^1.4.0", "reconnecting-eventsource": "^1.6.2" } } diff --git a/src/api/index.ts b/src/api/index.ts index e322152..2c34c69 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,2 +1,2 @@ -export * from "./createMakeRequest"; +export * from "./makeRequest"; export * from "./tickets"; \ No newline at end of file diff --git a/src/api/createMakeRequest.ts b/src/api/makeRequest.ts similarity index 61% rename from src/api/createMakeRequest.ts rename to src/api/makeRequest.ts index 0b1a08f..ce5687a 100644 --- a/src/api/createMakeRequest.ts +++ b/src/api/makeRequest.ts @@ -1,19 +1,34 @@ +import { create } from "zustand"; +import { persist } from "zustand/middleware"; import axios, { AxiosResponse, Method } from "axios"; -interface MakeRequestArgs { - method?: Method; - url: string; - body?: T; - /** Send access token */ - useToken?: boolean; - contentType?: boolean; - signal?: AbortSignal; - /** Send refresh token */ - withCredentials?: boolean; +interface AuthStore { + token: string; } -export const createMakeRequest = (getToken: () => string, setToken: (token: string) => void) => async ({ +export const useAuthStore = create()( + persist( + (set, get) => ({ + token: "", + }), + { + name: "token", + } + ) +); + +export const getAuthToken = () => useAuthStore.getState().token; + +export const setAuthToken = (token: string) => useAuthStore.setState({ token }); + +export const clearAuthToken = () => useAuthStore.setState({ token: "" }); + +export function useToken() { + return useAuthStore(state => state.token); +} + +export async function makeRequest({ method = "post", url, body, @@ -21,9 +36,19 @@ export const createMakeRequest = (getToken: () => string, setToken: (token: stri contentType = false, signal, withCredentials, -}: MakeRequestArgs): Promise => { +}: { + method?: Method; + url: string; + body?: TRequest; + /** Send access token */ + useToken?: boolean; + contentType?: boolean; + signal?: AbortSignal; + /** Send refresh token */ + withCredentials?: boolean; +}): Promise { const headers: Record = {}; - if (useToken) headers["Authorization"] = `Bearer ${getToken()}`; + if (useToken) headers["Authorization"] = `Bearer ${getAuthToken()}`; if (contentType) headers["Content-Type"] = "application/json"; try { @@ -37,14 +62,14 @@ export const createMakeRequest = (getToken: () => string, setToken: (token: stri }); if (response.data?.accessToken) { - setToken(response.data.accessToken); + setAuthToken(response.data.accessToken); } return response.data; } catch (error) { if (axios.isAxiosError(error) && error.response?.status === 401 && !withCredentials) { - const refreshResponse = await refresh(getToken()); - if (refreshResponse.data?.accessToken) setToken(refreshResponse.data.accessToken); + const refreshResponse = await refresh(getAuthToken()); + if (refreshResponse.data?.accessToken) setAuthToken(refreshResponse.data.accessToken); headers["Authorization"] = refreshResponse.data.accessToken; const response = await axios.request>({ diff --git a/src/api/tickets.ts b/src/api/tickets.ts index dee3171..cda5a33 100644 --- a/src/api/tickets.ts +++ b/src/api/tickets.ts @@ -1,9 +1,8 @@ import { CreateTicketRequest, CreateTicketResponse } from "../model/ticket"; -import { createMakeRequest } from "./createMakeRequest"; +import { makeRequest } from "./makeRequest"; -export function createTicket({ makeRequest, url,body, useToken = true }: { - makeRequest: ReturnType; +export function createTicket({ url, body, useToken = true }: { url: string; body: CreateTicketRequest; useToken?: boolean; diff --git a/src/hooks/useTicketMessages.ts b/src/hooks/useTicketMessages.ts index f14f0db..9bb6598 100644 --- a/src/hooks/useTicketMessages.ts +++ b/src/hooks/useTicketMessages.ts @@ -1,11 +1,10 @@ import { useState, useEffect } from "react"; -import { createMakeRequest } from "../api"; import { TicketMessage, GetMessagesRequest, GetMessagesResponse } from "../model"; import { devlog } from "../utils"; +import { makeRequest } from "../api"; -export function useTicketMessages({ makeRequest, url, messageApiPage, messagesPerPage, ticketId, onNewMessages, onError, isUnauth = false }: { - makeRequest: ReturnType; +export function useTicketMessages({ url, messageApiPage, messagesPerPage, ticketId, onNewMessages, onError, isUnauth = false }: { url: string; ticketId: string | undefined; messagesPerPage: number; diff --git a/src/hooks/useTickets.ts b/src/hooks/useTickets.ts index e6b2bda..7d2c3e0 100644 --- a/src/hooks/useTickets.ts +++ b/src/hooks/useTickets.ts @@ -1,11 +1,10 @@ import { useState, useEffect } from "react"; -import { createMakeRequest } from "../api"; import { GetTicketsResponse, GetTicketsRequest } from "../model"; import { devlog } from "../utils"; +import { makeRequest } from "../api"; -export function useTickets({ makeRequest, url, ticketsPerPage, ticketApiPage, onNewTickets, onError }: { - makeRequest: ReturnType; +export function useTickets({ url, ticketsPerPage, ticketApiPage, onNewTickets, onError }: { url: string; ticketsPerPage: number; ticketApiPage: number; diff --git a/yarn.lock b/yarn.lock index 70827b8..b9eb6a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -131,3 +131,15 @@ typescript@^5.0.4: version "5.0.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + +use-sync-external-store@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + +zustand@^4.3.8: + version "4.3.8" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.3.8.tgz#37113df8e9e1421b0be1b2dca02b49b76210e7c4" + integrity sha512-4h28KCkHg5ii/wcFFJ5Fp+k1J3gJoasaIbppdgZFO4BPJnsNxL0mQXBSFgOgAdCdBj35aDTPvdAJReTMntFPGg== + dependencies: + use-sync-external-store "1.2.0"