izen-react-starter 2.3.7 → 2.4.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/README.md +121 -0
- package/dist/{2SSKDMRQ-BWxJ7KHy.js → 2SSKDMRQ-D50rlKfr.js} +2 -2
- package/dist/{AP7HFJJL-uVnY5RPz.js → AP7HFJJL-B_liWFpt.js} +1 -1
- package/dist/{WDYDFRGG-Pjnjsi2V.js → WDYDFRGG-Cml_4Hf-.js} +2 -2
- package/dist/components/form/FormLayout.d.ts +1 -3
- package/dist/components/form/FormLayout.d.ts.map +1 -1
- package/dist/components/form/inputs/FileUpload.d.ts +1 -1
- package/dist/components/form/inputs/FileUpload.d.ts.map +1 -1
- package/dist/{index-BWKXTVrJ.js → index-Gs1Xd6jo.js} +10910 -10938
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/api/axios/hooks/useAxiosAuth.d.ts +1 -1
- package/dist/lib/api/axios/hooks/useAxiosAuth.d.ts.map +1 -1
- package/dist/lib/api/queries/generic.d.ts +2 -99
- package/dist/lib/api/queries/generic.d.ts.map +1 -1
- package/dist/lib/api/queries/index.d.ts +0 -1
- package/dist/lib/api/queries/index.d.ts.map +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +28 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/react-starter.js +1 -1
- package/dist/react-starter.umd.cjs +222 -222
- package/dist/services/apiService.d.ts +7 -0
- package/dist/services/apiService.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -681,6 +681,127 @@ export function UsersPage() {
|
|
|
681
681
|
```
|
|
682
682
|
> **Tip:** You only need to set the baseURL once per app session. After that, all requests will use this base URL automatically. The token will always be injected from AuthProvider for every request.
|
|
683
683
|
|
|
684
|
+
#### Refresh token endpoint (optional)
|
|
685
|
+
|
|
686
|
+
If your backend uses a refresh endpoint, set it alongside the base URL so auth-aware hooks can reuse it:
|
|
687
|
+
|
|
688
|
+
```tsx
|
|
689
|
+
import { useEffect } from 'react';
|
|
690
|
+
import { useApiService } from 'izen-react-starter';
|
|
691
|
+
|
|
692
|
+
function App() {
|
|
693
|
+
const apiService = useApiService();
|
|
694
|
+
|
|
695
|
+
useEffect(() => {
|
|
696
|
+
apiService.setBaseURL('https://api.example.com');
|
|
697
|
+
apiService.setRefreshTokenUrl('/auth/refresh');
|
|
698
|
+
}, [apiService]);
|
|
699
|
+
|
|
700
|
+
return <YourApp />;
|
|
701
|
+
}
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### Auth Axios hook (useAxiosAuth)
|
|
705
|
+
|
|
706
|
+
`useAxiosAuth` returns an axios instance with auth interceptors and automatic token refresh. It uses the `baseURL` and optional refresh URL you set on `apiService`.
|
|
707
|
+
|
|
708
|
+
```tsx
|
|
709
|
+
import { useEffect } from 'react';
|
|
710
|
+
import { useApiService } from 'izen-react-starter';
|
|
711
|
+
import { useAxiosAuth } from 'izen-react-starter';
|
|
712
|
+
|
|
713
|
+
function Profile() {
|
|
714
|
+
const apiService = useApiService();
|
|
715
|
+
|
|
716
|
+
// Ensure base URL (and refresh URL if needed) are set once
|
|
717
|
+
useEffect(() => {
|
|
718
|
+
apiService.setBaseURL('https://api.example.com');
|
|
719
|
+
apiService.setRefreshTokenUrl('/auth/refresh');
|
|
720
|
+
}, [apiService]);
|
|
721
|
+
|
|
722
|
+
const axiosAuth = useAxiosAuth();
|
|
723
|
+
|
|
724
|
+
const loadProfile = async () => {
|
|
725
|
+
const res = await axiosAuth.get('/me');
|
|
726
|
+
return res.data;
|
|
727
|
+
};
|
|
728
|
+
|
|
729
|
+
// ...use loadProfile inside effects or react-query
|
|
730
|
+
return null;
|
|
731
|
+
}
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
### Generic queries (useGet / useGetSingle)
|
|
735
|
+
|
|
736
|
+
React Query wrappers that reuse the auth axios instance. Make sure `apiService` has a base URL set before calling them.
|
|
737
|
+
|
|
738
|
+
```tsx
|
|
739
|
+
import { useEffect } from 'react';
|
|
740
|
+
import { useApiService, useGet, useGetSingle } from 'izen-react-starter';
|
|
741
|
+
|
|
742
|
+
function UsersScreen() {
|
|
743
|
+
const apiService = useApiService();
|
|
744
|
+
|
|
745
|
+
useEffect(() => {
|
|
746
|
+
apiService.setBaseURL('https://api.example.com');
|
|
747
|
+
}, [apiService]);
|
|
748
|
+
|
|
749
|
+
const usersQuery = useGet<{ id: string; name: string }>('/users');
|
|
750
|
+
const userQuery = useGetSingle<{ id: string; name: string }>(`/users/${usersQuery.data?.[0]?.id}`, undefined, undefined, '/users/1');
|
|
751
|
+
|
|
752
|
+
if (usersQuery.isLoading) return <div>Loading users...</div>;
|
|
753
|
+
if (usersQuery.error) return <div>Error: {String(usersQuery.error)}</div>;
|
|
754
|
+
|
|
755
|
+
return (
|
|
756
|
+
<div>
|
|
757
|
+
{usersQuery.data?.map((u) => (
|
|
758
|
+
<div key={u.id}>{u.name}</div>
|
|
759
|
+
))}
|
|
760
|
+
<div>User detail: {userQuery.data?.name}</div>
|
|
761
|
+
</div>
|
|
762
|
+
);
|
|
763
|
+
}
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
### Utility helpers (payload, time, HTML)
|
|
767
|
+
|
|
768
|
+
These utilities are exported from `izen-react-starter/lib`:
|
|
769
|
+
|
|
770
|
+
- `formatPayloadForEndpoint` (alias: `formatAxiosData`) — normalize payloads per endpoint (e.g., multipart for file-heavy routes, boolean fixes, role permissions, employee shifts).
|
|
771
|
+
- `buildMultipartFormData`, `buildRolePermissionsFormData`, `buildEmployeeShiftFormData` — helpers used by `formatPayloadForEndpoint` that you can also call directly.
|
|
772
|
+
- `removeHtmlTags` — strip HTML tags from strings.
|
|
773
|
+
- Time helpers: `parseTimeToMilliseconds`, `diffHoursFromTimestamps` (alias: `TimeDiffHours`), `subtractTimeStrings`, `sumTimeStrings`, `formatSecondsToHms` (aliases: `secondsToTime`, `formatTimeStr`).
|
|
774
|
+
- Date helpers: `toUTCDateString`/`toUTCDateTimeString`, `getWeekRange` (alias: `getWeekBounds`).
|
|
775
|
+
|
|
776
|
+
Example payload formatting:
|
|
777
|
+
|
|
778
|
+
```ts
|
|
779
|
+
import { formatPayloadForEndpoint } from 'izen-react-starter/lib';
|
|
780
|
+
|
|
781
|
+
// Multipart for file upload endpoints
|
|
782
|
+
const payload = { name: 'Test', image: myFile };
|
|
783
|
+
const body = formatPayloadForEndpoint(payload, '/lessons');
|
|
784
|
+
await axios.post('/lessons', body);
|
|
785
|
+
|
|
786
|
+
// Role permissions (only true values become permissions[])
|
|
787
|
+
const roleBody = formatPayloadForEndpoint({ name: 'admin', manage_users: true }, '/roles');
|
|
788
|
+
await axios.post('/roles', roleBody);
|
|
789
|
+
|
|
790
|
+
// Employee shifts schedule
|
|
791
|
+
const shiftBody = formatPayloadForEndpoint({ employeeShifts: { mon: { start: '09:00', end: '17:00' } } }, '/employee-shifts/schedule-update');
|
|
792
|
+
await axios.post('/employee-shifts/schedule-update', shiftBody);
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
Example time helpers:
|
|
796
|
+
|
|
797
|
+
```ts
|
|
798
|
+
import { parseTimeToMilliseconds, subtractTimeStrings, formatSecondsToHms } from 'izen-react-starter/lib';
|
|
799
|
+
|
|
800
|
+
const ms = parseTimeToMilliseconds('09:30'); // 34200000
|
|
801
|
+
const diff = subtractTimeStrings('10:30', '09:00'); // "01:30:00"
|
|
802
|
+
const pretty = formatSecondsToHms(3661); // "01:01:01"
|
|
803
|
+
```
|
|
804
|
+
|
|
684
805
|
### Role-Based Access Control (RBAC)
|
|
685
806
|
|
|
686
807
|
The RBAC system is now fully configurable! Define your own roles, resources, and rules.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as s, T as c, P as u, a as i, b as m, C as P, Q as d } from "./AP7HFJJL-
|
|
2
|
-
import { g as h, c as v, a as e } from "./index-
|
|
1
|
+
import { c as s, T as c, P as u, a as i, b as m, C as P, Q as d } from "./AP7HFJJL-B_liWFpt.js";
|
|
2
|
+
import { g as h, c as v, a as e } from "./index-Gs1Xd6jo.js";
|
|
3
3
|
var C = (r) => {
|
|
4
4
|
const [t, o] = s({
|
|
5
5
|
prefix: "TanstackQueryDevtools"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var xs = Object.defineProperty;
|
|
2
2
|
var $s = (e, t, n) => t in e ? xs(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
|
|
3
3
|
var Re = (e, t, n) => $s(e, typeof t != "symbol" ? t + "" : t, n);
|
|
4
|
-
import { b as $e, d as B, o as ft, e as H, c as P, a as m, P as No, m as ve, S as K, t as _, i as k, f as U, h as F, j as Cs, k as ur, u as Ce, l as V, s as Qn, n as Yn, p as gt, q as T, r as Ss, v as Ut, w as _t, x as qe, y as ks, z as Rt, A as Bt, B as Es, C as Ds, D as En, F as As, E as Ht, $ as Ho, G as Ms, H as Ts, I as W, J as Vr, K as Fs, L as Is, M as cr, N as Os, O as Ls, Q as Hn, R as Ps, T as qs, U as ie, V as _s, W as Rs } from "./index-
|
|
4
|
+
import { b as $e, d as B, o as ft, e as H, c as P, a as m, P as No, m as ve, S as K, t as _, i as k, f as U, h as F, j as Cs, k as ur, u as Ce, l as V, s as Qn, n as Yn, p as gt, q as T, r as Ss, v as Ut, w as _t, x as qe, y as ks, z as Rt, A as Bt, B as Es, C as Ds, D as En, F as As, E as Ht, $ as Ho, G as Ms, H as Ts, I as W, J as Vr, K as Fs, L as Is, M as cr, N as Os, O as Ls, Q as Hn, R as Ps, T as qs, U as ie, V as _s, W as Rs } from "./index-Gs1Xd6jo.js";
|
|
5
5
|
var zs = (e) => e != null, Ks = (e) => e.filter(zs);
|
|
6
6
|
function Bs(e) {
|
|
7
7
|
return (...t) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c, T as l, P as m, a as u, D as v, Q as i } from "./AP7HFJJL-
|
|
2
|
-
import { g as d, c as f, a as e } from "./index-
|
|
1
|
+
import { c, T as l, P as m, a as u, D as v, Q as i } from "./AP7HFJJL-B_liWFpt.js";
|
|
2
|
+
import { g as d, c as f, a as e } from "./index-Gs1Xd6jo.js";
|
|
3
3
|
var h = (t) => {
|
|
4
4
|
const [r, o] = c({
|
|
5
5
|
prefix: "TanstackQueryDevtools"
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AxiosInstance } from 'axios';
|
|
2
1
|
import { z } from 'zod';
|
|
3
2
|
export interface FormLayoutProps<TFieldValues extends Record<string, any> = Record<string, any>> {
|
|
4
3
|
item?: Partial<TFieldValues>;
|
|
@@ -17,7 +16,6 @@ export interface FormLayoutProps<TFieldValues extends Record<string, any> = Reco
|
|
|
17
16
|
dataFormatter?: Partial<Record<keyof TFieldValues | string, (data: any) => unknown>>;
|
|
18
17
|
baseURL?: string;
|
|
19
18
|
multipartUrls?: string[];
|
|
20
|
-
axiosInstance?: AxiosInstance;
|
|
21
19
|
}
|
|
22
|
-
export default function FormLayout<TFieldValues extends Record<string, any> = Record<string, any>>({ item, url, redirectUrl, edit, showCancelBtn, showNewBtn, onSave, onReset, onError, children, resetForm, validationSchema, requestHeaders, dataFormatter, baseURL, multipartUrls,
|
|
20
|
+
export default function FormLayout<TFieldValues extends Record<string, any> = Record<string, any>>({ item, url, redirectUrl, edit, showCancelBtn, showNewBtn, onSave, onReset, onError, children, resetForm, validationSchema, requestHeaders, dataFormatter, baseURL, multipartUrls, }: FormLayoutProps<TFieldValues>): import("react/jsx-runtime").JSX.Element;
|
|
23
21
|
//# sourceMappingURL=FormLayout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormLayout.d.ts","sourceRoot":"","sources":["../../../src/components/form/FormLayout.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FormLayout.d.ts","sourceRoot":"","sources":["../../../src/components/form/FormLayout.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB,MAAM,WAAW,eAAe,CAAC,YAAY,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC7F,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,GAAG,MAAM,KAAK,IAAI,CAAC;IACnD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC;IACrF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAoCD,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,YAAY,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EACjG,IAAI,EACJ,GAAG,EACH,WAAW,EACX,IAAW,EACX,aAAqB,EACrB,UAAiB,EACjB,MAAM,EACN,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,OAAY,EACZ,aAAkB,GACjB,EAAE,eAAe,CAAC,YAAY,CAAC,2CAyKjC"}
|
|
@@ -16,5 +16,5 @@ export interface FileUploadProps {
|
|
|
16
16
|
axiosInstance?: AxiosInstance;
|
|
17
17
|
mapResponseToAttachment?: (response: any, file: File) => Attachment;
|
|
18
18
|
}
|
|
19
|
-
export default function FileUpload({ title, name, uploadUrl, downloadBaseUrl, accept, headers, baseURL,
|
|
19
|
+
export default function FileUpload({ title, name, uploadUrl, downloadBaseUrl, accept, headers, baseURL, mapResponseToAttachment, }: FileUploadProps): import("react/jsx-runtime").JSX.Element;
|
|
20
20
|
//# sourceMappingURL=FileUpload.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileUpload.d.ts","sourceRoot":"","sources":["../../../../src/components/form/inputs/FileUpload.tsx"],"names":[],"mappings":"AACA,OAAO,EAAe,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAsB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"FileUpload.d.ts","sourceRoot":"","sources":["../../../../src/components/form/inputs/FileUpload.tsx"],"names":[],"mappings":"AACA,OAAO,EAAe,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAsB,MAAM,OAAO,CAAC;AAS1D,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,uBAAuB,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,KAAK,UAAU,CAAC;CACrE;AAMD,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EACjC,KAAK,EACL,IAAI,EACJ,SAAS,EACT,eAAe,EACf,MAAsB,EACtB,OAAO,EACP,OAAY,EACZ,uBAAuB,GACxB,EAAE,eAAe,2CA4LjB"}
|