profile-view-refactored
This commit is contained in:
parent
6d3629592a
commit
90691aa650
|
@ -1 +0,0 @@
|
|||
export { ProfileSettings } from './ProfileSettings'
|
305
src/components/Views/Profile/ProfileSecurity.tsx
Normal file
305
src/components/Views/Profile/ProfileSecurity.tsx
Normal file
|
@ -0,0 +1,305 @@
|
|||
import { UpdateProfileInput } from '@authorizerdev/authorizer-js'
|
||||
import { clsx } from 'clsx'
|
||||
import { Show, createEffect, createSignal, on } from 'solid-js'
|
||||
import { AuthGuard } from '~/components/AuthGuard'
|
||||
import { PasswordField } from '~/components/Nav/AuthModal/PasswordField'
|
||||
import { ProfileSettingsNavigation } from '~/components/Nav/ProfileSettingsNavigation'
|
||||
import { Button } from '~/components/_shared/Button'
|
||||
import { Icon } from '~/components/_shared/Icon'
|
||||
import { Loading } from '~/components/_shared/Loading'
|
||||
import { useLocalize } from '~/context/localize'
|
||||
import { useSession } from '~/context/session'
|
||||
import { DEFAULT_HEADER_OFFSET, useSnackbar, useUI } from '~/context/ui'
|
||||
import { validateEmail } from '~/utils/validateEmail'
|
||||
import styles from './Settings.module.scss'
|
||||
|
||||
type FormField = 'oldPassword' | 'newPassword' | 'newPasswordConfirm' | 'email'
|
||||
type FormData = Record<FormField, string | undefined>
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
export const ProfileSecurityView = (_props: any) => {
|
||||
const { t } = useLocalize()
|
||||
const { updateProfile, session, isSessionLoaded } = useSession()
|
||||
const { showConfirm } = useUI()
|
||||
const { showSnackbar } = useSnackbar()
|
||||
const [newPasswordError, setNewPasswordError] = createSignal<string | undefined>()
|
||||
const [oldPasswordError, setOldPasswordError] = createSignal<string | undefined>()
|
||||
const [emailError, setEmailError] = createSignal<string | undefined>()
|
||||
const [isSubmitting, setIsSubmitting] = createSignal<boolean>()
|
||||
const [isFloatingPanelVisible, setIsFloatingPanelVisible] = createSignal(false)
|
||||
|
||||
const initialState = {
|
||||
oldPassword: undefined,
|
||||
newPassword: undefined,
|
||||
newPasswordConfirm: undefined,
|
||||
email: undefined
|
||||
} as FormData
|
||||
|
||||
const [formData, setFormData] = createSignal(initialState)
|
||||
let oldPasswordRef: HTMLDivElement | undefined
|
||||
let newPasswordRepeatRef: HTMLDivElement | undefined
|
||||
|
||||
createEffect(
|
||||
on(
|
||||
() => session()?.user?.email,
|
||||
(email) => {
|
||||
setFormData((prevData: FormData) => ({ ...prevData, email }) as FormData)
|
||||
}
|
||||
)
|
||||
)
|
||||
const handleInputChange = (name: FormField, value: string) => {
|
||||
if (
|
||||
name === 'email' ||
|
||||
(name === 'newPasswordConfirm' && value && value?.length > 0 && !emailError() && !newPasswordError())
|
||||
) {
|
||||
setIsFloatingPanelVisible(true)
|
||||
} else {
|
||||
setIsFloatingPanelVisible(false)
|
||||
}
|
||||
setFormData((prevData) => ({
|
||||
...prevData,
|
||||
[name]: value
|
||||
}))
|
||||
}
|
||||
|
||||
const handleCancel = async () => {
|
||||
const isConfirmed = await showConfirm({
|
||||
confirmBody: t('Do you really want to reset all changes?'),
|
||||
confirmButtonVariant: 'primary',
|
||||
declineButtonVariant: 'secondary'
|
||||
})
|
||||
if (isConfirmed) {
|
||||
setEmailError()
|
||||
setFormData({
|
||||
...initialState,
|
||||
['email']: session()?.user?.email
|
||||
})
|
||||
setIsFloatingPanelVisible(false)
|
||||
}
|
||||
}
|
||||
const handleChangeEmail = (_value: string) => {
|
||||
if (formData() && !validateEmail(formData()['email'] || '')) {
|
||||
setEmailError(t('Invalid email'))
|
||||
return
|
||||
}
|
||||
}
|
||||
const handleCheckNewPassword = (value: string) => {
|
||||
handleInputChange('newPasswordConfirm', value)
|
||||
if (newPasswordRepeatRef && value !== formData()['newPassword']) {
|
||||
const rect = newPasswordRepeatRef.getBoundingClientRect()
|
||||
const topPosition = window.scrollY + rect.top - DEFAULT_HEADER_OFFSET * 2
|
||||
window.scrollTo({
|
||||
top: topPosition,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
showSnackbar({ type: 'error', body: t('Incorrect new password confirm') })
|
||||
setNewPasswordError(t('Passwords are not equal'))
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
setIsSubmitting(true)
|
||||
|
||||
const options: UpdateProfileInput = {
|
||||
old_password: formData()['oldPassword'],
|
||||
new_password: formData()['newPassword'] || formData()['oldPassword'],
|
||||
confirm_new_password: formData()['newPassword'] || formData()['oldPassword'],
|
||||
email: formData()['email']
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await updateProfile(options)
|
||||
if (result) {
|
||||
// FIXME: const { errors } = result
|
||||
if (oldPasswordRef) {
|
||||
// && errors.some((obj: Error) => obj.message === 'incorrect old password')) {
|
||||
setOldPasswordError(t('Incorrect old password'))
|
||||
showSnackbar({ type: 'error', body: t('Incorrect old password') })
|
||||
const rect = oldPasswordRef.getBoundingClientRect()
|
||||
const topPosition = window.scrollY + rect.top - DEFAULT_HEADER_OFFSET * 2
|
||||
window.scrollTo({
|
||||
top: topPosition,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
setIsFloatingPanelVisible(false)
|
||||
}
|
||||
return
|
||||
}
|
||||
showSnackbar({ type: 'success', body: t('Profile successfully saved') })
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
setIsSubmitting(false)
|
||||
}
|
||||
}
|
||||
return (
|
||||
<AuthGuard>
|
||||
<Show when={isSessionLoaded()} fallback={<Loading />}>
|
||||
<div class="wide-container">
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<div class={clsx('left-navigation', styles.leftNavigation)}>
|
||||
<ProfileSettingsNavigation />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-19">
|
||||
<div class="row">
|
||||
<div class="col-md-20 col-lg-18 col-xl-16">
|
||||
<h1>{t('Login and security')}</h1>
|
||||
<p class="description">{t('Settings for account, email, password and login methods.')}</p>
|
||||
|
||||
<form>
|
||||
<h4>{t('Email')}</h4>
|
||||
<div class="pretty-form__item">
|
||||
<input
|
||||
type="text"
|
||||
name="email"
|
||||
id="email"
|
||||
disabled={isSubmitting()}
|
||||
value={formData()['email'] || ''}
|
||||
placeholder={t('Email')}
|
||||
onFocus={() => setEmailError()}
|
||||
onInput={(event) => handleChangeEmail(event.target.value)}
|
||||
/>
|
||||
<label for="email">{t('Email')}</label>
|
||||
<Show when={emailError()}>
|
||||
<div
|
||||
class={clsx(styles.emailValidationError, {
|
||||
'form-message--error': emailError()
|
||||
})}
|
||||
>
|
||||
{emailError()}
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
|
||||
<h4>{t('Change password')}</h4>
|
||||
<h5>{t('Current password')}</h5>
|
||||
|
||||
<div ref={(el: HTMLDivElement) => (oldPasswordRef = el)}>
|
||||
<PasswordField
|
||||
onFocus={() => setOldPasswordError()}
|
||||
setError={oldPasswordError()}
|
||||
onInput={(value) => handleInputChange('oldPassword', value)}
|
||||
value={formData()['oldPassword'] || undefined}
|
||||
disabled={isSubmitting()}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<h5>{t('New password')}</h5>
|
||||
<PasswordField
|
||||
onInput={(value) => {
|
||||
handleInputChange('newPassword', value)
|
||||
handleInputChange('newPasswordConfirm', '')
|
||||
}}
|
||||
value={formData()['newPassword'] ?? ''}
|
||||
disabled={isSubmitting()}
|
||||
disableAutocomplete={true}
|
||||
/>
|
||||
|
||||
<h5>{t('Confirm your new password')}</h5>
|
||||
<div ref={(el) => (newPasswordRepeatRef = el)}>
|
||||
<PasswordField
|
||||
noValidate={true}
|
||||
value={formData?.()['newPasswordConfirm']}
|
||||
onFocus={() => setNewPasswordError()}
|
||||
setError={newPasswordError()}
|
||||
onInput={(value) => handleCheckNewPassword(value)}
|
||||
disabled={isSubmitting()}
|
||||
disableAutocomplete={true}
|
||||
/>
|
||||
</div>
|
||||
<h4>{t('Social networks')}</h4>
|
||||
<h5>Google</h5>
|
||||
<div class="pretty-form__item">
|
||||
<p>
|
||||
<button class={clsx('button', 'button--light', styles.socialButton)} type="button">
|
||||
<Icon name="google" class={styles.icon} />
|
||||
{t('Connect')}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h5>VK</h5>
|
||||
<div class="pretty-form__item">
|
||||
<p>
|
||||
<button class={clsx(styles.socialButton, 'button', 'button--light')} type="button">
|
||||
<Icon name="vk" class={styles.icon} />
|
||||
{t('Connect')}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h5>Facebook</h5>
|
||||
<div class="pretty-form__item">
|
||||
<p>
|
||||
<button class={clsx(styles.socialButton, 'button', 'button--light')} type="button">
|
||||
<Icon name="facebook" class={styles.icon} />
|
||||
{t('Connect')}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h5>Apple</h5>
|
||||
<div class="pretty-form__item">
|
||||
<p>
|
||||
<button
|
||||
class={clsx(
|
||||
styles.socialButton,
|
||||
styles.socialButtonApple,
|
||||
'button' + ' button--light'
|
||||
)}
|
||||
type="button"
|
||||
>
|
||||
<Icon name="apple" class={styles.icon} />
|
||||
{t('Connect')}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<Show when={isFloatingPanelVisible() && !emailError() && !newPasswordError()}>
|
||||
<div class={styles.formActions}>
|
||||
<div class="wide-container">
|
||||
<div class="row">
|
||||
<div class="col-md-19 offset-md-5">
|
||||
<div class="row">
|
||||
<div class="col-md-20 col-lg-18 col-xl-16">
|
||||
<div class={styles.content}>
|
||||
<Button
|
||||
class={styles.cancel}
|
||||
variant="light"
|
||||
value={
|
||||
<>
|
||||
<span class={styles.cancelLabel}>{t('Cancel changes')}</span>
|
||||
<span class={styles.cancelLabelMobile}>{t('Cancel')}</span>
|
||||
</>
|
||||
}
|
||||
onClick={handleCancel}
|
||||
/>
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
variant="primary"
|
||||
disabled={isSubmitting()}
|
||||
value={isSubmitting() ? t('Saving...') : t('Save settings')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
</AuthGuard>
|
||||
)
|
||||
}
|
|
@ -24,14 +24,14 @@ import { handleImageUpload } from '~/lib/handleImageUpload'
|
|||
import { profileSocialLinks } from '~/lib/profileSocialLinks'
|
||||
import { clone } from '~/utils/clone'
|
||||
import { validateUrl } from '~/utils/validateUrl'
|
||||
import { Modal } from '../Nav/Modal'
|
||||
import { ProfileSettingsNavigation } from '../Nav/ProfileSettingsNavigation'
|
||||
import { Button } from '../_shared/Button'
|
||||
import { Icon } from '../_shared/Icon'
|
||||
import { ImageCropper } from '../_shared/ImageCropper'
|
||||
import { Loading } from '../_shared/Loading'
|
||||
import { Popover } from '../_shared/Popover'
|
||||
import { SocialNetworkInput } from '../_shared/SocialNetworkInput'
|
||||
import { Modal } from '../../Nav/Modal'
|
||||
import { ProfileSettingsNavigation } from '../../Nav/ProfileSettingsNavigation'
|
||||
import { Button } from '../../_shared/Button'
|
||||
import { Icon } from '../../_shared/Icon'
|
||||
import { ImageCropper } from '../../_shared/ImageCropper'
|
||||
import { Loading } from '../../_shared/Loading'
|
||||
import { Popover } from '../../_shared/Popover'
|
||||
import { SocialNetworkInput } from '../../_shared/SocialNetworkInput'
|
||||
import styles from './Settings.module.scss'
|
||||
|
||||
const SimplifiedEditor = lazy(() => import('~/components/Editor/SimplifiedEditor'))
|
|
@ -9,8 +9,8 @@ import { dummyFilter } from '~/lib/dummyFilter'
|
|||
import stylesSettings from '../../../styles/FeedSettings.module.scss'
|
||||
import { AuthorBadge } from '../../Author/AuthorBadge'
|
||||
import { ProfileSettingsNavigation } from '../../Nav/ProfileSettingsNavigation'
|
||||
import styles from '../../ProfileSettings/Settings.module.scss'
|
||||
import { TopicBadge } from '../../Topic/TopicBadge'
|
||||
import styles from '../Profile/Settings.module.scss'
|
||||
|
||||
export const ProfileSubscriptions = () => {
|
||||
const { t, lang } = useLocalize()
|
|
@ -1 +0,0 @@
|
|||
export { ProfileSubscriptions } from './ProfileSubscriptions'
|
|
@ -1,5 +1,5 @@
|
|||
import { AuthGuard } from '~/components/AuthGuard'
|
||||
import { ProfileSettings } from '~/components/ProfileSettings'
|
||||
import { ProfileSettings } from '~/components/Views/Profile/ProfileSettings'
|
||||
import { PageLayout } from '~/components/_shared/PageLayout'
|
||||
import { useLocalize } from '~/context/localize'
|
||||
import { ProfileProvider } from '~/context/profile'
|
||||
|
|
|
@ -1,317 +1,17 @@
|
|||
import { UpdateProfileInput } from '@authorizerdev/authorizer-js'
|
||||
import { clsx } from 'clsx'
|
||||
import { Show, createEffect, createSignal, on } from 'solid-js'
|
||||
import { AuthGuard } from '~/components/AuthGuard'
|
||||
import { PasswordField } from '~/components/Nav/AuthModal/PasswordField'
|
||||
import { ProfileSettingsNavigation } from '~/components/Nav/ProfileSettingsNavigation'
|
||||
import { Button } from '~/components/_shared/Button'
|
||||
import { Icon } from '~/components/_shared/Icon'
|
||||
import { Loading } from '~/components/_shared/Loading'
|
||||
import { ProfileSecurityView } from '~/components/Views/Profile/ProfileSecurity'
|
||||
import { PageLayout } from '~/components/_shared/PageLayout'
|
||||
import { useLocalize } from '~/context/localize'
|
||||
import { useSession } from '~/context/session'
|
||||
import { DEFAULT_HEADER_OFFSET, useSnackbar, useUI } from '~/context/ui'
|
||||
import { validateEmail } from '~/utils/validateEmail'
|
||||
import styles from './Settings.module.scss'
|
||||
import { ProfileProvider } from '~/context/profile'
|
||||
|
||||
type FormField = 'oldPassword' | 'newPassword' | 'newPasswordConfirm' | 'email'
|
||||
type FormData = Record<FormField, string | undefined>
|
||||
export default () => {
|
||||
const { t } = useLocalize()
|
||||
const { updateProfile, session, isSessionLoaded } = useSession()
|
||||
const { showSnackbar } = useSnackbar()
|
||||
const { showConfirm } = useUI()
|
||||
const [newPasswordError, setNewPasswordError] = createSignal<string | undefined>()
|
||||
const [oldPasswordError, setOldPasswordError] = createSignal<string | undefined>()
|
||||
const [emailError, setEmailError] = createSignal<string | undefined>()
|
||||
const [isSubmitting, setIsSubmitting] = createSignal<boolean>()
|
||||
const [isFloatingPanelVisible, setIsFloatingPanelVisible] = createSignal(false)
|
||||
|
||||
const initialState = {
|
||||
oldPassword: undefined,
|
||||
newPassword: undefined,
|
||||
newPasswordConfirm: undefined,
|
||||
email: undefined
|
||||
} as FormData
|
||||
|
||||
const [formData, setFormData] = createSignal(initialState)
|
||||
let oldPasswordRef: HTMLDivElement | undefined
|
||||
let newPasswordRepeatRef: HTMLDivElement | undefined
|
||||
|
||||
createEffect(
|
||||
on(
|
||||
() => session()?.user?.email,
|
||||
(email) => {
|
||||
setFormData((prevData: FormData) => ({ ...prevData, email }) as FormData)
|
||||
}
|
||||
)
|
||||
)
|
||||
const handleInputChange = (name: FormField, value: string) => {
|
||||
if (
|
||||
name === 'email' ||
|
||||
(name === 'newPasswordConfirm' && value && value?.length > 0 && !emailError() && !newPasswordError())
|
||||
) {
|
||||
setIsFloatingPanelVisible(true)
|
||||
} else {
|
||||
setIsFloatingPanelVisible(false)
|
||||
}
|
||||
setFormData((prevData) => ({
|
||||
...prevData,
|
||||
[name]: value
|
||||
}))
|
||||
}
|
||||
|
||||
const handleCancel = async () => {
|
||||
const isConfirmed = await showConfirm({
|
||||
confirmBody: t('Do you really want to reset all changes?'),
|
||||
confirmButtonVariant: 'primary',
|
||||
declineButtonVariant: 'secondary'
|
||||
})
|
||||
if (isConfirmed) {
|
||||
setEmailError()
|
||||
setFormData({
|
||||
...initialState,
|
||||
['email']: session()?.user?.email
|
||||
})
|
||||
setIsFloatingPanelVisible(false)
|
||||
}
|
||||
}
|
||||
const handleChangeEmail = (_value: string) => {
|
||||
if (formData() && !validateEmail(formData()['email'] || '')) {
|
||||
setEmailError(t('Invalid email'))
|
||||
return
|
||||
}
|
||||
}
|
||||
const handleCheckNewPassword = (value: string) => {
|
||||
handleInputChange('newPasswordConfirm', value)
|
||||
if (newPasswordRepeatRef && value !== formData()['newPassword']) {
|
||||
const rect = newPasswordRepeatRef.getBoundingClientRect()
|
||||
const topPosition = window.scrollY + rect.top - DEFAULT_HEADER_OFFSET * 2
|
||||
window.scrollTo({
|
||||
top: topPosition,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
showSnackbar({ type: 'error', body: t('Incorrect new password confirm') })
|
||||
setNewPasswordError(t('Passwords are not equal'))
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
setIsSubmitting(true)
|
||||
|
||||
const options: UpdateProfileInput = {
|
||||
old_password: formData()['oldPassword'],
|
||||
new_password: formData()['newPassword'] || formData()['oldPassword'],
|
||||
confirm_new_password: formData()['newPassword'] || formData()['oldPassword'],
|
||||
email: formData()['email']
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await updateProfile(options)
|
||||
if (result) {
|
||||
// FIXME: const { errors } = result
|
||||
if (oldPasswordRef) {
|
||||
// && errors.some((obj: Error) => obj.message === 'incorrect old password')) {
|
||||
setOldPasswordError(t('Incorrect old password'))
|
||||
showSnackbar({ type: 'error', body: t('Incorrect old password') })
|
||||
const rect = oldPasswordRef.getBoundingClientRect()
|
||||
const topPosition = window.scrollY + rect.top - DEFAULT_HEADER_OFFSET * 2
|
||||
window.scrollTo({
|
||||
top: topPosition,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
setIsFloatingPanelVisible(false)
|
||||
}
|
||||
return
|
||||
}
|
||||
showSnackbar({ type: 'success', body: t('Profile successfully saved') })
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
setIsSubmitting(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<PageLayout withPadding={true} title={`${t('Discours')} :: ${t('Security')}`}>
|
||||
<AuthGuard>
|
||||
<Show when={isSessionLoaded()} fallback={<Loading />}>
|
||||
<div class="wide-container">
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<div class={clsx('left-navigation', styles.leftNavigation)}>
|
||||
<ProfileSettingsNavigation />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-19">
|
||||
<div class="row">
|
||||
<div class="col-md-20 col-lg-18 col-xl-16">
|
||||
<h1>{t('Login and security')}</h1>
|
||||
<p class="description">
|
||||
{t('Settings for account, email, password and login methods.')}
|
||||
</p>
|
||||
|
||||
<form>
|
||||
<h4>{t('Email')}</h4>
|
||||
<div class="pretty-form__item">
|
||||
<input
|
||||
type="text"
|
||||
name="email"
|
||||
id="email"
|
||||
disabled={isSubmitting()}
|
||||
value={formData()['email'] || ''}
|
||||
placeholder={t('Email')}
|
||||
onFocus={() => setEmailError()}
|
||||
onInput={(event) => handleChangeEmail(event.target.value)}
|
||||
/>
|
||||
<label for="email">{t('Email')}</label>
|
||||
<Show when={emailError()}>
|
||||
<div
|
||||
class={clsx(styles.emailValidationError, {
|
||||
'form-message--error': emailError()
|
||||
})}
|
||||
>
|
||||
{emailError()}
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
|
||||
<h4>{t('Change password')}</h4>
|
||||
<h5>{t('Current password')}</h5>
|
||||
|
||||
<div ref={(el: HTMLDivElement) => (oldPasswordRef = el)}>
|
||||
<PasswordField
|
||||
onFocus={() => setOldPasswordError()}
|
||||
setError={oldPasswordError()}
|
||||
onInput={(value) => handleInputChange('oldPassword', value)}
|
||||
value={formData()['oldPassword'] || undefined}
|
||||
disabled={isSubmitting()}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<h5>{t('New password')}</h5>
|
||||
<PasswordField
|
||||
onInput={(value) => {
|
||||
handleInputChange('newPassword', value)
|
||||
handleInputChange('newPasswordConfirm', '')
|
||||
}}
|
||||
value={formData()['newPassword'] ?? ''}
|
||||
disabled={isSubmitting()}
|
||||
disableAutocomplete={true}
|
||||
/>
|
||||
|
||||
<h5>{t('Confirm your new password')}</h5>
|
||||
<div ref={(el) => (newPasswordRepeatRef = el)}>
|
||||
<PasswordField
|
||||
noValidate={true}
|
||||
value={formData?.()['newPasswordConfirm']}
|
||||
onFocus={() => setNewPasswordError()}
|
||||
setError={newPasswordError()}
|
||||
onInput={(value) => handleCheckNewPassword(value)}
|
||||
disabled={isSubmitting()}
|
||||
disableAutocomplete={true}
|
||||
/>
|
||||
</div>
|
||||
<h4>{t('Social networks')}</h4>
|
||||
<h5>Google</h5>
|
||||
<div class="pretty-form__item">
|
||||
<p>
|
||||
<button
|
||||
class={clsx('button', 'button--light', styles.socialButton)}
|
||||
type="button"
|
||||
>
|
||||
<Icon name="google" class={styles.icon} />
|
||||
{t('Connect')}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h5>VK</h5>
|
||||
<div class="pretty-form__item">
|
||||
<p>
|
||||
<button
|
||||
class={clsx(styles.socialButton, 'button', 'button--light')}
|
||||
type="button"
|
||||
>
|
||||
<Icon name="vk" class={styles.icon} />
|
||||
{t('Connect')}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h5>Facebook</h5>
|
||||
<div class="pretty-form__item">
|
||||
<p>
|
||||
<button
|
||||
class={clsx(styles.socialButton, 'button', 'button--light')}
|
||||
type="button"
|
||||
>
|
||||
<Icon name="facebook" class={styles.icon} />
|
||||
{t('Connect')}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h5>Apple</h5>
|
||||
<div class="pretty-form__item">
|
||||
<p>
|
||||
<button
|
||||
class={clsx(
|
||||
styles.socialButton,
|
||||
styles.socialButtonApple,
|
||||
'button' + ' button--light'
|
||||
)}
|
||||
type="button"
|
||||
>
|
||||
<Icon name="apple" class={styles.icon} />
|
||||
{t('Connect')}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<Show when={isFloatingPanelVisible() && !emailError() && !newPasswordError()}>
|
||||
<div class={styles.formActions}>
|
||||
<div class="wide-container">
|
||||
<div class="row">
|
||||
<div class="col-md-19 offset-md-5">
|
||||
<div class="row">
|
||||
<div class="col-md-20 col-lg-18 col-xl-16">
|
||||
<div class={styles.content}>
|
||||
<Button
|
||||
class={styles.cancel}
|
||||
variant="light"
|
||||
value={
|
||||
<>
|
||||
<span class={styles.cancelLabel}>{t('Cancel changes')}</span>
|
||||
<span class={styles.cancelLabelMobile}>{t('Cancel')}</span>
|
||||
</>
|
||||
}
|
||||
onClick={handleCancel}
|
||||
/>
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
variant="primary"
|
||||
disabled={isSubmitting()}
|
||||
value={isSubmitting() ? t('Saving...') : t('Save settings')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
<ProfileProvider>
|
||||
<ProfileSecurityView />
|
||||
</ProfileProvider>
|
||||
</AuthGuard>
|
||||
</PageLayout>
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { AuthGuard } from '~/components/AuthGuard'
|
||||
import { ProfileSubscriptions } from '~/components/Views/ProfileSubscriptions'
|
||||
import { ProfileSubscriptions } from '~/components/Views/Profile/ProfileSubscriptions'
|
||||
import { PageLayout } from '~/components/_shared/PageLayout'
|
||||
import { useLocalize } from '~/context/localize'
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user