mantur-components 0.1.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 ADDED
@@ -0,0 +1,178 @@
1
+ # mantur-components
2
+
3
+ Reusable Mantur React component library for React and Arco Design.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install mantur-components
9
+ ```
10
+
11
+ Required peer dependencies:
12
+
13
+ ```bash
14
+ npm install react react-dom @arco-design/web-react next-themes react-i18next
15
+ ```
16
+
17
+ The library uses Tailwind utility classes and does not export a standalone CSS file.
18
+
19
+ ## ManturHeader
20
+
21
+ `ManturHeader` is the shared Mantur user header. It owns the header UI and the API calls for:
22
+
23
+ - tenant list
24
+ - current tenant
25
+ - tenant switching
26
+ - user points
27
+ - profile update
28
+ - logout
29
+ - language switch
30
+ - theme switch
31
+
32
+ Basic usage:
33
+
34
+ ```tsx
35
+ import { ManturHeader } from "mantur-components";
36
+
37
+ export function Header({ userInfo }: { userInfo: { username?: string; nickname?: string; avatar?: string } | null }) {
38
+ return <ManturHeader user={userInfo} />;
39
+ }
40
+ ```
41
+
42
+ With disabled tenant switching and custom slots:
43
+
44
+ ```tsx
45
+ import { ManturHeader } from "mantur-components";
46
+
47
+ export function Header({ userInfo, disabled }: { userInfo: UserInfo | null; disabled?: boolean }) {
48
+ return (
49
+ <ManturHeader
50
+ user={userInfo}
51
+ disabled={disabled}
52
+ brandSlot={<span className="text-lg font-bold">Custom Brand</span>}
53
+ >
54
+ <div className="px-4">Custom center content</div>
55
+ </ManturHeader>
56
+ );
57
+ }
58
+ ```
59
+
60
+ ### Props
61
+
62
+ ```ts
63
+ interface ManturHeaderProps {
64
+ user?: ManturHeaderUser | null;
65
+ disabled?: boolean;
66
+ brandSlot?: React.ReactNode;
67
+ children?: React.ReactNode;
68
+ }
69
+ ```
70
+
71
+ `user`: Current user shown in the right user menu.
72
+
73
+ `disabled`: Disables tenant switching. When true, the tenant selector is shown as disabled and cannot be opened or switched.
74
+
75
+ `brandSlot`: Replaces the default brand title next to the logo. If omitted, the default localized title is shown.
76
+
77
+ `children`: Renders custom content in the middle flexible header area. If omitted, the area stays empty.
78
+
79
+ ### User Type
80
+
81
+ ```ts
82
+ interface ManturHeaderUser {
83
+ userId?: string;
84
+ username?: string;
85
+ nickname?: string;
86
+ avatar?: string;
87
+ email?: string;
88
+ }
89
+ ```
90
+
91
+ ### API Base
92
+
93
+ By default, API requests use `import.meta.env.VITE_API` and fall back to `/api`.
94
+
95
+ You can override it before rendering:
96
+
97
+ ```ts
98
+ window.__MANTUR_COMPONENTS_API_BASE__ = "/api";
99
+ ```
100
+
101
+ Points endpoint defaults to `/users/me/points`. It can be overridden:
102
+
103
+ ```ts
104
+ window.__MANTUR_COMPONENTS_POINTS_ENDPOINT__ = "/users/me/points";
105
+ ```
106
+
107
+ ### Tenant Context Event
108
+
109
+ The header fetches and switches tenants internally. If the host app needs to sync local stores, listen to `MANTUR_TENANT_CONTEXT_CHANGE_EVENT`.
110
+
111
+ ```tsx
112
+ import {
113
+ getManturTenantContextSnapshot,
114
+ MANTUR_TENANT_CONTEXT_CHANGE_EVENT,
115
+ type ManturTenantContextDetail,
116
+ } from "mantur-components";
117
+
118
+ function applyTenantContext(detail: ManturTenantContextDetail) {
119
+ const tenantId = detail.auth?.tenantId || detail.currentTenant?.tenantId;
120
+
121
+ // Sync host app stores here.
122
+ // setActiveTenantId(tenantId)
123
+ // setPermissions(detail.auth?.permissions || [])
124
+ // setRoles(detail.auth?.roles || [])
125
+ // setEnabledApps(detail.auth?.enabledApps || [])
126
+ }
127
+
128
+ window.addEventListener(MANTUR_TENANT_CONTEXT_CHANGE_EVENT, (event) => {
129
+ if (event instanceof CustomEvent) {
130
+ applyTenantContext(event.detail as ManturTenantContextDetail);
131
+ }
132
+ });
133
+
134
+ const snapshot = getManturTenantContextSnapshot();
135
+ if (snapshot) {
136
+ applyTenantContext(snapshot);
137
+ }
138
+ ```
139
+
140
+ Tenant context detail:
141
+
142
+ ```ts
143
+ interface ManturTenantContextDetail {
144
+ tenants: ManturTenant[];
145
+ currentTenant?: ManturTenant;
146
+ auth?: {
147
+ tenantId: string;
148
+ tenantName?: string;
149
+ roles?: string[];
150
+ permissions?: string[];
151
+ enabledApps?: string[];
152
+ };
153
+ reason: "refresh" | "switch";
154
+ }
155
+ ```
156
+
157
+ ### Exported Helpers
158
+
159
+ ```ts
160
+ import {
161
+ getManturCurrentTenant,
162
+ getManturTenantContextSnapshot,
163
+ getManturTenants,
164
+ getManturUserPoints,
165
+ MANTUR_POINTS_REFRESH_EVENT,
166
+ MANTUR_TENANT_CONTEXT_CHANGE_EVENT,
167
+ refreshManturTenantContext,
168
+ refreshManturUserPoints,
169
+ switchAndRefreshManturTenant,
170
+ switchManturTenant,
171
+ } from "mantur-components";
172
+ ```
173
+
174
+ ## Build
175
+
176
+ ```bash
177
+ npm run build
178
+ ```
package/dist/api.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ import type { ManturHeaderUser, ManturProfileValues, ManturTenant, ManturTenantAuthContext, ManturTenantContextDetail, ManturUserPoints } from "./types";
2
+ export declare const MANTUR_POINTS_REFRESH_EVENT = "mantur-points-refresh";
3
+ export declare const MANTUR_TENANT_CONTEXT_CHANGE_EVENT = "mantur-tenant-context-change";
4
+ declare global {
5
+ interface Window {
6
+ __MANTUR_COMPONENTS_API_BASE__?: string;
7
+ __MANTUR_COMPONENTS_POINTS_ENDPOINT__?: string;
8
+ __MANTUR_COMPONENTS_TENANT_CONTEXT__?: ManturTenantContextDetail;
9
+ }
10
+ }
11
+ export declare function removeManturCookie(name: string): void;
12
+ export declare function logoutManturUser(): Promise<void>;
13
+ export declare function updateManturProfile(values: ManturProfileValues): Promise<ManturHeaderUser | undefined>;
14
+ export declare function getManturUserPoints(): Promise<ManturUserPoints>;
15
+ export declare function refreshManturUserPoints(): Promise<ManturUserPoints>;
16
+ export declare function getManturTenantContextSnapshot(): ManturTenantContextDetail | undefined;
17
+ export declare function getManturTenants(): Promise<ManturTenant[]>;
18
+ export declare function getManturCurrentTenant(): Promise<ManturTenantAuthContext | undefined>;
19
+ export declare function switchManturTenant(tenantId: string): Promise<ManturTenantAuthContext | undefined>;
20
+ export declare function refreshManturTenantContext(reason?: ManturTenantContextDetail["reason"]): Promise<ManturTenantContextDetail>;
21
+ export declare function switchAndRefreshManturTenant(tenantId: string): Promise<ManturTenantContextDetail>;
@@ -0,0 +1,2 @@
1
+ import type { ManturHeaderProps } from "../types";
2
+ export declare function ManturHeader({ user, disabled, brandSlot, children, }: ManturHeaderProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import type { ManturHeaderLabels, ManturUserPoints } from "../../types";
2
+ export declare function PointsDetailModal({ visible, points, text, onCancel, onRecharge, }: {
3
+ visible: boolean;
4
+ points: Required<ManturUserPoints>;
5
+ text: ManturHeaderLabels;
6
+ onCancel: () => void;
7
+ onRecharge: () => void;
8
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import type { ProfileModalProps } from "../../types";
2
+ export declare function ProfileModal({ visible, user, labels, onCancel, onSubmit, }: ProfileModalProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import type { ManturHeaderLabels, ManturHeaderUser, ManturUserPoints } from "../../types";
2
+ import { type RechargePackage } from "../mock";
3
+ export declare function RechargeModal({ visible, user, points, text, onCancel, onPay, }: {
4
+ visible: boolean;
5
+ user?: ManturHeaderUser | null;
6
+ points: Required<ManturUserPoints>;
7
+ text: ManturHeaderLabels;
8
+ onCancel: () => void;
9
+ onPay: (rechargePackage: RechargePackage) => void;
10
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import type { ManturHeaderUser } from "../../types";
2
+ export declare function getUserInitial(user?: ManturHeaderUser | null): string;
3
+ export declare function ManturUserAvatar({ user, size, className, }: {
4
+ user?: ManturHeaderUser | null;
5
+ size: number;
6
+ className?: string;
7
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import type { ManturHeaderLabels, ManturHeaderUser, ManturUserPoints } from "../../types";
2
+ export declare function UserMenu({ user, points, text, onEditProfile, onRecharge, onPointsDetail, onLogout, }: {
3
+ user?: ManturHeaderUser | null;
4
+ points: Required<ManturUserPoints>;
5
+ text: ManturHeaderLabels;
6
+ onEditProfile: () => void;
7
+ onRecharge: () => void;
8
+ onPointsDetail: () => void;
9
+ onLogout?: () => void | Promise<void>;
10
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { ManturHeader } from "./ManturHeader";
@@ -0,0 +1,35 @@
1
+ export declare const RECHARGE_PACKAGES: readonly [{
2
+ readonly id: "points-500";
3
+ readonly points: 500;
4
+ readonly price: 5;
5
+ }, {
6
+ readonly id: "points-1000";
7
+ readonly points: 1000;
8
+ readonly price: 10;
9
+ }, {
10
+ readonly id: "points-5500";
11
+ readonly points: 5500;
12
+ readonly price: 50;
13
+ readonly recommended: true;
14
+ }, {
15
+ readonly id: "points-24000";
16
+ readonly points: 24000;
17
+ readonly price: 200;
18
+ }];
19
+ export type RechargePackage = (typeof RECHARGE_PACKAGES)[number];
20
+ export type RechargePackageId = RechargePackage["id"];
21
+ export type PointsLedgerType = "all" | "income" | "expense";
22
+ export type PointsLedgerSource = "all" | "recharge" | "gift";
23
+ export type PointsLedgerBadgeKind = "recharge" | "gift" | "deducted" | "expired";
24
+ export interface PointsLedgerRecord {
25
+ id: string;
26
+ type: Exclude<PointsLedgerType, "all">;
27
+ source?: Exclude<PointsLedgerSource, "all">;
28
+ name: string;
29
+ meta: string;
30
+ date: string;
31
+ amount: number;
32
+ badgeKind: PointsLedgerBadgeKind;
33
+ badgeText: string;
34
+ }
35
+ export declare const MOCK_POINTS_LEDGER: PointsLedgerRecord[];
package/dist/i18n.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import type { ManturHeaderLabels } from "./types";
2
+ export type ManturLocale = "zh-CN" | "en-US";
3
+ export interface ManturMessages extends ManturHeaderLabels {
4
+ languageZh: string;
5
+ languageEn: string;
6
+ }
7
+ export declare const MANTUR_LANGUAGE_STORAGE_KEY = "i18nextLng";
8
+ export declare const MANTUR_LANGUAGE_SOURCE_STORAGE_KEY = "manturLanguageSource";
9
+ export declare const MANTUR_LANGUAGE_CHANGE_EVENT = "mantur-language-change";
10
+ export declare const MANTUR_MESSAGES: Record<ManturLocale, ManturMessages>;
11
+ export declare function normalizeManturLocale(language?: string): ManturLocale;
12
+ export declare function getStoredManturLocale(): ManturLocale;
13
+ export declare function getManturMessages(language?: string): ManturMessages;
@@ -0,0 +1,7 @@
1
+ export { ManturHeader } from "./header";
2
+ export { getManturCurrentTenant, getManturTenantContextSnapshot, getManturTenants, getManturUserPoints, MANTUR_POINTS_REFRESH_EVENT, MANTUR_TENANT_CONTEXT_CHANGE_EVENT, refreshManturUserPoints, refreshManturTenantContext, switchAndRefreshManturTenant, switchManturTenant, } from "./api";
3
+ export { getManturMessages, getStoredManturLocale, MANTUR_LANGUAGE_CHANGE_EVENT, MANTUR_LANGUAGE_SOURCE_STORAGE_KEY, MANTUR_LANGUAGE_STORAGE_KEY, MANTUR_MESSAGES, normalizeManturLocale, } from "./i18n";
4
+ export { LangSwitch, LANGUAGE_SOURCE_STORAGE_KEY, LANGUAGE_STORAGE_KEY } from "./lang-switch";
5
+ export { ThemeSwitch } from "./theme-switch";
6
+ export type { ManturLocale, ManturMessages } from "./i18n";
7
+ export type { ManturHeaderLabels, ManturHeaderProps, ManturHeaderUser, ManturProfileValues, ManturRole, ManturTenant, ManturTenantAuthContext, ManturTenantContextDetail, ManturUserPoints, } from "./types";
@@ -0,0 +1,3 @@
1
+ import type { ManturHeaderLabels } from "./types";
2
+ export declare const DEFAULT_LABELS: ManturHeaderLabels;
3
+ export declare function mergeLabels(labels?: Partial<ManturHeaderLabels>): ManturHeaderLabels;
@@ -0,0 +1,3 @@
1
+ export declare const LANGUAGE_STORAGE_KEY = "i18nextLng";
2
+ export declare const LANGUAGE_SOURCE_STORAGE_KEY = "manturLanguageSource";
3
+ export declare function LangSwitch(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { LANGUAGE_SOURCE_STORAGE_KEY, LANGUAGE_STORAGE_KEY, LangSwitch } from "./LangSwitch";