@licklist/design 0.78.5-dev.69 → 0.78.5-dev.70

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 (123) hide show
  1. package/dist/styles/themes/bookedit/_fonts.scss +2 -0
  2. package/dist/v2/components/ActionMenu/ActionMenu.d.ts.map +1 -1
  3. package/dist/v2/components/ActionMenu/ActionMenu.js +5 -3
  4. package/dist/v2/components/AvatarUpload/AvatarUpload.d.ts +12 -0
  5. package/dist/v2/components/AvatarUpload/AvatarUpload.d.ts.map +1 -0
  6. package/dist/v2/components/AvatarUpload/index.d.ts +2 -0
  7. package/dist/v2/components/AvatarUpload/index.d.ts.map +1 -0
  8. package/dist/v2/components/Button/Button.d.ts +1 -1
  9. package/dist/v2/components/Button/Button.d.ts.map +1 -1
  10. package/dist/v2/components/Button/Button.scss.js +1 -1
  11. package/dist/v2/components/DataTable/DataTable.d.ts +41 -0
  12. package/dist/v2/components/DataTable/DataTable.d.ts.map +1 -0
  13. package/dist/v2/components/DataTable/index.d.ts +3 -0
  14. package/dist/v2/components/DataTable/index.d.ts.map +1 -0
  15. package/dist/v2/components/EmptyState/EmptyState.d.ts +14 -0
  16. package/dist/v2/components/EmptyState/EmptyState.d.ts.map +1 -0
  17. package/dist/v2/components/EmptyState/index.d.ts +3 -0
  18. package/dist/v2/components/EmptyState/index.d.ts.map +1 -0
  19. package/dist/v2/components/FormField/FormField.scss.js +1 -1
  20. package/dist/v2/components/InfoGrid/InfoGrid.d.ts +13 -0
  21. package/dist/v2/components/InfoGrid/InfoGrid.d.ts.map +1 -0
  22. package/dist/v2/components/InfoGrid/index.d.ts +2 -0
  23. package/dist/v2/components/InfoGrid/index.d.ts.map +1 -0
  24. package/dist/v2/components/NewTable/NewTable.scss.js +1 -1
  25. package/dist/v2/components/RadioCard/RadioCard.d.ts +17 -0
  26. package/dist/v2/components/RadioCard/RadioCard.d.ts.map +1 -0
  27. package/dist/v2/components/RadioCard/index.d.ts +2 -0
  28. package/dist/v2/components/RadioCard/index.d.ts.map +1 -0
  29. package/dist/v2/components/StatusBadge/StatusBadge.d.ts +8 -0
  30. package/dist/v2/components/StatusBadge/StatusBadge.d.ts.map +1 -0
  31. package/dist/v2/components/StatusBadge/index.d.ts +3 -0
  32. package/dist/v2/components/StatusBadge/index.d.ts.map +1 -0
  33. package/dist/v2/components/StepIndicator/StepIndicator.d.ts +9 -0
  34. package/dist/v2/components/StepIndicator/StepIndicator.d.ts.map +1 -0
  35. package/dist/v2/components/StepIndicator/index.d.ts +2 -0
  36. package/dist/v2/components/StepIndicator/index.d.ts.map +1 -0
  37. package/dist/v2/components/TableControls/TableControls.d.ts +28 -0
  38. package/dist/v2/components/TableControls/TableControls.d.ts.map +1 -0
  39. package/dist/v2/components/TableControls/index.d.ts +3 -0
  40. package/dist/v2/components/TableControls/index.d.ts.map +1 -0
  41. package/dist/v2/components/Tabs/Tabs.d.ts +15 -0
  42. package/dist/v2/components/Tabs/Tabs.d.ts.map +1 -0
  43. package/dist/v2/components/Tabs/index.d.ts +3 -0
  44. package/dist/v2/components/Tabs/index.d.ts.map +1 -0
  45. package/dist/v2/icons/index.d.ts +42 -0
  46. package/dist/v2/icons/index.d.ts.map +1 -1
  47. package/dist/v2/index.d.ts +18 -0
  48. package/dist/v2/index.d.ts.map +1 -1
  49. package/dist/v2/pages/CreateUser/CreateUserPage.d.ts +110 -0
  50. package/dist/v2/pages/CreateUser/CreateUserPage.d.ts.map +1 -0
  51. package/dist/v2/pages/CreateUser/index.d.ts +3 -0
  52. package/dist/v2/pages/CreateUser/index.d.ts.map +1 -0
  53. package/dist/v2/pages/RoleSelection/RoleSelectionPage.d.ts +26 -0
  54. package/dist/v2/pages/RoleSelection/RoleSelectionPage.d.ts.map +1 -0
  55. package/dist/v2/pages/RoleSelection/index.d.ts +3 -0
  56. package/dist/v2/pages/RoleSelection/index.d.ts.map +1 -0
  57. package/dist/v2/pages/UserDetails/UserDetailsPage.d.ts +37 -0
  58. package/dist/v2/pages/UserDetails/UserDetailsPage.d.ts.map +1 -0
  59. package/dist/v2/pages/UserDetails/index.d.ts +3 -0
  60. package/dist/v2/pages/UserDetails/index.d.ts.map +1 -0
  61. package/dist/v2/pages/auth/CreatePassword/CreatePasswordPage.d.ts.map +1 -1
  62. package/dist/v2/pages/auth/Login/LoginPage.d.ts.map +1 -1
  63. package/dist/v2/pages/auth/ResetPassword/ResetPasswordPage.d.ts.map +1 -1
  64. package/dist/v2/styles/components/Button.scss +27 -0
  65. package/package.json +2 -2
  66. package/src/styles/themes/bookedit/_fonts.scss +2 -0
  67. package/src/v2/components/ActionMenu/ActionMenu.tsx +4 -2
  68. package/src/v2/components/AvatarUpload/AvatarUpload.scss +68 -0
  69. package/src/v2/components/AvatarUpload/AvatarUpload.stories.tsx +83 -0
  70. package/src/v2/components/AvatarUpload/AvatarUpload.tsx +69 -0
  71. package/src/v2/components/AvatarUpload/index.ts +1 -0
  72. package/src/v2/components/Button/Button.tsx +1 -0
  73. package/src/v2/components/DataTable/DataTable.scss +181 -0
  74. package/src/v2/components/DataTable/DataTable.tsx +256 -0
  75. package/src/v2/components/DataTable/index.ts +7 -0
  76. package/src/v2/components/EmptyState/EmptyState.scss +39 -0
  77. package/src/v2/components/EmptyState/EmptyState.stories.tsx +45 -0
  78. package/src/v2/components/EmptyState/EmptyState.tsx +37 -0
  79. package/src/v2/components/EmptyState/index.ts +2 -0
  80. package/src/v2/components/FormField/FormField.scss +12 -0
  81. package/src/v2/components/InfoGrid/InfoGrid.scss +51 -0
  82. package/src/v2/components/InfoGrid/InfoGrid.stories.tsx +76 -0
  83. package/src/v2/components/InfoGrid/InfoGrid.tsx +28 -0
  84. package/src/v2/components/InfoGrid/index.ts +1 -0
  85. package/src/v2/components/NewTable/NewTable.scss +4 -4
  86. package/src/v2/components/RadioCard/RadioCard.scss +76 -0
  87. package/src/v2/components/RadioCard/RadioCard.stories.tsx +115 -0
  88. package/src/v2/components/RadioCard/RadioCard.tsx +68 -0
  89. package/src/v2/components/RadioCard/index.ts +1 -0
  90. package/src/v2/components/StatusBadge/StatusBadge.scss +53 -0
  91. package/src/v2/components/StatusBadge/StatusBadge.tsx +31 -0
  92. package/src/v2/components/StatusBadge/index.ts +2 -0
  93. package/src/v2/components/StepIndicator/StepIndicator.scss +62 -0
  94. package/src/v2/components/StepIndicator/StepIndicator.stories.tsx +37 -0
  95. package/src/v2/components/StepIndicator/StepIndicator.tsx +41 -0
  96. package/src/v2/components/StepIndicator/index.ts +1 -0
  97. package/src/v2/components/TableControls/TableControls.scss +63 -0
  98. package/src/v2/components/TableControls/TableControls.tsx +110 -0
  99. package/src/v2/components/TableControls/index.ts +7 -0
  100. package/src/v2/components/Tabs/Tabs.scss +36 -0
  101. package/src/v2/components/Tabs/Tabs.stories.tsx +75 -0
  102. package/src/v2/components/Tabs/Tabs.tsx +52 -0
  103. package/src/v2/components/Tabs/index.ts +2 -0
  104. package/src/v2/icons/index.tsx +219 -0
  105. package/src/v2/index.ts +98 -0
  106. package/src/v2/pages/CreateUser/CreateUserPage.scss +760 -0
  107. package/src/v2/pages/CreateUser/CreateUserPage.stories.tsx +157 -0
  108. package/src/v2/pages/CreateUser/CreateUserPage.tsx +1062 -0
  109. package/src/v2/pages/CreateUser/index.ts +13 -0
  110. package/src/v2/pages/RoleSelection/RoleSelectionPage.scss +193 -0
  111. package/src/v2/pages/RoleSelection/RoleSelectionPage.stories.tsx +112 -0
  112. package/src/v2/pages/RoleSelection/RoleSelectionPage.tsx +127 -0
  113. package/src/v2/pages/RoleSelection/index.ts +2 -0
  114. package/src/v2/pages/UserDetails/UserDetailsPage.scss +236 -0
  115. package/src/v2/pages/UserDetails/UserDetailsPage.stories.tsx +84 -0
  116. package/src/v2/pages/UserDetails/UserDetailsPage.tsx +210 -0
  117. package/src/v2/pages/UserDetails/index.ts +2 -0
  118. package/src/v2/pages/auth/AuthLayout/AuthLayout.scss +8 -6
  119. package/src/v2/pages/auth/CreatePassword/CreatePasswordPage.tsx +1 -3
  120. package/src/v2/pages/auth/Login/LoginPage.tsx +1 -3
  121. package/src/v2/pages/auth/ResetPassword/ResetPasswordPage.scss +2 -0
  122. package/src/v2/pages/auth/ResetPassword/ResetPasswordPage.tsx +1 -2
  123. package/src/v2/styles/components/Button.scss +27 -0
@@ -0,0 +1,84 @@
1
+ import React from 'react'
2
+ import type { Meta, StoryObj } from '@storybook/react'
3
+ import { UserDetailsPage } from './UserDetailsPage'
4
+ import type { ExistingUserInfo } from './UserDetailsPage'
5
+
6
+ // ─── Mock data ────────────────────────────────────────────────────────────────
7
+
8
+ const mockExistingUser: ExistingUserInfo = {
9
+ id: 'usr-001',
10
+ fullName: 'Jane Smith',
11
+ email: 'jane.smith@example.com',
12
+ userNumber: 1042,
13
+ assignments: [
14
+ { id: 'v-001', name: 'The Grand Arena', type: 'venue', friendlyId: 'V-10203', role: 'Admin' },
15
+ { id: 'c-001', name: 'Live Events Co.', type: 'company', friendlyId: 'C-7890', role: 'Manager' },
16
+ { id: 'p-001', name: 'City Promotions', type: 'promoter', friendlyId: 'P-4405', role: 'Staff' },
17
+ ],
18
+ }
19
+
20
+ // ─── Meta ─────────────────────────────────────────────────────────────────────
21
+
22
+ const meta: Meta<typeof UserDetailsPage> = {
23
+ title: 'v2/Pages/UserDetails',
24
+ component: UserDetailsPage,
25
+ parameters: { layout: 'fullscreen' },
26
+ }
27
+
28
+ export default meta
29
+ type Story = StoryObj<typeof UserDetailsPage>
30
+
31
+ // ─── Stories ──────────────────────────────────────────────────────────────────
32
+
33
+ /**
34
+ * **New User** — no existing account found for this email.
35
+ *
36
+ * Shows the "User Details" form where the admin enters the new user's
37
+ * first and last name before advancing to role selection.
38
+ */
39
+ export const NewUser: Story = {
40
+ name: 'New User',
41
+ args: {
42
+ pageTitle: 'Add Team Member',
43
+ onNext: (firstName, lastName) => console.log('Next:', firstName, lastName),
44
+ onBack: () => console.log('Back'),
45
+ onCancel: () => console.log('Cancel'),
46
+ },
47
+ }
48
+
49
+ /**
50
+ * **Existing User Found** — an account already exists for this email.
51
+ *
52
+ * Shows the user card (name, email, user number) plus their current
53
+ * assignments. The admin can continue to assign a role to this user.
54
+ */
55
+ export const ExistingUserFound: Story = {
56
+ name: 'Existing User Found',
57
+ args: {
58
+ pageTitle: 'Add Team Member',
59
+ existingUser: mockExistingUser,
60
+ onNext: (firstName, lastName) => console.log('Continue with:', firstName, lastName),
61
+ onBack: () => console.log('Back'),
62
+ onCancel: () => console.log('Cancel'),
63
+ },
64
+ }
65
+
66
+ /**
67
+ * **Existing User — No Assignments** — account exists but has no prior assignments.
68
+ *
69
+ * The assignment section is hidden when there are no prior assignments.
70
+ */
71
+ export const ExistingUserNoAssignments: Story = {
72
+ name: 'Existing User — No Assignments',
73
+ args: {
74
+ pageTitle: 'Add Team Member',
75
+ existingUser: {
76
+ id: 'usr-002',
77
+ fullName: 'Tom Baker',
78
+ email: 'tom.baker@example.com',
79
+ },
80
+ onNext: (firstName, lastName) => console.log('Continue with:', firstName, lastName),
81
+ onBack: () => console.log('Back'),
82
+ onCancel: () => console.log('Cancel'),
83
+ },
84
+ }
@@ -0,0 +1,210 @@
1
+ import React, { useState } from 'react'
2
+ import { Button } from '../../components/Button'
3
+ import { FormField } from '../../components/FormField'
4
+ import { UserAvatar } from '../../components/UserAvatar'
5
+ import { ArrowLeftIcon } from '../../icons'
6
+ import './UserDetailsPage.scss'
7
+
8
+ // ─── Types ────────────────────────────────────────────────────────────────────
9
+
10
+ export interface UserAssignmentItem {
11
+ id: string
12
+ name: string
13
+ type: 'company' | 'venue' | 'promoter'
14
+ role?: string
15
+ friendlyId: string
16
+ }
17
+
18
+ export interface ExistingUserInfo {
19
+ id: string
20
+ fullName: string
21
+ email: string
22
+ userNumber?: number
23
+ assignments?: UserAssignmentItem[]
24
+ }
25
+
26
+ export interface UserDetailsPageProps {
27
+ /** Page-level title shown in the sticky header */
28
+ pageTitle?: string
29
+ /**
30
+ * When provided the page shows the "Existing User Found" card view.
31
+ * When absent the page shows the "User Details" name-entry form.
32
+ */
33
+ existingUser?: ExistingUserInfo
34
+ /** Pre-fill first name (only used in the new-user form) */
35
+ defaultFirstName?: string
36
+ /** Pre-fill last name (only used in the new-user form) */
37
+ defaultLastName?: string
38
+ /** Called with (firstName, lastName) — for new users these are the form values; for existing users they come from the existing user record */
39
+ onNext: (firstName: string, lastName: string) => void
40
+ onBack?: () => void
41
+ onCancel?: () => void
42
+ isLoading?: boolean
43
+ error?: string
44
+ }
45
+
46
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
47
+
48
+ function getInitials(fullName: string): string {
49
+ return fullName
50
+ .split(' ')
51
+ .map((n) => n[0] ?? '')
52
+ .join('')
53
+ .slice(0, 2)
54
+ .toUpperCase()
55
+ }
56
+
57
+ // ─── Component ────────────────────────────────────────────────────────────────
58
+
59
+ export const UserDetailsPage: React.FC<UserDetailsPageProps> = ({
60
+ pageTitle = 'Add User',
61
+ existingUser,
62
+ defaultFirstName = '',
63
+ defaultLastName = '',
64
+ onNext,
65
+ onBack,
66
+ onCancel,
67
+ isLoading = false,
68
+ error,
69
+ }) => {
70
+ const [firstName, setFirstName] = useState(defaultFirstName)
71
+ const [lastName, setLastName] = useState(defaultLastName)
72
+ const [fieldErrors, setFieldErrors] = useState<{ firstName?: string; lastName?: string }>({})
73
+
74
+ const handleNext = () => {
75
+ if (existingUser) {
76
+ const parts = existingUser.fullName.trim().split(' ')
77
+ onNext(parts[0] ?? '', parts.slice(1).join(' '))
78
+ return
79
+ }
80
+
81
+ const errs: { firstName?: string; lastName?: string } = {}
82
+ if (!firstName.trim()) errs.firstName = 'First name is required'
83
+ if (!lastName.trim()) errs.lastName = 'Last name is required'
84
+
85
+ if (Object.keys(errs).length > 0) {
86
+ setFieldErrors(errs)
87
+ return
88
+ }
89
+
90
+ setFieldErrors({})
91
+ onNext(firstName.trim(), lastName.trim())
92
+ }
93
+
94
+ return (
95
+ <div className="user-details-page">
96
+ {/* ── Header ── */}
97
+ <header className="user-details-page__header">
98
+ <h1 className="user-details-page__title">{pageTitle}</h1>
99
+ {onCancel && (
100
+ <Button variant="secondary-soft" onClick={onCancel}>
101
+ Cancel
102
+ </Button>
103
+ )}
104
+ </header>
105
+
106
+ {/* ── Body ── */}
107
+ <div className="user-details-page__body">
108
+ {onBack && (
109
+ <button className="user-details-page__back" type="button" onClick={onBack}>
110
+ <ArrowLeftIcon />
111
+ Back
112
+ </button>
113
+ )}
114
+
115
+ {error && (
116
+ <div className="user-details-page__error-banner" role="alert">
117
+ {error}
118
+ </div>
119
+ )}
120
+
121
+ {existingUser ? (
122
+ /* ── Existing user found ── */
123
+ <div className="user-details-page__existing">
124
+ <div className="user-details-page__step-header">
125
+ <h2 className="user-details-page__step-title">Existing User Found</h2>
126
+ <p className="user-details-page__step-desc">
127
+ A user with this email already exists in the system.
128
+ </p>
129
+ </div>
130
+
131
+ <div className="user-details-page__user-card">
132
+ <UserAvatar initials={getInitials(existingUser.fullName)} size="lg" />
133
+ <div className="user-details-page__user-info">
134
+ <span className="user-details-page__user-name">{existingUser.fullName}</span>
135
+ <span className="user-details-page__user-email">{existingUser.email}</span>
136
+ {existingUser.userNumber != null && (
137
+ <span className="user-details-page__user-number">#{existingUser.userNumber}</span>
138
+ )}
139
+ </div>
140
+ </div>
141
+
142
+ {existingUser.assignments && existingUser.assignments.length > 0 && (
143
+ <div className="user-details-page__assignments">
144
+ <p className="user-details-page__assignments-label">Current assignments</p>
145
+ <ul className="user-details-page__assignment-list">
146
+ {existingUser.assignments.map((a) => (
147
+ <li key={a.id} className="user-details-page__assignment-item">
148
+ <span
149
+ className={`user-details-page__entity-badge user-details-page__entity-badge--${a.type}`}
150
+ >
151
+ {a.type}
152
+ </span>
153
+ <span className="user-details-page__assignment-name">{a.name}</span>
154
+ <span className="user-details-page__assignment-id">{a.friendlyId}</span>
155
+ {a.role && (
156
+ <span className="user-details-page__assignment-role">{a.role}</span>
157
+ )}
158
+ </li>
159
+ ))}
160
+ </ul>
161
+ </div>
162
+ )}
163
+
164
+ <Button variant="primary" onClick={handleNext} isLoading={isLoading} disabled={isLoading}>
165
+ Continue
166
+ </Button>
167
+ </div>
168
+ ) : (
169
+ /* ── New user — name form ── */
170
+ <div className="user-details-page__form">
171
+ <div className="user-details-page__step-header">
172
+ <h2 className="user-details-page__step-title">User Details</h2>
173
+ </div>
174
+
175
+ <div className="user-details-page__fields">
176
+ <FormField
177
+ label="First Name"
178
+ value={firstName}
179
+ onChange={(e) => {
180
+ setFirstName(e.target.value)
181
+ if (fieldErrors.firstName) {
182
+ setFieldErrors((prev) => ({ ...prev, firstName: undefined }))
183
+ }
184
+ }}
185
+ error={fieldErrors.firstName}
186
+ disabled={isLoading}
187
+ />
188
+ <FormField
189
+ label="Last Name"
190
+ value={lastName}
191
+ onChange={(e) => {
192
+ setLastName(e.target.value)
193
+ if (fieldErrors.lastName) {
194
+ setFieldErrors((prev) => ({ ...prev, lastName: undefined }))
195
+ }
196
+ }}
197
+ error={fieldErrors.lastName}
198
+ disabled={isLoading}
199
+ />
200
+ </div>
201
+
202
+ <Button variant="primary" onClick={handleNext} isLoading={isLoading} disabled={isLoading}>
203
+ Next
204
+ </Button>
205
+ </div>
206
+ )}
207
+ </div>
208
+ </div>
209
+ )
210
+ }
@@ -0,0 +1,2 @@
1
+ export { UserDetailsPage } from './UserDetailsPage'
2
+ export type { UserDetailsPageProps, ExistingUserInfo, UserAssignmentItem } from './UserDetailsPage'
@@ -7,7 +7,8 @@
7
7
  align-items: center;
8
8
  justify-content: flex-start;
9
9
  background-color: var(--surface-secondary);
10
- padding: 0 16px 40px;
10
+ padding: 0 16px;
11
+ padding-bottom: 0;
11
12
 
12
13
  &__alert {
13
14
  width: 846px;
@@ -54,6 +55,11 @@
54
55
  justify-content: space-between;
55
56
  padding: 16px;
56
57
  border-bottom: 1px solid var(--border-primary);
58
+
59
+ .new-badge {
60
+ padding: 6px 10px;
61
+ font-size: 11px;
62
+ }
57
63
  }
58
64
 
59
65
  &__body {
@@ -111,12 +117,8 @@
111
117
  font-weight: 400;
112
118
  line-height: 1;
113
119
  color: var(--label-secondary);
114
- margin: 8px 0 0;
120
+ margin: 16px 0 0;
115
121
  padding: 0;
116
-
117
- @media (max-width: 768px) {
118
- margin-top: 4px;
119
- }
120
122
  }
121
123
 
122
124
  &__form-area {
@@ -26,7 +26,7 @@ export const CreatePasswordPage: React.FC<CreatePasswordPageProps> = ({
26
26
  error,
27
27
  }) => {
28
28
  const { t } = useTranslation(['Validation', 'User'])
29
- const { register, handleSubmit, watch, formState: { errors, touchedFields } } = useForm<FormValues>({ mode: 'onChange' })
29
+ const { register, handleSubmit, watch, formState: { errors } } = useForm<FormValues>({ mode: 'onChange' })
30
30
 
31
31
  const password = watch('password', '')
32
32
  const confirmPassword = watch('confirmPassword', '')
@@ -101,7 +101,6 @@ export const CreatePasswordPage: React.FC<CreatePasswordPageProps> = ({
101
101
  type="password"
102
102
  disabled={isLoading}
103
103
  error={errors.password?.message}
104
- success={!!touchedFields.password && !errors.password}
105
104
  {...register('password', {
106
105
  required: t('Validation:fieldRequired', { attribute: t('User:password') }) as string,
107
106
  minLength: {
@@ -135,7 +134,6 @@ export const CreatePasswordPage: React.FC<CreatePasswordPageProps> = ({
135
134
  type="password"
136
135
  disabled={isLoading}
137
136
  error={errors.confirmPassword?.message}
138
- success={!!touchedFields.confirmPassword && !errors.confirmPassword}
139
137
  {...register('confirmPassword', {
140
138
  required: t('Validation:fieldRequired', { attribute: t('User:confirmPassword') }) as string,
141
139
  validate: (value) =>
@@ -29,7 +29,7 @@ export const LoginPage: React.FC<LoginPageProps> = ({
29
29
  version,
30
30
  }) => {
31
31
  const { t } = useTranslation(['Validation', 'User'])
32
- const { register, handleSubmit, formState: { errors, touchedFields } } = useForm<FormValues>({ mode: 'onChange' })
32
+ const { register, handleSubmit, formState: { errors } } = useForm<FormValues>({ mode: 'onChange' })
33
33
 
34
34
  const onFormSubmit = async (data: FormValues) => {
35
35
  await onSubmit(data.email, data.password)
@@ -51,7 +51,6 @@ export const LoginPage: React.FC<LoginPageProps> = ({
51
51
  type="email"
52
52
  disabled={isLoading}
53
53
  error={errors.email?.message}
54
- success={!!touchedFields.email && !errors.email}
55
54
  {...register('email', {
56
55
  required: t('Validation:fieldRequired', { attribute: t('User:email') }) as string,
57
56
  pattern: {
@@ -67,7 +66,6 @@ export const LoginPage: React.FC<LoginPageProps> = ({
67
66
  type="password"
68
67
  disabled={isLoading}
69
68
  error={errors.password?.message}
70
- success={!!touchedFields.password && !errors.password}
71
69
  {...register('password', {
72
70
  required: t('Validation:fieldRequired', { attribute: t('User:password') }) as string,
73
71
  })}
@@ -48,6 +48,8 @@
48
48
  font-weight: inherit;
49
49
 
50
50
  &:hover {
51
+ color: var(--label-action);
52
+ text-decoration: underline;
51
53
  opacity: 0.8;
52
54
  }
53
55
  }
@@ -30,7 +30,7 @@ export const ResetPasswordPage: React.FC<ResetPasswordPageProps> = ({
30
30
  version,
31
31
  }) => {
32
32
  const { t } = useTranslation(['Validation', 'User'])
33
- const { register, handleSubmit, formState: { errors, touchedFields } } = useForm<FormValues>({ mode: 'onChange' })
33
+ const { register, handleSubmit, formState: { errors } } = useForm<FormValues>({ mode: 'onChange' })
34
34
 
35
35
  const onFormSubmit = async (data: FormValues) => {
36
36
  await onSubmit(data.email)
@@ -57,7 +57,6 @@ export const ResetPasswordPage: React.FC<ResetPasswordPageProps> = ({
57
57
  type="email"
58
58
  disabled={isLoading}
59
59
  error={errors.email?.message}
60
- success={!!touchedFields.email && !errors.email}
61
60
  {...register('email', {
62
61
  required: t('Validation:fieldRequired', { attribute: t('User:email') }) as string,
63
62
  pattern: {
@@ -47,6 +47,33 @@
47
47
  }
48
48
  }
49
49
 
50
+ // Neutral Outline (border-primary border, label-primary text)
51
+ &--outline {
52
+ border: 1px solid var(--border-primary, #e8e9ef);
53
+ background-color: var(--surface-primary, #ffffff);
54
+ color: var(--label-primary, #121e52);
55
+ font-weight: 500;
56
+ min-height: 40px;
57
+ padding: 8px 16px 8px 12px;
58
+ border-radius: 6px;
59
+ font-size: 14px;
60
+ line-height: 20px;
61
+
62
+ svg {
63
+ fill: currentColor;
64
+ flex-shrink: 0;
65
+ }
66
+
67
+ &:hover {
68
+ background-color: var(--surface-secondary, #f8f8fa);
69
+ border-color: var(--border-secondary, #d0d3e3);
70
+ }
71
+
72
+ &:active {
73
+ background-color: var(--surface-tertiary, #f0f0f5);
74
+ }
75
+ }
76
+
50
77
  // Primary - Outline
51
78
  &--primary-outline {
52
79
  border: 2px solid var(--fills-main-fill-action, #6200ee);