Skip to content

Commit 6680a97

Browse files
authored
Merge pull request #243 from brionmario/fix-asgardeo-v2-signup
chore: improve `SignIn` & `SignUp` styling
2 parents f369ce0 + 7d932db commit 6680a97

File tree

12 files changed

+175
-279
lines changed

12 files changed

+175
-279
lines changed

.changeset/yummy-suns-trade.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@asgardeo/react': patch
3+
'@asgardeo/i18n': patch
4+
---
5+
6+
improve `SignIn` & `SignUp` styling

packages/i18n/src/translations/en-US.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const translations: I18nTranslations = {
5454

5555
/* Base Sign In */
5656
'signin.title': 'Sign In',
57-
'signin.subtitle': 'Enter your credentials to continue.',
57+
'signin.subtitle': 'Welcome back! Please sign in to continue.',
5858

5959
/* Base Sign Up */
6060
'signup.title': 'Sign Up',

packages/react/src/components/presentation/SignIn/BaseSignIn.styles.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,12 @@ const useStyles = (theme: Theme, colorScheme: string) => {
4444
display: flex;
4545
flex-direction: column;
4646
align-items: center;
47-
margin-bottom: calc(${theme.vars.spacing.unit} * 3);
47+
margin-bottom: calc(${theme.vars.spacing.unit} * 2);
4848
`;
4949

5050
const header = css`
5151
gap: 0;
52+
align-items: center;
5253
`;
5354

5455
const title = css`
@@ -57,7 +58,7 @@ const useStyles = (theme: Theme, colorScheme: string) => {
5758
`;
5859

5960
const subtitle = css`
60-
margin-top: calc(${theme.vars.spacing.unit} * 1);
61+
margin-bottom: calc(${theme.vars.spacing.unit} * 1);
6162
color: ${theme.vars.colors.text.secondary};
6263
`;
6364

@@ -144,7 +145,7 @@ const useStyles = (theme: Theme, colorScheme: string) => {
144145
`;
145146

146147
const flowMessagesContainer = css`
147-
margin-top: calc(${theme.vars.spacing.unit} * 2);
148+
margin-bottom: calc(${theme.vars.spacing.unit} * 2);
148149
`;
149150

150151
const flowMessageItem = css`

packages/react/src/components/presentation/SignIn/SignIn.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const SignIn: FC<SignInProps> = ({className, size = 'medium', children, ...rest}
7070
* Initialize the authentication flow.
7171
*/
7272
const handleInitialize = async (): Promise<EmbeddedSignInFlowInitiateResponse> => {
73-
return await signIn({response_mode: 'direct'}) as EmbeddedSignInFlowInitiateResponse;
73+
return (await signIn({response_mode: 'direct'})) as EmbeddedSignInFlowInitiateResponse;
7474
};
7575

7676
/**
@@ -80,7 +80,7 @@ const SignIn: FC<SignInProps> = ({className, size = 'medium', children, ...rest}
8080
payload: EmbeddedSignInFlowHandleRequestPayload,
8181
request: Request,
8282
): Promise<EmbeddedSignInFlowHandleResponse> => {
83-
return await signIn(payload, request) as EmbeddedSignInFlowHandleResponse;
83+
return (await signIn(payload, request)) as EmbeddedSignInFlowHandleResponse;
8484
};
8585

8686
/**
@@ -123,6 +123,9 @@ const SignIn: FC<SignInProps> = ({className, size = 'medium', children, ...rest}
123123
onSuccess={handleSuccess}
124124
className={className}
125125
size={size}
126+
showLogo={true}
127+
showSubtitle={true}
128+
showTitle={true}
126129
{...rest}
127130
/>
128131
);

packages/react/src/components/presentation/SignIn/component-driven/BaseSignIn.tsx

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import useFlow from '../../../../contexts/Flow/useFlow';
3131
import FlowProvider from '../../../../contexts/Flow/FlowProvider';
3232
import {FormField, useForm} from '../../../../hooks/useForm';
3333
import {renderSignInComponents} from './SignInOptionFactory';
34+
import {extractErrorMessage} from '../../SignUp/transformer';
3435

3536
/**
3637
* Render props for custom UI rendering
@@ -61,11 +62,6 @@ export interface BaseSignInRenderProps {
6162
*/
6263
isLoading: boolean;
6364

64-
/**
65-
* Current error message
66-
*/
67-
error: string | null;
68-
6965
/**
7066
* Flow components
7167
*/
@@ -174,6 +170,21 @@ export interface BaseSignInProps {
174170
* Render props function for custom UI
175171
*/
176172
children?: (props: BaseSignInRenderProps) => ReactNode;
173+
174+
/**
175+
* Whether to show the title.
176+
*/
177+
showTitle?: boolean;
178+
179+
/**
180+
* Whether to show the subtitle.
181+
*/
182+
showSubtitle?: boolean;
183+
184+
/**
185+
* Whether to show the logo.
186+
*/
187+
showLogo?: boolean;
177188
}
178189

179190
/**
@@ -225,17 +236,19 @@ export interface BaseSignInProps {
225236
* </BaseSignIn>
226237
* ```
227238
*/
228-
const BaseSignIn: FC<BaseSignInProps> = props => {
239+
const BaseSignIn: FC<BaseSignInProps> = ({showLogo = true, ...rest}: BaseSignInProps): ReactElement => {
229240
const {theme} = useTheme();
230241
const styles = useStyles(theme, theme.vars.colors.text.primary);
231242

232243
return (
233244
<div>
234-
<div className={styles.logoContainer}>
235-
<Logo size="large" />
236-
</div>
245+
{showLogo && (
246+
<div className={styles.logoContainer}>
247+
<Logo size="large" />
248+
</div>
249+
)}
237250
<FlowProvider>
238-
<BaseSignInContent {...props} />
251+
<BaseSignInContent showLogo={showLogo} {...rest} />
239252
</FlowProvider>
240253
</div>
241254
);
@@ -257,17 +270,37 @@ const BaseSignInContent: FC<BaseSignInProps> = ({
257270
variant = 'outlined',
258271
isLoading: externalIsLoading,
259272
children,
273+
showTitle = true,
274+
showSubtitle = true,
275+
showLogo = true,
260276
}) => {
261277
const {theme} = useTheme();
262278
const {t} = useTranslation();
263-
const {subtitle: flowSubtitle, title: flowTitle, messages: flowMessages} = useFlow();
279+
const {subtitle: flowSubtitle, title: flowTitle, messages: flowMessages, addMessage, clearMessages} = useFlow();
264280
const styles = useStyles(theme, theme.vars.colors.text.primary);
265281

266282
const [isSubmitting, setIsSubmitting] = useState(false);
267-
const [error, setError] = useState<string | null>(null);
268283

269284
const isLoading: boolean = externalIsLoading || isSubmitting;
270285

286+
/**
287+
* Handle error responses and extract meaningful error messages
288+
* Uses the transformer's extractErrorMessage function for consistency
289+
*/
290+
const handleError = useCallback(
291+
(error: any) => {
292+
const errorMessage: string = extractErrorMessage(error, t);
293+
294+
// Clear existing messages and add the error message
295+
clearMessages();
296+
addMessage({
297+
type: 'error',
298+
message: errorMessage,
299+
});
300+
},
301+
[t, addMessage, clearMessages],
302+
);
303+
271304
/**
272305
* Extract form fields from flow components
273306
*/
@@ -351,7 +384,7 @@ const BaseSignInContent: FC<BaseSignInProps> = ({
351384
}
352385

353386
setIsSubmitting(true);
354-
setError(null);
387+
clearMessages();
355388

356389
try {
357390
// Filter out empty or undefined input values
@@ -380,8 +413,7 @@ const BaseSignInContent: FC<BaseSignInProps> = ({
380413

381414
await onSubmit?.(payload, component);
382415
} catch (err) {
383-
const errorMessage = err instanceof Error ? err.message : t('errors.sign.in.flow.failure');
384-
setError(errorMessage);
416+
handleError(err);
385417
onError?.(err as Error);
386418
} finally {
387419
setIsSubmitting(false);
@@ -435,7 +467,6 @@ const BaseSignInContent: FC<BaseSignInProps> = ({
435467
handleInputChange,
436468
{
437469
buttonClassName: buttonClasses,
438-
error,
439470
inputClassName: inputClasses,
440471
onInputBlur: handleInputBlur,
441472
onSubmit: handleSubmit,
@@ -451,7 +482,6 @@ const BaseSignInContent: FC<BaseSignInProps> = ({
451482
isLoading,
452483
size,
453484
variant,
454-
error,
455485
inputClasses,
456486
buttonClasses,
457487
handleInputBlur,
@@ -467,7 +497,6 @@ const BaseSignInContent: FC<BaseSignInProps> = ({
467497
touched: touchedFields,
468498
isValid: isFormValid,
469499
isLoading,
470-
error,
471500
components,
472501
handleInputChange,
473502
handleSubmit,
@@ -507,13 +536,21 @@ const BaseSignInContent: FC<BaseSignInProps> = ({
507536

508537
return (
509538
<Card className={cx(containerClasses, styles.card)} variant={variant}>
510-
<Card.Header className={styles.header}>
511-
<Card.Title level={2} className={styles.title}>
512-
{flowTitle || t('signin.title')}
513-
</Card.Title>
514-
<Typography variant="body1" className={styles.subtitle}>
515-
{flowSubtitle || t('signin.subtitle')}
516-
</Typography>
539+
{(showTitle || showSubtitle) && (
540+
<Card.Header className={styles.header}>
541+
{showTitle && (
542+
<Card.Title level={2} className={styles.title}>
543+
{flowTitle || t('signin.title')}
544+
</Card.Title>
545+
)}
546+
{showSubtitle && (
547+
<Typography variant="body1" className={styles.subtitle}>
548+
{flowSubtitle || t('signin.subtitle')}
549+
</Typography>
550+
)}
551+
</Card.Header>
552+
)}
553+
<Card.Content>
517554
{flowMessages && flowMessages.length > 0 && (
518555
<div className={styles.flowMessagesContainer}>
519556
{flowMessages.map((message, index) => (
@@ -527,16 +564,6 @@ const BaseSignInContent: FC<BaseSignInProps> = ({
527564
))}
528565
</div>
529566
)}
530-
</Card.Header>
531-
532-
<Card.Content>
533-
{error && (
534-
<Alert variant="error" className={cx(styles.errorContainer, errorClasses)}>
535-
<Alert.Title>{t('errors.title')}</Alert.Title>
536-
<Alert.Description>{error}</Alert.Description>
537-
</Alert>
538-
)}
539-
540567
<div className={styles.contentContainer}>{components && renderComponents(components)}</div>
541568
</Card.Content>
542569
</Card>

packages/react/src/components/presentation/SignIn/component-driven/SignInOptionFactory.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ const createSignInComponentFromFlow = (
7171
onInputChange: (name: string, value: string) => void,
7272
options: {
7373
buttonClassName?: string;
74-
error?: string | null;
7574
inputClassName?: string;
7675
key?: string | number;
7776
onInputBlur?: (name: string) => void;
@@ -216,7 +215,6 @@ export const renderSignInComponents = (
216215
onInputChange: (name: string, value: string) => void,
217216
options?: {
218217
buttonClassName?: string;
219-
error?: string | null;
220218
inputClassName?: string;
221219
onInputBlur?: (name: string) => void;
222220
onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>) => void;

0 commit comments

Comments
 (0)