react-unified-auth 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -23
- package/dist/components/Button.d.ts +8 -0
- package/dist/components/DynamicForm.d.ts +9 -0
- package/dist/components/LoginForm.d.ts +6 -0
- package/dist/components/SocialLogin.d.ts +15 -0
- package/dist/components/UserInfoBox.d.ts +8 -0
- package/dist/context/AuthContext.d.ts +8 -0
- package/dist/hooks/useAuth.d.ts +10 -0
- package/dist/hooks/useDynamicForm.d.ts +6 -0
- package/dist/index.css +438 -0
- package/dist/index.d.ts +18 -158
- package/dist/index.esm.css +1 -0
- package/dist/index.esm.js +23 -28
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +35 -40
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +59 -0
- package/dist/utils/api-client.d.ts +14 -0
- package/dist/utils/validation.d.ts +9 -0
- package/package.json +6 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,158 +1,18 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
required?: boolean;
|
|
20
|
-
options?: Array<{
|
|
21
|
-
label: string;
|
|
22
|
-
value: string;
|
|
23
|
-
}>;
|
|
24
|
-
validation?: {
|
|
25
|
-
pattern?: string;
|
|
26
|
-
minLength?: number;
|
|
27
|
-
maxLength?: number;
|
|
28
|
-
min?: number;
|
|
29
|
-
max?: number;
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
interface DynamicFormConfig {
|
|
33
|
-
fields: FormField[];
|
|
34
|
-
submitUrl: string;
|
|
35
|
-
method?: 'POST' | 'PUT' | 'PATCH';
|
|
36
|
-
submitButton?: {
|
|
37
|
-
text: string;
|
|
38
|
-
variant?: 'primary' | 'secondary' | 'outline';
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
interface UserInfo {
|
|
42
|
-
id: string;
|
|
43
|
-
name: string;
|
|
44
|
-
email?: string;
|
|
45
|
-
avatar?: string;
|
|
46
|
-
[key: string]: any;
|
|
47
|
-
}
|
|
48
|
-
interface AuthResponse {
|
|
49
|
-
success: boolean;
|
|
50
|
-
data?: {
|
|
51
|
-
user?: UserInfo;
|
|
52
|
-
token?: string;
|
|
53
|
-
refreshToken?: string;
|
|
54
|
-
};
|
|
55
|
-
error?: string;
|
|
56
|
-
}
|
|
57
|
-
interface SocialProvider {
|
|
58
|
-
id: string;
|
|
59
|
-
name: string;
|
|
60
|
-
icon?: string;
|
|
61
|
-
authUrl: string;
|
|
62
|
-
scope?: string[];
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
interface AuthProviderProps {
|
|
66
|
-
config: AuthConfig;
|
|
67
|
-
children: ReactNode;
|
|
68
|
-
}
|
|
69
|
-
declare function AuthProvider({ config, children }: AuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
70
|
-
declare function useAuthConfig(): AuthConfig;
|
|
71
|
-
|
|
72
|
-
declare function useAuth(): {
|
|
73
|
-
user: UserInfo | null;
|
|
74
|
-
loading: boolean;
|
|
75
|
-
error: string | null;
|
|
76
|
-
login: (credentials: Record<string, any>) => Promise<AuthResponse>;
|
|
77
|
-
logout: () => Promise<void>;
|
|
78
|
-
getUserInfo: () => Promise<UserInfo | null>;
|
|
79
|
-
isAuthenticated: boolean;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
declare function useDynamicForm(formId: string): {
|
|
83
|
-
formConfig: DynamicFormConfig | null;
|
|
84
|
-
loading: boolean;
|
|
85
|
-
error: string | null;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
89
|
-
variant?: 'primary' | 'secondary' | 'outline';
|
|
90
|
-
size?: 'sm' | 'md' | 'lg';
|
|
91
|
-
loading?: boolean;
|
|
92
|
-
fullWidth?: boolean;
|
|
93
|
-
}
|
|
94
|
-
declare function Button({ variant, size, loading, fullWidth, children, disabled, className, ...props }: ButtonProps): react_jsx_runtime.JSX.Element;
|
|
95
|
-
|
|
96
|
-
interface DynamicFormProps {
|
|
97
|
-
fields: FormField[];
|
|
98
|
-
onSubmit: (values: Record<string, any>) => void;
|
|
99
|
-
submitText?: string;
|
|
100
|
-
submitVariant?: 'primary' | 'secondary' | 'outline';
|
|
101
|
-
loading?: boolean;
|
|
102
|
-
}
|
|
103
|
-
declare function DynamicForm({ fields, onSubmit, submitText, submitVariant, loading, }: DynamicFormProps): react_jsx_runtime.JSX.Element;
|
|
104
|
-
|
|
105
|
-
interface LoginFormProps {
|
|
106
|
-
formId: string;
|
|
107
|
-
onSuccess?: (data: any) => void;
|
|
108
|
-
onError?: (error: string) => void;
|
|
109
|
-
}
|
|
110
|
-
declare function LoginForm({ formId, onSuccess, onError }: LoginFormProps): react_jsx_runtime.JSX.Element | null;
|
|
111
|
-
|
|
112
|
-
interface UserInfoBoxProps {
|
|
113
|
-
user: UserInfo;
|
|
114
|
-
onLogout?: () => void;
|
|
115
|
-
loading?: boolean;
|
|
116
|
-
className?: string;
|
|
117
|
-
}
|
|
118
|
-
declare function UserInfoBox({ user, onLogout, loading, className }: UserInfoBoxProps): react_jsx_runtime.JSX.Element;
|
|
119
|
-
|
|
120
|
-
interface SocialLoginButtonProps {
|
|
121
|
-
provider: SocialProvider;
|
|
122
|
-
onClick: (provider: SocialProvider) => void;
|
|
123
|
-
loading?: boolean;
|
|
124
|
-
className?: string;
|
|
125
|
-
}
|
|
126
|
-
declare function SocialLoginButton({ provider, onClick, loading, className }: SocialLoginButtonProps): react_jsx_runtime.JSX.Element;
|
|
127
|
-
interface SocialLoginProps {
|
|
128
|
-
providers: SocialProvider[];
|
|
129
|
-
onLogin: (provider: SocialProvider) => void;
|
|
130
|
-
loading?: boolean;
|
|
131
|
-
className?: string;
|
|
132
|
-
}
|
|
133
|
-
declare function SocialLogin({ providers, onLogin, loading, className }: SocialLoginProps): react_jsx_runtime.JSX.Element | null;
|
|
134
|
-
|
|
135
|
-
declare class ApiClient {
|
|
136
|
-
private client;
|
|
137
|
-
constructor(config: {
|
|
138
|
-
baseURL: string;
|
|
139
|
-
timeout?: number;
|
|
140
|
-
headers?: Record<string, string>;
|
|
141
|
-
});
|
|
142
|
-
get<T>(url: string, config?: AxiosRequestConfig): Promise<T>;
|
|
143
|
-
post<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
|
|
144
|
-
put<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
|
|
145
|
-
patch<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
|
|
146
|
-
delete<T>(url: string, config?: AxiosRequestConfig): Promise<T>;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
declare function validateField(field: FormField, value: any): {
|
|
150
|
-
valid: boolean;
|
|
151
|
-
error?: string;
|
|
152
|
-
};
|
|
153
|
-
declare function validateForm(fields: FormField[], values: Record<string, any>): {
|
|
154
|
-
valid: boolean;
|
|
155
|
-
errors: Record<string, string>;
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
export { ApiClient, AuthConfig, AuthProvider, AuthProviderProps, AuthResponse, Button, ButtonProps, DynamicForm, DynamicFormConfig, DynamicFormProps, FormField, LoginForm, LoginFormProps, SocialLogin, SocialLoginButton, SocialLoginButtonProps, SocialLoginProps, SocialProvider, UserInfo, UserInfoBox, UserInfoBoxProps, useAuth, useAuthConfig, useDynamicForm, validateField, validateForm };
|
|
1
|
+
import './styles/index.css';
|
|
2
|
+
export { AuthProvider, useAuthConfig } from './context/AuthContext';
|
|
3
|
+
export { useAuth } from './hooks/useAuth';
|
|
4
|
+
export { useDynamicForm } from './hooks/useDynamicForm';
|
|
5
|
+
export { Button } from './components/Button';
|
|
6
|
+
export { DynamicForm } from './components/DynamicForm';
|
|
7
|
+
export { LoginForm } from './components/LoginForm';
|
|
8
|
+
export { UserInfoBox } from './components/UserInfoBox';
|
|
9
|
+
export { SocialLogin, SocialLoginButton } from './components/SocialLogin';
|
|
10
|
+
export { ApiClient } from './utils/api-client';
|
|
11
|
+
export { validateField, validateForm } from './utils/validation';
|
|
12
|
+
export type { AuthConfig, FormField, DynamicFormConfig, UserInfo, AuthResponse, SocialProvider, } from './types';
|
|
13
|
+
export type { AuthProviderProps } from './context/AuthContext';
|
|
14
|
+
export type { ButtonProps } from './components/Button';
|
|
15
|
+
export type { DynamicFormProps } from './components/DynamicForm';
|
|
16
|
+
export type { LoginFormProps } from './components/LoginForm';
|
|
17
|
+
export type { UserInfoBoxProps } from './components/UserInfoBox';
|
|
18
|
+
export type { SocialLoginProps, SocialLoginButtonProps } from './components/SocialLogin';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.-ml-1{margin-left:-.25rem}.mb-1{margin-bottom:.25rem}.ml-1{margin-left:.25rem}.mr-2{margin-right:.5rem}.mt-1{margin-top:.25rem}.mt-4{margin-top:1rem}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.h-16{height:4rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-8{height:2rem}.w-16{width:4rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-8{width:2rem}.w-full{width:100%}.flex-1{flex:1 1 0%}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.items-center{align-items:center}.justify-center{justify-content:center}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.75rem*var(--tw-space-y-reverse));margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.border-2{border-width:2px}.border-b-2{border-bottom-width:2px}.border-blue-600{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity,1))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-red-200{--tw-border-opacity:1;border-color:rgb(254 202 202/var(--tw-border-opacity,1))}.border-red-500{--tw-border-opacity:1;border-color:rgb(239 68 68/var(--tw-border-opacity,1))}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity,1))}.bg-red-50{--tw-bg-opacity:1;background-color:rgb(254 242 242/var(--tw-bg-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.object-cover{-o-object-fit:cover;object-fit:cover}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1\.5{padding-bottom:.375rem;padding-top:.375rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.opacity-25{opacity:.25}.opacity-75{opacity:.75}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.outline{outline-style:solid}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.hover\:bg-blue-50:hover{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.hover\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity,1))}.hover\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\:ring-gray-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(107 114 128/var(--tw-ring-opacity,1))}.focus\:ring-red-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(239 68 68/var(--tw-ring-opacity,1))}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}
|
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import
|
|
2
|
+
import { createContext, useContext, useState, useEffect } from 'react';
|
|
3
3
|
|
|
4
4
|
const AuthContext = createContext(undefined);
|
|
5
5
|
function AuthProvider({ config, children }) {
|
|
@@ -4062,19 +4062,14 @@ function useDynamicForm(formId) {
|
|
|
4062
4062
|
}
|
|
4063
4063
|
|
|
4064
4064
|
function Button({ variant = 'primary', size = 'md', loading = false, fullWidth = false, children, disabled, className = '', ...props }) {
|
|
4065
|
-
const
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
md: 'px-4 py-2 text-base',
|
|
4074
|
-
lg: 'px-6 py-3 text-lg',
|
|
4075
|
-
};
|
|
4076
|
-
const widthStyles = fullWidth ? 'w-full' : '';
|
|
4077
|
-
return (jsxs("button", { className: `${baseStyles} ${variantStyles[variant]} ${sizeStyles[size]} ${widthStyles} ${className}`, disabled: disabled || loading, ...props, children: [loading && (jsxs("svg", { className: "animate-spin -ml-1 mr-2 h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] })), children] }));
|
|
4065
|
+
const buttonClasses = [
|
|
4066
|
+
'usa-button',
|
|
4067
|
+
`usa-button--${variant}`,
|
|
4068
|
+
`usa-button--${size}`,
|
|
4069
|
+
fullWidth ? 'usa-button--full-width' : '',
|
|
4070
|
+
className
|
|
4071
|
+
].filter(Boolean).join(' ');
|
|
4072
|
+
return (jsxs("button", { className: buttonClasses, disabled: disabled || loading, ...props, children: [loading && (jsxs("svg", { className: "usa-loading-spinner", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] })), children] }));
|
|
4078
4073
|
}
|
|
4079
4074
|
|
|
4080
4075
|
function validateField(field, value) {
|
|
@@ -4163,8 +4158,8 @@ function DynamicForm({ fields, onSubmit, submitText = 'Submit', submitVariant =
|
|
|
4163
4158
|
const renderField = (field) => {
|
|
4164
4159
|
const error = touched[field.name] ? errors[field.name] : '';
|
|
4165
4160
|
const hasError = !!error;
|
|
4166
|
-
const baseInputStyles = '
|
|
4167
|
-
const errorStyles = hasError ? '
|
|
4161
|
+
const baseInputStyles = 'usa-form__input';
|
|
4162
|
+
const errorStyles = hasError ? 'usa-form__input--error' : '';
|
|
4168
4163
|
switch (field.type) {
|
|
4169
4164
|
case 'text':
|
|
4170
4165
|
case 'email':
|
|
@@ -4172,24 +4167,24 @@ function DynamicForm({ fields, onSubmit, submitText = 'Submit', submitVariant =
|
|
|
4172
4167
|
case 'number':
|
|
4173
4168
|
return (jsx("input", { type: field.type, name: field.name, value: values[field.name] || '', onChange: (e) => handleChange(field.name, e.target.value), onBlur: () => handleBlur(field.name), placeholder: field.placeholder, className: `${baseInputStyles} ${errorStyles}`, disabled: loading }));
|
|
4174
4169
|
case 'textarea':
|
|
4175
|
-
return (jsx("textarea", { name: field.name, value: values[field.name] || '', onChange: (e) => handleChange(field.name, e.target.value), onBlur: () => handleBlur(field.name), placeholder: field.placeholder, rows: 4, className:
|
|
4170
|
+
return (jsx("textarea", { name: field.name, value: values[field.name] || '', onChange: (e) => handleChange(field.name, e.target.value), onBlur: () => handleBlur(field.name), placeholder: field.placeholder, rows: 4, className: "usa-form__textarea", disabled: loading }));
|
|
4176
4171
|
case 'select':
|
|
4177
|
-
return (jsxs("select", { name: field.name, value: values[field.name] || '', onChange: (e) => handleChange(field.name, e.target.value), onBlur: () => handleBlur(field.name), className:
|
|
4172
|
+
return (jsxs("select", { name: field.name, value: values[field.name] || '', onChange: (e) => handleChange(field.name, e.target.value), onBlur: () => handleBlur(field.name), className: "usa-form__select", disabled: loading, children: [jsx("option", { value: "", children: "Select an option" }), field.options?.map((option) => (jsx("option", { value: option.value, children: option.label }, option.value)))] }));
|
|
4178
4173
|
case 'checkbox':
|
|
4179
|
-
return (jsx("input", { type: "checkbox", name: field.name, checked: values[field.name] || false, onChange: (e) => handleChange(field.name, e.target.checked), onBlur: () => handleBlur(field.name), className: "
|
|
4174
|
+
return (jsx("input", { type: "checkbox", name: field.name, checked: values[field.name] || false, onChange: (e) => handleChange(field.name, e.target.checked), onBlur: () => handleBlur(field.name), className: "usa-form__checkbox", disabled: loading }));
|
|
4180
4175
|
case 'radio':
|
|
4181
|
-
return (jsx("div", { className: "
|
|
4176
|
+
return (jsx("div", { className: "usa-form__radio-group", children: field.options?.map((option) => (jsxs("label", { className: "usa-form__radio-label", children: [jsx("input", { type: "radio", name: field.name, value: option.value, checked: values[field.name] === option.value, onChange: (e) => handleChange(field.name, e.target.value), onBlur: () => handleBlur(field.name), className: "usa-form__radio", disabled: loading }), jsx("span", { children: option.label })] }, option.value))) }));
|
|
4182
4177
|
default:
|
|
4183
4178
|
return null;
|
|
4184
4179
|
}
|
|
4185
4180
|
};
|
|
4186
|
-
return (jsxs("form", { onSubmit: handleSubmit, className: "
|
|
4181
|
+
return (jsxs("form", { onSubmit: handleSubmit, className: "usa-form", children: [fields.map((field) => (jsxs("div", { className: "usa-form__field-group", children: [jsx("label", { className: `usa-form__label ${field.required ? 'usa-form__label--required' : ''}`, children: field.label }), renderField(field), touched[field.name] && errors[field.name] && (jsx("p", { className: "usa-form__error", children: errors[field.name] }))] }, field.name))), jsx(Button, { type: "submit", variant: submitVariant, loading: loading, fullWidth: true, children: submitText })] }));
|
|
4187
4182
|
}
|
|
4188
4183
|
|
|
4189
4184
|
function LoginForm({ formId, onSuccess, onError }) {
|
|
4190
4185
|
const config = useAuthConfig();
|
|
4191
4186
|
const { formConfig, loading: formLoading, error: formError } = useDynamicForm(formId);
|
|
4192
|
-
const [submitting, setSubmitting] =
|
|
4187
|
+
const [submitting, setSubmitting] = useState(false);
|
|
4193
4188
|
const handleSubmit = async (values) => {
|
|
4194
4189
|
if (!formConfig)
|
|
4195
4190
|
return;
|
|
@@ -4216,32 +4211,32 @@ function LoginForm({ formId, onSuccess, onError }) {
|
|
|
4216
4211
|
}
|
|
4217
4212
|
};
|
|
4218
4213
|
if (formLoading) {
|
|
4219
|
-
return (jsx("div", { className: "
|
|
4214
|
+
return (jsx("div", { className: "usa-login-form__loading", children: jsx("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600" }) }));
|
|
4220
4215
|
}
|
|
4221
4216
|
if (formError) {
|
|
4222
|
-
return (jsx("div", { className: "
|
|
4217
|
+
return (jsx("div", { className: "usa-login-form__error", children: jsx("p", { className: "text-red-600", children: formError }) }));
|
|
4223
4218
|
}
|
|
4224
4219
|
if (!formConfig) {
|
|
4225
4220
|
return null;
|
|
4226
4221
|
}
|
|
4227
|
-
return (jsx("div", { className: "
|
|
4222
|
+
return (jsx("div", { className: "usa-login-form", children: jsx(DynamicForm, { fields: formConfig.fields, onSubmit: handleSubmit, submitText: formConfig.submitButton?.text || 'Login', submitVariant: formConfig.submitButton?.variant || 'primary', loading: submitting }) }));
|
|
4228
4223
|
}
|
|
4229
4224
|
|
|
4230
4225
|
function UserInfoBox({ user, onLogout, loading = false, className = '' }) {
|
|
4231
|
-
return (jsxs("div", { className: `
|
|
4226
|
+
return (jsxs("div", { className: `usa-user-info-box ${className}`, children: [jsxs("div", { className: "usa-user-info-box__header", children: [user.avatar && (jsx("img", { src: user.avatar, alt: user.name, className: "usa-user-info-box__avatar" })), jsxs("div", { className: "usa-user-info-box__details", children: [jsx("h3", { className: "usa-user-info-box__name", children: user.name }), user.email && (jsx("p", { className: "usa-user-info-box__email", children: user.email }))] })] }), onLogout && (jsx("div", { className: "mt-4", children: jsx(Button, { variant: "outline", size: "sm", onClick: onLogout, loading: loading, fullWidth: true, children: "Logout" }) }))] }));
|
|
4232
4227
|
}
|
|
4233
4228
|
|
|
4234
4229
|
function SocialLoginButton({ provider, onClick, loading = false, className = '' }) {
|
|
4235
4230
|
const handleClick = () => {
|
|
4236
4231
|
onClick(provider);
|
|
4237
4232
|
};
|
|
4238
|
-
return (jsxs(Button, { variant: "outline", onClick: handleClick, loading: loading, fullWidth: true, className: `
|
|
4233
|
+
return (jsxs(Button, { variant: "outline", onClick: handleClick, loading: loading, fullWidth: true, className: `usa-social-login-button ${className}`, children: [provider.icon && (jsx("img", { src: provider.icon, alt: provider.name, className: "usa-social-login-button__icon" })), jsxs("span", { children: ["Continue with ", provider.name] })] }));
|
|
4239
4234
|
}
|
|
4240
4235
|
function SocialLogin({ providers, onLogin, loading = false, className = '' }) {
|
|
4241
4236
|
if (providers.length === 0) {
|
|
4242
4237
|
return null;
|
|
4243
4238
|
}
|
|
4244
|
-
return (jsx("div", { className: `
|
|
4239
|
+
return (jsx("div", { className: `usa-social-login ${className}`, children: providers.map((provider) => (jsx(SocialLoginButton, { provider: provider, onClick: onLogin, loading: loading }, provider.id))) }));
|
|
4245
4240
|
}
|
|
4246
4241
|
|
|
4247
4242
|
export { ApiClient, AuthProvider, Button, DynamicForm, LoginForm, SocialLogin, SocialLoginButton, UserInfoBox, useAuth, useAuthConfig, useDynamicForm, validateField, validateForm };
|