init
This commit is contained in:
31
src/services/auth/index.ts
Normal file
31
src/services/auth/index.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { pageLinks } from '@/helpers/constants';
|
||||
import { CookiesStore, LocalStore } from '@/services/local-store';
|
||||
import { BROWSER_TOKEN_KEY } from '@/services/request';
|
||||
|
||||
class AuthService {
|
||||
store: LocalStore;
|
||||
|
||||
constructor(config: { store: LocalStore }) {
|
||||
this.store = config.store;
|
||||
}
|
||||
|
||||
getToken() {
|
||||
return this.store.get(BROWSER_TOKEN_KEY);
|
||||
}
|
||||
|
||||
login(access_token: string) {
|
||||
this.store.save(BROWSER_TOKEN_KEY, access_token);
|
||||
}
|
||||
|
||||
clearCredentials() {
|
||||
this.store.delete(BROWSER_TOKEN_KEY);
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.store.delete(BROWSER_TOKEN_KEY);
|
||||
this.store.resetStore();
|
||||
window.location.replace(pageLinks.home);
|
||||
}
|
||||
}
|
||||
|
||||
export const auth_service = new AuthService({ store: new CookiesStore() });
|
||||
29
src/services/file-service/index.ts
Normal file
29
src/services/file-service/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
class FileService {
|
||||
download(file: File, name?: string) {
|
||||
const link = document.createElement('a');
|
||||
const fileUrl = URL.createObjectURL(file);
|
||||
|
||||
link.download = name || file.name;
|
||||
link.href = fileUrl;
|
||||
link.click();
|
||||
|
||||
URL.revokeObjectURL(fileUrl);
|
||||
}
|
||||
|
||||
downloadByDisposition(disposition: string, blob: Blob) {
|
||||
const fileUrl = URL.createObjectURL(blob);
|
||||
const contentDisposition = disposition;
|
||||
const filename = contentDisposition.split('filename=')[1] as string;
|
||||
|
||||
const downloadFileName = filename.slice(1, filename.length - 1);
|
||||
|
||||
const link = document.createElement('a');
|
||||
link.download = downloadFileName;
|
||||
link.href = fileUrl;
|
||||
link.click();
|
||||
|
||||
URL.revokeObjectURL(fileUrl);
|
||||
}
|
||||
}
|
||||
|
||||
export const file_service = new FileService();
|
||||
23
src/services/local-store/CookiesStore.ts
Normal file
23
src/services/local-store/CookiesStore.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { LocalStore } from '@/services/local-store';
|
||||
import { setCookie, getCookie, deleteCookie, hasCookie } from 'cookies-next';
|
||||
|
||||
export class CookiesStore implements LocalStore {
|
||||
get(key: string) {
|
||||
if (hasCookie(key)) {
|
||||
return getCookie(key);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
save(key: string, data: string) {
|
||||
setCookie(key, data, {
|
||||
expires: new Date('2099.01.01'),
|
||||
});
|
||||
}
|
||||
delete(key: string) {
|
||||
deleteCookie(key);
|
||||
}
|
||||
resetStore() {
|
||||
document.cookie = '';
|
||||
}
|
||||
}
|
||||
16
src/services/local-store/LocalStorageStore.ts
Normal file
16
src/services/local-store/LocalStorageStore.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { LocalStore } from '@/services/local-store';
|
||||
|
||||
export class LocalStorageStore implements LocalStore {
|
||||
get(key: string) {
|
||||
return localStorage.getItem(key);
|
||||
}
|
||||
save(key: string, data: string) {
|
||||
localStorage.setItem(key, data);
|
||||
}
|
||||
delete(key: string) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
resetStore() {
|
||||
localStorage.clear();
|
||||
}
|
||||
}
|
||||
9
src/services/local-store/index.ts
Normal file
9
src/services/local-store/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export interface LocalStore {
|
||||
save: (key: string, data: string) => void;
|
||||
get: (key: string) => any;
|
||||
delete: (key: string) => void;
|
||||
resetStore: () => void;
|
||||
}
|
||||
|
||||
export { CookiesStore } from './CookiesStore';
|
||||
export { LocalStorageStore } from './LocalStorageStore';
|
||||
62
src/services/notification/index.ts
Normal file
62
src/services/notification/index.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { AxiosError } from 'axios';
|
||||
import get from 'lodash.get';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
export async function tryToGetErrorMessage(error: unknown): Promise<string> {
|
||||
if (error instanceof Error || error instanceof AxiosError || typeof error === 'string') {
|
||||
try {
|
||||
if (error instanceof AxiosError) {
|
||||
const errMsg = get(error, 'response.data.message');
|
||||
if (typeof errMsg === 'string') {
|
||||
return errMsg;
|
||||
} else if (error instanceof AxiosError && get(error, 'response.data.type') === 'application/json') {
|
||||
const jsonBlob = get(error, 'response.data');
|
||||
const responseData = JSON.parse(await jsonBlob.text());
|
||||
const parsedErrText = get(responseData, 'message');
|
||||
return parsedErrText;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('tryToGetErrorMessage error happened: ', err);
|
||||
}
|
||||
return error.toString();
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function notifySuccess(msg: string) {
|
||||
toast.success(msg.toString());
|
||||
}
|
||||
|
||||
async function notifyError(msg: string | Error | AxiosError) {
|
||||
const errorText = await tryToGetErrorMessage(msg);
|
||||
toast.error(errorText);
|
||||
|
||||
// try {
|
||||
// if (msg instanceof AxiosError) {
|
||||
// const errMsg = get(msg, 'response.data.message');
|
||||
// if (typeof errMsg === 'string') {
|
||||
// toast.error(errMsg);
|
||||
// return;
|
||||
// } else if (msg instanceof AxiosError && get(msg, 'response.data.type') === 'application/json') {
|
||||
// const jsonBlob = get(msg, 'response.data');
|
||||
// const responseData = JSON.parse(await jsonBlob.text());
|
||||
// const parsedErrText = get(responseData, 'message');
|
||||
// toast.error(parsedErrText);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// } catch (_) {}
|
||||
// toast.error(msg.toString());
|
||||
}
|
||||
|
||||
function notifyUnknownError(msg: unknown) {
|
||||
if (msg instanceof Error || msg instanceof AxiosError || typeof msg === 'string') {
|
||||
notifyError(msg);
|
||||
} else {
|
||||
console.error('UNKNOWN ERROR: ', msg);
|
||||
}
|
||||
}
|
||||
|
||||
export { notifySuccess, notifyError, notifyUnknownError };
|
||||
5
src/services/request/constants.ts
Normal file
5
src/services/request/constants.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
const backendURL = process.env.NEXT_PUBLIC_API_URL;
|
||||
const isServer = () => typeof window === 'undefined';
|
||||
const BROWSER_TOKEN_KEY = 'C_POST_TOKEN';
|
||||
|
||||
export { BROWSER_TOKEN_KEY, backendURL, isServer };
|
||||
2
src/services/request/index.ts
Normal file
2
src/services/request/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as request } from './request';
|
||||
export * from './constants';
|
||||
38
src/services/request/request.ts
Normal file
38
src/services/request/request.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { BROWSER_TOKEN_KEY, backendURL, isServer } from '@/services/request/constants';
|
||||
import axios, { AxiosError, AxiosResponse } from 'axios';
|
||||
import { getCookie } from 'cookies-next';
|
||||
|
||||
const request = axios.create({
|
||||
baseURL: backendURL + '/api/v1',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
request.interceptors.request.use(async config => {
|
||||
if (isServer()) {
|
||||
const { cookies } = await import('next/headers');
|
||||
const token = cookies().get(BROWSER_TOKEN_KEY)?.value;
|
||||
|
||||
if (token) {
|
||||
config.headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
} else {
|
||||
if (getCookie(BROWSER_TOKEN_KEY)) {
|
||||
config.headers['Authorization'] = config.headers['Authorization'] || `Bearer ${getCookie(BROWSER_TOKEN_KEY)}`;
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
});
|
||||
|
||||
request.interceptors.response.use(
|
||||
async (response: AxiosResponse) => {
|
||||
return response;
|
||||
},
|
||||
async (error: AxiosError) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default request;
|
||||
12
src/services/ssr/commonGetStaticProps.ts
Normal file
12
src/services/ssr/commonGetStaticProps.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { GetStaticProps } from 'next';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
|
||||
const commonGetStaticProps: GetStaticProps = async ({ locale }) => {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale || 'en', ['common'])),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export { commonGetStaticProps };
|
||||
Reference in New Issue
Block a user