add api methods

This commit is contained in:
nflnkr 2022-12-20 19:09:54 +03:00
parent 47d958d893
commit 7debbb4923
3 changed files with 98 additions and 4 deletions

@ -21,6 +21,7 @@
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router-dom": "^6.4.3", "react-router-dom": "^6.4.3",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"reconnecting-eventsource": "^1.6.2",
"typescript": "^4.9.3", "typescript": "^4.9.3",
"web-vitals": "^2.1.0" "web-vitals": "^2.1.0"
}, },

@ -1,8 +1,21 @@
import { RegistrationRequest, AuthenticationSuccessResponse, LoginRequest, RefreshRequest } from "./types"; import {
RegistrationRequest,
AuthenticationSuccessResponse,
LoginRequest,
RefreshRequest,
CreateTicketRequest,
CreateTicketResponse,
SendTicketMessageRequest,
GetTicketsRequest,
Ticket,
TicketMessage
} from "./types";
import ReconnectingEventSource from "reconnecting-eventsource";
class ApiRequestHandler { class ApiRequestHandler {
private apiUrl: string; private apiUrl: string;
private accessToken?: string;
constructor(apiUrl: string) { constructor(apiUrl: string) {
this.apiUrl = apiUrl; this.apiUrl = apiUrl;
@ -21,6 +34,8 @@ class ApiRequestHandler {
const result = await response.json(); const result = await response.json();
if (result.error) return new Error(result.message); if (result.error) return new Error(result.message);
this.accessToken = (result as AuthenticationSuccessResponse).accessToken;
return result as AuthenticationSuccessResponse; return result as AuthenticationSuccessResponse;
} catch (error) { } catch (error) {
return error as Error; return error as Error;
@ -39,6 +54,8 @@ class ApiRequestHandler {
const result = await response.json(); const result = await response.json();
if (result.error) return new Error(result.message); if (result.error) return new Error(result.message);
this.accessToken = (result as AuthenticationSuccessResponse).accessToken;
return result as AuthenticationSuccessResponse; return result as AuthenticationSuccessResponse;
} catch (error) { } catch (error) {
return error as Error; return error as Error;
@ -67,12 +84,83 @@ class ApiRequestHandler {
method: "POST", method: "POST",
credentials: "include" credentials: "include"
}); });
const result = await response.json(); if (response.status !== 200) return new Error(`Unexpected status code. Expected: 200, received: ${response.status}`); // TODO correct success status code
return result;
return null;
} catch (error) { } catch (error) {
return error; return error;
} }
} }
public async createTicket(request: CreateTicketRequest) {
try {
const response = await fetch(this.apiUrl + "support/create", {
method: "POST",
credentials: "include",
body: JSON.stringify(request),
headers: {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json"
},
});
const result = await response.json();
if (result.error) return new Error(result.message);
return result as CreateTicketResponse;
} catch (error) {
return error as Error;
}
}
public subscribeToAllTickets(onMessage: (e: MessageEvent<Ticket>) => void, onError: (e: Event) => void) {
if (!this.accessToken) throw new Error("Trying to subscribe to SSE without access token");
const eventSource = new ReconnectingEventSource(`support/subscribe?Authorization=${this.accessToken}`);
eventSource.addEventListener("message", onMessage);
eventSource.addEventListener("error", onError);
}
public subscribeToTicket(ticketId: string, onMessage: (e: MessageEvent<TicketMessage>) => void, onError: (e: Event) => void) {
if (!this.accessToken) throw new Error("Trying to subscribe to SSE without access token");
const eventSource = new ReconnectingEventSource(`support/ticket?ticket=${ticketId}&Authorization=${this.accessToken}`);
eventSource.addEventListener("message", onMessage);
eventSource.addEventListener("error", onError);
}
public async sendTicketMessage(request: SendTicketMessageRequest) {
try {
const response = await fetch(this.apiUrl + "support/send", {
method: "POST",
credentials: "include",
body: JSON.stringify(request),
headers: {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json"
},
});
if (response.status !== 200) return new Error(`Unexpected status code. Expected: 200, received: ${response.status}`); // TODO correct success status code
return null;
} catch (error) {
return error as Error;
}
}
public async getTickets(request: GetTicketsRequest) {
try {
const response = await fetch(this.apiUrl + "support/getTickets", {
method: "POST",
credentials: "include",
body: JSON.stringify(request),
headers: {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json"
},
});
const result = await response.json();
if (result.error) return new Error(result.message);
return result as Ticket[];
} catch (error) {
return error as Error;
}
}
} }
export const apiRequestHandler = new ApiRequestHandler("http://localhost:8080/"); export const apiRequestHandler = new ApiRequestHandler("http://localhost:8080/");

@ -7858,6 +7858,11 @@ readdirp@~3.6.0:
dependencies: dependencies:
picomatch "^2.2.1" picomatch "^2.2.1"
reconnecting-eventsource@^1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/reconnecting-eventsource/-/reconnecting-eventsource-1.6.2.tgz#b7f5b03b1c76291f6fbcb0203004892a57ae253b"
integrity sha512-vHhoxVLbA2YcfljWMKEbgR1KVTgwIrnyh/bzVJc+gfQbGcUIToLL6jNhkUL4E+9FbnAcfUVNLIw2YCiliTg/4g==
recursive-readdir@^2.2.2: recursive-readdir@^2.2.2:
version "2.2.3" version "2.2.3"
resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372"