next-recomponents 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +122 -0
- package/dist/index.d.ts +122 -0
- package/dist/index.js +50922 -0
- package/dist/index.mjs +50909 -0
- package/package.json +18 -0
- package/src/alert/index.tsx +24 -0
- package/src/button/colors.tsx +9 -0
- package/src/button/index.tsx +42 -0
- package/src/container/icons.tsx +65 -0
- package/src/container/index.tsx +175 -0
- package/src/form/index.tsx +95 -0
- package/src/index.tsx +10 -0
- package/src/input/index.tsx +43 -0
- package/src/regular-expresions/index.ts +11 -0
- package/src/select/close.tsx +15 -0
- package/src/select/icon.tsx +15 -0
- package/src/select/index.tsx +212 -0
- package/src/table/export.tsx +29 -0
- package/src/table/filter.menu.tsx +188 -0
- package/src/table/filters.tsx +77 -0
- package/src/table/h.tsx +185 -0
- package/src/table/index.tsx +55 -0
- package/src/table/td.tsx +75 -0
- package/src/text-area/index.tsx +52 -0
- package/src/use-resources/encode.decode.tsx +25 -0
- package/src/use-resources/functions.ts +0 -0
- package/src/use-resources/get.token.tsx +15 -0
- package/src/use-resources/http.codes.ts +77 -0
- package/src/use-resources/index.ts +189 -0
- package/src/use-resources/types.ts +41 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ReactNode, useState } from "react";
|
|
2
|
+
import HTable from "./h";
|
|
3
|
+
import useExport from "./export";
|
|
4
|
+
import { ExcelIcon } from "./filters";
|
|
5
|
+
|
|
6
|
+
export interface TableProps
|
|
7
|
+
extends React.DetailedHTMLProps<
|
|
8
|
+
React.TableHTMLAttributes<HTMLTableElement>,
|
|
9
|
+
HTMLTableElement
|
|
10
|
+
> {
|
|
11
|
+
data: Record<string, any> | Array<Record<string, any>>;
|
|
12
|
+
dataTypes?: Record<string, any>;
|
|
13
|
+
mapedData?: any;
|
|
14
|
+
setMapedData?: any;
|
|
15
|
+
totals?: Array<string>;
|
|
16
|
+
symbols?: Record<string, ReactNode>;
|
|
17
|
+
exportName?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default function Table(props: TableProps) {
|
|
21
|
+
const [mapedData, setMapedData] = useState([]);
|
|
22
|
+
const isArray = Array.isArray(props.data);
|
|
23
|
+
const exported = useExport();
|
|
24
|
+
return (
|
|
25
|
+
<div className="bg-gray-200 border rounded shadow p-1">
|
|
26
|
+
{props?.exportName && (
|
|
27
|
+
<button
|
|
28
|
+
className="p-2 border rounded shadow bg-green-800 text-white flex gap-1"
|
|
29
|
+
onClick={(e) =>
|
|
30
|
+
exported.export(
|
|
31
|
+
mapedData.map((md: any) => {
|
|
32
|
+
for (let i of Object.keys(md)) {
|
|
33
|
+
md[i] = md[i].content;
|
|
34
|
+
}
|
|
35
|
+
return md;
|
|
36
|
+
}),
|
|
37
|
+
props.exportName
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
>
|
|
41
|
+
<ExcelIcon /> Exportar
|
|
42
|
+
</button>
|
|
43
|
+
)}
|
|
44
|
+
{isArray && (
|
|
45
|
+
<HTable
|
|
46
|
+
{...{
|
|
47
|
+
...props,
|
|
48
|
+
mapedData,
|
|
49
|
+
setMapedData,
|
|
50
|
+
}}
|
|
51
|
+
/>
|
|
52
|
+
)}
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
}
|
package/src/table/td.tsx
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import React, { useMemo, useState } from "react";
|
|
2
|
+
import { EditIcon } from "./filters";
|
|
3
|
+
|
|
4
|
+
interface TDProps
|
|
5
|
+
extends React.DetailedHTMLProps<
|
|
6
|
+
React.TdHTMLAttributes<HTMLTableCellElement>,
|
|
7
|
+
HTMLTableCellElement
|
|
8
|
+
> {
|
|
9
|
+
index: number;
|
|
10
|
+
item: { cellTypeOf: string; content: string; title: string; name: string };
|
|
11
|
+
color: string;
|
|
12
|
+
symbols: Record<string, any> | undefined;
|
|
13
|
+
}
|
|
14
|
+
export default function TD({
|
|
15
|
+
className,
|
|
16
|
+
item,
|
|
17
|
+
index,
|
|
18
|
+
color,
|
|
19
|
+
symbols,
|
|
20
|
+
|
|
21
|
+
...props
|
|
22
|
+
}: TDProps) {
|
|
23
|
+
const [isHidded, setIsHidded] = useState(false);
|
|
24
|
+
const isNode = useMemo(() => {
|
|
25
|
+
return (
|
|
26
|
+
symbols &&
|
|
27
|
+
typeof symbols[item.name] == "object" &&
|
|
28
|
+
symbols[item.name]?.props
|
|
29
|
+
);
|
|
30
|
+
}, [symbols]);
|
|
31
|
+
const newProps =
|
|
32
|
+
symbols &&
|
|
33
|
+
isNode &&
|
|
34
|
+
Object.keys(symbols[item.name].props).reduce(
|
|
35
|
+
(acc: any, i) => {
|
|
36
|
+
try {
|
|
37
|
+
const newAcc = { ...acc };
|
|
38
|
+
const hasEvent = `${i}`.startsWith("on");
|
|
39
|
+
if (hasEvent) {
|
|
40
|
+
newAcc[i] = (e: any) => {
|
|
41
|
+
e.item = item;
|
|
42
|
+
symbols[item.name].props[i]?.(e);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return newAcc;
|
|
46
|
+
} catch (error) {}
|
|
47
|
+
},
|
|
48
|
+
{ defaultValue: item.content }
|
|
49
|
+
);
|
|
50
|
+
return (
|
|
51
|
+
<td
|
|
52
|
+
onDoubleClick={(e) => setIsHidded(!isHidded)}
|
|
53
|
+
title={item.title}
|
|
54
|
+
className={[
|
|
55
|
+
isHidded && color,
|
|
56
|
+
!isHidded && "whitespace-nowrap overflow-hidden text-ellipsis ",
|
|
57
|
+
"border-b max-w-[200px] p-5 ",
|
|
58
|
+
["number", "money"].includes(item.cellTypeOf) && "text-right",
|
|
59
|
+
].join(" ")}
|
|
60
|
+
>
|
|
61
|
+
<div className={symbols && symbols[item.name] && "flex justify-between"}>
|
|
62
|
+
<div>
|
|
63
|
+
{symbols &&
|
|
64
|
+
symbols[item.name] &&
|
|
65
|
+
(isNode
|
|
66
|
+
? React.cloneElement(symbols[item.name], {
|
|
67
|
+
...newProps,
|
|
68
|
+
})
|
|
69
|
+
: symbols[item.name])}
|
|
70
|
+
</div>
|
|
71
|
+
<div>{item.content}</div>
|
|
72
|
+
</div>
|
|
73
|
+
</td>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
DetailedHTMLProps,
|
|
3
|
+
TextareaHTMLAttributes,
|
|
4
|
+
useState,
|
|
5
|
+
} from "react";
|
|
6
|
+
|
|
7
|
+
interface Props
|
|
8
|
+
extends DetailedHTMLProps<
|
|
9
|
+
TextareaHTMLAttributes<HTMLTextAreaElement>,
|
|
10
|
+
HTMLTextAreaElement
|
|
11
|
+
> {
|
|
12
|
+
label?: React.ReactNode;
|
|
13
|
+
maxLength?: number;
|
|
14
|
+
}
|
|
15
|
+
export default function TextArea({
|
|
16
|
+
label,
|
|
17
|
+
className,
|
|
18
|
+
maxLength,
|
|
19
|
+
onChange,
|
|
20
|
+
children = "",
|
|
21
|
+
...props
|
|
22
|
+
}: Props) {
|
|
23
|
+
const [value, setValue] = useState<string>(children as string);
|
|
24
|
+
return (
|
|
25
|
+
<div className="w-full">
|
|
26
|
+
<label className="flex flex-col gap-1">
|
|
27
|
+
<div className="font-bold ">{label}</div>
|
|
28
|
+
<div>
|
|
29
|
+
<textarea
|
|
30
|
+
{...props}
|
|
31
|
+
className={["p-1 w-full rounded border shadow", className].join(
|
|
32
|
+
" "
|
|
33
|
+
)}
|
|
34
|
+
onChange={(e) => {
|
|
35
|
+
if (maxLength) {
|
|
36
|
+
e.target.value = e.target.value.slice(0, maxLength);
|
|
37
|
+
}
|
|
38
|
+
setValue(e.target.value);
|
|
39
|
+
onChange?.(e);
|
|
40
|
+
}}
|
|
41
|
+
value={value}
|
|
42
|
+
></textarea>
|
|
43
|
+
{maxLength && (
|
|
44
|
+
<div className=" text-xs text-gray text-right">
|
|
45
|
+
{value.length} / {maxLength}
|
|
46
|
+
</div>
|
|
47
|
+
)}
|
|
48
|
+
</div>
|
|
49
|
+
</label>
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import CryptoJS from "crypto-js";
|
|
3
|
+
import useToken from "./get.token";
|
|
4
|
+
// import { config } from "dotenv";
|
|
5
|
+
// config();
|
|
6
|
+
|
|
7
|
+
export const encryptData = (data: object, secretKey: string): string => {
|
|
8
|
+
const stringData = JSON.stringify(data);
|
|
9
|
+
const encriptedText = CryptoJS.AES.encrypt(stringData, secretKey).toString();
|
|
10
|
+
window.localStorage.setItem("resources", encriptedText);
|
|
11
|
+
return encriptedText;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const decryptData = (secretKey: string): any => {
|
|
15
|
+
const ciphertext = window.localStorage.getItem("resources");
|
|
16
|
+
if (!ciphertext) return null;
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const bytes = CryptoJS.AES.decrypt(ciphertext, secretKey);
|
|
20
|
+
const decrypted = bytes.toString(CryptoJS.enc.Utf8);
|
|
21
|
+
return JSON.parse(decrypted);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
|
|
3
|
+
export default function useToken(): string {
|
|
4
|
+
const token = useMemo(() => {
|
|
5
|
+
if (typeof window != "undefined") {
|
|
6
|
+
const t = window.localStorage.getItem("token");
|
|
7
|
+
if (!t) throw Error("Token undefined");
|
|
8
|
+
|
|
9
|
+
return t;
|
|
10
|
+
}
|
|
11
|
+
return "";
|
|
12
|
+
}, [typeof window]);
|
|
13
|
+
|
|
14
|
+
return token;
|
|
15
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const httpStatusCodes = [
|
|
2
|
+
{
|
|
3
|
+
code: 100,
|
|
4
|
+
meaning:
|
|
5
|
+
"Continue: El servidor ha recibido los encabezados y el cliente debe continuar con la solicitud.",
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
code: 101,
|
|
9
|
+
meaning: "Switching Protocols: El servidor acepta cambiar de protocolo.",
|
|
10
|
+
},
|
|
11
|
+
{ code: 200, meaning: "OK: La solicitud fue exitosa." },
|
|
12
|
+
{ code: 201, meaning: "Created: Recurso creado exitosamente." },
|
|
13
|
+
{
|
|
14
|
+
code: 202,
|
|
15
|
+
meaning: "Accepted: La solicitud ha sido aceptada pero aún no procesada.",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
code: 204,
|
|
19
|
+
meaning: "No Content: Éxito, pero sin contenido para devolver.",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
code: 301,
|
|
23
|
+
meaning: "Moved Permanently: El recurso se ha movido de forma permanente.",
|
|
24
|
+
},
|
|
25
|
+
{ code: 302, meaning: "Found: El recurso se ha movido temporalmente." },
|
|
26
|
+
{
|
|
27
|
+
code: 304,
|
|
28
|
+
meaning:
|
|
29
|
+
"Not Modified: El recurso no ha cambiado desde la última solicitud.",
|
|
30
|
+
},
|
|
31
|
+
{ code: 400, meaning: "Bad Request: La solicitud es inválida." },
|
|
32
|
+
{
|
|
33
|
+
code: 401,
|
|
34
|
+
meaning: "Unauthorized: No autorizado. Puede requerir autenticación.",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
code: 403,
|
|
38
|
+
meaning: "Forbidden: Acceso denegado, aunque estés autenticado.",
|
|
39
|
+
},
|
|
40
|
+
{ code: 404, meaning: "Not Found: Recurso no encontrado." },
|
|
41
|
+
{
|
|
42
|
+
code: 405,
|
|
43
|
+
meaning: "Method Not Allowed: Método HTTP no permitido para este recurso.",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
code: 409,
|
|
47
|
+
meaning: "Conflict: Conflicto con el estado actual del recurso.",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
code: 422,
|
|
51
|
+
meaning:
|
|
52
|
+
"Unprocessable Entity: La solicitud está bien formada pero tiene errores semánticos.",
|
|
53
|
+
},
|
|
54
|
+
{ code: 429, meaning: "Too Many Requests: Límite de peticiones excedido." },
|
|
55
|
+
{ code: 500, meaning: "Internal Server Error: Error en el servidor." },
|
|
56
|
+
{
|
|
57
|
+
code: 501,
|
|
58
|
+
meaning: "Not Implemented: El servidor no reconoce el método solicitado.",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
code: 502,
|
|
62
|
+
meaning:
|
|
63
|
+
"Bad Gateway: El servidor recibió una respuesta inválida del servidor upstream.",
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
code: 503,
|
|
67
|
+
meaning:
|
|
68
|
+
"Service Unavailable: El servidor no está disponible temporalmente.",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
code: 504,
|
|
72
|
+
meaning:
|
|
73
|
+
"Gateway Timeout: Tiempo de espera agotado desde el servidor upstream.",
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
export default httpStatusCodes;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { EnhancedEndpoints, ItemsRecord, Props, ShowOptions } from "./types";
|
|
3
|
+
import useToken from "./get.token";
|
|
4
|
+
import axios from "axios";
|
|
5
|
+
import httpStatusCodes from "./http.codes";
|
|
6
|
+
import { useRouter } from "next/navigation";
|
|
7
|
+
|
|
8
|
+
export default function useResources<T extends Record<string, ItemsRecord>>({
|
|
9
|
+
baseURI,
|
|
10
|
+
authURI = "/auth/login",
|
|
11
|
+
endpoints,
|
|
12
|
+
}: Props) {
|
|
13
|
+
const token = useToken();
|
|
14
|
+
const router = useRouter();
|
|
15
|
+
const [info, setInfo] = useState<Record<string, any>>({});
|
|
16
|
+
|
|
17
|
+
const result = useMemo(() => {
|
|
18
|
+
const r = {} as EnhancedEndpoints<T>;
|
|
19
|
+
|
|
20
|
+
for (const key in endpoints) {
|
|
21
|
+
const endpoint = endpoints[key];
|
|
22
|
+
const showFunc = async ({
|
|
23
|
+
limit = 10,
|
|
24
|
+
page = 1,
|
|
25
|
+
merge = true,
|
|
26
|
+
...query
|
|
27
|
+
}: ShowOptions) => {
|
|
28
|
+
const options = {
|
|
29
|
+
method: "GET",
|
|
30
|
+
url: `${baseURI}/${key}`,
|
|
31
|
+
params: { limit, page, ...query },
|
|
32
|
+
headers: { Authorization: token },
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const newInfo = { ...info };
|
|
36
|
+
newInfo[key] = newInfo[key] || {};
|
|
37
|
+
newInfo[key].state = "loading";
|
|
38
|
+
newInfo[key].errorMessage = "";
|
|
39
|
+
newInfo[key].params = query;
|
|
40
|
+
|
|
41
|
+
setInfo(newInfo);
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const consulta = await axios.request(options);
|
|
45
|
+
const d = consulta.data;
|
|
46
|
+
newInfo[key].state = "success";
|
|
47
|
+
newInfo[key].errorMessage = "";
|
|
48
|
+
newInfo[key].data = merge
|
|
49
|
+
? page == 1
|
|
50
|
+
? d.data
|
|
51
|
+
: [...d.data, ...(newInfo[key].data || [])]
|
|
52
|
+
: d.data;
|
|
53
|
+
newInfo[key].totalItems = d.totalItems;
|
|
54
|
+
newInfo[key].totalPages = d.totalPages;
|
|
55
|
+
newInfo[key].currentPage = d.currentPage;
|
|
56
|
+
setInfo({ ...newInfo });
|
|
57
|
+
return d.data;
|
|
58
|
+
} catch (error: any) {
|
|
59
|
+
const item = httpStatusCodes.find((s) => s.code == error.status);
|
|
60
|
+
|
|
61
|
+
newInfo[key].state = "error";
|
|
62
|
+
newInfo[key].errorMessage = item?.meaning;
|
|
63
|
+
if (error.status == 403) {
|
|
64
|
+
router.push(authURI);
|
|
65
|
+
}
|
|
66
|
+
setInfo({ ...newInfo });
|
|
67
|
+
return error;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
(r as any)[key] = {
|
|
71
|
+
...endpoint,
|
|
72
|
+
show: showFunc,
|
|
73
|
+
find: async (id: number, query: any) => {
|
|
74
|
+
const options = {
|
|
75
|
+
method: "GET",
|
|
76
|
+
url: `${baseURI}/${key}/${id}`,
|
|
77
|
+
params: { ...query },
|
|
78
|
+
headers: { Authorization: token },
|
|
79
|
+
};
|
|
80
|
+
const newInfo = { ...info };
|
|
81
|
+
newInfo[key] = newInfo[key] || {};
|
|
82
|
+
newInfo[key].state = "loading";
|
|
83
|
+
newInfo[key].errorMessage = "";
|
|
84
|
+
newInfo[key].params = query;
|
|
85
|
+
|
|
86
|
+
setInfo(newInfo);
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
const consulta = await axios.request(options);
|
|
90
|
+
const d = consulta.data;
|
|
91
|
+
newInfo[key].state = "success";
|
|
92
|
+
newInfo[key].errorMessage = "";
|
|
93
|
+
newInfo[key].selectedItem = d;
|
|
94
|
+
const index = newInfo[key]?.data?.findIndex(
|
|
95
|
+
(d: any) => d?.id == d?.id
|
|
96
|
+
);
|
|
97
|
+
if (index >= 0) {
|
|
98
|
+
newInfo[key].data[index] = d;
|
|
99
|
+
} else {
|
|
100
|
+
if (newInfo[key]?.data) {
|
|
101
|
+
newInfo[key].data.unshift(d);
|
|
102
|
+
} else {
|
|
103
|
+
newInfo[key].data = [d];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
setInfo({ ...newInfo });
|
|
107
|
+
return d.data;
|
|
108
|
+
} catch (error: any) {
|
|
109
|
+
const item = httpStatusCodes.find((s) => s.code == error.status);
|
|
110
|
+
|
|
111
|
+
newInfo[key].state = "error";
|
|
112
|
+
newInfo[key].errorMessage = item?.meaning || error.message;
|
|
113
|
+
if (error.status == 403) {
|
|
114
|
+
router.push(authURI);
|
|
115
|
+
}
|
|
116
|
+
setInfo({ ...newInfo });
|
|
117
|
+
return error;
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
create: async (data: any) => {
|
|
121
|
+
const options = {
|
|
122
|
+
method: "POST",
|
|
123
|
+
url: `${baseURI}/${key}`,
|
|
124
|
+
data: { ...data },
|
|
125
|
+
headers: { Authorization: token },
|
|
126
|
+
};
|
|
127
|
+
const newInfo = { ...info };
|
|
128
|
+
newInfo[key] = newInfo[key] || {};
|
|
129
|
+
newInfo[key].state = "loading";
|
|
130
|
+
newInfo[key].errorMessage = "";
|
|
131
|
+
|
|
132
|
+
setInfo(newInfo);
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
const consulta = await axios.request(options);
|
|
136
|
+
const d = consulta.data;
|
|
137
|
+
newInfo[key].state = "success";
|
|
138
|
+
newInfo[key].errorMessage = "";
|
|
139
|
+
newInfo[key].selectedItem = d;
|
|
140
|
+
const index = newInfo[key]?.data?.findIndex(
|
|
141
|
+
(d: any) => d?.id == d?.id
|
|
142
|
+
);
|
|
143
|
+
if (index >= 0) {
|
|
144
|
+
newInfo[key].data[index] = d;
|
|
145
|
+
} else {
|
|
146
|
+
if (newInfo[key]?.data) {
|
|
147
|
+
newInfo[key].data.unshift(d);
|
|
148
|
+
} else {
|
|
149
|
+
newInfo[key].data = [d];
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
setInfo({ ...newInfo });
|
|
153
|
+
return d.data;
|
|
154
|
+
} catch (error: any) {
|
|
155
|
+
const item = httpStatusCodes.find((s) => s.code == error.status);
|
|
156
|
+
|
|
157
|
+
newInfo[key].state = "error";
|
|
158
|
+
newInfo[key].errorMessage = item?.meaning || error.message;
|
|
159
|
+
if (error.status == 403) {
|
|
160
|
+
router.push(authURI);
|
|
161
|
+
}
|
|
162
|
+
setInfo({ ...newInfo });
|
|
163
|
+
return error;
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
update: async (id: number, data: any) => {
|
|
167
|
+
console.log("update", id, data);
|
|
168
|
+
},
|
|
169
|
+
remove: async (id: number) => {
|
|
170
|
+
console.log("remove", id);
|
|
171
|
+
},
|
|
172
|
+
totalPages: info[key]?.totalPages,
|
|
173
|
+
currentPage: info[key]?.currentPage,
|
|
174
|
+
state: info[key]?.state || "success",
|
|
175
|
+
errorMessage: info[key]?.errorMessage,
|
|
176
|
+
params: info[key]?.params,
|
|
177
|
+
getAllPages: async (limit = 10) => {
|
|
178
|
+
console.log("Not aviable");
|
|
179
|
+
},
|
|
180
|
+
data: info[key]?.data || [],
|
|
181
|
+
selectedItem: info[key]?.selectedItem || {},
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return r;
|
|
186
|
+
}, [info, token, endpoints]);
|
|
187
|
+
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface ItemsRecord {
|
|
2
|
+
typeof: Object;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export interface Props {
|
|
6
|
+
baseURI: string;
|
|
7
|
+
authURI?: string;
|
|
8
|
+
endpoints: Record<string, Partial<ItemsRecord>>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ShowOptions {
|
|
12
|
+
limit?: number;
|
|
13
|
+
merge?: boolean;
|
|
14
|
+
page?: number;
|
|
15
|
+
[key: string | number]: string | number | undefined | null | boolean;
|
|
16
|
+
}
|
|
17
|
+
export type EnhancedEndpoints<T extends Record<string, ItemsRecord>> = {
|
|
18
|
+
[K in keyof T]: {
|
|
19
|
+
typeof: T[K]["typeof"];
|
|
20
|
+
state: "success" | "loading" | "error";
|
|
21
|
+
show: (props: ShowOptions) => Promise<Array<T[K]["typeof"]>>;
|
|
22
|
+
create: (data: Partial<T[K]["typeof"]>) => Promise<T[K]["typeof"]>;
|
|
23
|
+
update: (
|
|
24
|
+
id: number | string,
|
|
25
|
+
data: Partial<T[K]["typeof"]>
|
|
26
|
+
) => Promise<T[K]["typeof"]>;
|
|
27
|
+
remove: (id: number | string) => Promise<T[K]["typeof"]>;
|
|
28
|
+
find: (
|
|
29
|
+
id: number | string,
|
|
30
|
+
props?: Record<string, string>
|
|
31
|
+
) => Promise<T[K]["typeof"]>;
|
|
32
|
+
getAllPages: (limit: number) => Promise<Array<T[K]["typeof"]>>;
|
|
33
|
+
data: T[K]["typeof"][];
|
|
34
|
+
selectedItem: T[K]["typeof"];
|
|
35
|
+
params: Record<string, any>;
|
|
36
|
+
currentPage: number;
|
|
37
|
+
totalItems: number;
|
|
38
|
+
totalPages: number;
|
|
39
|
+
errorMessage: string;
|
|
40
|
+
};
|
|
41
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES6",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"jsx": "react-jsx",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"moduleResolution": "node",
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"strict": true,
|
|
12
|
+
"baseUrl": "."
|
|
13
|
+
},
|
|
14
|
+
"include": ["src"]
|
|
15
|
+
}
|