@m5kdev/frontend 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/.cursor/rules/frontend.mdc +49 -0
  2. package/.turbo/turbo-build.log +5 -0
  3. package/.turbo/turbo-check-types.log +5 -0
  4. package/.turbo/turbo-lint$colon$fix.log +101 -0
  5. package/.turbo/turbo-lint.log +162 -0
  6. package/LICENSE +621 -0
  7. package/dist/src/modules/auth/auth.lib.d.ts +2222 -0
  8. package/dist/src/modules/auth/auth.lib.d.ts.map +1 -0
  9. package/dist/src/modules/auth/auth.lib.js +41 -0
  10. package/dist/src/modules/auth/components/AuthProvider.d.ts +15 -0
  11. package/dist/src/modules/auth/components/AuthProvider.d.ts.map +1 -0
  12. package/dist/src/modules/auth/components/AuthProvider.js +73 -0
  13. package/dist/src/modules/auth/hooks/useAuth.d.ts +4 -0
  14. package/dist/src/modules/auth/hooks/useAuth.d.ts.map +1 -0
  15. package/dist/src/modules/auth/hooks/useAuth.js +14 -0
  16. package/dist/src/modules/auth/hooks/useAuthAdmin.d.ts +21 -0
  17. package/dist/src/modules/auth/hooks/useAuthAdmin.d.ts.map +1 -0
  18. package/dist/src/modules/auth/hooks/useAuthAdmin.js +160 -0
  19. package/dist/src/modules/auth/hooks/useSession.d.ts +38 -0
  20. package/dist/src/modules/auth/hooks/useSession.d.ts.map +1 -0
  21. package/dist/src/modules/auth/hooks/useSession.js +5 -0
  22. package/dist/src/modules/billing/components/BillingProvider.d.ts +14 -0
  23. package/dist/src/modules/billing/components/BillingProvider.d.ts.map +1 -0
  24. package/dist/src/modules/billing/components/BillingProvider.js +25 -0
  25. package/dist/src/modules/billing/hooks/useSubscription.d.ts +5 -0
  26. package/dist/src/modules/billing/hooks/useSubscription.d.ts.map +1 -0
  27. package/dist/src/modules/billing/hooks/useSubscription.js +5 -0
  28. package/dist/src/modules/file/hooks/useS3DownloadUrl.d.ts +3 -0
  29. package/dist/src/modules/file/hooks/useS3DownloadUrl.d.ts.map +1 -0
  30. package/dist/src/modules/file/hooks/useS3DownloadUrl.js +14 -0
  31. package/dist/src/modules/file/hooks/useS3Upload.d.ts +10 -0
  32. package/dist/src/modules/file/hooks/useS3Upload.d.ts.map +1 -0
  33. package/dist/src/modules/file/hooks/useS3Upload.js +76 -0
  34. package/dist/src/modules/file/hooks/useUpload.d.ts +30 -0
  35. package/dist/src/modules/file/hooks/useUpload.d.ts.map +1 -0
  36. package/dist/src/modules/file/hooks/useUpload.js +167 -0
  37. package/dist/src/modules/table/hooks/useDateRangeFilter.d.ts +28 -0
  38. package/dist/src/modules/table/hooks/useDateRangeFilter.d.ts.map +1 -0
  39. package/dist/src/modules/table/hooks/useDateRangeFilter.js +20 -0
  40. package/dist/src/modules/table/hooks/useNuqsQueryParams.d.ts +25 -0
  41. package/dist/src/modules/table/hooks/useNuqsQueryParams.d.ts.map +1 -0
  42. package/dist/src/modules/table/hooks/useNuqsQueryParams.js +82 -0
  43. package/dist/src/modules/table/hooks/useNuqsTable.d.ts +33 -0
  44. package/dist/src/modules/table/hooks/useNuqsTable.d.ts.map +1 -0
  45. package/dist/src/modules/table/hooks/useNuqsTable.js +32 -0
  46. package/dist/src/modules/table/hooks/useQueryWithParams.d.ts +26 -0
  47. package/dist/src/modules/table/hooks/useQueryWithParams.d.ts.map +1 -0
  48. package/dist/src/modules/table/hooks/useQueryWithParams.js +24 -0
  49. package/dist/src/types.d.ts +4 -0
  50. package/dist/src/types.d.ts.map +1 -0
  51. package/dist/src/types.js +1 -0
  52. package/dist/src/utils/date.d.ts +24 -0
  53. package/dist/src/utils/date.d.ts.map +1 -0
  54. package/dist/src/utils/date.js +71 -0
  55. package/dist/src/utils/query.d.ts +8 -0
  56. package/dist/src/utils/query.d.ts.map +1 -0
  57. package/dist/src/utils/query.js +46 -0
  58. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  59. package/package.json +85 -0
  60. package/src/modules/auth/auth.lib.ts +49 -0
  61. package/src/modules/auth/components/AuthProvider.tsx +105 -0
  62. package/src/modules/auth/hooks/useAuth.ts +20 -0
  63. package/src/modules/auth/hooks/useAuthAdmin.ts +188 -0
  64. package/src/modules/auth/hooks/useSession.ts +6 -0
  65. package/src/modules/billing/components/BillingProvider.tsx +58 -0
  66. package/src/modules/billing/hooks/useSubscription.ts +6 -0
  67. package/src/modules/file/hooks/useS3DownloadUrl.ts +18 -0
  68. package/src/modules/file/hooks/useS3Upload.ts +89 -0
  69. package/src/modules/file/hooks/useUpload.ts +220 -0
  70. package/src/modules/table/hooks/useDateRangeFilter.ts +55 -0
  71. package/src/modules/table/hooks/useNuqsQueryParams.ts +134 -0
  72. package/src/modules/table/hooks/useNuqsTable.ts +83 -0
  73. package/src/modules/table/hooks/useQueryWithParams.ts +62 -0
  74. package/src/types.ts +4 -0
  75. package/src/utils/date.ts +88 -0
  76. package/src/utils/query.ts +72 -0
  77. package/src/vite-env.d.ts +1 -0
  78. package/tsconfig.json +29 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.lib.d.ts","sourceRoot":"","sources":["../../../../src/modules/auth/auth.lib.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { adminClient, inferAdditionalFields, lastLoginMethodClient, organizationClient, } from "better-auth/client/plugins";
2
+ import { createAuthClient } from "better-auth/react";
3
+ const options = {
4
+ baseURL: import.meta.env.VITE_SERVER_URL,
5
+ plugins: [
6
+ lastLoginMethodClient(),
7
+ organizationClient({
8
+ teams: {
9
+ enabled: true,
10
+ },
11
+ }),
12
+ adminClient(),
13
+ inferAdditionalFields({
14
+ user: {
15
+ onboarding: {
16
+ type: "number",
17
+ required: false,
18
+ },
19
+ preferences: {
20
+ type: "string",
21
+ required: false,
22
+ },
23
+ flags: {
24
+ type: "string",
25
+ required: false,
26
+ },
27
+ stripeCustomerId: {
28
+ type: "string",
29
+ required: false,
30
+ },
31
+ },
32
+ teamMembers: {
33
+ role: {
34
+ type: "string",
35
+ required: true,
36
+ },
37
+ },
38
+ }),
39
+ ],
40
+ };
41
+ export const authClient = createAuthClient(options);
@@ -0,0 +1,15 @@
1
+ import { authClient } from "../auth.lib";
2
+ type Session = ReturnType<typeof authClient.useSession>["data"];
3
+ export declare const authProviderContext: import("react").Context<{
4
+ isLoading: boolean;
5
+ data: Session | null;
6
+ signOut: () => void;
7
+ registerSession: (onSuccess: () => void) => void;
8
+ }>;
9
+ export declare function AuthProvider({ children, loader, onSession, }: {
10
+ children: React.ReactNode;
11
+ loader?: React.ReactNode;
12
+ onSession?: (session: Session | null) => void;
13
+ }): string | number | bigint | true | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element;
14
+ export {};
15
+ //# sourceMappingURL=AuthProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../../../../src/modules/auth/components/AuthProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAOhE,eAAO,MAAM,mBAAmB;eACnB,OAAO;UACZ,OAAO,GAAG,IAAI;aACX,MAAM,IAAI;qBACF,CAAC,SAAS,EAAE,MAAM,IAAI,KAAK,IAAI;EAMhD,CAAC;AAEH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,MAAM,EACN,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;CAC/C,qVAyEA"}
@@ -0,0 +1,73 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { usePostHog } from "posthog-js/react";
3
+ import { createContext, useCallback, useEffect, useState } from "react";
4
+ import { authClient } from "../auth.lib";
5
+ function isImpersonatedSession(session) {
6
+ const sessionData = session?.session;
7
+ return Boolean(sessionData?.impersonatedBy);
8
+ }
9
+ export const authProviderContext = createContext({
10
+ isLoading: true,
11
+ data: null,
12
+ signOut: () => { },
13
+ registerSession: () => { },
14
+ });
15
+ export function AuthProvider({ children, loader, onSession, }) {
16
+ const posthog = usePostHog();
17
+ const [isLoading, setIsLoading] = useState(true);
18
+ const [session, setSession] = useState(null);
19
+ const registerSession = useCallback((onSuccess) => {
20
+ authClient
21
+ .getSession()
22
+ .then(({ data: nextSession }) => {
23
+ setIsLoading(false);
24
+ setSession(nextSession);
25
+ onSession?.(nextSession);
26
+ if (isImpersonatedSession(nextSession)) {
27
+ posthog.opt_out_capturing();
28
+ posthog.reset();
29
+ onSuccess?.();
30
+ return;
31
+ }
32
+ posthog.opt_in_capturing();
33
+ if (nextSession?.user) {
34
+ posthog.identify(nextSession.user.id, {
35
+ email: nextSession.user.email,
36
+ name: nextSession.user.name,
37
+ createdAt: nextSession.user.createdAt,
38
+ updatedAt: nextSession.user.updatedAt,
39
+ role: nextSession.user.role,
40
+ image: nextSession.user.image,
41
+ preferences: nextSession.user.preferences,
42
+ onboarding: nextSession.user.onboarding,
43
+ flags: nextSession.user.flags,
44
+ });
45
+ }
46
+ else {
47
+ posthog.reset();
48
+ }
49
+ onSuccess?.();
50
+ })
51
+ .catch((error) => {
52
+ console.error("Failed to get session:", error);
53
+ setIsLoading(false);
54
+ setSession(null);
55
+ });
56
+ }, [onSession, posthog]);
57
+ // biome-ignore lint/correctness/useExhaustiveDependencies(registerSession): registerSession is a callback
58
+ useEffect(() => {
59
+ registerSession();
60
+ }, []);
61
+ const signOut = useCallback(() => {
62
+ authClient.signOut().then(() => {
63
+ posthog.reset();
64
+ posthog.opt_in_capturing();
65
+ setSession(null);
66
+ });
67
+ }, [posthog]);
68
+ // Show loading screen while checking authentication status
69
+ if (isLoading) {
70
+ return loader ? loader : "Loading...";
71
+ }
72
+ return (_jsx(authProviderContext.Provider, { value: { isLoading, data: session, signOut, registerSession }, children: children }));
73
+ }
@@ -0,0 +1,4 @@
1
+ import { type AnyUseMutationOptions } from "@tanstack/react-query";
2
+ export declare function useUpdateUser(options: AnyUseMutationOptions): import("@tanstack/react-query").UseMutationResult<any, any, any, any>;
3
+ export declare function useUpdateUserPreferences<T extends Record<string, any>>(options: AnyUseMutationOptions): import("@tanstack/react-query").UseMutationResult<any, any, any, any>;
4
+ //# sourceMappingURL=useAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../../../../../src/modules/auth/hooks/useAuth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAe,MAAM,uBAAuB,CAAC;AAGhF,wBAAgB,aAAa,CAAC,OAAO,EAAE,qBAAqB,yEAM3D;AAED,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACpE,OAAO,EAAE,qBAAqB,yEAO/B"}
@@ -0,0 +1,14 @@
1
+ import { useMutation } from "@tanstack/react-query";
2
+ import { authClient } from "../auth.lib";
3
+ export function useUpdateUser(options) {
4
+ return useMutation({
5
+ mutationFn: (...args) => authClient.updateUser(...args),
6
+ ...options,
7
+ });
8
+ }
9
+ export function useUpdateUserPreferences(options) {
10
+ return useMutation({
11
+ mutationFn: (preferences) => authClient.updateUser({ preferences: JSON.stringify(preferences) }),
12
+ ...options,
13
+ });
14
+ }
@@ -0,0 +1,21 @@
1
+ import { type AnyUseMutationOptions } from "@tanstack/react-query";
2
+ import { authClient } from "../auth.lib";
3
+ type ListUsersArgs = Parameters<typeof authClient.admin.listUsers>;
4
+ export declare function useInvalidateListUsers(...args: ListUsersArgs): () => Promise<void>;
5
+ export declare function useListUsers(...args: ListUsersArgs): import("@tanstack/react-query").UseQueryResult<NonNullable<{
6
+ users: import("better-auth/plugins").UserWithRole[];
7
+ total: number;
8
+ limit: number | undefined;
9
+ offset: number | undefined;
10
+ } | {
11
+ users: never[];
12
+ total: number;
13
+ }>, Error>;
14
+ export declare function useRemoveUser(options: AnyUseMutationOptions): import("@tanstack/react-query").UseMutationResult<any, any, any, any>;
15
+ export declare function useUpdateUser(options: AnyUseMutationOptions): import("@tanstack/react-query").UseMutationResult<any, any, any, any>;
16
+ export declare function useBanUser(options: AnyUseMutationOptions): import("@tanstack/react-query").UseMutationResult<any, any, any, any>;
17
+ export declare function useUnbanUser(options: AnyUseMutationOptions): import("@tanstack/react-query").UseMutationResult<any, any, any, any>;
18
+ export declare function useImpersonateUser(options: AnyUseMutationOptions): import("@tanstack/react-query").UseMutationResult<any, any, any, any>;
19
+ export declare function useStopImpersonating(options: AnyUseMutationOptions): import("@tanstack/react-query").UseMutationResult<any, any, any, any>;
20
+ export {};
21
+ //# sourceMappingURL=useAuthAdmin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAuthAdmin.d.ts","sourceRoot":"","sources":["../../../../../src/modules/auth/hooks/useAuthAdmin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,qBAAqB,EAI3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AASzC,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AA4EnE,wBAAgB,sBAAsB,CAAC,GAAG,IAAI,EAAE,aAAa,uBAG5D;AAoCD,wBAAgB,YAAY,CAAC,GAAG,IAAI,EAAE,aAAa;;;;;;;;WAUlD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,qBAAqB,yEAM3D;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,qBAAqB,yEAM3D;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,qBAAqB,yEAMxD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,qBAAqB,yEAM1D;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,qBAAqB,yEAMhE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,yEAKlE"}
@@ -0,0 +1,160 @@
1
+ import { useMutation, useQuery, useQueryClient, } from "@tanstack/react-query";
2
+ import { authClient } from "../auth.lib";
3
+ /*
4
+ type ListUsersParams = Parameters<typeof authClient.admin.listUsers>;
5
+ type ListUsersArgs = Record<string, unknown>;
6
+
7
+ type FilterOperator = "eq" | "ne" | "lt" | "lte" | "gt" | "gte";
8
+
9
+ type BetterAuthFilterParams = {
10
+ filterField: string;
11
+ filterValue: string | number | boolean;
12
+ filterOperator: FilterOperator;
13
+ };
14
+
15
+ export const authFilterMethods: FilterMethods = {
16
+ string: [{ value: "equals", label: "Equals", component: "text" }],
17
+ number: [
18
+ { value: "equals", label: "Equals", component: "number" },
19
+ { value: "greater_than", label: "Greater Than", component: "number" },
20
+ { value: "less_than", label: "Less Than", component: "number" },
21
+ ],
22
+ date: [
23
+ { value: "on", label: "On", component: "date" },
24
+ { value: "before", label: "Before", component: "date" },
25
+ { value: "after", label: "After", component: "date" },
26
+ ],
27
+ boolean: [{ value: "equals", label: "Equals", component: "radio" }],
28
+ enum: [{ value: "equals", label: "Equals", component: "select" }],
29
+ };
30
+
31
+ const baseMethodOperatorMap: Partial<Record<FilterMethodName, FilterOperator>> = {
32
+ equals: "eq",
33
+ greater_than: "gt",
34
+ less_than: "lt",
35
+ before: "lte",
36
+ after: "gte",
37
+ on: "eq",
38
+ };
39
+
40
+ const getAllowedMethods = (): Record<FilterMethodName, FilterOperator> => {
41
+ const operatorMap: Partial<Record<FilterMethodName, FilterOperator>> = {};
42
+ Object.values(authFilterMethods).forEach((methodsForType) => {
43
+ methodsForType.forEach((method: FilterMethod) => {
44
+ const operator = baseMethodOperatorMap[method.value];
45
+ if (operator) {
46
+ operatorMap[method.value] = operator;
47
+ }
48
+ });
49
+ });
50
+ return operatorMap as Record<FilterMethodName, FilterOperator>;
51
+ };
52
+
53
+ const filterMethodToOperatorMap = getAllowedMethods();
54
+
55
+ const mapFilterToBetterAuth = (filter?: QueryFilter): Partial<BetterAuthFilterParams> => {
56
+ if (!filter) return {};
57
+ if (!filter.type) return {};
58
+ const allowedMethodsForType = authFilterMethods[filter.type]?.map((method) => method.value) ?? [];
59
+ if (!allowedMethodsForType.includes(filter.method)) return {};
60
+ const operator = filterMethodToOperatorMap[filter.method];
61
+ if (!operator) return {};
62
+ const { columnId, value, type } = filter;
63
+ if (value === undefined || value === null) return {};
64
+ if (type === "boolean" && typeof value === "boolean" && operator === "eq") {
65
+ return { filterField: columnId, filterValue: value, filterOperator: operator };
66
+ }
67
+ if (type === "number" && typeof value === "number") {
68
+ return { filterField: columnId, filterValue: value, filterOperator: operator };
69
+ }
70
+ if ((type === "string" || type === "enum" || type === "date") && typeof value === "string") {
71
+ return { filterField: columnId, filterValue: value, filterOperator: operator };
72
+ }
73
+ return {};
74
+ };
75
+ */
76
+ export function useInvalidateListUsers(...args) {
77
+ const queryClient = useQueryClient();
78
+ return () => queryClient.invalidateQueries({ queryKey: ["auth-admin-list-users", ...args] });
79
+ }
80
+ /*
81
+ export function getListUsers(input: ListUsersArgs): any {
82
+ const {
83
+ filters,
84
+ page,
85
+ limit,
86
+ sort,
87
+ order,
88
+ ...listUsersParams
89
+ } = input as ListUsersArgs & QueryInput;
90
+ const filterParams = mapFilterToBetterAuth(filters?.[0]);
91
+ const sortDirection: "asc" | "desc" = order === "asc" ? "asc" : "desc";
92
+ const queryPayload = {
93
+ ...listUsersParams,
94
+ limit,
95
+ sortBy: sort,
96
+ sortDirection,
97
+ offset: (page - 1) * limit,
98
+ ...filterParams,
99
+ };
100
+
101
+ return {
102
+ queryKey: ["auth-admin-list-users", input],
103
+ queryFn: async () => {
104
+ const { data, error } = await authClient.admin.listUsers({
105
+ query: queryPayload,
106
+ });
107
+ if (error) return Promise.reject(error);
108
+ return data;
109
+ },
110
+ };
111
+ }
112
+ */
113
+ export function useListUsers(...args) {
114
+ return useQuery({
115
+ queryKey: ["auth-admin-list-users", ...args],
116
+ queryFn: async ({ queryKey }) => {
117
+ const listUserArgs = queryKey.slice(1);
118
+ const { data, error } = await authClient.admin.listUsers(...listUserArgs);
119
+ if (error)
120
+ return Promise.reject(error);
121
+ return data;
122
+ },
123
+ });
124
+ }
125
+ export function useRemoveUser(options) {
126
+ return useMutation({
127
+ mutationFn: (...args) => authClient.admin.removeUser(...args),
128
+ ...options,
129
+ });
130
+ }
131
+ export function useUpdateUser(options) {
132
+ return useMutation({
133
+ mutationFn: (...args) => authClient.admin.updateUser(...args),
134
+ ...options,
135
+ });
136
+ }
137
+ export function useBanUser(options) {
138
+ return useMutation({
139
+ mutationFn: (...args) => authClient.admin.banUser(...args),
140
+ ...options,
141
+ });
142
+ }
143
+ export function useUnbanUser(options) {
144
+ return useMutation({
145
+ mutationFn: (...args) => authClient.admin.unbanUser(...args),
146
+ ...options,
147
+ });
148
+ }
149
+ export function useImpersonateUser(options) {
150
+ return useMutation({
151
+ mutationFn: (...args) => authClient.admin.impersonateUser(...args),
152
+ ...options,
153
+ });
154
+ }
155
+ export function useStopImpersonating(options) {
156
+ return useMutation({
157
+ mutationFn: () => authClient.admin.stopImpersonating(),
158
+ ...options,
159
+ });
160
+ }
@@ -0,0 +1,38 @@
1
+ export declare function useSession(): {
2
+ isLoading: boolean;
3
+ data: ({
4
+ user: {
5
+ id: string;
6
+ createdAt: Date;
7
+ updatedAt: Date;
8
+ email: string;
9
+ emailVerified: boolean;
10
+ name: string;
11
+ image?: string | null | undefined;
12
+ banned: boolean | null | undefined;
13
+ role?: string | null | undefined;
14
+ banReason?: string | null | undefined;
15
+ banExpires?: Date | null | undefined;
16
+ stripeCustomerId?: string | null | undefined;
17
+ preferences?: string | null | undefined;
18
+ onboarding?: number | null | undefined;
19
+ flags?: string | null | undefined;
20
+ };
21
+ session: {
22
+ id: string;
23
+ createdAt: Date;
24
+ updatedAt: Date;
25
+ userId: string;
26
+ expiresAt: Date;
27
+ token: string;
28
+ ipAddress?: string | null | undefined;
29
+ userAgent?: string | null | undefined;
30
+ activeOrganizationId?: string | null | undefined;
31
+ activeTeamId?: string | null | undefined;
32
+ impersonatedBy?: string | null | undefined;
33
+ };
34
+ } | null) | null;
35
+ signOut: () => void;
36
+ registerSession: (onSuccess: () => void) => void;
37
+ };
38
+ //# sourceMappingURL=useSession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSession.d.ts","sourceRoot":"","sources":["../../../../../src/modules/auth/hooks/useSession.ts"],"names":[],"mappings":"AAGA,wBAAgB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEzB"}
@@ -0,0 +1,5 @@
1
+ import { useContext } from "react";
2
+ import { authProviderContext } from "../components/AuthProvider";
3
+ export function useSession() {
4
+ return useContext(authProviderContext);
5
+ }
@@ -0,0 +1,14 @@
1
+ import type { BillingSchema } from "@m5kdev/commons/modules/billing/billing.schema";
2
+ import type { UseBackendTRPC } from "#types";
3
+ export declare const billingProviderContext: import("react").Context<{
4
+ isLoading: boolean;
5
+ data: BillingSchema | null;
6
+ }>;
7
+ export declare function BillingProvider({ useTRPC, children, loader, planPage, skipPlanCheck, }: {
8
+ useTRPC: UseBackendTRPC;
9
+ children: React.ReactNode;
10
+ loader?: React.ReactNode;
11
+ planPage: React.ReactNode;
12
+ skipPlanCheck?: boolean;
13
+ }): string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
14
+ //# sourceMappingURL=BillingProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BillingProvider.d.ts","sourceRoot":"","sources":["../../../../../src/modules/billing/components/BillingProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAGpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7C,eAAO,MAAM,sBAAsB;eACtB,OAAO;UACZ,aAAa,GAAG,IAAI;EAI1B,CAAC;AAEH,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,aAAqB,GACtB,EAAE;IACD,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,2WAgCA"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useQuery } from "@tanstack/react-query";
3
+ import { createContext } from "react";
4
+ export const billingProviderContext = createContext({
5
+ isLoading: true,
6
+ data: null,
7
+ });
8
+ export function BillingProvider({ useTRPC, children, loader, planPage, skipPlanCheck = false, }) {
9
+ const trpc = useTRPC();
10
+ const { data: activeSubscription, isLoading } = useQuery(trpc.billing.getActiveSubscription.queryOptions(undefined, {
11
+ staleTime: 1000 * 60 * 60 * 4, // 4 hours
12
+ enabled: !skipPlanCheck,
13
+ }));
14
+ if (skipPlanCheck) {
15
+ return (_jsx(billingProviderContext.Provider, { value: { isLoading: false, data: null }, children: children }));
16
+ }
17
+ // Show loading screen while checking subscription status
18
+ if (isLoading) {
19
+ return loader ? loader : "Loading...";
20
+ }
21
+ if (!activeSubscription) {
22
+ return planPage;
23
+ }
24
+ return (_jsx(billingProviderContext.Provider, { value: { isLoading, data: activeSubscription ?? null }, children: children }));
25
+ }
@@ -0,0 +1,5 @@
1
+ export declare function useSubscription(): {
2
+ isLoading: boolean;
3
+ data: import("@m5kdev/commons/modules/billing/billing.schema").BillingSchema | null;
4
+ };
5
+ //# sourceMappingURL=useSubscription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSubscription.d.ts","sourceRoot":"","sources":["../../../../../src/modules/billing/hooks/useSubscription.ts"],"names":[],"mappings":"AAGA,wBAAgB,eAAe;;;EAE9B"}
@@ -0,0 +1,5 @@
1
+ import { useContext } from "react";
2
+ import { billingProviderContext } from "../components/BillingProvider";
3
+ export function useSubscription() {
4
+ return useContext(billingProviderContext);
5
+ }
@@ -0,0 +1,3 @@
1
+ export declare function fetchS3DownloadUrl(filePath: string, serverUrl?: any): Promise<string>;
2
+ export declare function useS3DownloadUrl(filePath: string, serverUrl?: any): import("@tanstack/react-query").UseQueryResult<string, Error>;
3
+ //# sourceMappingURL=useS3DownloadUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useS3DownloadUrl.d.ts","sourceRoot":"","sources":["../../../../../src/modules/file/hooks/useS3DownloadUrl.ts"],"names":[],"mappings":"AAEA,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,SAAS,MAAkC,mBAK5C;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,MAAkC,iEAM7F"}
@@ -0,0 +1,14 @@
1
+ import { useQuery } from "@tanstack/react-query";
2
+ export async function fetchS3DownloadUrl(filePath, serverUrl = import.meta.env.VITE_SERVER_URL) {
3
+ const res = await fetch(`${serverUrl}/upload/files/${filePath}`);
4
+ if (!res.ok)
5
+ throw new Error("Failed to get download URL");
6
+ return (await res.json()).url;
7
+ }
8
+ export function useS3DownloadUrl(filePath, serverUrl = import.meta.env.VITE_SERVER_URL) {
9
+ return useQuery({
10
+ queryKey: ["s3DownloadUrl", filePath],
11
+ queryFn: () => fetchS3DownloadUrl(filePath, serverUrl),
12
+ enabled: Boolean(filePath),
13
+ });
14
+ }
@@ -0,0 +1,10 @@
1
+ export type S3UploadStatus = "idle" | "uploading" | "success" | "error";
2
+ export declare function useS3Upload(serverUrl?: string): {
3
+ upload: (file: File | Blob, prefix?: string) => Promise<string>;
4
+ progress: number;
5
+ status: S3UploadStatus;
6
+ error: string | null;
7
+ uploadedUrl: string | null;
8
+ reset: () => void;
9
+ };
10
+ //# sourceMappingURL=useS3Upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useS3Upload.d.ts","sourceRoot":"","sources":["../../../../../src/modules/file/hooks/useS3Upload.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;AAiBxE,wBAAgB,WAAW,CAAC,SAAS,SAAK;mBAMA,IAAI,GAAG,IAAI,WAAW,MAAM;;;;;;EA+DrE"}
@@ -0,0 +1,76 @@
1
+ import { useCallback, useState } from "react";
2
+ async function getPresignedUrl(filename, filetype, serverUrl = "") {
3
+ const res = await fetch(`${serverUrl}/upload/s3-presigned-url`, {
4
+ method: "POST",
5
+ headers: { "Content-Type": "application/json" },
6
+ body: JSON.stringify({ filename, filetype }),
7
+ });
8
+ if (!res.ok)
9
+ throw new Error("Failed to get presigned URL");
10
+ const data = (await res.json());
11
+ return data.url;
12
+ }
13
+ export function useS3Upload(serverUrl = "") {
14
+ const [progress, setProgress] = useState(0);
15
+ const [status, setStatus] = useState("idle");
16
+ const [error, setError] = useState(null);
17
+ const [uploadedUrl, setUploadedUrl] = useState(null);
18
+ const upload = useCallback(async (file, prefix) => {
19
+ setProgress(0);
20
+ setStatus("uploading");
21
+ setError(null);
22
+ setUploadedUrl(null);
23
+ try {
24
+ const originalFilename = file instanceof File ? file.name : `upload-${Date.now()}`;
25
+ const extension = originalFilename.split(".").pop() || "";
26
+ const uuid = crypto.randomUUID();
27
+ const filename = prefix
28
+ ? `${prefix}/${uuid}.${extension}`
29
+ : `${uuid}.${extension}`;
30
+ const filetype = file instanceof File ? file.type : "application/octet-stream";
31
+ const presignedUrl = await getPresignedUrl(filename, filetype, serverUrl);
32
+ return await new Promise((resolve, reject) => {
33
+ const xhr = new XMLHttpRequest();
34
+ xhr.open("PUT", presignedUrl);
35
+ xhr.setRequestHeader("Content-Type", filetype);
36
+ xhr.upload.onprogress = (event) => {
37
+ if (event.lengthComputable) {
38
+ setProgress(Math.round((event.loaded * 100) / event.total));
39
+ }
40
+ };
41
+ xhr.onload = () => {
42
+ if (xhr.status >= 200 && xhr.status < 300) {
43
+ setProgress(100);
44
+ setStatus("success");
45
+ // Remove query params to get the public URL
46
+ setUploadedUrl(presignedUrl.split("?")[0]);
47
+ resolve(filename);
48
+ }
49
+ else {
50
+ setStatus("error");
51
+ setError(`Upload failed with status ${xhr.status}`);
52
+ reject(new Error(`Upload failed with status ${xhr.status}`));
53
+ }
54
+ };
55
+ xhr.onerror = () => {
56
+ setStatus("error");
57
+ setError("Network error during upload");
58
+ reject(new Error("Network error during upload"));
59
+ };
60
+ xhr.send(file);
61
+ });
62
+ }
63
+ catch (err) {
64
+ setStatus("error");
65
+ setError(err?.message || "Unknown error");
66
+ return Promise.reject(err);
67
+ }
68
+ }, [serverUrl]);
69
+ const reset = useCallback(() => {
70
+ setProgress(0);
71
+ setStatus("idle");
72
+ setError(null);
73
+ setUploadedUrl(null);
74
+ }, []);
75
+ return { upload, progress, status, error, uploadedUrl, reset };
76
+ }
@@ -0,0 +1,30 @@
1
+ export type UploadStatus = "pending" | "uploading" | "completed" | "error";
2
+ export interface UploadFileTask {
3
+ id: string;
4
+ file: File;
5
+ progress: number;
6
+ status: UploadStatus;
7
+ errorMessage?: string;
8
+ bytesUploaded: number;
9
+ totalBytes: number;
10
+ }
11
+ export declare function useFileUpload(): {
12
+ upload: <T>(type: string, file: File) => Promise<T>;
13
+ reset: () => void;
14
+ id?: string | undefined;
15
+ file?: File | undefined;
16
+ progress?: number | undefined;
17
+ status?: UploadStatus | undefined;
18
+ errorMessage?: string;
19
+ bytesUploaded?: number | undefined;
20
+ totalBytes?: number | undefined;
21
+ };
22
+ export declare function useMultipartUpload(): {
23
+ uploadQueue: UploadFileTask[];
24
+ overallProgress: number;
25
+ uploadFiles: (type: string, files: File[]) => Promise<void>;
26
+ reset: () => void;
27
+ getTotalBytes: () => number;
28
+ getTotalBytesUploaded: () => number;
29
+ };
30
+ //# sourceMappingURL=useUpload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useUpload.d.ts","sourceRoot":"","sources":["../../../../../src/modules/file/hooks/useUpload.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,OAAO,CAAC;AAE3E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAmED,wBAAgB,aAAa;aAGO,CAAC,QAAQ,MAAM,QAAQ,IAAI,KAAG,OAAO,CAAC,CAAC,CAAC;;;;;;mBAzE3D,MAAM;;;EAuHtB;AAGD,wBAAgB,kBAAkB;;;wBA6DjB,MAAM,SAAS,IAAI,EAAE;;;;EA2BrC"}