|
1 | 1 | import { useState } from 'react'; |
2 | | -import { Button, Input, Label, tokens, Card, Text } from '@fluentui/react-components'; |
3 | | -import { PersonRegular, LockClosedRegular } from '@fluentui/react-icons'; |
| 2 | +import { Button, Input, Label, tokens, Card, Text, mergeClasses } from '@fluentui/react-components'; |
4 | 3 | import { useNavigate } from 'react-router'; |
5 | 4 | import { useForm } from 'react-hook-form'; |
6 | 5 | import { mainLayoutStyles } from '../styles/Styles'; |
@@ -38,114 +37,51 @@ export default function Login() { |
38 | 37 | }; |
39 | 38 |
|
40 | 39 | return ( |
41 | | - <Card style={{ |
42 | | - width: '100%', |
43 | | - maxWidth: '520px', |
44 | | - margin: '0 auto', |
45 | | - padding: `${tokens.spacingVerticalXXL} ${tokens.spacingHorizontalXXXL}` |
46 | | - }}> |
47 | | - {/* Header - Visual Hierarchy (HCI Principle) */} |
48 | | - <div style={{ marginBottom: tokens.spacingVerticalXXL, textAlign: 'center' }}> |
49 | | - <Text size={800} weight="semibold" block style={{ marginBottom: tokens.spacingVerticalM }}> |
50 | | - Welcome back |
51 | | - </Text> |
52 | | - <Text size={400} style={{ color: tokens.colorNeutralForeground3 }}> |
53 | | - Sign in to continue to Flowboard |
54 | | - </Text> |
55 | | - </div> |
56 | | - |
57 | | - <form onSubmit={handleSubmit(onSubmit)}> |
58 | | - {/* Adequate spacing for readability and reduced cognitive load */} |
59 | | - <div style={{ display: 'flex', flexDirection: 'column', gap: tokens.spacingVerticalL }}> |
60 | | - <div className={styles.formField}> |
61 | | - <Label htmlFor="userNameOrEmail" required size="medium" style={{ marginBottom: tokens.spacingVerticalXS }}> |
62 | | - Username or Email |
63 | | - </Label> |
64 | | - <Input |
65 | | - id="userNameOrEmail" |
66 | | - type="text" |
67 | | - placeholder="Enter your username or email" |
68 | | - autoComplete="username" |
69 | | - size="large" |
70 | | - contentBefore={<PersonRegular />} |
71 | | - style={{ width: '100%' }} |
72 | | - {...register('userNameOrEmail', { required: 'Username or Email is required' })} |
73 | | - /> |
74 | | - {errors.userNameOrEmail && ( |
75 | | - <Text className={styles.errorText} style={{ marginTop: tokens.spacingVerticalXS }}> |
76 | | - {errors.userNameOrEmail.message} |
77 | | - </Text> |
78 | | - )} |
79 | | - </div> |
80 | | - |
81 | | - <div className={styles.formField}> |
82 | | - <Label htmlFor="password" required size="medium" style={{ marginBottom: tokens.spacingVerticalXS }}> |
83 | | - Password |
84 | | - </Label> |
85 | | - <Input |
86 | | - id="password" |
87 | | - type="password" |
88 | | - placeholder="Enter your password" |
89 | | - autoComplete="current-password" |
90 | | - size="large" |
91 | | - contentBefore={<LockClosedRegular />} |
92 | | - style={{ width: '100%' }} |
93 | | - {...register('password', { required: 'Password is required' })} |
94 | | - /> |
95 | | - {errors.password && ( |
96 | | - <Text className={styles.errorText} style={{ marginTop: tokens.spacingVerticalXS }}> |
97 | | - {errors.password.message} |
98 | | - </Text> |
99 | | - )} |
100 | | - </div> |
101 | | - |
102 | | - {formError && ( |
103 | | - <Text className={styles.errorText} style={{ display: 'block', textAlign: 'center' }}> |
104 | | - {formError} |
105 | | - </Text> |
| 40 | + <Card className={mergeClasses(styles.layoutPadding, styles.flexColFit, styles.componentBorder)} style={{ width: '55%' }}> |
| 41 | + <h2 className={styles.brand}>Sign in</h2> |
| 42 | + <form className={styles.formSection} onSubmit={handleSubmit(onSubmit)}> |
| 43 | + <div className={styles.formField}> |
| 44 | + <Label htmlFor="userNameOrEmail">Username or Email</Label> |
| 45 | + <Input |
| 46 | + className={styles.formField} |
| 47 | + id="userNameOrEmail" |
| 48 | + type="text" |
| 49 | + placeholder="username or you@email.com" |
| 50 | + autoComplete="username" |
| 51 | + {...register('userNameOrEmail', { required: 'Username or Email is required' })} |
| 52 | + /> |
| 53 | + {errors.userNameOrEmail && ( |
| 54 | + <Text as="span" className={styles.errorText}>{errors.userNameOrEmail.message}</Text> |
106 | 55 | )} |
107 | | - |
108 | | - {/* Fitts's Law - Large clickable target for primary action */} |
109 | | - <Button |
110 | | - appearance="primary" |
111 | | - type="submit" |
112 | | - size="large" |
113 | | - disabled={loading} |
114 | | - style={{ |
115 | | - width: '100%', |
116 | | - marginTop: tokens.spacingVerticalM, |
117 | | - padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalL}` |
118 | | - }} |
119 | | - > |
| 56 | + </div> |
| 57 | + <div className={styles.formField}> |
| 58 | + <Label htmlFor="password">Password</Label> |
| 59 | + <Input |
| 60 | + className={styles.formField} |
| 61 | + id="password" |
| 62 | + type="password" |
| 63 | + placeholder="Password" |
| 64 | + autoComplete="current-password" |
| 65 | + {...register('password', { required: 'Password is required' })} |
| 66 | + /> |
| 67 | + {errors.password && ( |
| 68 | + <Text as="span" className={styles.errorText}>{errors.password.message}</Text> |
| 69 | + )} |
| 70 | + </div> |
| 71 | + {formError && ( |
| 72 | + <Text as="span" className={styles.errorText} style={{ marginTop: tokens.spacingVerticalXS }}> |
| 73 | + {formError} |
| 74 | + </Text> |
| 75 | + )} |
| 76 | + <div className={styles.formSection}> |
| 77 | + <Button className={styles.formField} appearance="primary" type="submit" size="large" disabled={loading}> |
120 | 78 | {loading ? 'Signing In...' : 'Sign In'} |
121 | 79 | </Button> |
| 80 | + <Button className={styles.formField} appearance="outline" size="large" onClick={() => { navigate("/register") }} type="button"> |
| 81 | + Create Account |
| 82 | + </Button> |
122 | 83 | </div> |
123 | 84 | </form> |
124 | | - |
125 | | - {/* Footer - Clear visual separation and secondary action */} |
126 | | - <div style={{ |
127 | | - marginTop: tokens.spacingVerticalXXL, |
128 | | - paddingTop: tokens.spacingVerticalL, |
129 | | - borderTop: `1px solid ${tokens.colorNeutralStroke2}`, |
130 | | - textAlign: 'center', |
131 | | - display: 'flex', |
132 | | - alignItems: 'center', |
133 | | - justifyContent: 'center', |
134 | | - gap: tokens.spacingHorizontalXS |
135 | | - }}> |
136 | | - <Text size={400} style={{ color: tokens.colorNeutralForeground3 }}> |
137 | | - Don't have an account? |
138 | | - </Text> |
139 | | - <Button |
140 | | - appearance="transparent" |
141 | | - size="medium" |
142 | | - onClick={() => navigate('/register')} |
143 | | - type="button" |
144 | | - style={{ padding: `0 ${tokens.spacingHorizontalXS}`, minWidth: 'auto', fontWeight: 600 }} |
145 | | - > |
146 | | - Create one |
147 | | - </Button> |
148 | | - </div> |
149 | 85 | </Card> |
150 | 86 | ); |
151 | 87 | } |
0 commit comments