@licklist/design 0.78.5-dev.60 → 0.78.5-dev.63

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 (94) hide show
  1. package/dist/auth/Login/LoginPage.d.ts +8 -0
  2. package/dist/auth/Login/LoginPage.d.ts.map +1 -0
  3. package/dist/auth/Login/LoginPage.js +206 -0
  4. package/dist/auth/Login/index.d.ts +1 -0
  5. package/dist/auth/Login/index.d.ts.map +1 -1
  6. package/dist/index.js +1 -0
  7. package/dist/v2/components/ActionMenu/ActionMenu.d.ts.map +1 -1
  8. package/dist/v2/components/ActionMenu/ActionMenu.js +6 -16
  9. package/dist/v2/components/ActionMenu/ActionMenu.scss.js +1 -1
  10. package/dist/v2/components/FormField/FormField.d.ts +2 -0
  11. package/dist/v2/components/FormField/FormField.d.ts.map +1 -1
  12. package/dist/v2/components/FormField/FormField.js +12 -3
  13. package/dist/v2/components/FormField/FormField.scss.js +1 -1
  14. package/dist/v2/components/NewPageHeader/NewPageHeader.scss.js +1 -1
  15. package/dist/v2/components/ZoneCard/ResourceRow.d.ts +11 -0
  16. package/dist/v2/components/ZoneCard/ResourceRow.d.ts.map +1 -1
  17. package/dist/v2/components/ZoneCard/ResourceRow.js +61 -9
  18. package/dist/v2/components/ZoneCard/ZoneCard.d.ts +0 -1
  19. package/dist/v2/components/ZoneCard/ZoneCard.d.ts.map +1 -1
  20. package/dist/v2/components/ZoneCard/ZoneCard.js +1 -2
  21. package/dist/v2/components/ZoneCard/ZoneCard.scss.js +1 -1
  22. package/dist/v2/components/ZoneCard/ZoneHeader.d.ts +6 -1
  23. package/dist/v2/components/ZoneCard/ZoneHeader.d.ts.map +1 -1
  24. package/dist/v2/components/ZoneCard/ZoneHeader.js +30 -13
  25. package/dist/v2/components/ZoneCard/index.d.ts +1 -1
  26. package/dist/v2/components/ZoneCard/index.d.ts.map +1 -1
  27. package/dist/v2/icons/index.d.ts +18 -2
  28. package/dist/v2/icons/index.d.ts.map +1 -1
  29. package/dist/v2/icons/index.js +21 -41
  30. package/dist/v2/index.d.ts +3 -1
  31. package/dist/v2/index.d.ts.map +1 -1
  32. package/dist/v2/pages/ZonesResources/ZonesResourcesPage.d.ts.map +1 -1
  33. package/dist/v2/pages/ZonesResources/ZonesResourcesPage.js +20 -16
  34. package/dist/v2/pages/ZonesResources/ZonesResourcesPage.scss.js +1 -1
  35. package/dist/v2/pages/auth/AuthLayout/AuthLayout.d.ts +14 -0
  36. package/dist/v2/pages/auth/AuthLayout/AuthLayout.d.ts.map +1 -0
  37. package/dist/v2/pages/auth/AuthLayout/index.d.ts +3 -0
  38. package/dist/v2/pages/auth/AuthLayout/index.d.ts.map +1 -0
  39. package/dist/v2/pages/auth/CreatePassword/CreatePasswordPage.d.ts +10 -0
  40. package/dist/v2/pages/auth/CreatePassword/CreatePasswordPage.d.ts.map +1 -0
  41. package/dist/v2/pages/auth/CreatePassword/index.d.ts +3 -0
  42. package/dist/v2/pages/auth/CreatePassword/index.d.ts.map +1 -0
  43. package/dist/v2/pages/auth/Login/LoginPage.d.ts +11 -0
  44. package/dist/v2/pages/auth/Login/LoginPage.d.ts.map +1 -0
  45. package/dist/v2/pages/auth/Login/index.d.ts +3 -0
  46. package/dist/v2/pages/auth/Login/index.d.ts.map +1 -0
  47. package/dist/v2/pages/auth/ResetPassword/ResetPasswordPage.d.ts +12 -0
  48. package/dist/v2/pages/auth/ResetPassword/ResetPasswordPage.d.ts.map +1 -0
  49. package/dist/v2/pages/auth/ResetPassword/index.d.ts +3 -0
  50. package/dist/v2/pages/auth/ResetPassword/index.d.ts.map +1 -0
  51. package/dist/v2/pages/auth/VerifyEmail/VerifyEmailPage.d.ts +9 -0
  52. package/dist/v2/pages/auth/VerifyEmail/VerifyEmailPage.d.ts.map +1 -0
  53. package/dist/v2/pages/auth/VerifyEmail/index.d.ts +3 -0
  54. package/dist/v2/pages/auth/VerifyEmail/index.d.ts.map +1 -0
  55. package/dist/v2/pages/auth/index.d.ts +11 -0
  56. package/dist/v2/pages/auth/index.d.ts.map +1 -0
  57. package/package.json +2 -2
  58. package/src/auth/Login/LoginPage.tsx +52 -0
  59. package/src/auth/Login/index.ts +1 -0
  60. package/src/v2/components/ActionMenu/ActionMenu.scss +7 -20
  61. package/src/v2/components/ActionMenu/ActionMenu.tsx +2 -5
  62. package/src/v2/components/FormField/FormField.scss +9 -1
  63. package/src/v2/components/FormField/FormField.tsx +31 -19
  64. package/src/v2/components/NewPageHeader/NewPageHeader.scss +1 -5
  65. package/src/v2/components/ZoneCard/ResourceRow.tsx +56 -9
  66. package/src/v2/components/ZoneCard/ZoneCard.scss +74 -10
  67. package/src/v2/components/ZoneCard/ZoneCard.stories.tsx +2 -5
  68. package/src/v2/components/ZoneCard/ZoneCard.tsx +0 -3
  69. package/src/v2/components/ZoneCard/ZoneHeader.tsx +34 -11
  70. package/src/v2/components/ZoneCard/index.ts +1 -1
  71. package/src/v2/icons/index.tsx +113 -16
  72. package/src/v2/index.ts +5 -1
  73. package/src/v2/pages/ZonesResources/ZonesResourcesPage.scss +25 -0
  74. package/src/v2/pages/ZonesResources/ZonesResourcesPage.tsx +10 -7
  75. package/src/v2/pages/auth/AuthLayout/AuthLayout.scss +135 -0
  76. package/src/v2/pages/auth/AuthLayout/AuthLayout.tsx +61 -0
  77. package/src/v2/pages/auth/AuthLayout/index.ts +2 -0
  78. package/src/v2/pages/auth/CreatePassword/CreatePasswordPage.scss +149 -0
  79. package/src/v2/pages/auth/CreatePassword/CreatePasswordPage.stories.tsx +45 -0
  80. package/src/v2/pages/auth/CreatePassword/CreatePasswordPage.tsx +181 -0
  81. package/src/v2/pages/auth/CreatePassword/index.ts +2 -0
  82. package/src/v2/pages/auth/Login/LoginPage.scss +49 -0
  83. package/src/v2/pages/auth/Login/LoginPage.stories.tsx +45 -0
  84. package/src/v2/pages/auth/Login/LoginPage.tsx +100 -0
  85. package/src/v2/pages/auth/Login/index.ts +2 -0
  86. package/src/v2/pages/auth/ResetPassword/ResetPasswordPage.scss +82 -0
  87. package/src/v2/pages/auth/ResetPassword/ResetPasswordPage.stories.tsx +53 -0
  88. package/src/v2/pages/auth/ResetPassword/ResetPasswordPage.tsx +110 -0
  89. package/src/v2/pages/auth/ResetPassword/index.ts +2 -0
  90. package/src/v2/pages/auth/VerifyEmail/VerifyEmailPage.scss +72 -0
  91. package/src/v2/pages/auth/VerifyEmail/VerifyEmailPage.stories.tsx +41 -0
  92. package/src/v2/pages/auth/VerifyEmail/VerifyEmailPage.tsx +110 -0
  93. package/src/v2/pages/auth/VerifyEmail/index.ts +2 -0
  94. package/src/v2/pages/auth/index.ts +14 -0
@@ -0,0 +1,53 @@
1
+ import React from 'react'
2
+ import type { Meta, StoryObj } from '@storybook/react'
3
+ import { ResetPasswordPage } from './ResetPasswordPage'
4
+
5
+ const meta: Meta<typeof ResetPasswordPage> = {
6
+ title: 'v2/Pages/Auth/Reset Password',
7
+ component: ResetPasswordPage,
8
+ parameters: {
9
+ layout: 'fullscreen',
10
+ },
11
+ argTypes: {
12
+ onSubmit: { action: 'submitted' },
13
+ onBackToLogin: { action: 'back-to-login' },
14
+ isLoading: { control: 'boolean' },
15
+ error: { control: 'text' },
16
+ successMessage: { control: 'text' },
17
+ },
18
+ }
19
+
20
+ export default meta
21
+ type Story = StoryObj<typeof ResetPasswordPage>
22
+
23
+ export const Default: Story = {
24
+ args: {
25
+ onSubmit: async (email) => {
26
+ console.log('Reset password for:', email)
27
+ },
28
+ onBackToLogin: () => {
29
+ console.log('Back to login clicked')
30
+ },
31
+ },
32
+ }
33
+
34
+ export const Loading: Story = {
35
+ args: {
36
+ ...Default.args,
37
+ isLoading: true,
38
+ },
39
+ }
40
+
41
+ export const WithError: Story = {
42
+ args: {
43
+ ...Default.args,
44
+ error: 'Failed to send reset email. Please try again.',
45
+ },
46
+ }
47
+
48
+ export const WithSuccess: Story = {
49
+ args: {
50
+ ...Default.args,
51
+ successMessage: 'Password reset email sent! Check your inbox.',
52
+ },
53
+ }
@@ -0,0 +1,110 @@
1
+ import React from 'react'
2
+ import { useForm } from 'react-hook-form'
3
+ import { useTranslation } from 'react-i18next'
4
+ import { AuthLayout } from '../AuthLayout'
5
+ import { FormField } from '../../../components/FormField'
6
+ import { Button } from '../../../components/Button'
7
+ import { RefreshIcon } from '../../../icons'
8
+ import emailRule from '@licklist/plugins/dist/validation/Rules/emailRule'
9
+ import './ResetPasswordPage.scss'
10
+
11
+ type FormValues = {
12
+ email: string
13
+ }
14
+
15
+ export interface ResetPasswordPageProps {
16
+ onSubmit: (email: string) => Promise<void> | void
17
+ onBackToLogin?: () => void
18
+ isLoading?: boolean
19
+ error?: string
20
+ successMessage?: string
21
+ version?: string
22
+ }
23
+
24
+ export const ResetPasswordPage: React.FC<ResetPasswordPageProps> = ({
25
+ onSubmit,
26
+ onBackToLogin,
27
+ isLoading = false,
28
+ error,
29
+ successMessage,
30
+ version,
31
+ }) => {
32
+ const { t } = useTranslation(['Validation', 'User'])
33
+ const { register, handleSubmit, formState: { errors, touchedFields } } = useForm<FormValues>({ mode: 'onChange' })
34
+
35
+ const onFormSubmit = async (data: FormValues) => {
36
+ await onSubmit(data.email)
37
+ }
38
+
39
+ return (
40
+ <AuthLayout
41
+ badgeLabel={t('User:resetPasswordTitle')}
42
+ icon={<RefreshIcon />}
43
+ title={t('User:resetPasswordTitle')}
44
+ subtitle={t('User:resetPasswordSubtitle')}
45
+ version={version}
46
+ error={error}
47
+ successMessage={successMessage}
48
+ >
49
+ <form className="auth-reset" onSubmit={handleSubmit(onFormSubmit)} noValidate>
50
+ <p className="auth-reset__description">
51
+ {t('User:resetPasswordDescription')}
52
+ </p>
53
+
54
+ <FormField
55
+ className="auth-reset__field"
56
+ label={t('User:emailAddress')}
57
+ type="email"
58
+ disabled={isLoading}
59
+ error={errors.email?.message}
60
+ success={!!touchedFields.email && !errors.email}
61
+ {...register('email', {
62
+ required: t('Validation:fieldRequired', { attribute: t('User:email') }) as string,
63
+ pattern: {
64
+ value: emailRule,
65
+ message: t('Validation:fieldValidEmail', { attribute: t('User:email') }) as string,
66
+ },
67
+ })}
68
+ />
69
+
70
+ <div className="auth-reset__actions">
71
+ <Button
72
+ type="submit"
73
+ variant="primary"
74
+ isLoading={isLoading}
75
+ disabled={isLoading}
76
+ >
77
+ {t('User:resetPasswordTitle')}
78
+ </Button>
79
+ </div>
80
+
81
+ <div className="auth-reset__footer">
82
+ {onBackToLogin && (
83
+ <p className="auth-reset__footer-text">
84
+ {t('User:resetPasswordAlreadyAccount')}{' '}
85
+ <button
86
+ type="button"
87
+ className="auth-reset__link"
88
+ onClick={onBackToLogin}
89
+ disabled={isLoading}
90
+ >
91
+ {t('User:login')}
92
+ </button>
93
+ .
94
+ </p>
95
+ )}
96
+ <p className="auth-reset__footer-text">
97
+ {t('User:forFurtherSupport')}{' '}
98
+ <a
99
+ href="mailto:support@booked.it"
100
+ className="auth-reset__link"
101
+ >
102
+ {t('User:contactUs')}
103
+ </a>
104
+ .
105
+ </p>
106
+ </div>
107
+ </form>
108
+ </AuthLayout>
109
+ )
110
+ }
@@ -0,0 +1,2 @@
1
+ export { ResetPasswordPage } from './ResetPasswordPage'
2
+ export type { ResetPasswordPageProps } from './ResetPasswordPage'
@@ -0,0 +1,72 @@
1
+ .auth-verify-email {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 0;
5
+
6
+ &__label {
7
+ font-family: var(--font-family-sans, 'Geist', sans-serif);
8
+ font-size: 15px;
9
+ font-weight: 600;
10
+ line-height: 20px;
11
+ color: var(--label-primary);
12
+ display: block;
13
+ margin-bottom: 8px;
14
+ }
15
+
16
+ &__description {
17
+ font-family: var(--font-family-sans, 'Geist', sans-serif);
18
+ font-size: 14px;
19
+ font-weight: 400;
20
+ color: var(--label-secondary);
21
+ margin: 0 0 16px;
22
+ padding: 0;
23
+ }
24
+
25
+ &__otp-group {
26
+ display: flex;
27
+ gap: 8px;
28
+ margin-bottom: 24px;
29
+ height: 62px;
30
+ }
31
+
32
+ &__otp-input {
33
+ flex: 1;
34
+ background-color: var(--surface-secondary);
35
+ border: 2px solid var(--border-primary);
36
+ border-radius: 8px;
37
+ text-align: center;
38
+ font-family: var(--font-family-sans, 'Geist', sans-serif);
39
+ font-size: 20px;
40
+ font-weight: 600;
41
+ color: var(--label-primary);
42
+ transition: border-color 0.2s ease;
43
+ min-width: 0;
44
+
45
+ &:focus {
46
+ outline: none;
47
+ border-color: var(--border-selected, #6200EE);
48
+ }
49
+
50
+ &::placeholder {
51
+ color: var(--label-secondary);
52
+ }
53
+ }
54
+
55
+ &__actions {
56
+ margin-bottom: 0;
57
+ }
58
+
59
+ &__error {
60
+ display: flex;
61
+ align-items: center;
62
+ gap: 8px;
63
+ padding: 10px 12px;
64
+ border-radius: 8px;
65
+ background-color: var(--surface-status-error);
66
+ border: 1px solid var(--border-status-error);
67
+ font-family: var(--font-family-sans, 'Geist', sans-serif);
68
+ font-size: 13px;
69
+ color: var(--label-status-error);
70
+ margin-bottom: 16px;
71
+ }
72
+ }
@@ -0,0 +1,41 @@
1
+ import React from 'react'
2
+ import type { Meta, StoryObj } from '@storybook/react'
3
+ import { VerifyEmailPage } from './VerifyEmailPage'
4
+
5
+ const meta: Meta<typeof VerifyEmailPage> = {
6
+ title: 'v2/Pages/Auth/Verify Email',
7
+ component: VerifyEmailPage,
8
+ parameters: {
9
+ layout: 'fullscreen',
10
+ },
11
+ argTypes: {
12
+ onSubmit: { action: 'submitted' },
13
+ isLoading: { control: 'boolean' },
14
+ error: { control: 'text' },
15
+ },
16
+ }
17
+
18
+ export default meta
19
+ type Story = StoryObj<typeof VerifyEmailPage>
20
+
21
+ export const Default: Story = {
22
+ args: {
23
+ onSubmit: async (code) => {
24
+ console.log('Verify code:', code)
25
+ },
26
+ },
27
+ }
28
+
29
+ export const Loading: Story = {
30
+ args: {
31
+ ...Default.args,
32
+ isLoading: true,
33
+ },
34
+ }
35
+
36
+ export const WithError: Story = {
37
+ args: {
38
+ ...Default.args,
39
+ error: 'Invalid verification code. Please try again.',
40
+ },
41
+ }
@@ -0,0 +1,110 @@
1
+ import React, { useState, useRef } from 'react'
2
+ import { useTranslation } from 'react-i18next'
3
+ import { AuthLayout } from '../AuthLayout'
4
+ import { VerifyEmailIcon } from '../../../icons'
5
+ import { Button } from '../../../components/Button'
6
+ import './VerifyEmailPage.scss'
7
+
8
+ const CODE_LENGTH = 6
9
+
10
+ export interface VerifyEmailPageProps {
11
+ onSubmit: (code: string) => Promise<void> | void
12
+ isLoading?: boolean
13
+ error?: string
14
+ }
15
+
16
+ export const VerifyEmailPage: React.FC<VerifyEmailPageProps> = ({
17
+ onSubmit,
18
+ isLoading = false,
19
+ error,
20
+ }) => {
21
+ const { t } = useTranslation(['User'])
22
+ const [digits, setDigits] = useState<string[]>(Array(CODE_LENGTH).fill(''))
23
+ const inputRefs = useRef<(HTMLInputElement | null)[]>([])
24
+
25
+ const handleChange = (index: number, value: string) => {
26
+ const digit = value.replace(/\D/g, '').slice(-1)
27
+ const newDigits = [...digits]
28
+ newDigits[index] = digit
29
+ setDigits(newDigits)
30
+
31
+ if (digit && index < CODE_LENGTH - 1) {
32
+ inputRefs.current[index + 1]?.focus()
33
+ }
34
+ }
35
+
36
+ const handleKeyDown = (index: number, e: React.KeyboardEvent<HTMLInputElement>) => {
37
+ if (e.key === 'Backspace' && !digits[index] && index > 0) {
38
+ inputRefs.current[index - 1]?.focus()
39
+ }
40
+ }
41
+
42
+ const handlePaste = (e: React.ClipboardEvent) => {
43
+ e.preventDefault()
44
+ const pasted = e.clipboardData.getData('text').replace(/\D/g, '').slice(0, CODE_LENGTH)
45
+ if (!pasted) return
46
+ const newDigits = [...digits]
47
+ pasted.split('').forEach((char, i) => {
48
+ newDigits[i] = char
49
+ })
50
+ setDigits(newDigits)
51
+ const nextEmpty = pasted.length < CODE_LENGTH ? pasted.length : CODE_LENGTH - 1
52
+ inputRefs.current[nextEmpty]?.focus()
53
+ }
54
+
55
+ const code = digits.join('')
56
+
57
+ const handleSubmit = async (e: React.FormEvent) => {
58
+ e.preventDefault()
59
+ if (code.length !== CODE_LENGTH) return
60
+ await onSubmit(code)
61
+ }
62
+
63
+ return (
64
+ <AuthLayout
65
+ badgeLabel={t('User:verifyEmail')}
66
+ icon={<VerifyEmailIcon />}
67
+ title={t('User:verifyEmail')}
68
+ subtitle={t('User:verifyEmailSubtitle')}
69
+ error={error}
70
+ >
71
+ <form className="auth-verify-email" onSubmit={handleSubmit} noValidate>
72
+ <label className="auth-verify-email__label">
73
+ {t('User:verifyEmailCode')}
74
+ </label>
75
+ <p className="auth-verify-email__description">
76
+ {t('User:verifyEmailDescription')}
77
+ </p>
78
+
79
+ <div className="auth-verify-email__otp-group" onPaste={handlePaste}>
80
+ {digits.map((digit, index) => (
81
+ <input
82
+ key={index}
83
+ ref={(el) => { inputRefs.current[index] = el }}
84
+ type="text"
85
+ inputMode="numeric"
86
+ maxLength={1}
87
+ value={digit}
88
+ onChange={(e) => handleChange(index, e.target.value)}
89
+ onKeyDown={(e) => handleKeyDown(index, e)}
90
+ className="auth-verify-email__otp-input"
91
+ disabled={isLoading}
92
+ aria-label={`Digit ${index + 1}`}
93
+ />
94
+ ))}
95
+ </div>
96
+
97
+ <div className="auth-verify-email__actions">
98
+ <Button
99
+ type="submit"
100
+ variant="primary"
101
+ isLoading={isLoading}
102
+ disabled={isLoading}
103
+ >
104
+ {t('User:verifyCode')}
105
+ </Button>
106
+ </div>
107
+ </form>
108
+ </AuthLayout>
109
+ )
110
+ }
@@ -0,0 +1,2 @@
1
+ export { VerifyEmailPage } from './VerifyEmailPage'
2
+ export type { VerifyEmailPageProps } from './VerifyEmailPage'
@@ -0,0 +1,14 @@
1
+ export { AuthLayout } from './AuthLayout'
2
+ export type { AuthLayoutProps } from './AuthLayout'
3
+
4
+ export { LoginPage } from './Login'
5
+ export type { LoginPageProps } from './Login'
6
+
7
+ export { ResetPasswordPage } from './ResetPassword'
8
+ export type { ResetPasswordPageProps } from './ResetPassword'
9
+
10
+ export { CreatePasswordPage } from './CreatePassword'
11
+ export type { CreatePasswordPageProps } from './CreatePassword'
12
+
13
+ export { VerifyEmailPage } from './VerifyEmail'
14
+ export type { VerifyEmailPageProps } from './VerifyEmail'