@dreamtree-org/landing-kit 0.9.0 → 0.10.1
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/MIGRATION.md +16 -0
- package/PLATFORM-API.md +17 -13
- package/README.md +41 -1
- package/ai-skills/landing-kit.md +7 -6
- package/auth.css +57 -0
- package/auth.d.ts +2 -2
- package/dist/auth.cjs +143 -38
- package/dist/auth.js +139 -34
- package/dist/index.cjs +605 -540
- package/dist/index.js +573 -508
- package/dist/platform.cjs +1208 -408
- package/dist/platform.js +1209 -409
- package/index.d.ts +25 -0
- package/package.json +3 -2
- package/platform.d.ts +37 -3
- package/styles.css +57 -0
package/index.d.ts
CHANGED
|
@@ -57,6 +57,26 @@ export interface AuthShellProps {
|
|
|
57
57
|
* the form. Nothing renders when `load` returns no accounts (demo mode off).
|
|
58
58
|
*/
|
|
59
59
|
demoAccounts?: AuthDemoAccounts | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Dreamtree ID single sign-on (DTID-32). Absent = today's local form, unchanged.
|
|
62
|
+
* 'hybrid' adds a "Continue with Dreamtree" button and an "or" divider above `children`;
|
|
63
|
+
* 'sso' drops `children` (and the demo-accounts panel) and redirects to the start URL on mount.
|
|
64
|
+
*/
|
|
65
|
+
ssoProvider?: SsoProvider | undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface SsoProvider {
|
|
69
|
+
/** The app's SSO entry point, e.g. '/auth/sso/start'. May already carry a query or #hash. */
|
|
70
|
+
startUrl: string;
|
|
71
|
+
mode: 'hybrid' | 'sso';
|
|
72
|
+
/** Button text. Default "Continue with Dreamtree". */
|
|
73
|
+
label?: string | undefined;
|
|
74
|
+
/** Sent as `dt_company` (the /c/[slug]/login company). */
|
|
75
|
+
companySlug?: string | undefined;
|
|
76
|
+
/** Sent as `return_to`: where the app lands after sign-in. */
|
|
77
|
+
returnTo?: string | undefined;
|
|
78
|
+
/** 'sso' only: redirect with window.location.assign after mount. Default true; the button always stays as a fallback. */
|
|
79
|
+
autoRedirect?: boolean | undefined;
|
|
60
80
|
}
|
|
61
81
|
|
|
62
82
|
export interface DemoAccount {
|
|
@@ -89,6 +109,11 @@ export interface DemoAccountsProps {
|
|
|
89
109
|
}
|
|
90
110
|
|
|
91
111
|
export declare function AuthShell(props: AuthShellProps): ReactElement;
|
|
112
|
+
/**
|
|
113
|
+
* `startUrl` plus `return_to` / `dt_company` (URI-encoded, replacing same-named params already
|
|
114
|
+
* there; other params and the #hash are kept). Pure: safe during SSR.
|
|
115
|
+
*/
|
|
116
|
+
export declare function buildSsoUrl(startUrl: string, opts?: Pick<SsoProvider, 'returnTo' | 'companySlug'>): string;
|
|
92
117
|
/** The chip row AuthShell reveals; render it yourself for a login outside AuthShell. */
|
|
93
118
|
export declare function DemoAccounts(props: DemoAccountsProps): ReactElement | null;
|
|
94
119
|
/** `taps` clicks, each within `windowMs` of the last, set `revealed` for the page's life. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dreamtree-org/landing-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "The shared marketing site, auth frame (AuthShell + brands) and Platform admin console for every Dreamtree product: content-driven landing pages, login/signup shell, platform console client, Express routes, prerender and SEO files.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Partha Preetham Krishna",
|
|
@@ -106,7 +106,8 @@
|
|
|
106
106
|
"esbuild": "^0.25.0",
|
|
107
107
|
"express": "^4.22.3",
|
|
108
108
|
"react": "^18.3.1",
|
|
109
|
-
"react-dom": "^18.3.1"
|
|
109
|
+
"react-dom": "^18.3.1",
|
|
110
|
+
"react-test-renderer": "^18.3.1"
|
|
110
111
|
},
|
|
111
112
|
"engines": {
|
|
112
113
|
"node": ">=18"
|
package/platform.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export const PLATFORM_API_BASE: '/api/platform';
|
|
|
5
5
|
export const PLATFORM_LOGIN_PATH: '/platform/login';
|
|
6
6
|
export const STEP_UP_REQUIRED: 'STEP_UP_REQUIRED';
|
|
7
7
|
|
|
8
|
-
export type PlatformFeature = 'overview' | 'companies' | 'jobs' | 'plans' | 'audit' | 'support' | 'settings' | 'admins';
|
|
8
|
+
export type PlatformFeature = 'overview' | 'companies' | 'jobs' | 'plans' | 'audit' | 'support' | 'settings' | 'domains' | 'admins';
|
|
9
9
|
/** Every console feature, in nav order. */
|
|
10
10
|
export const PLATFORM_FEATURES: readonly PlatformFeature[];
|
|
11
11
|
/** Features a server without `GET /me` serves. */
|
|
@@ -91,7 +91,7 @@ export interface PlatformMe {
|
|
|
91
91
|
permissions: string[];
|
|
92
92
|
/** `console` false = enrollment-only session (enroll an authenticator first). */
|
|
93
93
|
access?: { console: boolean; stepUpFresh: boolean };
|
|
94
|
-
features: Partial<Record<PlatformFeature
|
|
94
|
+
features: Partial<Record<PlatformFeature, boolean>>;
|
|
95
95
|
app: { key: string; name: string; companyLoginPath?: string };
|
|
96
96
|
}
|
|
97
97
|
|
|
@@ -187,28 +187,35 @@ export interface Plan {
|
|
|
187
187
|
seats?: number | null;
|
|
188
188
|
limits?: Record<string, number | null>;
|
|
189
189
|
features?: string[];
|
|
190
|
+
sort?: number;
|
|
190
191
|
}
|
|
191
192
|
|
|
192
193
|
export interface Subscription {
|
|
193
194
|
id: string;
|
|
194
195
|
companyId: string;
|
|
195
196
|
planId: string;
|
|
197
|
+
planCode?: string | null;
|
|
198
|
+
planName?: string | null;
|
|
196
199
|
status: 'trial' | 'active' | 'past_due' | 'cancelled' | 'expired';
|
|
197
200
|
startsAt: Iso;
|
|
198
201
|
endsAt: Iso | null;
|
|
199
202
|
seats?: number | null;
|
|
200
203
|
notes?: string | null;
|
|
204
|
+
createdBy?: string | null;
|
|
205
|
+
createdAt?: Iso;
|
|
201
206
|
}
|
|
202
207
|
|
|
203
208
|
export interface SettingsField {
|
|
204
209
|
key: string;
|
|
205
210
|
label: string;
|
|
206
211
|
type: 'text' | 'number' | 'boolean' | 'select' | 'secret' | 'email' | 'url';
|
|
207
|
-
options?: string
|
|
212
|
+
options?: Array<{ value: string; label: string }>;
|
|
208
213
|
/** Secret values come back masked (`set: true`), never in clear. */
|
|
209
214
|
value?: unknown;
|
|
210
215
|
set?: boolean;
|
|
211
216
|
help?: string;
|
|
217
|
+
/** Where the value comes from. */
|
|
218
|
+
source?: 'branch' | 'company' | 'default' | null;
|
|
212
219
|
}
|
|
213
220
|
export interface SettingsFamily {
|
|
214
221
|
family: string;
|
|
@@ -216,24 +223,37 @@ export interface SettingsFamily {
|
|
|
216
223
|
scope: 'platform' | 'company';
|
|
217
224
|
fields: SettingsField[];
|
|
218
225
|
}
|
|
226
|
+
/** GET settings?company= */
|
|
227
|
+
export interface SettingsResponse {
|
|
228
|
+
families: SettingsFamily[];
|
|
229
|
+
/** Send back with PUT settings/:family; a stale version answers 409. */
|
|
230
|
+
version: number;
|
|
231
|
+
}
|
|
219
232
|
|
|
220
233
|
export interface SupportGrant {
|
|
221
234
|
id: string;
|
|
222
235
|
companyId: string;
|
|
223
236
|
companyName?: string;
|
|
224
237
|
requestedBy: string;
|
|
238
|
+
requestedById?: string;
|
|
225
239
|
approvedBy?: string | null;
|
|
226
240
|
reason: string;
|
|
241
|
+
/** Length of the access window, counted from approval. */
|
|
242
|
+
minutes?: number | null;
|
|
227
243
|
status: 'requested' | 'active' | 'expired' | 'revoked';
|
|
228
244
|
expiresAt: Iso | null;
|
|
245
|
+
approvedAt?: Iso | null;
|
|
246
|
+
revokedAt?: Iso | null;
|
|
229
247
|
createdAt: Iso;
|
|
230
248
|
}
|
|
231
249
|
|
|
232
250
|
export interface CompanyDomain {
|
|
233
251
|
id: string;
|
|
234
252
|
host: string;
|
|
253
|
+
status?: 'pending' | 'verified';
|
|
235
254
|
primary: boolean;
|
|
236
255
|
verifiedAt: Iso | null;
|
|
256
|
+
createdAt?: Iso;
|
|
237
257
|
verification?: { type: 'TXT'; name: string; value: string };
|
|
238
258
|
}
|
|
239
259
|
|
|
@@ -327,6 +347,8 @@ export function usePlatform(): {
|
|
|
327
347
|
href(rel?: string): string;
|
|
328
348
|
navigate(href: string): void;
|
|
329
349
|
can(permission: string): boolean;
|
|
350
|
+
/** Features this console shows (requested ∩ advertised by GET /me). */
|
|
351
|
+
features: PlatformFeature[];
|
|
330
352
|
companyLoginPath(slug: string): string;
|
|
331
353
|
companyLoginUrl(slug: string): string;
|
|
332
354
|
};
|
|
@@ -340,3 +362,15 @@ export const CopyButton: ComponentType<{ value: string; label?: string }>;
|
|
|
340
362
|
export const OneTimeSecret: ComponentType<{ title?: string; loginUrl?: string; email: string; password: string; onDone?: () => void }>;
|
|
341
363
|
export const InspectResult: ComponentType<{ report: Record<string, any> }>;
|
|
342
364
|
export function describeAction(action: string): string;
|
|
365
|
+
/** "₹999.00 / month" from minor units. */
|
|
366
|
+
export function formatPrice(priceMinor: number, currency?: string, interval?: Plan['interval']): string;
|
|
367
|
+
|
|
368
|
+
/** Built-in v1.1 views, exported for products that compose their own console. They render inside <PlatformConsole>. */
|
|
369
|
+
export const PlansView: ComponentType;
|
|
370
|
+
export const SupportAccessView: ComponentType;
|
|
371
|
+
export const SupportGrants: ComponentType<{ companyId?: string; companyName?: string }>;
|
|
372
|
+
type CompanyTabProps = { company: { id: string; displayName?: string } & Record<string, any>; setFlash(flash: { kind: 'success' | 'error' | 'warning' | 'info'; msg: string } | null): void };
|
|
373
|
+
export const SubscriptionTab: ComponentType<CompanyTabProps>;
|
|
374
|
+
export const DomainsTab: ComponentType<CompanyTabProps>;
|
|
375
|
+
export const SettingsTab: ComponentType<CompanyTabProps>;
|
|
376
|
+
export const SupportTab: ComponentType<CompanyTabProps>;
|
package/styles.css
CHANGED
|
@@ -850,6 +850,63 @@ html:has(.dt-landing) { scroll-behavior: smooth; scroll-padding-top: calc(var(--
|
|
|
850
850
|
.dt-auth-demo-note { margin: 0.625rem 0 0; font-size: 0.75rem; color: var(--dt-auth-muted); }
|
|
851
851
|
.dt-auth-demo-note code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.75rem; color: inherit; }
|
|
852
852
|
|
|
853
|
+
/* ---- Dreamtree ID single sign-on (ssoProvider, DTID-32) ---- */
|
|
854
|
+
.dt-auth-sso-btn {
|
|
855
|
+
display: flex;
|
|
856
|
+
align-items: center;
|
|
857
|
+
justify-content: center;
|
|
858
|
+
gap: 0.5rem;
|
|
859
|
+
width: 100%;
|
|
860
|
+
min-height: 2.75rem;
|
|
861
|
+
padding: 0.625rem 1rem;
|
|
862
|
+
border: 1px solid var(--dt-brand);
|
|
863
|
+
border-radius: 0.5rem;
|
|
864
|
+
background: var(--dt-brand);
|
|
865
|
+
color: #fff;
|
|
866
|
+
font: inherit;
|
|
867
|
+
font-size: 0.9375rem;
|
|
868
|
+
font-weight: 600;
|
|
869
|
+
text-decoration: none;
|
|
870
|
+
transition: background-color 120ms;
|
|
871
|
+
}
|
|
872
|
+
.dt-auth-sso-btn:hover { background: color-mix(in oklab, var(--dt-brand) 88%, black); }
|
|
873
|
+
.dt-auth-sso-btn:focus-visible { outline: 2px solid var(--dt-brand); outline-offset: 2px; }
|
|
874
|
+
.dt-auth-sso-icon { flex: none; }
|
|
875
|
+
.dt-auth-or {
|
|
876
|
+
display: flex;
|
|
877
|
+
align-items: center;
|
|
878
|
+
gap: 0.75rem;
|
|
879
|
+
margin: 1.25rem 0;
|
|
880
|
+
font-size: 0.75rem;
|
|
881
|
+
letter-spacing: 0.08em;
|
|
882
|
+
text-transform: uppercase;
|
|
883
|
+
color: var(--dt-auth-muted);
|
|
884
|
+
}
|
|
885
|
+
.dt-auth-or::before,
|
|
886
|
+
.dt-auth-or::after { content: ''; flex: 1; border-top: 1px solid var(--dt-auth-border); }
|
|
887
|
+
.dt-auth-sso-status {
|
|
888
|
+
display: flex;
|
|
889
|
+
align-items: center;
|
|
890
|
+
gap: 0.625rem;
|
|
891
|
+
margin: 0 0 1rem;
|
|
892
|
+
font-size: 0.875rem;
|
|
893
|
+
color: var(--dt-auth-muted);
|
|
894
|
+
}
|
|
895
|
+
.dt-auth-sso-spinner {
|
|
896
|
+
flex: none;
|
|
897
|
+
width: 1rem;
|
|
898
|
+
height: 1rem;
|
|
899
|
+
border: 2px solid var(--dt-brand-soft);
|
|
900
|
+
border-top-color: var(--dt-brand);
|
|
901
|
+
border-radius: 999px;
|
|
902
|
+
animation: dt-auth-sso-spin 0.8s linear infinite;
|
|
903
|
+
}
|
|
904
|
+
@keyframes dt-auth-sso-spin { to { transform: rotate(360deg); } }
|
|
905
|
+
@media (prefers-reduced-motion: reduce) {
|
|
906
|
+
.dt-auth-sso-spinner { animation: none; }
|
|
907
|
+
.dt-auth-sso-btn { transition: none; }
|
|
908
|
+
}
|
|
909
|
+
|
|
853
910
|
/* ---- phones ---- */
|
|
854
911
|
.dt-auth-column,
|
|
855
912
|
.dt-auth-card { min-width: 0; }
|