@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.
- package/dist/styles/themes/bookedit/_fonts.scss +2 -0
- package/dist/v2/components/ActionMenu/ActionMenu.d.ts.map +1 -1
- package/dist/v2/components/ActionMenu/ActionMenu.js +5 -3
- package/dist/v2/components/AvatarUpload/AvatarUpload.d.ts +12 -0
- package/dist/v2/components/AvatarUpload/AvatarUpload.d.ts.map +1 -0
- package/dist/v2/components/AvatarUpload/index.d.ts +2 -0
- package/dist/v2/components/AvatarUpload/index.d.ts.map +1 -0
- package/dist/v2/components/Button/Button.d.ts +1 -1
- package/dist/v2/components/Button/Button.d.ts.map +1 -1
- package/dist/v2/components/Button/Button.scss.js +1 -1
- package/dist/v2/components/DataTable/DataTable.d.ts +41 -0
- package/dist/v2/components/DataTable/DataTable.d.ts.map +1 -0
- package/dist/v2/components/DataTable/index.d.ts +3 -0
- package/dist/v2/components/DataTable/index.d.ts.map +1 -0
- package/dist/v2/components/EmptyState/EmptyState.d.ts +14 -0
- package/dist/v2/components/EmptyState/EmptyState.d.ts.map +1 -0
- package/dist/v2/components/EmptyState/index.d.ts +3 -0
- package/dist/v2/components/EmptyState/index.d.ts.map +1 -0
- package/dist/v2/components/FormField/FormField.scss.js +1 -1
- package/dist/v2/components/InfoGrid/InfoGrid.d.ts +13 -0
- package/dist/v2/components/InfoGrid/InfoGrid.d.ts.map +1 -0
- package/dist/v2/components/InfoGrid/index.d.ts +2 -0
- package/dist/v2/components/InfoGrid/index.d.ts.map +1 -0
- package/dist/v2/components/NewTable/NewTable.scss.js +1 -1
- package/dist/v2/components/RadioCard/RadioCard.d.ts +17 -0
- package/dist/v2/components/RadioCard/RadioCard.d.ts.map +1 -0
- package/dist/v2/components/RadioCard/index.d.ts +2 -0
- package/dist/v2/components/RadioCard/index.d.ts.map +1 -0
- package/dist/v2/components/StatusBadge/StatusBadge.d.ts +8 -0
- package/dist/v2/components/StatusBadge/StatusBadge.d.ts.map +1 -0
- package/dist/v2/components/StatusBadge/index.d.ts +3 -0
- package/dist/v2/components/StatusBadge/index.d.ts.map +1 -0
- package/dist/v2/components/StepIndicator/StepIndicator.d.ts +9 -0
- package/dist/v2/components/StepIndicator/StepIndicator.d.ts.map +1 -0
- package/dist/v2/components/StepIndicator/index.d.ts +2 -0
- package/dist/v2/components/StepIndicator/index.d.ts.map +1 -0
- package/dist/v2/components/TableControls/TableControls.d.ts +28 -0
- package/dist/v2/components/TableControls/TableControls.d.ts.map +1 -0
- package/dist/v2/components/TableControls/index.d.ts +3 -0
- package/dist/v2/components/TableControls/index.d.ts.map +1 -0
- package/dist/v2/components/Tabs/Tabs.d.ts +15 -0
- package/dist/v2/components/Tabs/Tabs.d.ts.map +1 -0
- package/dist/v2/components/Tabs/index.d.ts +3 -0
- package/dist/v2/components/Tabs/index.d.ts.map +1 -0
- package/dist/v2/icons/index.d.ts +42 -0
- package/dist/v2/icons/index.d.ts.map +1 -1
- package/dist/v2/index.d.ts +18 -0
- package/dist/v2/index.d.ts.map +1 -1
- package/dist/v2/pages/CreateUser/CreateUserPage.d.ts +110 -0
- package/dist/v2/pages/CreateUser/CreateUserPage.d.ts.map +1 -0
- package/dist/v2/pages/CreateUser/index.d.ts +3 -0
- package/dist/v2/pages/CreateUser/index.d.ts.map +1 -0
- package/dist/v2/pages/RoleSelection/RoleSelectionPage.d.ts +26 -0
- package/dist/v2/pages/RoleSelection/RoleSelectionPage.d.ts.map +1 -0
- package/dist/v2/pages/RoleSelection/index.d.ts +3 -0
- package/dist/v2/pages/RoleSelection/index.d.ts.map +1 -0
- package/dist/v2/pages/UserDetails/UserDetailsPage.d.ts +37 -0
- package/dist/v2/pages/UserDetails/UserDetailsPage.d.ts.map +1 -0
- package/dist/v2/pages/UserDetails/index.d.ts +3 -0
- package/dist/v2/pages/UserDetails/index.d.ts.map +1 -0
- package/dist/v2/pages/auth/CreatePassword/CreatePasswordPage.d.ts.map +1 -1
- package/dist/v2/pages/auth/Login/LoginPage.d.ts.map +1 -1
- package/dist/v2/pages/auth/ResetPassword/ResetPasswordPage.d.ts.map +1 -1
- package/dist/v2/styles/components/Button.scss +27 -0
- package/package.json +2 -2
- package/src/styles/themes/bookedit/_fonts.scss +2 -0
- package/src/v2/components/ActionMenu/ActionMenu.tsx +4 -2
- package/src/v2/components/AvatarUpload/AvatarUpload.scss +68 -0
- package/src/v2/components/AvatarUpload/AvatarUpload.stories.tsx +83 -0
- package/src/v2/components/AvatarUpload/AvatarUpload.tsx +69 -0
- package/src/v2/components/AvatarUpload/index.ts +1 -0
- package/src/v2/components/Button/Button.tsx +1 -0
- package/src/v2/components/DataTable/DataTable.scss +181 -0
- package/src/v2/components/DataTable/DataTable.tsx +256 -0
- package/src/v2/components/DataTable/index.ts +7 -0
- package/src/v2/components/EmptyState/EmptyState.scss +39 -0
- package/src/v2/components/EmptyState/EmptyState.stories.tsx +45 -0
- package/src/v2/components/EmptyState/EmptyState.tsx +37 -0
- package/src/v2/components/EmptyState/index.ts +2 -0
- package/src/v2/components/FormField/FormField.scss +12 -0
- package/src/v2/components/InfoGrid/InfoGrid.scss +51 -0
- package/src/v2/components/InfoGrid/InfoGrid.stories.tsx +76 -0
- package/src/v2/components/InfoGrid/InfoGrid.tsx +28 -0
- package/src/v2/components/InfoGrid/index.ts +1 -0
- package/src/v2/components/NewTable/NewTable.scss +4 -4
- package/src/v2/components/RadioCard/RadioCard.scss +76 -0
- package/src/v2/components/RadioCard/RadioCard.stories.tsx +115 -0
- package/src/v2/components/RadioCard/RadioCard.tsx +68 -0
- package/src/v2/components/RadioCard/index.ts +1 -0
- package/src/v2/components/StatusBadge/StatusBadge.scss +53 -0
- package/src/v2/components/StatusBadge/StatusBadge.tsx +31 -0
- package/src/v2/components/StatusBadge/index.ts +2 -0
- package/src/v2/components/StepIndicator/StepIndicator.scss +62 -0
- package/src/v2/components/StepIndicator/StepIndicator.stories.tsx +37 -0
- package/src/v2/components/StepIndicator/StepIndicator.tsx +41 -0
- package/src/v2/components/StepIndicator/index.ts +1 -0
- package/src/v2/components/TableControls/TableControls.scss +63 -0
- package/src/v2/components/TableControls/TableControls.tsx +110 -0
- package/src/v2/components/TableControls/index.ts +7 -0
- package/src/v2/components/Tabs/Tabs.scss +36 -0
- package/src/v2/components/Tabs/Tabs.stories.tsx +75 -0
- package/src/v2/components/Tabs/Tabs.tsx +52 -0
- package/src/v2/components/Tabs/index.ts +2 -0
- package/src/v2/icons/index.tsx +219 -0
- package/src/v2/index.ts +98 -0
- package/src/v2/pages/CreateUser/CreateUserPage.scss +760 -0
- package/src/v2/pages/CreateUser/CreateUserPage.stories.tsx +157 -0
- package/src/v2/pages/CreateUser/CreateUserPage.tsx +1062 -0
- package/src/v2/pages/CreateUser/index.ts +13 -0
- package/src/v2/pages/RoleSelection/RoleSelectionPage.scss +193 -0
- package/src/v2/pages/RoleSelection/RoleSelectionPage.stories.tsx +112 -0
- package/src/v2/pages/RoleSelection/RoleSelectionPage.tsx +127 -0
- package/src/v2/pages/RoleSelection/index.ts +2 -0
- package/src/v2/pages/UserDetails/UserDetailsPage.scss +236 -0
- package/src/v2/pages/UserDetails/UserDetailsPage.stories.tsx +84 -0
- package/src/v2/pages/UserDetails/UserDetailsPage.tsx +210 -0
- package/src/v2/pages/UserDetails/index.ts +2 -0
- package/src/v2/pages/auth/AuthLayout/AuthLayout.scss +8 -6
- package/src/v2/pages/auth/CreatePassword/CreatePasswordPage.tsx +1 -3
- package/src/v2/pages/auth/Login/LoginPage.tsx +1 -3
- package/src/v2/pages/auth/ResetPassword/ResetPasswordPage.scss +2 -0
- package/src/v2/pages/auth/ResetPassword/ResetPasswordPage.tsx +1 -2
- 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
|
+
}
|
|
@@ -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
|
|
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:
|
|
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
|
|
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
|
|
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
|
})}
|
|
@@ -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
|
|
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);
|