@ezcoder.dev/sdk 1.0.0 → 1.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/dist/DatabaseProvider-DalP-KHC.d.ts +167 -0
- package/dist/analytics/index.d.ts +22 -1
- package/dist/analytics/index.js +78 -5
- package/dist/analytics/index.js.map +1 -1
- package/dist/animation/index.js.map +1 -1
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.js +3 -3
- package/dist/auth/index.js.map +1 -1
- package/dist/{chunk-G7XDUN3Z.js → chunk-2WG4O4J2.js} +24 -8
- package/dist/chunk-2WG4O4J2.js.map +1 -0
- package/dist/chunk-7VGYFCQC.js +640 -0
- package/dist/chunk-7VGYFCQC.js.map +1 -0
- package/dist/{chunk-YNDCD53D.js → chunk-AWU47M6N.js} +36 -12
- package/dist/chunk-AWU47M6N.js.map +1 -0
- package/dist/{chunk-5XIZHBKE.js → chunk-GPF4AYNG.js} +23 -6
- package/dist/chunk-GPF4AYNG.js.map +1 -0
- package/dist/cms/index.js +1 -1
- package/dist/cms/index.js.map +1 -1
- package/dist/cron/index.d.ts +15 -0
- package/dist/cron/index.js +49 -0
- package/dist/cron/index.js.map +1 -0
- package/dist/database/index.d.ts +37 -0
- package/dist/database/index.js +31 -0
- package/dist/database/index.js.map +1 -0
- package/dist/email/index.d.ts +11 -0
- package/dist/email/index.js +45 -0
- package/dist/email/index.js.map +1 -0
- package/dist/errors/index.js.map +1 -1
- package/dist/index.d.ts +9 -2
- package/dist/index.js +11 -3
- package/dist/notifications/index.d.ts +10 -1
- package/dist/notifications/index.js +25 -3
- package/dist/notifications/index.js.map +1 -1
- package/dist/payments/index.d.ts +11 -3
- package/dist/payments/index.js +98 -6
- package/dist/payments/index.js.map +1 -1
- package/dist/roles/index.js +3 -3
- package/dist/roles/index.js.map +1 -1
- package/dist/seo/index.js.map +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.js +15 -8
- package/dist/storage/index.js.map +1 -1
- package/dist/{types-DtY5lp3P.d.ts → types-1uP3V_pe.d.ts} +5 -0
- package/package.json +120 -105
- package/dist/chunk-5XIZHBKE.js.map +0 -1
- package/dist/chunk-G7XDUN3Z.js.map +0 -1
- package/dist/chunk-YNDCD53D.js.map +0 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { SupabaseClient } from '@supabase/supabase-js';
|
|
4
|
+
|
|
5
|
+
interface DatabaseResult<T = Record<string, unknown>> {
|
|
6
|
+
success: boolean;
|
|
7
|
+
data: T[];
|
|
8
|
+
rowCount: number;
|
|
9
|
+
error?: string;
|
|
10
|
+
schema?: string;
|
|
11
|
+
}
|
|
12
|
+
interface SingleResult<T = Record<string, unknown>> {
|
|
13
|
+
success: boolean;
|
|
14
|
+
data: T | null;
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
interface MutationResult {
|
|
18
|
+
success: boolean;
|
|
19
|
+
rowCount: number;
|
|
20
|
+
error?: string;
|
|
21
|
+
schema?: string;
|
|
22
|
+
executed_sql?: string;
|
|
23
|
+
}
|
|
24
|
+
interface ColumnInfo {
|
|
25
|
+
name: string;
|
|
26
|
+
type: string;
|
|
27
|
+
nullable: boolean;
|
|
28
|
+
default: string | null;
|
|
29
|
+
ordinal: number;
|
|
30
|
+
}
|
|
31
|
+
interface IndexInfo {
|
|
32
|
+
name: string;
|
|
33
|
+
definition: string;
|
|
34
|
+
is_unique: boolean;
|
|
35
|
+
is_primary: boolean;
|
|
36
|
+
}
|
|
37
|
+
interface ForeignKeyInfo {
|
|
38
|
+
name: string;
|
|
39
|
+
column: string;
|
|
40
|
+
references_table: string;
|
|
41
|
+
references_column: string;
|
|
42
|
+
}
|
|
43
|
+
interface PolicyInfo {
|
|
44
|
+
name: string;
|
|
45
|
+
command: string;
|
|
46
|
+
permissive: boolean;
|
|
47
|
+
roles: string[];
|
|
48
|
+
}
|
|
49
|
+
interface TableInfo {
|
|
50
|
+
name: string;
|
|
51
|
+
columns: ColumnInfo[];
|
|
52
|
+
rowCount: number;
|
|
53
|
+
indexes: IndexInfo[];
|
|
54
|
+
foreignKeys: ForeignKeyInfo[];
|
|
55
|
+
rlsPolicies: PolicyInfo[];
|
|
56
|
+
}
|
|
57
|
+
interface SchemaInfo {
|
|
58
|
+
exists: boolean;
|
|
59
|
+
schema?: string;
|
|
60
|
+
tables: TableInfo[];
|
|
61
|
+
tablesCount: number;
|
|
62
|
+
createdAt?: string;
|
|
63
|
+
lastAccessedAt?: string;
|
|
64
|
+
}
|
|
65
|
+
interface OrderOption {
|
|
66
|
+
ascending?: boolean;
|
|
67
|
+
nullsFirst?: boolean;
|
|
68
|
+
}
|
|
69
|
+
type FilterValue = string | number | boolean | null;
|
|
70
|
+
|
|
71
|
+
interface ServerProxy {
|
|
72
|
+
serverQuery: (sql: string) => Promise<{
|
|
73
|
+
success: boolean;
|
|
74
|
+
data?: unknown[];
|
|
75
|
+
rowCount?: number;
|
|
76
|
+
error?: string;
|
|
77
|
+
schema?: string;
|
|
78
|
+
}>;
|
|
79
|
+
serverExec: (sql: string) => Promise<{
|
|
80
|
+
success: boolean;
|
|
81
|
+
data?: unknown[];
|
|
82
|
+
rowCount?: number;
|
|
83
|
+
error?: string;
|
|
84
|
+
schema?: string;
|
|
85
|
+
}>;
|
|
86
|
+
}
|
|
87
|
+
declare class QueryBuilder<T = Record<string, unknown>> {
|
|
88
|
+
private readonly supabase;
|
|
89
|
+
private readonly projectId;
|
|
90
|
+
private readonly table;
|
|
91
|
+
private readonly serverProxy?;
|
|
92
|
+
private operation;
|
|
93
|
+
private selectColumns;
|
|
94
|
+
private filters;
|
|
95
|
+
private orderClauses;
|
|
96
|
+
private limitValue;
|
|
97
|
+
private offsetValue;
|
|
98
|
+
private insertData;
|
|
99
|
+
private updateData;
|
|
100
|
+
private upsertConflict;
|
|
101
|
+
private singleMode;
|
|
102
|
+
private maybeSingleMode;
|
|
103
|
+
constructor(supabase: SupabaseClient, projectId: string, table: string, serverProxy?: ServerProxy);
|
|
104
|
+
select(columns?: string): this;
|
|
105
|
+
eq(column: string, value: FilterValue): this;
|
|
106
|
+
neq(column: string, value: FilterValue): this;
|
|
107
|
+
gt(column: string, value: FilterValue): this;
|
|
108
|
+
lt(column: string, value: FilterValue): this;
|
|
109
|
+
gte(column: string, value: FilterValue): this;
|
|
110
|
+
lte(column: string, value: FilterValue): this;
|
|
111
|
+
like(column: string, pattern: string): this;
|
|
112
|
+
ilike(column: string, pattern: string): this;
|
|
113
|
+
in(column: string, values: FilterValue[]): this;
|
|
114
|
+
is(column: string, value: null | boolean): this;
|
|
115
|
+
order(column: string, options?: OrderOption): this;
|
|
116
|
+
limit(count: number): this;
|
|
117
|
+
offset(count: number): this;
|
|
118
|
+
insert(records: Record<string, FilterValue> | Record<string, FilterValue>[]): this;
|
|
119
|
+
update(values: Record<string, FilterValue>): this;
|
|
120
|
+
delete(): this;
|
|
121
|
+
upsert(records: Record<string, FilterValue> | Record<string, FilterValue>[], options?: {
|
|
122
|
+
onConflict?: string;
|
|
123
|
+
}): this;
|
|
124
|
+
count(): QueryBuilder<{
|
|
125
|
+
count: number;
|
|
126
|
+
}>;
|
|
127
|
+
single(): QueryBuilder<T>;
|
|
128
|
+
maybeSingle(): QueryBuilder<T>;
|
|
129
|
+
private buildWhereClause;
|
|
130
|
+
private buildSelectSql;
|
|
131
|
+
private buildCountSql;
|
|
132
|
+
private buildInsertSql;
|
|
133
|
+
private buildUpsertSql;
|
|
134
|
+
private buildUpdateSql;
|
|
135
|
+
private buildDeleteSql;
|
|
136
|
+
private executeQuery;
|
|
137
|
+
then<TResult1 = DatabaseResult<T> | SingleResult<T>, TResult2 = never>(onfulfilled?: ((value: DatabaseResult<T> | SingleResult<T>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
declare class DatabaseClient {
|
|
141
|
+
private readonly supabase;
|
|
142
|
+
private readonly projectId;
|
|
143
|
+
private apiKey?;
|
|
144
|
+
private platformUrl?;
|
|
145
|
+
private serverMode;
|
|
146
|
+
constructor(supabase: SupabaseClient | null, projectId: string);
|
|
147
|
+
static createServerClient(projectId: string, apiKey: string, platformUrl?: string): DatabaseClient;
|
|
148
|
+
from<T = Record<string, unknown>>(table: string): QueryBuilder<T>;
|
|
149
|
+
sql<T = Record<string, unknown>>(query: string): Promise<DatabaseResult<T>>;
|
|
150
|
+
execute(sql: string): Promise<MutationResult>;
|
|
151
|
+
getSchema(): Promise<SchemaInfo>;
|
|
152
|
+
private _serverRequest;
|
|
153
|
+
private _serverQuery;
|
|
154
|
+
private _serverExecute;
|
|
155
|
+
private _serverGetSchema;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
interface DatabaseProviderProps {
|
|
159
|
+
children: ReactNode;
|
|
160
|
+
projectId?: string;
|
|
161
|
+
}
|
|
162
|
+
declare function DatabaseProvider({ children, projectId }: DatabaseProviderProps): react_jsx_runtime.JSX.Element;
|
|
163
|
+
declare function useDatabase(): DatabaseClient;
|
|
164
|
+
declare function useDatabaseOptional(): DatabaseClient | null;
|
|
165
|
+
declare function useIsDatabaseConfigured(): boolean;
|
|
166
|
+
|
|
167
|
+
export { type ColumnInfo as C, DatabaseClient as D, type FilterValue as F, type IndexInfo as I, type MutationResult as M, type OrderOption as O, type PolicyInfo as P, QueryBuilder as Q, type SchemaInfo as S, type TableInfo as T, DatabaseProvider as a, type DatabaseResult as b, type ForeignKeyInfo as c, type SingleResult as d, useDatabaseOptional as e, useIsDatabaseConfigured as f, useDatabase as u };
|
|
@@ -15,4 +15,25 @@ interface UseAnalyticsReturn {
|
|
|
15
15
|
}
|
|
16
16
|
declare function useAnalytics(): UseAnalyticsReturn;
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
interface MetricResult<T = Record<string, unknown>> {
|
|
19
|
+
data: T | null;
|
|
20
|
+
error: string | null;
|
|
21
|
+
}
|
|
22
|
+
interface UseMetricsReturn {
|
|
23
|
+
getTotalUsers: () => Promise<MetricResult<{
|
|
24
|
+
count: number;
|
|
25
|
+
}>>;
|
|
26
|
+
getUserGrowth: (days?: number) => Promise<MetricResult<Array<{
|
|
27
|
+
date: string;
|
|
28
|
+
count: number;
|
|
29
|
+
}>>>;
|
|
30
|
+
getActiveUsers: (days?: number) => Promise<MetricResult<{
|
|
31
|
+
count: number;
|
|
32
|
+
}>>;
|
|
33
|
+
getRecentActivity: (limit?: number) => Promise<MetricResult<Array<Record<string, unknown>>>>;
|
|
34
|
+
runQuery: <T = Record<string, unknown>>(sql: string) => Promise<MetricResult<T>>;
|
|
35
|
+
isConfigured: boolean;
|
|
36
|
+
}
|
|
37
|
+
declare function useMetrics(): UseMetricsReturn;
|
|
38
|
+
|
|
39
|
+
export { useAnalytics, useMetrics };
|
package/dist/analytics/index.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AuthContext
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-AWU47M6N.js";
|
|
4
4
|
import {
|
|
5
5
|
ezcoder,
|
|
6
6
|
ezcoderAuthIntegration
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-GPF4AYNG.js";
|
|
8
8
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
env,
|
|
10
|
+
features,
|
|
11
|
+
isSupabaseConfigured,
|
|
12
|
+
supabase
|
|
13
|
+
} from "../chunk-2WG4O4J2.js";
|
|
11
14
|
|
|
12
15
|
// src/analytics/useAnalytics.ts
|
|
13
16
|
import { useEffect, useRef, useCallback, useContext } from "react";
|
|
@@ -70,7 +73,77 @@ function useAnalytics() {
|
|
|
70
73
|
isConfigured: features.analytics
|
|
71
74
|
};
|
|
72
75
|
}
|
|
76
|
+
|
|
77
|
+
// src/analytics/useMetrics.ts
|
|
78
|
+
import { useCallback as useCallback2, useMemo } from "react";
|
|
79
|
+
async function queryRpc(sql, projectId) {
|
|
80
|
+
const { data, error } = await supabase.rpc("sdk_query_project", {
|
|
81
|
+
p_project_id: projectId,
|
|
82
|
+
p_sql: sql
|
|
83
|
+
});
|
|
84
|
+
if (error) {
|
|
85
|
+
return { data: null, error: error.message };
|
|
86
|
+
}
|
|
87
|
+
const result = data;
|
|
88
|
+
if (!result?.success) {
|
|
89
|
+
return { data: null, error: result?.error || "Query failed" };
|
|
90
|
+
}
|
|
91
|
+
return { data: result.data, error: null };
|
|
92
|
+
}
|
|
93
|
+
function useMetrics() {
|
|
94
|
+
const projectId = env.EZC_PROJECT_ID;
|
|
95
|
+
const configured = isSupabaseConfigured && Boolean(projectId);
|
|
96
|
+
const getTotalUsers = useCallback2(async () => {
|
|
97
|
+
if (!configured || !projectId) return { data: null, error: "Not configured" };
|
|
98
|
+
const result = await queryRpc(
|
|
99
|
+
"SELECT COUNT(*)::integer as count FROM user_profiles",
|
|
100
|
+
projectId
|
|
101
|
+
);
|
|
102
|
+
return {
|
|
103
|
+
data: result.data?.[0] ?? null,
|
|
104
|
+
error: result.error
|
|
105
|
+
};
|
|
106
|
+
}, [configured, projectId]);
|
|
107
|
+
const getUserGrowth = useCallback2(async (days = 30) => {
|
|
108
|
+
if (!configured || !projectId) return { data: null, error: "Not configured" };
|
|
109
|
+
return queryRpc(
|
|
110
|
+
`SELECT date_trunc('day', created_at)::date::text as date, COUNT(*)::integer as count FROM user_profiles WHERE created_at > NOW() - INTERVAL '${days} days' GROUP BY 1 ORDER BY 1`,
|
|
111
|
+
projectId
|
|
112
|
+
);
|
|
113
|
+
}, [configured, projectId]);
|
|
114
|
+
const getActiveUsers = useCallback2(async (days = 7) => {
|
|
115
|
+
if (!configured || !projectId) return { data: null, error: "Not configured" };
|
|
116
|
+
const result = await queryRpc(
|
|
117
|
+
`SELECT COUNT(DISTINCT user_id)::integer as count FROM activity_log WHERE created_at > NOW() - INTERVAL '${days} days'`,
|
|
118
|
+
projectId
|
|
119
|
+
);
|
|
120
|
+
return {
|
|
121
|
+
data: result.data?.[0] ?? null,
|
|
122
|
+
error: result.error
|
|
123
|
+
};
|
|
124
|
+
}, [configured, projectId]);
|
|
125
|
+
const getRecentActivity = useCallback2(async (limit = 20) => {
|
|
126
|
+
if (!configured || !projectId) return { data: null, error: "Not configured" };
|
|
127
|
+
return queryRpc(
|
|
128
|
+
`SELECT * FROM activity_log ORDER BY created_at DESC LIMIT ${limit}`,
|
|
129
|
+
projectId
|
|
130
|
+
);
|
|
131
|
+
}, [configured, projectId]);
|
|
132
|
+
const runQuery = useCallback2(async (sql) => {
|
|
133
|
+
if (!configured || !projectId) return { data: null, error: "Not configured" };
|
|
134
|
+
return queryRpc(sql, projectId);
|
|
135
|
+
}, [configured, projectId]);
|
|
136
|
+
return useMemo(() => ({
|
|
137
|
+
getTotalUsers,
|
|
138
|
+
getUserGrowth,
|
|
139
|
+
getActiveUsers,
|
|
140
|
+
getRecentActivity,
|
|
141
|
+
runQuery,
|
|
142
|
+
isConfigured: configured
|
|
143
|
+
}), [getTotalUsers, getUserGrowth, getActiveUsers, getRecentActivity, runQuery, configured]);
|
|
144
|
+
}
|
|
73
145
|
export {
|
|
74
|
-
useAnalytics
|
|
146
|
+
useAnalytics,
|
|
147
|
+
useMetrics
|
|
75
148
|
};
|
|
76
149
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/analytics/useAnalytics.ts"],"sourcesContent":["import { useEffect, useRef, useCallback, useContext } from 'react';\nimport { ezcoder, ezcoderAuthIntegration } from '../core/platform';\nimport { features } from '../core/config';\nimport { AuthContext } from '../auth/AuthProvider';\n\ninterface UseAnalyticsReturn {\n trackEvent: (eventName: string, properties?: Record<string, unknown>) => void;\n trackPageView: (pathname?: string) => void;\n trackError: (message: string, context?: Record<string, unknown>) => void;\n identify: (userId: string, traits?: Record<string, unknown>) => void;\n trackSignup: (user: { id?: string; email?: string }) => void;\n trackLogin: (user: { id?: string }) => void;\n trackLogout: (userId: string) => void;\n isConfigured: boolean;\n}\n\nexport function useAnalytics(): UseAnalyticsReturn {\n const auth = useContext(AuthContext);\n const lastPageViewRef = useRef<string>('');\n\n const enrichProperties = useCallback((properties: Record<string, unknown> = {}): Record<string, unknown> => {\n const enriched = { ...properties };\n if (auth?.user?.id) {\n enriched.userId = auth.user.id;\n enriched.userEmail = auth.user.email;\n }\n if (auth?.profile) {\n const profile = auth.profile as unknown as Record<string, unknown>;\n enriched.userTier = profile.subscription_tier || 'free';\n enriched.userName = profile.display_name;\n }\n return enriched;\n }, [auth?.user, auth?.profile]);\n\n const trackEvent = useCallback((eventName: string, properties: Record<string, unknown> = {}) => {\n if (!features.analytics) return;\n ezcoder.analytics.track(eventName, enrichProperties(properties));\n }, [enrichProperties]);\n\n const trackPageView = useCallback((pathname?: string) => {\n if (!features.analytics) return;\n const path = pathname || (typeof window !== 'undefined' ? window.location.pathname : '/');\n if (path === lastPageViewRef.current) return;\n lastPageViewRef.current = path;\n ezcoder.analytics.pageView(path);\n }, []);\n\n const trackError = useCallback((message: string, context: Record<string, unknown> = {}) => {\n if (!features.analytics) return;\n ezcoder.analytics.error(message, enrichProperties(context));\n }, [enrichProperties]);\n\n const identify = useCallback((userId: string, traits: Record<string, unknown> = {}) => {\n if (!features.analytics) return;\n ezcoder.analytics.identify(userId, traits);\n }, []);\n\n const trackSignup = useCallback((user: { id?: string; email?: string }) => {\n ezcoderAuthIntegration.onSignup(user);\n }, []);\n\n const trackLogin = useCallback((user: { id?: string }) => {\n ezcoderAuthIntegration.onLogin(user);\n }, []);\n\n const trackLogout = useCallback((userId: string) => {\n ezcoderAuthIntegration.onLogout(userId);\n }, []);\n\n useEffect(() => {\n if (!features.analytics) return;\n trackPageView();\n }, [trackPageView]);\n\n return {\n trackEvent,\n trackPageView,\n trackError,\n identify,\n trackSignup,\n trackLogin,\n trackLogout,\n isConfigured: features.analytics,\n };\n}\n"],"mappings":";;;;;;;;;;;;AAAA,SAAS,WAAW,QAAQ,aAAa,kBAAkB;AAgBpD,SAAS,eAAmC;AACjD,QAAM,OAAO,WAAW,WAAW;AACnC,QAAM,kBAAkB,OAAe,EAAE;AAEzC,QAAM,mBAAmB,YAAY,CAAC,aAAsC,CAAC,MAA+B;AAC1G,UAAM,WAAW,EAAE,GAAG,WAAW;AACjC,QAAI,MAAM,MAAM,IAAI;AAClB,eAAS,SAAS,KAAK,KAAK;AAC5B,eAAS,YAAY,KAAK,KAAK;AAAA,IACjC;AACA,QAAI,MAAM,SAAS;AACjB,YAAM,UAAU,KAAK;AACrB,eAAS,WAAW,QAAQ,qBAAqB;AACjD,eAAS,WAAW,QAAQ;AAAA,IAC9B;AACA,WAAO;AAAA,EACT,GAAG,CAAC,MAAM,MAAM,MAAM,OAAO,CAAC;AAE9B,QAAM,aAAa,YAAY,CAAC,WAAmB,aAAsC,CAAC,MAAM;AAC9F,QAAI,CAAC,SAAS,UAAW;AACzB,YAAQ,UAAU,MAAM,WAAW,iBAAiB,UAAU,CAAC;AAAA,EACjE,GAAG,CAAC,gBAAgB,CAAC;AAErB,QAAM,gBAAgB,YAAY,CAAC,aAAsB;AACvD,QAAI,CAAC,SAAS,UAAW;AACzB,UAAM,OAAO,aAAa,OAAO,WAAW,cAAc,OAAO,SAAS,WAAW;AACrF,QAAI,SAAS,gBAAgB,QAAS;AACtC,oBAAgB,UAAU;AAC1B,YAAQ,UAAU,SAAS,IAAI;AAAA,EACjC,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,YAAY,CAAC,SAAiB,UAAmC,CAAC,MAAM;AACzF,QAAI,CAAC,SAAS,UAAW;AACzB,YAAQ,UAAU,MAAM,SAAS,iBAAiB,OAAO,CAAC;AAAA,EAC5D,GAAG,CAAC,gBAAgB,CAAC;AAErB,QAAM,WAAW,YAAY,CAAC,QAAgB,SAAkC,CAAC,MAAM;AACrF,QAAI,CAAC,SAAS,UAAW;AACzB,YAAQ,UAAU,SAAS,QAAQ,MAAM;AAAA,EAC3C,GAAG,CAAC,CAAC;AAEL,QAAM,cAAc,YAAY,CAAC,SAA0C;AACzE,2BAAuB,SAAS,IAAI;AAAA,EACtC,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,YAAY,CAAC,SAA0B;AACxD,2BAAuB,QAAQ,IAAI;AAAA,EACrC,GAAG,CAAC,CAAC;AAEL,QAAM,cAAc,YAAY,CAAC,WAAmB;AAClD,2BAAuB,SAAS,MAAM;AAAA,EACxC,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,CAAC,SAAS,UAAW;AACzB,kBAAc;AAAA,EAChB,GAAG,CAAC,aAAa,CAAC;AAElB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,SAAS;AAAA,EACzB;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/analytics/useAnalytics.ts","../../src/analytics/useMetrics.ts"],"sourcesContent":["import { useEffect, useRef, useCallback, useContext } from 'react';\r\nimport { ezcoder, ezcoderAuthIntegration } from '../core/platform';\r\nimport { features } from '../core/config';\r\nimport { AuthContext } from '../auth/AuthProvider';\r\n\r\ninterface UseAnalyticsReturn {\r\n trackEvent: (eventName: string, properties?: Record<string, unknown>) => void;\r\n trackPageView: (pathname?: string) => void;\r\n trackError: (message: string, context?: Record<string, unknown>) => void;\r\n identify: (userId: string, traits?: Record<string, unknown>) => void;\r\n trackSignup: (user: { id?: string; email?: string }) => void;\r\n trackLogin: (user: { id?: string }) => void;\r\n trackLogout: (userId: string) => void;\r\n isConfigured: boolean;\r\n}\r\n\r\nexport function useAnalytics(): UseAnalyticsReturn {\r\n const auth = useContext(AuthContext);\r\n const lastPageViewRef = useRef<string>('');\r\n\r\n const enrichProperties = useCallback((properties: Record<string, unknown> = {}): Record<string, unknown> => {\r\n const enriched = { ...properties };\r\n if (auth?.user?.id) {\r\n enriched.userId = auth.user.id;\r\n enriched.userEmail = auth.user.email;\r\n }\r\n if (auth?.profile) {\r\n const profile = auth.profile as unknown as Record<string, unknown>;\r\n enriched.userTier = profile.subscription_tier || 'free';\r\n enriched.userName = profile.display_name;\r\n }\r\n return enriched;\r\n }, [auth?.user, auth?.profile]);\r\n\r\n const trackEvent = useCallback((eventName: string, properties: Record<string, unknown> = {}) => {\r\n if (!features.analytics) return;\r\n ezcoder.analytics.track(eventName, enrichProperties(properties));\r\n }, [enrichProperties]);\r\n\r\n const trackPageView = useCallback((pathname?: string) => {\r\n if (!features.analytics) return;\r\n const path = pathname || (typeof window !== 'undefined' ? window.location.pathname : '/');\r\n if (path === lastPageViewRef.current) return;\r\n lastPageViewRef.current = path;\r\n ezcoder.analytics.pageView(path);\r\n }, []);\r\n\r\n const trackError = useCallback((message: string, context: Record<string, unknown> = {}) => {\r\n if (!features.analytics) return;\r\n ezcoder.analytics.error(message, enrichProperties(context));\r\n }, [enrichProperties]);\r\n\r\n const identify = useCallback((userId: string, traits: Record<string, unknown> = {}) => {\r\n if (!features.analytics) return;\r\n ezcoder.analytics.identify(userId, traits);\r\n }, []);\r\n\r\n const trackSignup = useCallback((user: { id?: string; email?: string }) => {\r\n ezcoderAuthIntegration.onSignup(user);\r\n }, []);\r\n\r\n const trackLogin = useCallback((user: { id?: string }) => {\r\n ezcoderAuthIntegration.onLogin(user);\r\n }, []);\r\n\r\n const trackLogout = useCallback((userId: string) => {\r\n ezcoderAuthIntegration.onLogout(userId);\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!features.analytics) return;\r\n trackPageView();\r\n }, [trackPageView]);\r\n\r\n return {\r\n trackEvent,\r\n trackPageView,\r\n trackError,\r\n identify,\r\n trackSignup,\r\n trackLogin,\r\n trackLogout,\r\n isConfigured: features.analytics,\r\n };\r\n}\r\n","import { useCallback, useMemo } from 'react';\r\nimport { supabase, isSupabaseConfigured } from '../core/supabase';\r\nimport { env } from '../core/config';\r\n\r\ninterface MetricResult<T = Record<string, unknown>> {\r\n data: T | null;\r\n error: string | null;\r\n}\r\n\r\ninterface UseMetricsReturn {\r\n getTotalUsers: () => Promise<MetricResult<{ count: number }>>;\r\n getUserGrowth: (days?: number) => Promise<MetricResult<Array<{ date: string; count: number }>>>;\r\n getActiveUsers: (days?: number) => Promise<MetricResult<{ count: number }>>;\r\n getRecentActivity: (limit?: number) => Promise<MetricResult<Array<Record<string, unknown>>>>;\r\n runQuery: <T = Record<string, unknown>>(sql: string) => Promise<MetricResult<T>>;\r\n isConfigured: boolean;\r\n}\r\n\r\nasync function queryRpc<T>(sql: string, projectId: string): Promise<MetricResult<T>> {\r\n const { data, error } = await supabase.rpc('sdk_query_project', {\r\n p_project_id: projectId,\r\n p_sql: sql,\r\n });\r\n\r\n if (error) {\r\n return { data: null, error: error.message };\r\n }\r\n\r\n const result = data as { success: boolean; data: T; error?: string };\r\n if (!result?.success) {\r\n return { data: null, error: result?.error || 'Query failed' };\r\n }\r\n\r\n return { data: result.data, error: null };\r\n}\r\n\r\nexport function useMetrics(): UseMetricsReturn {\r\n const projectId = env.EZC_PROJECT_ID;\r\n const configured = isSupabaseConfigured && Boolean(projectId);\r\n\r\n const getTotalUsers = useCallback(async () => {\r\n if (!configured || !projectId) return { data: null, error: 'Not configured' };\r\n const result = await queryRpc<Array<{ count: number }>>(\r\n 'SELECT COUNT(*)::integer as count FROM user_profiles',\r\n projectId,\r\n );\r\n return {\r\n data: result.data?.[0] ?? null,\r\n error: result.error,\r\n };\r\n }, [configured, projectId]);\r\n\r\n const getUserGrowth = useCallback(async (days = 30) => {\r\n if (!configured || !projectId) return { data: null, error: 'Not configured' };\r\n return queryRpc<Array<{ date: string; count: number }>>(\r\n `SELECT date_trunc('day', created_at)::date::text as date, COUNT(*)::integer as count FROM user_profiles WHERE created_at > NOW() - INTERVAL '${days} days' GROUP BY 1 ORDER BY 1`,\r\n projectId,\r\n );\r\n }, [configured, projectId]);\r\n\r\n const getActiveUsers = useCallback(async (days = 7) => {\r\n if (!configured || !projectId) return { data: null, error: 'Not configured' };\r\n const result = await queryRpc<Array<{ count: number }>>(\r\n `SELECT COUNT(DISTINCT user_id)::integer as count FROM activity_log WHERE created_at > NOW() - INTERVAL '${days} days'`,\r\n projectId,\r\n );\r\n return {\r\n data: result.data?.[0] ?? null,\r\n error: result.error,\r\n };\r\n }, [configured, projectId]);\r\n\r\n const getRecentActivity = useCallback(async (limit = 20) => {\r\n if (!configured || !projectId) return { data: null, error: 'Not configured' };\r\n return queryRpc<Array<Record<string, unknown>>>(\r\n `SELECT * FROM activity_log ORDER BY created_at DESC LIMIT ${limit}`,\r\n projectId,\r\n );\r\n }, [configured, projectId]);\r\n\r\n const runQuery = useCallback(async <T = Record<string, unknown>>(sql: string) => {\r\n if (!configured || !projectId) return { data: null, error: 'Not configured' } as MetricResult<T>;\r\n return queryRpc<T>(sql, projectId);\r\n }, [configured, projectId]);\r\n\r\n return useMemo(() => ({\r\n getTotalUsers,\r\n getUserGrowth,\r\n getActiveUsers,\r\n getRecentActivity,\r\n runQuery,\r\n isConfigured: configured,\r\n }), [getTotalUsers, getUserGrowth, getActiveUsers, getRecentActivity, runQuery, configured]);\r\n}\r\n"],"mappings":"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","names":["useCallback","useCallback"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/animation/variants.ts"],"sourcesContent":["export const DURATION = {\n fast: 0.15,\n normal: 0.3,\n slow: 0.5,\n};\n\nexport const EASING = {\n easeInOut: [0.4, 0, 0.2, 1] as const,\n easeOut: [0, 0, 0.2, 1] as const,\n spring: { type: 'spring' as const, stiffness: 300, damping: 30 },\n};\n\nexport const fadeIn = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: { duration: DURATION.normal },\n};\n\nexport const slideUp = {\n initial: { opacity: 0, y: 20 },\n animate: { opacity: 1, y: 0 },\n exit: { opacity: 0, y: -20 },\n transition: { duration: DURATION.normal },\n};\n\nexport const slideInLeft = {\n initial: { opacity: 0, x: -20 },\n animate: { opacity: 1, x: 0 },\n exit: { opacity: 0, x: 20 },\n transition: { duration: DURATION.normal },\n};\n\nexport const scaleIn = {\n initial: { opacity: 0, scale: 0.95 },\n animate: { opacity: 1, scale: 1 },\n exit: { opacity: 0, scale: 0.95 },\n transition: { duration: DURATION.fast },\n};\n\nexport const staggerContainer = {\n animate: {\n transition: {\n staggerChildren: 0.1,\n },\n },\n};\n\nexport const staggerItem = {\n initial: { opacity: 0, y: 10 },\n animate: { opacity: 1, y: 0 },\n};\n\nexport const pageTransition = {\n initial: { opacity: 0, y: 10 },\n animate: { opacity: 1, y: 0 },\n exit: { opacity: 0, y: -10 },\n transition: { duration: DURATION.normal },\n};\n\nexport const tailwindAnimations = {\n keyframes: {\n fadeIn: { '0%': { opacity: '0' }, '100%': { opacity: '1' } },\n slideUp: { '0%': { opacity: '0', transform: 'translateY(10px)' }, '100%': { opacity: '1', transform: 'translateY(0)' } },\n slideDown: { '0%': { opacity: '0', transform: 'translateY(-10px)' }, '100%': { opacity: '1', transform: 'translateY(0)' } },\n scaleIn: { '0%': { opacity: '0', transform: 'scale(0.95)' }, '100%': { opacity: '1', transform: 'scale(1)' } },\n shimmer: { '0%': { backgroundPosition: '-200% 0' }, '100%': { backgroundPosition: '200% 0' } },\n },\n animation: {\n 'fade-in': 'fadeIn 0.3s ease-out',\n 'slide-up': 'slideUp 0.3s ease-out',\n 'slide-down': 'slideDown 0.3s ease-out',\n 'scale-in': 'scaleIn 0.2s ease-out',\n shimmer: 'shimmer 2s infinite linear',\n },\n};\n"],"mappings":";AAAO,IAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,MAAM;AACR;AAEO,IAAM,SAAS;AAAA,EACpB,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC;AAAA,EAC1B,SAAS,CAAC,GAAG,GAAG,KAAK,CAAC;AAAA,EACtB,QAAQ,EAAE,MAAM,UAAmB,WAAW,KAAK,SAAS,GAAG;AACjE;AAEO,IAAM,SAAS;AAAA,EACpB,SAAS,EAAE,SAAS,EAAE;AAAA,EACtB,SAAS,EAAE,SAAS,EAAE;AAAA,EACtB,MAAM,EAAE,SAAS,EAAE;AAAA,EACnB,YAAY,EAAE,UAAU,SAAS,OAAO;AAC1C;AAEO,IAAM,UAAU;AAAA,EACrB,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,EAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,EAC5B,MAAM,EAAE,SAAS,GAAG,GAAG,IAAI;AAAA,EAC3B,YAAY,EAAE,UAAU,SAAS,OAAO;AAC1C;AAEO,IAAM,cAAc;AAAA,EACzB,SAAS,EAAE,SAAS,GAAG,GAAG,IAAI;AAAA,EAC9B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,EAC5B,MAAM,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,EAC1B,YAAY,EAAE,UAAU,SAAS,OAAO;AAC1C;AAEO,IAAM,UAAU;AAAA,EACrB,SAAS,EAAE,SAAS,GAAG,OAAO,KAAK;AAAA,EACnC,SAAS,EAAE,SAAS,GAAG,OAAO,EAAE;AAAA,EAChC,MAAM,EAAE,SAAS,GAAG,OAAO,KAAK;AAAA,EAChC,YAAY,EAAE,UAAU,SAAS,KAAK;AACxC;AAEO,IAAM,mBAAmB;AAAA,EAC9B,SAAS;AAAA,IACP,YAAY;AAAA,MACV,iBAAiB;AAAA,IACnB;AAAA,EACF;AACF;AAEO,IAAM,cAAc;AAAA,EACzB,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,EAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAC9B;AAEO,IAAM,iBAAiB;AAAA,EAC5B,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,EAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,EAC5B,MAAM,EAAE,SAAS,GAAG,GAAG,IAAI;AAAA,EAC3B,YAAY,EAAE,UAAU,SAAS,OAAO;AAC1C;AAEO,IAAM,qBAAqB;AAAA,EAChC,WAAW;AAAA,IACT,QAAQ,EAAE,MAAM,EAAE,SAAS,IAAI,GAAG,QAAQ,EAAE,SAAS,IAAI,EAAE;AAAA,IAC3D,SAAS,EAAE,MAAM,EAAE,SAAS,KAAK,WAAW,mBAAmB,GAAG,QAAQ,EAAE,SAAS,KAAK,WAAW,gBAAgB,EAAE;AAAA,IACvH,WAAW,EAAE,MAAM,EAAE,SAAS,KAAK,WAAW,oBAAoB,GAAG,QAAQ,EAAE,SAAS,KAAK,WAAW,gBAAgB,EAAE;AAAA,IAC1H,SAAS,EAAE,MAAM,EAAE,SAAS,KAAK,WAAW,cAAc,GAAG,QAAQ,EAAE,SAAS,KAAK,WAAW,WAAW,EAAE;AAAA,IAC7G,SAAS,EAAE,MAAM,EAAE,oBAAoB,UAAU,GAAG,QAAQ,EAAE,oBAAoB,SAAS,EAAE;AAAA,EAC/F;AAAA,EACA,WAAW;AAAA,IACT,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,SAAS;AAAA,EACX;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/animation/variants.ts"],"sourcesContent":["export const DURATION = {\r\n fast: 0.15,\r\n normal: 0.3,\r\n slow: 0.5,\r\n};\r\n\r\nexport const EASING = {\r\n easeInOut: [0.4, 0, 0.2, 1] as const,\r\n easeOut: [0, 0, 0.2, 1] as const,\r\n spring: { type: 'spring' as const, stiffness: 300, damping: 30 },\r\n};\r\n\r\nexport const fadeIn = {\r\n initial: { opacity: 0 },\r\n animate: { opacity: 1 },\r\n exit: { opacity: 0 },\r\n transition: { duration: DURATION.normal },\r\n};\r\n\r\nexport const slideUp = {\r\n initial: { opacity: 0, y: 20 },\r\n animate: { opacity: 1, y: 0 },\r\n exit: { opacity: 0, y: -20 },\r\n transition: { duration: DURATION.normal },\r\n};\r\n\r\nexport const slideInLeft = {\r\n initial: { opacity: 0, x: -20 },\r\n animate: { opacity: 1, x: 0 },\r\n exit: { opacity: 0, x: 20 },\r\n transition: { duration: DURATION.normal },\r\n};\r\n\r\nexport const scaleIn = {\r\n initial: { opacity: 0, scale: 0.95 },\r\n animate: { opacity: 1, scale: 1 },\r\n exit: { opacity: 0, scale: 0.95 },\r\n transition: { duration: DURATION.fast },\r\n};\r\n\r\nexport const staggerContainer = {\r\n animate: {\r\n transition: {\r\n staggerChildren: 0.1,\r\n },\r\n },\r\n};\r\n\r\nexport const staggerItem = {\r\n initial: { opacity: 0, y: 10 },\r\n animate: { opacity: 1, y: 0 },\r\n};\r\n\r\nexport const pageTransition = {\r\n initial: { opacity: 0, y: 10 },\r\n animate: { opacity: 1, y: 0 },\r\n exit: { opacity: 0, y: -10 },\r\n transition: { duration: DURATION.normal },\r\n};\r\n\r\nexport const tailwindAnimations = {\r\n keyframes: {\r\n fadeIn: { '0%': { opacity: '0' }, '100%': { opacity: '1' } },\r\n slideUp: { '0%': { opacity: '0', transform: 'translateY(10px)' }, '100%': { opacity: '1', transform: 'translateY(0)' } },\r\n slideDown: { '0%': { opacity: '0', transform: 'translateY(-10px)' }, '100%': { opacity: '1', transform: 'translateY(0)' } },\r\n scaleIn: { '0%': { opacity: '0', transform: 'scale(0.95)' }, '100%': { opacity: '1', transform: 'scale(1)' } },\r\n shimmer: { '0%': { backgroundPosition: '-200% 0' }, '100%': { backgroundPosition: '200% 0' } },\r\n },\r\n animation: {\r\n 'fade-in': 'fadeIn 0.3s ease-out',\r\n 'slide-up': 'slideUp 0.3s ease-out',\r\n 'slide-down': 'slideDown 0.3s ease-out',\r\n 'scale-in': 'scaleIn 0.2s ease-out',\r\n shimmer: 'shimmer 2s infinite linear',\r\n },\r\n};\r\n"],"mappings":";AAAO,IAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,MAAM;AACR;AAEO,IAAM,SAAS;AAAA,EACpB,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC;AAAA,EAC1B,SAAS,CAAC,GAAG,GAAG,KAAK,CAAC;AAAA,EACtB,QAAQ,EAAE,MAAM,UAAmB,WAAW,KAAK,SAAS,GAAG;AACjE;AAEO,IAAM,SAAS;AAAA,EACpB,SAAS,EAAE,SAAS,EAAE;AAAA,EACtB,SAAS,EAAE,SAAS,EAAE;AAAA,EACtB,MAAM,EAAE,SAAS,EAAE;AAAA,EACnB,YAAY,EAAE,UAAU,SAAS,OAAO;AAC1C;AAEO,IAAM,UAAU;AAAA,EACrB,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,EAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,EAC5B,MAAM,EAAE,SAAS,GAAG,GAAG,IAAI;AAAA,EAC3B,YAAY,EAAE,UAAU,SAAS,OAAO;AAC1C;AAEO,IAAM,cAAc;AAAA,EACzB,SAAS,EAAE,SAAS,GAAG,GAAG,IAAI;AAAA,EAC9B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,EAC5B,MAAM,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,EAC1B,YAAY,EAAE,UAAU,SAAS,OAAO;AAC1C;AAEO,IAAM,UAAU;AAAA,EACrB,SAAS,EAAE,SAAS,GAAG,OAAO,KAAK;AAAA,EACnC,SAAS,EAAE,SAAS,GAAG,OAAO,EAAE;AAAA,EAChC,MAAM,EAAE,SAAS,GAAG,OAAO,KAAK;AAAA,EAChC,YAAY,EAAE,UAAU,SAAS,KAAK;AACxC;AAEO,IAAM,mBAAmB;AAAA,EAC9B,SAAS;AAAA,IACP,YAAY;AAAA,MACV,iBAAiB;AAAA,IACnB;AAAA,EACF;AACF;AAEO,IAAM,cAAc;AAAA,EACzB,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,EAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAC9B;AAEO,IAAM,iBAAiB;AAAA,EAC5B,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,EAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,EAC5B,MAAM,EAAE,SAAS,GAAG,GAAG,IAAI;AAAA,EAC3B,YAAY,EAAE,UAAU,SAAS,OAAO;AAC1C;AAEO,IAAM,qBAAqB;AAAA,EAChC,WAAW;AAAA,IACT,QAAQ,EAAE,MAAM,EAAE,SAAS,IAAI,GAAG,QAAQ,EAAE,SAAS,IAAI,EAAE;AAAA,IAC3D,SAAS,EAAE,MAAM,EAAE,SAAS,KAAK,WAAW,mBAAmB,GAAG,QAAQ,EAAE,SAAS,KAAK,WAAW,gBAAgB,EAAE;AAAA,IACvH,WAAW,EAAE,MAAM,EAAE,SAAS,KAAK,WAAW,oBAAoB,GAAG,QAAQ,EAAE,SAAS,KAAK,WAAW,gBAAgB,EAAE;AAAA,IAC1H,SAAS,EAAE,MAAM,EAAE,SAAS,KAAK,WAAW,cAAc,GAAG,QAAQ,EAAE,SAAS,KAAK,WAAW,WAAW,EAAE;AAAA,IAC7G,SAAS,EAAE,MAAM,EAAE,oBAAoB,UAAU,GAAG,QAAQ,EAAE,oBAAoB,SAAS,EAAE;AAAA,EAC/F;AAAA,EACA,WAAW;AAAA,IACT,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,SAAS;AAAA,EACX;AACF;","names":[]}
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { User, Session } from '@supabase/supabase-js';
|
|
4
|
-
import { U as UserProfile, e as SubscriptionTier } from '../types-
|
|
4
|
+
import { U as UserProfile, e as SubscriptionTier } from '../types-1uP3V_pe.js';
|
|
5
5
|
|
|
6
6
|
interface AuthResult<T = unknown> {
|
|
7
7
|
data: T | null;
|
package/dist/auth/index.js
CHANGED
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
AuthContext,
|
|
3
3
|
AuthProvider,
|
|
4
4
|
useAuth
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-AWU47M6N.js";
|
|
6
|
+
import "../chunk-GPF4AYNG.js";
|
|
7
7
|
import {
|
|
8
8
|
supabase
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-2WG4O4J2.js";
|
|
10
10
|
|
|
11
11
|
// src/auth/ProtectedRoute.tsx
|
|
12
12
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
package/dist/auth/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/ProtectedRoute.tsx","../../src/auth/LoginForm.tsx","../../src/auth/SignupForm.tsx","../../src/auth/ForgotPasswordForm.tsx","../../src/auth/AuthCallback.tsx"],"sourcesContent":["import { useAuth } from './AuthProvider';\nimport type { SubscriptionTier } from '../core/types';\n\ninterface ProtectedRouteProps {\n children: React.ReactNode;\n requiredRoles?: string[];\n requiredTier?: SubscriptionTier;\n fallback?: React.ReactNode;\n unauthorizedFallback?: React.ReactNode;\n allowUnconfigured?: boolean;\n loadingComponent?: React.ReactNode;\n loginPath?: string;\n}\n\nconst TIER_LEVELS: Record<string, number> = {\n free: 0,\n starter: 1,\n creator: 2,\n pro: 3,\n business: 4,\n enterprise: 5,\n};\n\nfunction DefaultLoadingSpinner() {\n return (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '200px' }}>\n <div style={{\n width: '32px', height: '32px',\n border: '3px solid #e5e7eb', borderTopColor: '#3b82f6',\n borderRadius: '50%',\n animation: 'spin 0.6s linear infinite',\n }} />\n <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>\n </div>\n );\n}\n\nexport function ProtectedRoute({\n children,\n requiredTier,\n fallback,\n loadingComponent,\n allowUnconfigured = false,\n loginPath = '/login',\n}: ProtectedRouteProps) {\n const { user, profile, loading, isConfigured } = useAuth();\n\n if (loading) {\n return <>{loadingComponent || <DefaultLoadingSpinner />}</>;\n }\n\n if (!isConfigured && allowUnconfigured) {\n return <>{children}</>;\n }\n\n if (!user) {\n if (fallback) return <>{fallback}</>;\n if (typeof window !== 'undefined') {\n window.location.href = loginPath;\n }\n return null;\n }\n\n if (requiredTier) {\n const userTier = profile?.subscription_tier || 'free';\n const userLevel = TIER_LEVELS[userTier] ?? 0;\n const requiredLevel = TIER_LEVELS[requiredTier] ?? 0;\n\n if (userLevel < requiredLevel) {\n return (\n <div style={{ textAlign: 'center', padding: '40px' }}>\n <h2 style={{ fontSize: '1.5rem', fontWeight: 600, marginBottom: '8px' }}>Upgrade Required</h2>\n <p style={{ color: '#6b7280' }}>\n This feature requires the {requiredTier} plan or higher.\n </p>\n </div>\n );\n }\n }\n\n return <>{children}</>;\n}\n","import { useState } from 'react';\nimport { useAuth } from './AuthProvider';\n\ninterface LoginFormProps {\n onSuccess?: () => void;\n onForgotPassword?: () => void;\n onSignupClick?: () => void;\n showOAuth?: boolean;\n className?: string;\n}\n\nexport function LoginForm({\n onSuccess,\n onForgotPassword,\n onSignupClick,\n showOAuth = true,\n className = '',\n}: LoginFormProps) {\n const { signIn, signInWithProvider, isConfigured } = useAuth();\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n setLoading(true);\n\n const result = await signIn(email, password);\n setLoading(false);\n\n if (result.error) {\n setError(result.error.message);\n } else {\n onSuccess?.();\n }\n };\n\n const handleOAuth = async (provider: string) => {\n setError(null);\n const result = await signInWithProvider(provider);\n if (result.error) {\n setError(result.error.message);\n }\n };\n\n if (!isConfigured) {\n return (\n <div style={{ padding: '20px', textAlign: 'center', color: '#6b7280' }}>\n Authentication is not configured. Connect a database to enable login.\n </div>\n );\n }\n\n return (\n <div className={className} style={{ maxWidth: '400px', margin: '0 auto' }}>\n <h2 style={{ fontSize: '1.5rem', fontWeight: 600, marginBottom: '24px', textAlign: 'center' }}>\n Sign In\n </h2>\n\n {error && (\n <div style={{ padding: '12px', marginBottom: '16px', backgroundColor: '#fef2f2', color: '#dc2626', borderRadius: '8px', fontSize: '14px' }}>\n {error}\n </div>\n )}\n\n <form onSubmit={handleSubmit}>\n <div style={{ marginBottom: '16px' }}>\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '14px', fontWeight: 500 }}>Email</label>\n <input\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n style={{ width: '100%', padding: '8px 12px', border: '1px solid #d1d5db', borderRadius: '6px', fontSize: '14px' }}\n />\n </div>\n\n <div style={{ marginBottom: '16px' }}>\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '14px', fontWeight: 500 }}>Password</label>\n <input\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n style={{ width: '100%', padding: '8px 12px', border: '1px solid #d1d5db', borderRadius: '6px', fontSize: '14px' }}\n />\n </div>\n\n {onForgotPassword && (\n <div style={{ marginBottom: '16px', textAlign: 'right' }}>\n <button type=\"button\" onClick={onForgotPassword} style={{ background: 'none', border: 'none', color: '#3b82f6', cursor: 'pointer', fontSize: '14px' }}>\n Forgot password?\n </button>\n </div>\n )}\n\n <button\n type=\"submit\"\n disabled={loading}\n style={{\n width: '100%', padding: '10px', backgroundColor: '#3b82f6', color: 'white',\n border: 'none', borderRadius: '6px', fontSize: '14px', fontWeight: 500,\n cursor: loading ? 'not-allowed' : 'pointer', opacity: loading ? 0.7 : 1,\n }}\n >\n {loading ? 'Signing in...' : 'Sign In'}\n </button>\n </form>\n\n {showOAuth && (\n <div style={{ marginTop: '24px' }}>\n <div style={{ textAlign: 'center', color: '#9ca3af', fontSize: '14px', marginBottom: '16px' }}>or continue with</div>\n <div style={{ display: 'flex', gap: '12px' }}>\n <button\n onClick={() => handleOAuth('google')}\n style={{ flex: 1, padding: '10px', border: '1px solid #d1d5db', borderRadius: '6px', background: 'white', cursor: 'pointer', fontSize: '14px' }}\n >\n Google\n </button>\n <button\n onClick={() => handleOAuth('github')}\n style={{ flex: 1, padding: '10px', border: '1px solid #d1d5db', borderRadius: '6px', background: 'white', cursor: 'pointer', fontSize: '14px' }}\n >\n GitHub\n </button>\n </div>\n </div>\n )}\n\n {onSignupClick && (\n <div style={{ marginTop: '24px', textAlign: 'center', fontSize: '14px' }}>\n Don't have an account?{' '}\n <button type=\"button\" onClick={onSignupClick} style={{ background: 'none', border: 'none', color: '#3b82f6', cursor: 'pointer', fontWeight: 500 }}>\n Sign up\n </button>\n </div>\n )}\n </div>\n );\n}\n","import { useState } from 'react';\nimport { useAuth } from './AuthProvider';\n\ninterface SignupFormProps {\n onSuccess?: () => void;\n onLoginClick?: () => void;\n showOAuth?: boolean;\n className?: string;\n}\n\nexport function SignupForm({\n onSuccess,\n onLoginClick,\n showOAuth = true,\n className = '',\n}: SignupFormProps) {\n const { signUp, signInWithProvider, isConfigured } = useAuth();\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [agreed, setAgreed] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [success, setSuccess] = useState(false);\n const [loading, setLoading] = useState(false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!agreed) {\n setError('Please agree to the Terms of Service');\n return;\n }\n if (password.length < 8) {\n setError('Password must be at least 8 characters');\n return;\n }\n\n setError(null);\n setLoading(true);\n\n const result = await signUp(email, password, {\n metadata: { display_name: name },\n });\n setLoading(false);\n\n if (result.error) {\n setError(result.error.message);\n } else {\n setSuccess(true);\n onSuccess?.();\n }\n };\n\n const handleOAuth = async (provider: string) => {\n setError(null);\n const result = await signInWithProvider(provider);\n if (result.error) {\n setError(result.error.message);\n }\n };\n\n if (!isConfigured) {\n return (\n <div style={{ padding: '20px', textAlign: 'center', color: '#6b7280' }}>\n Authentication is not configured. Connect a database to enable signup.\n </div>\n );\n }\n\n if (success) {\n return (\n <div style={{ padding: '20px', textAlign: 'center' }}>\n <h3 style={{ fontSize: '1.25rem', fontWeight: 600, marginBottom: '8px', color: '#059669' }}>Check your email</h3>\n <p style={{ color: '#6b7280' }}>We sent a confirmation link to {email}</p>\n </div>\n );\n }\n\n return (\n <div className={className} style={{ maxWidth: '400px', margin: '0 auto' }}>\n <h2 style={{ fontSize: '1.5rem', fontWeight: 600, marginBottom: '24px', textAlign: 'center' }}>\n Create Account\n </h2>\n\n {error && (\n <div style={{ padding: '12px', marginBottom: '16px', backgroundColor: '#fef2f2', color: '#dc2626', borderRadius: '8px', fontSize: '14px' }}>\n {error}\n </div>\n )}\n\n <form onSubmit={handleSubmit}>\n <div style={{ marginBottom: '16px' }}>\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '14px', fontWeight: 500 }}>Name</label>\n <input type=\"text\" value={name} onChange={(e) => setName(e.target.value)} required\n style={{ width: '100%', padding: '8px 12px', border: '1px solid #d1d5db', borderRadius: '6px', fontSize: '14px' }} />\n </div>\n\n <div style={{ marginBottom: '16px' }}>\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '14px', fontWeight: 500 }}>Email</label>\n <input type=\"email\" value={email} onChange={(e) => setEmail(e.target.value)} required\n style={{ width: '100%', padding: '8px 12px', border: '1px solid #d1d5db', borderRadius: '6px', fontSize: '14px' }} />\n </div>\n\n <div style={{ marginBottom: '16px' }}>\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '14px', fontWeight: 500 }}>Password</label>\n <input type=\"password\" value={password} onChange={(e) => setPassword(e.target.value)} required minLength={8}\n style={{ width: '100%', padding: '8px 12px', border: '1px solid #d1d5db', borderRadius: '6px', fontSize: '14px' }} />\n <span style={{ fontSize: '12px', color: '#9ca3af' }}>Minimum 8 characters</span>\n </div>\n\n <div style={{ marginBottom: '16px' }}>\n <label style={{ display: 'flex', alignItems: 'center', gap: '8px', fontSize: '14px', cursor: 'pointer' }}>\n <input type=\"checkbox\" checked={agreed} onChange={(e) => setAgreed(e.target.checked)} />\n I agree to the Terms of Service and Privacy Policy\n </label>\n </div>\n\n <button type=\"submit\" disabled={loading}\n style={{\n width: '100%', padding: '10px', backgroundColor: '#3b82f6', color: 'white',\n border: 'none', borderRadius: '6px', fontSize: '14px', fontWeight: 500,\n cursor: loading ? 'not-allowed' : 'pointer', opacity: loading ? 0.7 : 1,\n }}>\n {loading ? 'Creating account...' : 'Create Account'}\n </button>\n </form>\n\n {showOAuth && (\n <div style={{ marginTop: '24px' }}>\n <div style={{ textAlign: 'center', color: '#9ca3af', fontSize: '14px', marginBottom: '16px' }}>or continue with</div>\n <div style={{ display: 'flex', gap: '12px' }}>\n <button onClick={() => handleOAuth('google')}\n style={{ flex: 1, padding: '10px', border: '1px solid #d1d5db', borderRadius: '6px', background: 'white', cursor: 'pointer', fontSize: '14px' }}>\n Google\n </button>\n <button onClick={() => handleOAuth('github')}\n style={{ flex: 1, padding: '10px', border: '1px solid #d1d5db', borderRadius: '6px', background: 'white', cursor: 'pointer', fontSize: '14px' }}>\n GitHub\n </button>\n </div>\n </div>\n )}\n\n {onLoginClick && (\n <div style={{ marginTop: '24px', textAlign: 'center', fontSize: '14px' }}>\n Already have an account?{' '}\n <button type=\"button\" onClick={onLoginClick} style={{ background: 'none', border: 'none', color: '#3b82f6', cursor: 'pointer', fontWeight: 500 }}>\n Sign in\n </button>\n </div>\n )}\n </div>\n );\n}\n","import { useState } from 'react';\nimport { useAuth } from './AuthProvider';\n\ninterface ForgotPasswordFormProps {\n onBack?: () => void;\n className?: string;\n}\n\nexport function ForgotPasswordForm({ onBack, className = '' }: ForgotPasswordFormProps) {\n const { resetPassword } = useAuth();\n const [email, setEmail] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [success, setSuccess] = useState(false);\n const [loading, setLoading] = useState(false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n setLoading(true);\n\n const result = await resetPassword(email);\n setLoading(false);\n\n if (result.error) {\n setError(result.error.message);\n } else {\n setSuccess(true);\n }\n };\n\n if (success) {\n return (\n <div className={className} style={{ maxWidth: '400px', margin: '0 auto', textAlign: 'center', padding: '20px' }}>\n <h3 style={{ fontSize: '1.25rem', fontWeight: 600, marginBottom: '8px', color: '#059669' }}>Check your email</h3>\n <p style={{ color: '#6b7280', marginBottom: '16px' }}>We sent a password reset link to {email}</p>\n {onBack && (\n <button type=\"button\" onClick={onBack} style={{ background: 'none', border: 'none', color: '#3b82f6', cursor: 'pointer', fontSize: '14px' }}>\n Back to login\n </button>\n )}\n </div>\n );\n }\n\n return (\n <div className={className} style={{ maxWidth: '400px', margin: '0 auto' }}>\n <h2 style={{ fontSize: '1.5rem', fontWeight: 600, marginBottom: '8px', textAlign: 'center' }}>Reset Password</h2>\n <p style={{ color: '#6b7280', textAlign: 'center', marginBottom: '24px', fontSize: '14px' }}>\n Enter your email and we'll send you a reset link\n </p>\n\n {error && (\n <div style={{ padding: '12px', marginBottom: '16px', backgroundColor: '#fef2f2', color: '#dc2626', borderRadius: '8px', fontSize: '14px' }}>\n {error}\n </div>\n )}\n\n <form onSubmit={handleSubmit}>\n <div style={{ marginBottom: '16px' }}>\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '14px', fontWeight: 500 }}>Email</label>\n <input type=\"email\" value={email} onChange={(e) => setEmail(e.target.value)} required\n style={{ width: '100%', padding: '8px 12px', border: '1px solid #d1d5db', borderRadius: '6px', fontSize: '14px' }} />\n </div>\n\n <button type=\"submit\" disabled={loading}\n style={{\n width: '100%', padding: '10px', backgroundColor: '#3b82f6', color: 'white',\n border: 'none', borderRadius: '6px', fontSize: '14px', fontWeight: 500,\n cursor: loading ? 'not-allowed' : 'pointer', opacity: loading ? 0.7 : 1,\n }}>\n {loading ? 'Sending...' : 'Send Reset Link'}\n </button>\n </form>\n\n {onBack && (\n <div style={{ marginTop: '16px', textAlign: 'center' }}>\n <button type=\"button\" onClick={onBack} style={{ background: 'none', border: 'none', color: '#3b82f6', cursor: 'pointer', fontSize: '14px' }}>\n Back to login\n </button>\n </div>\n )}\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\nimport { supabase } from '../core/supabase';\n\ninterface AuthCallbackProps {\n redirectTo?: string;\n loadingComponent?: React.ReactNode;\n}\n\nexport function AuthCallback({ redirectTo = '/', loadingComponent }: AuthCallbackProps) {\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const handleCallback = async () => {\n try {\n const { error } = await supabase.auth.getSession();\n if (error) {\n setError(error.message);\n return;\n }\n window.location.href = redirectTo;\n } catch (err: unknown) {\n setError(err instanceof Error ? err.message : 'Authentication callback failed');\n }\n };\n\n handleCallback();\n }, [redirectTo]);\n\n if (error) {\n return (\n <div style={{ textAlign: 'center', padding: '40px' }}>\n <h2 style={{ color: '#dc2626', marginBottom: '8px' }}>Authentication Error</h2>\n <p style={{ color: '#6b7280' }}>{error}</p>\n <a href=\"/login\" style={{ color: '#3b82f6', marginTop: '16px', display: 'inline-block' }}>\n Back to login\n </a>\n </div>\n );\n }\n\n return (\n <>\n {loadingComponent || (\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '200px' }}>\n <p style={{ color: '#6b7280' }}>Completing authentication...</p>\n </div>\n )}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;AAyBI,SAuBO,UAtBL,KADF;AAXJ,IAAM,cAAsC;AAAA,EAC1C,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,KAAK;AAAA,EACL,UAAU;AAAA,EACV,YAAY;AACd;AAEA,SAAS,wBAAwB;AAC/B,SACE,qBAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,gBAAgB,UAAU,WAAW,QAAQ,GAChG;AAAA,wBAAC,SAAI,OAAO;AAAA,MACV,OAAO;AAAA,MAAQ,QAAQ;AAAA,MACvB,QAAQ;AAAA,MAAqB,gBAAgB;AAAA,MAC7C,cAAc;AAAA,MACd,WAAW;AAAA,IACb,GAAG;AAAA,IACH,oBAAC,WAAO,mEAAwD;AAAA,KAClE;AAEJ;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAoB;AAAA,EACpB,YAAY;AACd,GAAwB;AACtB,QAAM,EAAE,MAAM,SAAS,SAAS,aAAa,IAAI,QAAQ;AAEzD,MAAI,SAAS;AACX,WAAO,gCAAG,8BAAoB,oBAAC,yBAAsB,GAAG;AAAA,EAC1D;AAEA,MAAI,CAAC,gBAAgB,mBAAmB;AACtC,WAAO,gCAAG,UAAS;AAAA,EACrB;AAEA,MAAI,CAAC,MAAM;AACT,QAAI,SAAU,QAAO,gCAAG,oBAAS;AACjC,QAAI,OAAO,WAAW,aAAa;AACjC,aAAO,SAAS,OAAO;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AAEA,MAAI,cAAc;AAChB,UAAM,WAAW,SAAS,qBAAqB;AAC/C,UAAM,YAAY,YAAY,QAAQ,KAAK;AAC3C,UAAM,gBAAgB,YAAY,YAAY,KAAK;AAEnD,QAAI,YAAY,eAAe;AAC7B,aACE,qBAAC,SAAI,OAAO,EAAE,WAAW,UAAU,SAAS,OAAO,GACjD;AAAA,4BAAC,QAAG,OAAO,EAAE,UAAU,UAAU,YAAY,KAAK,cAAc,MAAM,GAAG,8BAAgB;AAAA,QACzF,qBAAC,OAAE,OAAO,EAAE,OAAO,UAAU,GAAG;AAAA;AAAA,UACH;AAAA,UAAa;AAAA,WAC1C;AAAA,SACF;AAAA,IAEJ;AAAA,EACF;AAEA,SAAO,gCAAG,UAAS;AACrB;;;ACjFA,SAAS,gBAAgB;AAiDnB,gBAAAA,MAmBE,QAAAC,aAnBF;AAtCC,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,YAAY;AACd,GAAmB;AACjB,QAAM,EAAE,QAAQ,oBAAoB,aAAa,IAAI,QAAQ;AAC7D,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,EAAE;AACrC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,EAAE;AAC3C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAE5C,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAe;AACjB,aAAS,IAAI;AACb,eAAW,IAAI;AAEf,UAAM,SAAS,MAAM,OAAO,OAAO,QAAQ;AAC3C,eAAW,KAAK;AAEhB,QAAI,OAAO,OAAO;AAChB,eAAS,OAAO,MAAM,OAAO;AAAA,IAC/B,OAAO;AACL,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,QAAM,cAAc,OAAO,aAAqB;AAC9C,aAAS,IAAI;AACb,UAAM,SAAS,MAAM,mBAAmB,QAAQ;AAChD,QAAI,OAAO,OAAO;AAChB,eAAS,OAAO,MAAM,OAAO;AAAA,IAC/B;AAAA,EACF;AAEA,MAAI,CAAC,cAAc;AACjB,WACE,gBAAAD,KAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,WAAW,UAAU,OAAO,UAAU,GAAG,mFAExE;AAAA,EAEJ;AAEA,SACE,gBAAAC,MAAC,SAAI,WAAsB,OAAO,EAAE,UAAU,SAAS,QAAQ,SAAS,GACtE;AAAA,oBAAAD,KAAC,QAAG,OAAO,EAAE,UAAU,UAAU,YAAY,KAAK,cAAc,QAAQ,WAAW,SAAS,GAAG,qBAE/F;AAAA,IAEC,SACC,gBAAAA,KAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,cAAc,QAAQ,iBAAiB,WAAW,OAAO,WAAW,cAAc,OAAO,UAAU,OAAO,GACtI,iBACH;AAAA,IAGF,gBAAAC,MAAC,UAAK,UAAU,cACd;AAAA,sBAAAA,MAAC,SAAI,OAAO,EAAE,cAAc,OAAO,GACjC;AAAA,wBAAAD,KAAC,WAAM,OAAO,EAAE,SAAS,SAAS,cAAc,OAAO,UAAU,QAAQ,YAAY,IAAI,GAAG,mBAAK;AAAA,QACjG,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,YACxC,UAAQ;AAAA,YACR,OAAO,EAAE,OAAO,QAAQ,SAAS,YAAY,QAAQ,qBAAqB,cAAc,OAAO,UAAU,OAAO;AAAA;AAAA,QAClH;AAAA,SACF;AAAA,MAEA,gBAAAC,MAAC,SAAI,OAAO,EAAE,cAAc,OAAO,GACjC;AAAA,wBAAAD,KAAC,WAAM,OAAO,EAAE,SAAS,SAAS,cAAc,OAAO,UAAU,QAAQ,YAAY,IAAI,GAAG,sBAAQ;AAAA,QACpG,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,YAC3C,UAAQ;AAAA,YACR,OAAO,EAAE,OAAO,QAAQ,SAAS,YAAY,QAAQ,qBAAqB,cAAc,OAAO,UAAU,OAAO;AAAA;AAAA,QAClH;AAAA,SACF;AAAA,MAEC,oBACC,gBAAAA,KAAC,SAAI,OAAO,EAAE,cAAc,QAAQ,WAAW,QAAQ,GACrD,0BAAAA,KAAC,YAAO,MAAK,UAAS,SAAS,kBAAkB,OAAO,EAAE,YAAY,QAAQ,QAAQ,QAAQ,OAAO,WAAW,QAAQ,WAAW,UAAU,OAAO,GAAG,8BAEvJ,GACF;AAAA,MAGF,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU;AAAA,UACV,OAAO;AAAA,YACL,OAAO;AAAA,YAAQ,SAAS;AAAA,YAAQ,iBAAiB;AAAA,YAAW,OAAO;AAAA,YACnE,QAAQ;AAAA,YAAQ,cAAc;AAAA,YAAO,UAAU;AAAA,YAAQ,YAAY;AAAA,YACnE,QAAQ,UAAU,gBAAgB;AAAA,YAAW,SAAS,UAAU,MAAM;AAAA,UACxE;AAAA,UAEC,oBAAU,kBAAkB;AAAA;AAAA,MAC/B;AAAA,OACF;AAAA,IAEC,aACC,gBAAAC,MAAC,SAAI,OAAO,EAAE,WAAW,OAAO,GAC9B;AAAA,sBAAAD,KAAC,SAAI,OAAO,EAAE,WAAW,UAAU,OAAO,WAAW,UAAU,QAAQ,cAAc,OAAO,GAAG,8BAAgB;AAAA,MAC/G,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,OAAO,GACzC;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,SAAS,MAAM,YAAY,QAAQ;AAAA,YACnC,OAAO,EAAE,MAAM,GAAG,SAAS,QAAQ,QAAQ,qBAAqB,cAAc,OAAO,YAAY,SAAS,QAAQ,WAAW,UAAU,OAAO;AAAA,YAC/I;AAAA;AAAA,QAED;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAS,MAAM,YAAY,QAAQ;AAAA,YACnC,OAAO,EAAE,MAAM,GAAG,SAAS,QAAQ,QAAQ,qBAAqB,cAAc,OAAO,YAAY,SAAS,QAAQ,WAAW,UAAU,OAAO;AAAA,YAC/I;AAAA;AAAA,QAED;AAAA,SACF;AAAA,OACF;AAAA,IAGD,iBACC,gBAAAC,MAAC,SAAI,OAAO,EAAE,WAAW,QAAQ,WAAW,UAAU,UAAU,OAAO,GAAG;AAAA;AAAA,MAC5C;AAAA,MAC5B,gBAAAD,KAAC,YAAO,MAAK,UAAS,SAAS,eAAe,OAAO,EAAE,YAAY,QAAQ,QAAQ,QAAQ,OAAO,WAAW,QAAQ,WAAW,YAAY,IAAI,GAAG,qBAEnJ;AAAA,OACF;AAAA,KAEJ;AAEJ;;;AC7IA,SAAS,YAAAE,iBAAgB;AA8DnB,gBAAAC,MAUE,QAAAC,aAVF;AApDC,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,YAAY;AACd,GAAoB;AAClB,QAAM,EAAE,QAAQ,oBAAoB,aAAa,IAAI,QAAQ;AAC7D,QAAM,CAAC,MAAM,OAAO,IAAIC,UAAS,EAAE;AACnC,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAS,EAAE;AACrC,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,EAAE;AAC3C,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAS,KAAK;AAC1C,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwB,IAAI;AACtD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,KAAK;AAC5C,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,KAAK;AAE5C,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAe;AACjB,QAAI,CAAC,QAAQ;AACX,eAAS,sCAAsC;AAC/C;AAAA,IACF;AACA,QAAI,SAAS,SAAS,GAAG;AACvB,eAAS,wCAAwC;AACjD;AAAA,IACF;AAEA,aAAS,IAAI;AACb,eAAW,IAAI;AAEf,UAAM,SAAS,MAAM,OAAO,OAAO,UAAU;AAAA,MAC3C,UAAU,EAAE,cAAc,KAAK;AAAA,IACjC,CAAC;AACD,eAAW,KAAK;AAEhB,QAAI,OAAO,OAAO;AAChB,eAAS,OAAO,MAAM,OAAO;AAAA,IAC/B,OAAO;AACL,iBAAW,IAAI;AACf,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,QAAM,cAAc,OAAO,aAAqB;AAC9C,aAAS,IAAI;AACb,UAAM,SAAS,MAAM,mBAAmB,QAAQ;AAChD,QAAI,OAAO,OAAO;AAChB,eAAS,OAAO,MAAM,OAAO;AAAA,IAC/B;AAAA,EACF;AAEA,MAAI,CAAC,cAAc;AACjB,WACE,gBAAAF,KAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,WAAW,UAAU,OAAO,UAAU,GAAG,oFAExE;AAAA,EAEJ;AAEA,MAAI,SAAS;AACX,WACE,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,WAAW,SAAS,GACjD;AAAA,sBAAAD,KAAC,QAAG,OAAO,EAAE,UAAU,WAAW,YAAY,KAAK,cAAc,OAAO,OAAO,UAAU,GAAG,8BAAgB;AAAA,MAC5G,gBAAAC,MAAC,OAAE,OAAO,EAAE,OAAO,UAAU,GAAG;AAAA;AAAA,QAAgC;AAAA,SAAM;AAAA,OACxE;AAAA,EAEJ;AAEA,SACE,gBAAAA,MAAC,SAAI,WAAsB,OAAO,EAAE,UAAU,SAAS,QAAQ,SAAS,GACtE;AAAA,oBAAAD,KAAC,QAAG,OAAO,EAAE,UAAU,UAAU,YAAY,KAAK,cAAc,QAAQ,WAAW,SAAS,GAAG,4BAE/F;AAAA,IAEC,SACC,gBAAAA,KAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,cAAc,QAAQ,iBAAiB,WAAW,OAAO,WAAW,cAAc,OAAO,UAAU,OAAO,GACtI,iBACH;AAAA,IAGF,gBAAAC,MAAC,UAAK,UAAU,cACd;AAAA,sBAAAA,MAAC,SAAI,OAAO,EAAE,cAAc,OAAO,GACjC;AAAA,wBAAAD,KAAC,WAAM,OAAO,EAAE,SAAS,SAAS,cAAc,OAAO,UAAU,QAAQ,YAAY,IAAI,GAAG,kBAAI;AAAA,QAChG,gBAAAA;AAAA,UAAC;AAAA;AAAA,YAAM,MAAK;AAAA,YAAO,OAAO;AAAA,YAAM,UAAU,CAAC,MAAM,QAAQ,EAAE,OAAO,KAAK;AAAA,YAAG,UAAQ;AAAA,YAChF,OAAO,EAAE,OAAO,QAAQ,SAAS,YAAY,QAAQ,qBAAqB,cAAc,OAAO,UAAU,OAAO;AAAA;AAAA,QAAG;AAAA,SACvH;AAAA,MAEA,gBAAAC,MAAC,SAAI,OAAO,EAAE,cAAc,OAAO,GACjC;AAAA,wBAAAD,KAAC,WAAM,OAAO,EAAE,SAAS,SAAS,cAAc,OAAO,UAAU,QAAQ,YAAY,IAAI,GAAG,mBAAK;AAAA,QACjG,gBAAAA;AAAA,UAAC;AAAA;AAAA,YAAM,MAAK;AAAA,YAAQ,OAAO;AAAA,YAAO,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,YAAG,UAAQ;AAAA,YACnF,OAAO,EAAE,OAAO,QAAQ,SAAS,YAAY,QAAQ,qBAAqB,cAAc,OAAO,UAAU,OAAO;AAAA;AAAA,QAAG;AAAA,SACvH;AAAA,MAEA,gBAAAC,MAAC,SAAI,OAAO,EAAE,cAAc,OAAO,GACjC;AAAA,wBAAAD,KAAC,WAAM,OAAO,EAAE,SAAS,SAAS,cAAc,OAAO,UAAU,QAAQ,YAAY,IAAI,GAAG,sBAAQ;AAAA,QACpG,gBAAAA;AAAA,UAAC;AAAA;AAAA,YAAM,MAAK;AAAA,YAAW,OAAO;AAAA,YAAU,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,YAAG,UAAQ;AAAA,YAAC,WAAW;AAAA,YACxG,OAAO,EAAE,OAAO,QAAQ,SAAS,YAAY,QAAQ,qBAAqB,cAAc,OAAO,UAAU,OAAO;AAAA;AAAA,QAAG;AAAA,QACrH,gBAAAA,KAAC,UAAK,OAAO,EAAE,UAAU,QAAQ,OAAO,UAAU,GAAG,kCAAoB;AAAA,SAC3E;AAAA,MAEA,gBAAAA,KAAC,SAAI,OAAO,EAAE,cAAc,OAAO,GACjC,0BAAAC,MAAC,WAAM,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,OAAO,UAAU,QAAQ,QAAQ,UAAU,GACrG;AAAA,wBAAAD,KAAC,WAAM,MAAK,YAAW,SAAS,QAAQ,UAAU,CAAC,MAAM,UAAU,EAAE,OAAO,OAAO,GAAG;AAAA,QAAE;AAAA,SAE1F,GACF;AAAA,MAEA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UAAO,MAAK;AAAA,UAAS,UAAU;AAAA,UAC9B,OAAO;AAAA,YACL,OAAO;AAAA,YAAQ,SAAS;AAAA,YAAQ,iBAAiB;AAAA,YAAW,OAAO;AAAA,YACnE,QAAQ;AAAA,YAAQ,cAAc;AAAA,YAAO,UAAU;AAAA,YAAQ,YAAY;AAAA,YACnE,QAAQ,UAAU,gBAAgB;AAAA,YAAW,SAAS,UAAU,MAAM;AAAA,UACxE;AAAA,UACC,oBAAU,wBAAwB;AAAA;AAAA,MACrC;AAAA,OACF;AAAA,IAEC,aACC,gBAAAC,MAAC,SAAI,OAAO,EAAE,WAAW,OAAO,GAC9B;AAAA,sBAAAD,KAAC,SAAI,OAAO,EAAE,WAAW,UAAU,OAAO,WAAW,UAAU,QAAQ,cAAc,OAAO,GAAG,8BAAgB;AAAA,MAC/G,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,OAAO,GACzC;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YAAO,SAAS,MAAM,YAAY,QAAQ;AAAA,YACzC,OAAO,EAAE,MAAM,GAAG,SAAS,QAAQ,QAAQ,qBAAqB,cAAc,OAAO,YAAY,SAAS,QAAQ,WAAW,UAAU,OAAO;AAAA,YAAG;AAAA;AAAA,QAEnJ;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YAAO,SAAS,MAAM,YAAY,QAAQ;AAAA,YACzC,OAAO,EAAE,MAAM,GAAG,SAAS,QAAQ,QAAQ,qBAAqB,cAAc,OAAO,YAAY,SAAS,QAAQ,WAAW,UAAU,OAAO;AAAA,YAAG;AAAA;AAAA,QAEnJ;AAAA,SACF;AAAA,OACF;AAAA,IAGD,gBACC,gBAAAC,MAAC,SAAI,OAAO,EAAE,WAAW,QAAQ,WAAW,UAAU,UAAU,OAAO,GAAG;AAAA;AAAA,MAC/C;AAAA,MACzB,gBAAAD,KAAC,YAAO,MAAK,UAAS,SAAS,cAAc,OAAO,EAAE,YAAY,QAAQ,QAAQ,QAAQ,OAAO,WAAW,QAAQ,WAAW,YAAY,IAAI,GAAG,qBAElJ;AAAA,OACF;AAAA,KAEJ;AAEJ;;;ACxJA,SAAS,YAAAG,iBAAgB;AAiCjB,gBAAAC,MACA,QAAAC,aADA;AAzBD,SAAS,mBAAmB,EAAE,QAAQ,YAAY,GAAG,GAA4B;AACtF,QAAM,EAAE,cAAc,IAAI,QAAQ;AAClC,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAS,EAAE;AACrC,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwB,IAAI;AACtD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,KAAK;AAC5C,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,KAAK;AAE5C,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAe;AACjB,aAAS,IAAI;AACb,eAAW,IAAI;AAEf,UAAM,SAAS,MAAM,cAAc,KAAK;AACxC,eAAW,KAAK;AAEhB,QAAI,OAAO,OAAO;AAChB,eAAS,OAAO,MAAM,OAAO;AAAA,IAC/B,OAAO;AACL,iBAAW,IAAI;AAAA,IACjB;AAAA,EACF;AAEA,MAAI,SAAS;AACX,WACE,gBAAAD,MAAC,SAAI,WAAsB,OAAO,EAAE,UAAU,SAAS,QAAQ,UAAU,WAAW,UAAU,SAAS,OAAO,GAC5G;AAAA,sBAAAD,KAAC,QAAG,OAAO,EAAE,UAAU,WAAW,YAAY,KAAK,cAAc,OAAO,OAAO,UAAU,GAAG,8BAAgB;AAAA,MAC5G,gBAAAC,MAAC,OAAE,OAAO,EAAE,OAAO,WAAW,cAAc,OAAO,GAAG;AAAA;AAAA,QAAkC;AAAA,SAAM;AAAA,MAC7F,UACC,gBAAAD,KAAC,YAAO,MAAK,UAAS,SAAS,QAAQ,OAAO,EAAE,YAAY,QAAQ,QAAQ,QAAQ,OAAO,WAAW,QAAQ,WAAW,UAAU,OAAO,GAAG,2BAE7I;AAAA,OAEJ;AAAA,EAEJ;AAEA,SACE,gBAAAC,MAAC,SAAI,WAAsB,OAAO,EAAE,UAAU,SAAS,QAAQ,SAAS,GACtE;AAAA,oBAAAD,KAAC,QAAG,OAAO,EAAE,UAAU,UAAU,YAAY,KAAK,cAAc,OAAO,WAAW,SAAS,GAAG,4BAAc;AAAA,IAC5G,gBAAAA,KAAC,OAAE,OAAO,EAAE,OAAO,WAAW,WAAW,UAAU,cAAc,QAAQ,UAAU,OAAO,GAAG,8DAE7F;AAAA,IAEC,SACC,gBAAAA,KAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,cAAc,QAAQ,iBAAiB,WAAW,OAAO,WAAW,cAAc,OAAO,UAAU,OAAO,GACtI,iBACH;AAAA,IAGF,gBAAAC,MAAC,UAAK,UAAU,cACd;AAAA,sBAAAA,MAAC,SAAI,OAAO,EAAE,cAAc,OAAO,GACjC;AAAA,wBAAAD,KAAC,WAAM,OAAO,EAAE,SAAS,SAAS,cAAc,OAAO,UAAU,QAAQ,YAAY,IAAI,GAAG,mBAAK;AAAA,QACjG,gBAAAA;AAAA,UAAC;AAAA;AAAA,YAAM,MAAK;AAAA,YAAQ,OAAO;AAAA,YAAO,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,YAAG,UAAQ;AAAA,YACnF,OAAO,EAAE,OAAO,QAAQ,SAAS,YAAY,QAAQ,qBAAqB,cAAc,OAAO,UAAU,OAAO;AAAA;AAAA,QAAG;AAAA,SACvH;AAAA,MAEA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UAAO,MAAK;AAAA,UAAS,UAAU;AAAA,UAC9B,OAAO;AAAA,YACL,OAAO;AAAA,YAAQ,SAAS;AAAA,YAAQ,iBAAiB;AAAA,YAAW,OAAO;AAAA,YACnE,QAAQ;AAAA,YAAQ,cAAc;AAAA,YAAO,UAAU;AAAA,YAAQ,YAAY;AAAA,YACnE,QAAQ,UAAU,gBAAgB;AAAA,YAAW,SAAS,UAAU,MAAM;AAAA,UACxE;AAAA,UACC,oBAAU,eAAe;AAAA;AAAA,MAC5B;AAAA,OACF;AAAA,IAEC,UACC,gBAAAA,KAAC,SAAI,OAAO,EAAE,WAAW,QAAQ,WAAW,SAAS,GACnD,0BAAAA,KAAC,YAAO,MAAK,UAAS,SAAS,QAAQ,OAAO,EAAE,YAAY,QAAQ,QAAQ,QAAQ,OAAO,WAAW,QAAQ,WAAW,UAAU,OAAO,GAAG,2BAE7I,GACF;AAAA,KAEJ;AAEJ;;;ACnFA,SAAS,WAAW,YAAAG,iBAAgB;AA8B9B,SAWF,YAAAC,WAVI,OAAAC,MADF,QAAAC,aAAA;AAtBC,SAAS,aAAa,EAAE,aAAa,KAAK,iBAAiB,GAAsB;AACtF,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAwB,IAAI;AAEtD,YAAU,MAAM;AACd,UAAM,iBAAiB,YAAY;AACjC,UAAI;AACF,cAAM,EAAE,OAAAC,OAAM,IAAI,MAAM,SAAS,KAAK,WAAW;AACjD,YAAIA,QAAO;AACT,mBAASA,OAAM,OAAO;AACtB;AAAA,QACF;AACA,eAAO,SAAS,OAAO;AAAA,MACzB,SAAS,KAAc;AACrB,iBAAS,eAAe,QAAQ,IAAI,UAAU,gCAAgC;AAAA,MAChF;AAAA,IACF;AAEA,mBAAe;AAAA,EACjB,GAAG,CAAC,UAAU,CAAC;AAEf,MAAI,OAAO;AACT,WACE,gBAAAF,MAAC,SAAI,OAAO,EAAE,WAAW,UAAU,SAAS,OAAO,GACjD;AAAA,sBAAAD,KAAC,QAAG,OAAO,EAAE,OAAO,WAAW,cAAc,MAAM,GAAG,kCAAoB;AAAA,MAC1E,gBAAAA,KAAC,OAAE,OAAO,EAAE,OAAO,UAAU,GAAI,iBAAM;AAAA,MACvC,gBAAAA,KAAC,OAAE,MAAK,UAAS,OAAO,EAAE,OAAO,WAAW,WAAW,QAAQ,SAAS,eAAe,GAAG,2BAE1F;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,gBAAAA,KAAAD,WAAA,EACG,8BACC,gBAAAC,KAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,gBAAgB,UAAU,WAAW,QAAQ,GAChG,0BAAAA,KAAC,OAAE,OAAO,EAAE,OAAO,UAAU,GAAG,0CAA4B,GAC9D,GAEJ;AAEJ;","names":["jsx","jsxs","useState","jsx","jsxs","useState","useState","jsx","jsxs","useState","useState","Fragment","jsx","jsxs","useState","error"]}
|
|
1
|
+
{"version":3,"sources":["../../src/auth/ProtectedRoute.tsx","../../src/auth/LoginForm.tsx","../../src/auth/SignupForm.tsx","../../src/auth/ForgotPasswordForm.tsx","../../src/auth/AuthCallback.tsx"],"sourcesContent":["import { useAuth } from './AuthProvider';\r\nimport type { SubscriptionTier } from '../core/types';\r\n\r\ninterface ProtectedRouteProps {\r\n children: React.ReactNode;\r\n requiredRoles?: string[];\r\n requiredTier?: SubscriptionTier;\r\n fallback?: React.ReactNode;\r\n unauthorizedFallback?: React.ReactNode;\r\n allowUnconfigured?: boolean;\r\n loadingComponent?: React.ReactNode;\r\n loginPath?: string;\r\n}\r\n\r\nconst TIER_LEVELS: Record<string, number> = {\r\n free: 0,\r\n starter: 1,\r\n creator: 2,\r\n pro: 3,\r\n business: 4,\r\n enterprise: 5,\r\n};\r\n\r\nfunction DefaultLoadingSpinner() {\r\n return (\r\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '200px' }}>\r\n <div style={{\r\n width: '32px', height: '32px',\r\n border: '3px solid #e5e7eb', borderTopColor: '#3b82f6',\r\n borderRadius: '50%',\r\n animation: 'spin 0.6s linear infinite',\r\n }} />\r\n <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>\r\n </div>\r\n );\r\n}\r\n\r\nexport function ProtectedRoute({\r\n children,\r\n requiredTier,\r\n fallback,\r\n loadingComponent,\r\n allowUnconfigured = false,\r\n loginPath = '/login',\r\n}: ProtectedRouteProps) {\r\n const { user, profile, loading, isConfigured } = useAuth();\r\n\r\n if (loading) {\r\n return <>{loadingComponent || <DefaultLoadingSpinner />}</>;\r\n }\r\n\r\n if (!isConfigured && allowUnconfigured) {\r\n return <>{children}</>;\r\n }\r\n\r\n if (!user) {\r\n if (fallback) return <>{fallback}</>;\r\n if (typeof window !== 'undefined') {\r\n window.location.href = loginPath;\r\n }\r\n return null;\r\n }\r\n\r\n if (requiredTier) {\r\n const userTier = profile?.subscription_tier || 'free';\r\n const userLevel = TIER_LEVELS[userTier] ?? 0;\r\n const requiredLevel = TIER_LEVELS[requiredTier] ?? 0;\r\n\r\n if (userLevel < requiredLevel) {\r\n return (\r\n <div style={{ textAlign: 'center', padding: '40px' }}>\r\n <h2 style={{ fontSize: '1.5rem', fontWeight: 600, marginBottom: '8px' }}>Upgrade Required</h2>\r\n <p style={{ color: '#6b7280' }}>\r\n This feature requires the {requiredTier} plan or higher.\r\n </p>\r\n </div>\r\n );\r\n }\r\n }\r\n\r\n return <>{children}</>;\r\n}\r\n","import { useState } from 'react';\r\nimport { useAuth } from './AuthProvider';\r\n\r\ninterface LoginFormProps {\r\n onSuccess?: () => void;\r\n onForgotPassword?: () => void;\r\n onSignupClick?: () => void;\r\n showOAuth?: boolean;\r\n className?: string;\r\n}\r\n\r\nexport function LoginForm({\r\n onSuccess,\r\n onForgotPassword,\r\n onSignupClick,\r\n showOAuth = true,\r\n className = '',\r\n}: LoginFormProps) {\r\n const { signIn, signInWithProvider, isConfigured } = useAuth();\r\n const [email, setEmail] = useState('');\r\n const [password, setPassword] = useState('');\r\n const [error, setError] = useState<string | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setError(null);\r\n setLoading(true);\r\n\r\n const result = await signIn(email, password);\r\n setLoading(false);\r\n\r\n if (result.error) {\r\n setError(result.error.message);\r\n } else {\r\n onSuccess?.();\r\n }\r\n };\r\n\r\n const handleOAuth = async (provider: string) => {\r\n setError(null);\r\n const result = await signInWithProvider(provider);\r\n if (result.error) {\r\n setError(result.error.message);\r\n }\r\n };\r\n\r\n if (!isConfigured) {\r\n return (\r\n <div style={{ padding: '20px', textAlign: 'center', color: '#6b7280' }}>\r\n Authentication is not configured. Connect a database to enable login.\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={className} style={{ maxWidth: '400px', margin: '0 auto' }}>\r\n <h2 style={{ fontSize: '1.5rem', fontWeight: 600, marginBottom: '24px', textAlign: 'center' }}>\r\n Sign In\r\n </h2>\r\n\r\n {error && (\r\n <div style={{ padding: '12px', marginBottom: '16px', backgroundColor: '#fef2f2', color: '#dc2626', borderRadius: '8px', fontSize: '14px' }}>\r\n {error}\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit}>\r\n <div style={{ marginBottom: '16px' }}>\r\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '14px', fontWeight: 500 }}>Email</label>\r\n <input\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n required\r\n style={{ width: '100%', padding: '8px 12px', border: '1px solid #d1d5db', borderRadius: '6px', fontSize: '14px' }}\r\n />\r\n </div>\r\n\r\n <div style={{ marginBottom: '16px' }}>\r\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '14px', fontWeight: 500 }}>Password</label>\r\n <input\r\n type=\"password\"\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n required\r\n style={{ width: '100%', padding: '8px 12px', border: '1px solid #d1d5db', borderRadius: '6px', fontSize: '14px' }}\r\n />\r\n </div>\r\n\r\n {onForgotPassword && (\r\n <div style={{ marginBottom: '16px', textAlign: 'right' }}>\r\n <button type=\"button\" onClick={onForgotPassword} style={{ background: 'none', border: 'none', color: '#3b82f6', cursor: 'pointer', fontSize: '14px' }}>\r\n Forgot password?\r\n </button>\r\n </div>\r\n )}\r\n\r\n <button\r\n type=\"submit\"\r\n disabled={loading}\r\n style={{\r\n width: '100%', padding: '10px', backgroundColor: '#3b82f6', color: 'white',\r\n border: 'none', borderRadius: '6px', fontSize: '14px', fontWeight: 500,\r\n cursor: loading ? 'not-allowed' : 'pointer', opacity: loading ? 0.7 : 1,\r\n }}\r\n >\r\n {loading ? 'Signing in...' : 'Sign In'}\r\n </button>\r\n </form>\r\n\r\n {showOAuth && (\r\n <div style={{ marginTop: '24px' }}>\r\n <div style={{ textAlign: 'center', color: '#9ca3af', fontSize: '14px', marginBottom: '16px' }}>or continue with</div>\r\n <div style={{ display: 'flex', gap: '12px' }}>\r\n <button\r\n onClick={() => handleOAuth('google')}\r\n style={{ flex: 1, padding: '10px', border: '1px solid #d1d5db', borderRadius: '6px', background: 'white', cursor: 'pointer', fontSize: '14px' }}\r\n >\r\n Google\r\n </button>\r\n <button\r\n onClick={() => handleOAuth('github')}\r\n style={{ flex: 1, padding: '10px', border: '1px solid #d1d5db', borderRadius: '6px', background: 'white', cursor: 'pointer', fontSize: '14px' }}\r\n >\r\n GitHub\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {onSignupClick && (\r\n <div style={{ marginTop: '24px', textAlign: 'center', fontSize: '14px' }}>\r\n Don't have an account?{' '}\r\n <button type=\"button\" onClick={onSignupClick} style={{ background: 'none', border: 'none', color: '#3b82f6', cursor: 'pointer', fontWeight: 500 }}>\r\n Sign up\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState } from 'react';\r\nimport { useAuth } from './AuthProvider';\r\n\r\ninterface SignupFormProps {\r\n onSuccess?: () => void;\r\n onLoginClick?: () => void;\r\n showOAuth?: boolean;\r\n className?: string;\r\n}\r\n\r\nexport function SignupForm({\r\n onSuccess,\r\n onLoginClick,\r\n showOAuth = true,\r\n className = '',\r\n}: SignupFormProps) {\r\n const { signUp, signInWithProvider, isConfigured } = useAuth();\r\n const [name, setName] = useState('');\r\n const [email, setEmail] = useState('');\r\n const [password, setPassword] = useState('');\r\n const [agreed, setAgreed] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState(false);\r\n const [loading, setLoading] = useState(false);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (!agreed) {\r\n setError('Please agree to the Terms of Service');\r\n return;\r\n }\r\n if (password.length < 8) {\r\n setError('Password must be at least 8 characters');\r\n return;\r\n }\r\n\r\n setError(null);\r\n setLoading(true);\r\n\r\n const result = await signUp(email, password, {\r\n metadata: { display_name: name },\r\n });\r\n setLoading(false);\r\n\r\n if (result.error) {\r\n setError(result.error.message);\r\n } else {\r\n setSuccess(true);\r\n onSuccess?.();\r\n }\r\n };\r\n\r\n const handleOAuth = async (provider: string) => {\r\n setError(null);\r\n const result = await signInWithProvider(provider);\r\n if (result.error) {\r\n setError(result.error.message);\r\n }\r\n };\r\n\r\n if (!isConfigured) {\r\n return (\r\n <div style={{ padding: '20px', textAlign: 'center', color: '#6b7280' }}>\r\n Authentication is not configured. Connect a database to enable signup.\r\n </div>\r\n );\r\n }\r\n\r\n if (success) {\r\n return (\r\n <div style={{ padding: '20px', textAlign: 'center' }}>\r\n <h3 style={{ fontSize: '1.25rem', fontWeight: 600, marginBottom: '8px', color: '#059669' }}>Check your email</h3>\r\n <p style={{ color: '#6b7280' }}>We sent a confirmation link to {email}</p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={className} style={{ maxWidth: '400px', margin: '0 auto' }}>\r\n <h2 style={{ fontSize: '1.5rem', fontWeight: 600, marginBottom: '24px', textAlign: 'center' }}>\r\n Create Account\r\n </h2>\r\n\r\n {error && (\r\n <div style={{ padding: '12px', marginBottom: '16px', backgroundColor: '#fef2f2', color: '#dc2626', borderRadius: '8px', fontSize: '14px' }}>\r\n {error}\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit}>\r\n <div style={{ marginBottom: '16px' }}>\r\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '14px', fontWeight: 500 }}>Name</label>\r\n <input type=\"text\" value={name} onChange={(e) => setName(e.target.value)} required\r\n style={{ width: '100%', padding: '8px 12px', border: '1px solid #d1d5db', borderRadius: '6px', fontSize: '14px' }} />\r\n </div>\r\n\r\n <div style={{ marginBottom: '16px' }}>\r\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '14px', fontWeight: 500 }}>Email</label>\r\n <input type=\"email\" value={email} onChange={(e) => setEmail(e.target.value)} required\r\n style={{ width: '100%', padding: '8px 12px', border: '1px solid #d1d5db', borderRadius: '6px', fontSize: '14px' }} />\r\n </div>\r\n\r\n <div style={{ marginBottom: '16px' }}>\r\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '14px', fontWeight: 500 }}>Password</label>\r\n <input type=\"password\" value={password} onChange={(e) => setPassword(e.target.value)} required minLength={8}\r\n style={{ width: '100%', padding: '8px 12px', border: '1px solid #d1d5db', borderRadius: '6px', fontSize: '14px' }} />\r\n <span style={{ fontSize: '12px', color: '#9ca3af' }}>Minimum 8 characters</span>\r\n </div>\r\n\r\n <div style={{ marginBottom: '16px' }}>\r\n <label style={{ display: 'flex', alignItems: 'center', gap: '8px', fontSize: '14px', cursor: 'pointer' }}>\r\n <input type=\"checkbox\" checked={agreed} onChange={(e) => setAgreed(e.target.checked)} />\r\n I agree to the Terms of Service and Privacy Policy\r\n </label>\r\n </div>\r\n\r\n <button type=\"submit\" disabled={loading}\r\n style={{\r\n width: '100%', padding: '10px', backgroundColor: '#3b82f6', color: 'white',\r\n border: 'none', borderRadius: '6px', fontSize: '14px', fontWeight: 500,\r\n cursor: loading ? 'not-allowed' : 'pointer', opacity: loading ? 0.7 : 1,\r\n }}>\r\n {loading ? 'Creating account...' : 'Create Account'}\r\n </button>\r\n </form>\r\n\r\n {showOAuth && (\r\n <div style={{ marginTop: '24px' }}>\r\n <div style={{ textAlign: 'center', color: '#9ca3af', fontSize: '14px', marginBottom: '16px' }}>or continue with</div>\r\n <div style={{ display: 'flex', gap: '12px' }}>\r\n <button onClick={() => handleOAuth('google')}\r\n style={{ flex: 1, padding: '10px', border: '1px solid #d1d5db', borderRadius: '6px', background: 'white', cursor: 'pointer', fontSize: '14px' }}>\r\n Google\r\n </button>\r\n <button onClick={() => handleOAuth('github')}\r\n style={{ flex: 1, padding: '10px', border: '1px solid #d1d5db', borderRadius: '6px', background: 'white', cursor: 'pointer', fontSize: '14px' }}>\r\n GitHub\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {onLoginClick && (\r\n <div style={{ marginTop: '24px', textAlign: 'center', fontSize: '14px' }}>\r\n Already have an account?{' '}\r\n <button type=\"button\" onClick={onLoginClick} style={{ background: 'none', border: 'none', color: '#3b82f6', cursor: 'pointer', fontWeight: 500 }}>\r\n Sign in\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState } from 'react';\r\nimport { useAuth } from './AuthProvider';\r\n\r\ninterface ForgotPasswordFormProps {\r\n onBack?: () => void;\r\n className?: string;\r\n}\r\n\r\nexport function ForgotPasswordForm({ onBack, className = '' }: ForgotPasswordFormProps) {\r\n const { resetPassword } = useAuth();\r\n const [email, setEmail] = useState('');\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState(false);\r\n const [loading, setLoading] = useState(false);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setError(null);\r\n setLoading(true);\r\n\r\n const result = await resetPassword(email);\r\n setLoading(false);\r\n\r\n if (result.error) {\r\n setError(result.error.message);\r\n } else {\r\n setSuccess(true);\r\n }\r\n };\r\n\r\n if (success) {\r\n return (\r\n <div className={className} style={{ maxWidth: '400px', margin: '0 auto', textAlign: 'center', padding: '20px' }}>\r\n <h3 style={{ fontSize: '1.25rem', fontWeight: 600, marginBottom: '8px', color: '#059669' }}>Check your email</h3>\r\n <p style={{ color: '#6b7280', marginBottom: '16px' }}>We sent a password reset link to {email}</p>\r\n {onBack && (\r\n <button type=\"button\" onClick={onBack} style={{ background: 'none', border: 'none', color: '#3b82f6', cursor: 'pointer', fontSize: '14px' }}>\r\n Back to login\r\n </button>\r\n )}\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={className} style={{ maxWidth: '400px', margin: '0 auto' }}>\r\n <h2 style={{ fontSize: '1.5rem', fontWeight: 600, marginBottom: '8px', textAlign: 'center' }}>Reset Password</h2>\r\n <p style={{ color: '#6b7280', textAlign: 'center', marginBottom: '24px', fontSize: '14px' }}>\r\n Enter your email and we'll send you a reset link\r\n </p>\r\n\r\n {error && (\r\n <div style={{ padding: '12px', marginBottom: '16px', backgroundColor: '#fef2f2', color: '#dc2626', borderRadius: '8px', fontSize: '14px' }}>\r\n {error}\r\n </div>\r\n )}\r\n\r\n <form onSubmit={handleSubmit}>\r\n <div style={{ marginBottom: '16px' }}>\r\n <label style={{ display: 'block', marginBottom: '4px', fontSize: '14px', fontWeight: 500 }}>Email</label>\r\n <input type=\"email\" value={email} onChange={(e) => setEmail(e.target.value)} required\r\n style={{ width: '100%', padding: '8px 12px', border: '1px solid #d1d5db', borderRadius: '6px', fontSize: '14px' }} />\r\n </div>\r\n\r\n <button type=\"submit\" disabled={loading}\r\n style={{\r\n width: '100%', padding: '10px', backgroundColor: '#3b82f6', color: 'white',\r\n border: 'none', borderRadius: '6px', fontSize: '14px', fontWeight: 500,\r\n cursor: loading ? 'not-allowed' : 'pointer', opacity: loading ? 0.7 : 1,\r\n }}>\r\n {loading ? 'Sending...' : 'Send Reset Link'}\r\n </button>\r\n </form>\r\n\r\n {onBack && (\r\n <div style={{ marginTop: '16px', textAlign: 'center' }}>\r\n <button type=\"button\" onClick={onBack} style={{ background: 'none', border: 'none', color: '#3b82f6', cursor: 'pointer', fontSize: '14px' }}>\r\n Back to login\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useEffect, useState } from 'react';\r\nimport { supabase } from '../core/supabase';\r\n\r\ninterface AuthCallbackProps {\r\n redirectTo?: string;\r\n loadingComponent?: React.ReactNode;\r\n}\r\n\r\nexport function AuthCallback({ redirectTo = '/', loadingComponent }: AuthCallbackProps) {\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n useEffect(() => {\r\n const handleCallback = async () => {\r\n try {\r\n const { error } = await supabase.auth.getSession();\r\n if (error) {\r\n setError(error.message);\r\n return;\r\n }\r\n window.location.href = redirectTo;\r\n } catch (err: unknown) {\r\n setError(err instanceof Error ? err.message : 'Authentication callback failed');\r\n }\r\n };\r\n\r\n handleCallback();\r\n }, [redirectTo]);\r\n\r\n if (error) {\r\n return (\r\n <div style={{ textAlign: 'center', padding: '40px' }}>\r\n <h2 style={{ color: '#dc2626', marginBottom: '8px' }}>Authentication Error</h2>\r\n <p style={{ color: '#6b7280' }}>{error}</p>\r\n <a href=\"/login\" style={{ color: '#3b82f6', marginTop: '16px', display: 'inline-block' }}>\r\n Back to login\r\n </a>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <>\r\n {loadingComponent || (\r\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '200px' }}>\r\n <p style={{ color: '#6b7280' }}>Completing authentication...</p>\r\n </div>\r\n )}\r\n </>\r\n );\r\n}\r\n"],"mappings":"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","names":["jsx","jsxs","useState","jsx","jsxs","useState","useState","jsx","jsxs","useState","useState","Fragment","jsx","jsxs","useState","error"]}
|
|
@@ -17,19 +17,27 @@ var getEnv = (viteKey, nextKey) => {
|
|
|
17
17
|
var env = {
|
|
18
18
|
SUPABASE_URL: getEnv("VITE_SUPABASE_URL", "NEXT_PUBLIC_SUPABASE_URL"),
|
|
19
19
|
SUPABASE_ANON_KEY: getEnv("VITE_SUPABASE_ANON_KEY", "NEXT_PUBLIC_SUPABASE_ANON_KEY"),
|
|
20
|
+
EZCODER_AUTH_URL: getEnv("VITE_EZCODER_AUTH_URL", "NEXT_PUBLIC_EZCODER_AUTH_URL"),
|
|
21
|
+
EZCODER_AUTH_ANON_KEY: getEnv("VITE_EZCODER_AUTH_ANON_KEY", "NEXT_PUBLIC_EZCODER_AUTH_ANON_KEY"),
|
|
20
22
|
STRIPE_PUBLISHABLE_KEY: getEnv("VITE_STRIPE_PUBLISHABLE_KEY", "NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY"),
|
|
21
23
|
EZC_PROJECT_ID: getEnv("VITE_EZC_PROJECT_ID", "NEXT_PUBLIC_EZC_PROJECT_ID"),
|
|
22
24
|
EZCODER_API_URL: getEnv("VITE_EZCODER_API_URL", "NEXT_PUBLIC_EZCODER_API_URL"),
|
|
23
|
-
EZC_SECRET_KEY: getEnv("
|
|
25
|
+
EZC_SECRET_KEY: getEnv("EZC_SECRET_KEY", "EZC_SECRET_KEY"),
|
|
24
26
|
S3_BUCKET: getEnv("VITE_S3_BUCKET", "S3_BUCKET"),
|
|
25
|
-
CLOUDINARY_URL: getEnv("VITE_CLOUDINARY_URL", "CLOUDINARY_URL")
|
|
27
|
+
CLOUDINARY_URL: getEnv("VITE_CLOUDINARY_URL", "CLOUDINARY_URL"),
|
|
28
|
+
STORAGE_BUCKET_PUBLIC: getEnv("VITE_STORAGE_BUCKET_PUBLIC", "NEXT_PUBLIC_STORAGE_BUCKET_PUBLIC"),
|
|
29
|
+
STORAGE_BUCKET_PRIVATE: getEnv("VITE_STORAGE_BUCKET_PRIVATE", "NEXT_PUBLIC_STORAGE_BUCKET_PRIVATE")
|
|
26
30
|
};
|
|
27
31
|
var features = {
|
|
28
|
-
auth: Boolean(
|
|
32
|
+
auth: Boolean(
|
|
33
|
+
env.SUPABASE_URL && env.SUPABASE_ANON_KEY || env.EZCODER_AUTH_URL && env.EZCODER_AUTH_ANON_KEY
|
|
34
|
+
),
|
|
29
35
|
payments: Boolean(env.STRIPE_PUBLISHABLE_KEY),
|
|
30
36
|
analytics: Boolean(env.EZCODER_API_URL && env.EZC_PROJECT_ID),
|
|
31
|
-
storage: Boolean(env.SUPABASE_URL || env.S3_BUCKET || env.CLOUDINARY_URL),
|
|
32
|
-
database: Boolean(
|
|
37
|
+
storage: Boolean(env.SUPABASE_URL || env.EZCODER_AUTH_URL || env.S3_BUCKET || env.CLOUDINARY_URL),
|
|
38
|
+
database: Boolean(
|
|
39
|
+
(env.EZCODER_AUTH_URL || env.SUPABASE_URL) && env.EZC_PROJECT_ID
|
|
40
|
+
)
|
|
33
41
|
};
|
|
34
42
|
function isFeatureConfigured(feature) {
|
|
35
43
|
return features[feature];
|
|
@@ -122,14 +130,22 @@ function createStubClient() {
|
|
|
122
130
|
}
|
|
123
131
|
};
|
|
124
132
|
}
|
|
125
|
-
var
|
|
133
|
+
var authUrl = env.EZCODER_AUTH_URL || env.SUPABASE_URL;
|
|
134
|
+
var authKey = env.EZCODER_AUTH_ANON_KEY || env.SUPABASE_ANON_KEY;
|
|
135
|
+
var isConfigured = Boolean(authUrl && authKey);
|
|
136
|
+
if (!isConfigured && typeof window !== "undefined") {
|
|
137
|
+
console.warn(
|
|
138
|
+
"[EzCoder SDK] Supabase not configured \u2014 auth, database, and storage features are disabled. Set VITE_EZCODER_AUTH_URL and VITE_EZCODER_AUTH_ANON_KEY (or NEXT_PUBLIC_ equivalents) to enable."
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
var supabase = isConfigured ? createClient(authUrl, authKey, {
|
|
126
142
|
auth: {
|
|
127
143
|
autoRefreshToken: true,
|
|
128
144
|
persistSession: true,
|
|
129
145
|
detectSessionInUrl: true
|
|
130
146
|
}
|
|
131
147
|
}) : createStubClient();
|
|
132
|
-
var isSupabaseConfigured =
|
|
148
|
+
var isSupabaseConfigured = isConfigured;
|
|
133
149
|
|
|
134
150
|
export {
|
|
135
151
|
env,
|
|
@@ -138,4 +154,4 @@ export {
|
|
|
138
154
|
supabase,
|
|
139
155
|
isSupabaseConfigured
|
|
140
156
|
};
|
|
141
|
-
//# sourceMappingURL=chunk-
|
|
157
|
+
//# sourceMappingURL=chunk-2WG4O4J2.js.map
|