parent
a31d70003a
commit
5d5f4ccfdf
3
public/icons/social-facebook.svg
Normal file
3
public/icons/social-facebook.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.3459 13.1364H8.69673V22.1618C8.69673 22.34 8.85155 22.4844 9.04263 22.4844H13.0285C13.2196 22.4844 13.3744 22.34 13.3744 22.1618V13.1789H16.0769C16.2526 13.1789 16.4005 13.0559 16.4205 12.8931L16.831 9.57044C16.8423 9.47902 16.8112 9.38747 16.7456 9.31889C16.68 9.25025 16.586 9.21096 16.4874 9.21096H13.3746V7.12812C13.3746 6.50025 13.7371 6.18186 14.4521 6.18186C14.554 6.18186 16.4874 6.18186 16.4874 6.18186C16.6785 6.18186 16.8333 6.03741 16.8333 5.85928V2.80934C16.8333 2.63115 16.6785 2.48676 16.4874 2.48676H13.6825C13.6627 2.48586 13.6188 2.48438 13.554 2.48438C13.0673 2.48438 11.3757 2.57347 10.0394 3.71992C8.55878 4.99038 8.76459 6.51154 8.81378 6.77528V9.21089H6.3459C6.15483 9.21089 6 9.35528 6 9.53347V12.8137C6 12.9919 6.15483 13.1364 6.3459 13.1364Z" fill="#141414"/>
|
||||
</svg>
|
After Width: | Height: | Size: 901 B |
5
public/icons/social-instagram.svg
Normal file
5
public/icons/social-instagram.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="vk logo">
|
||||
<path id="Vector" d="M14.88 12.4844C14.88 13.054 14.7111 13.6108 14.3946 14.0844C14.0782 14.558 13.6284 14.9272 13.1021 15.1451C12.5759 15.3631 11.9968 15.4202 11.4381 15.309C10.8795 15.1979 10.3663 14.9236 9.96353 14.5208C9.56076 14.1181 9.28646 13.6049 9.17534 13.0462C9.06421 12.4876 9.12125 11.9085 9.33923 11.3822C9.55721 10.856 9.92634 10.4062 10.4 10.0897C10.8736 9.77328 11.4304 9.60438 12 9.60438C12.7636 9.60525 13.4956 9.90896 14.0355 10.4489C14.5754 10.9888 14.8791 11.7208 14.88 12.4844ZM21 8.52437V16.4444C20.9985 17.7806 20.467 19.0617 19.5221 20.0065C18.5773 20.9514 17.2962 21.4829 15.96 21.4844H8.04C6.70377 21.4829 5.42271 20.9514 4.47785 20.0065C3.533 19.0617 3.00151 17.7806 3 16.4444V8.52437C3.00151 7.18815 3.533 5.90708 4.47785 4.96223C5.42271 4.01737 6.70377 3.48589 8.04 3.48438H15.96C17.2962 3.48589 18.5773 4.01737 19.5221 4.96223C20.467 5.90708 20.9985 7.18815 21 8.52437ZM16.32 12.4844C16.32 11.63 16.0666 10.7947 15.5919 10.0843C15.1173 9.37389 14.4426 8.82019 13.6532 8.49322C12.8638 8.16625 11.9952 8.0807 11.1572 8.24738C10.3192 8.41407 9.54946 8.82551 8.9453 9.42967C8.34114 10.0338 7.9297 10.8036 7.76301 11.6416C7.59632 12.4796 7.68187 13.3482 8.00884 14.1376C8.33581 14.9269 8.88952 15.6016 9.59994 16.0763C10.3104 16.551 11.1456 16.8044 12 16.8044C13.1453 16.8031 14.2434 16.3475 15.0533 15.5376C15.8631 14.7278 16.3187 13.6297 16.32 12.4844ZM17.76 7.80438C17.76 7.59077 17.6967 7.38196 17.578 7.20436C17.4593 7.02675 17.2906 6.88833 17.0933 6.80659C16.896 6.72484 16.6788 6.70345 16.4693 6.74513C16.2598 6.7868 16.0674 6.88966 15.9163 7.0407C15.7653 7.19174 15.6624 7.38418 15.6208 7.59368C15.5791 7.80318 15.6005 8.02033 15.6822 8.21767C15.764 8.41502 15.9024 8.58369 16.08 8.70236C16.2576 8.82103 16.4664 8.88438 16.68 8.88438C16.9664 8.88438 17.2411 8.77059 17.4437 8.56805C17.6462 8.36551 17.76 8.09081 17.76 7.80438Z" fill="black"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
7
public/icons/social-linkedin.svg
Normal file
7
public/icons/social-linkedin.svg
Normal file
|
@ -0,0 +1,7 @@
|
|||
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="linkedin">
|
||||
<g id="Group">
|
||||
<path id="Vector" d="M6.93855 21.4004V9.51472H2.99144V21.4004H6.93896H6.93855ZM4.96582 7.89221C6.34197 7.89221 7.19872 6.97953 7.19872 5.83894C7.17296 4.67236 6.34197 3.78516 4.99199 3.78516C3.64109 3.78516 2.75879 4.67236 2.75879 5.83884C2.75879 6.97943 3.61522 7.89211 4.93996 7.89211H4.96551L4.96582 7.89221ZM9.12333 21.4004H13.0701V14.7636C13.0701 14.4089 13.0959 14.0532 13.2002 13.7998C13.4854 13.0897 14.1348 12.3548 15.2254 12.3548C16.6533 12.3548 17.2248 13.4446 17.2248 15.0426V21.4004H21.1715V14.5855C21.1715 10.9349 19.2246 9.23607 16.6278 9.23607C14.4987 9.23607 13.5637 10.4271 13.0442 11.2383H13.0704V9.51513H9.12353C9.17505 10.6302 9.12322 21.4008 9.12322 21.4008L9.12333 21.4004Z" fill="black"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 859 B |
5
public/icons/social-telegram.svg
Normal file
5
public/icons/social-telegram.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="telegram logo">
|
||||
<path id="Icon" d="M2.35326 12.1563L6.96167 13.7367L8.7454 19.0076C8.85953 19.3452 9.3088 19.4699 9.607 19.2459L12.1758 17.3218C12.4451 17.1202 12.8286 17.1101 13.11 17.2978L17.7432 20.3886C18.0622 20.6016 18.5141 20.441 18.5941 20.0869L21.9882 5.08587C22.0756 4.69898 21.6618 4.37623 21.2609 4.51871L2.34786 11.2226C1.88113 11.388 1.88519 11.9952 2.35326 12.1563ZM8.45793 12.8954L17.4645 7.79852C17.6263 7.70719 17.7929 7.90829 17.6539 8.02676L10.2209 14.3753C9.9596 14.5988 9.79107 14.8978 9.74334 15.2224L9.49014 16.9465C9.4566 17.1767 9.10467 17.1996 9.03553 16.9768L8.06173 13.8328C7.9502 13.4742 8.11273 13.0912 8.45793 12.8954Z" fill="#141414"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 784 B |
3
public/icons/social-vk.svg
Normal file
3
public/icons/social-vk.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19.2129 13.7512C19.8763 14.4052 20.5765 15.0206 21.1715 15.7406C21.4344 16.0605 21.6832 16.3907 21.8736 16.762C22.1433 17.2898 21.899 17.8707 21.4303 17.9022L18.5166 17.9009C17.7652 17.9638 17.1657 17.6584 16.6616 17.1395C16.2582 16.7246 15.8846 16.2831 15.4967 15.8542C15.3377 15.6789 15.1713 15.5139 14.9724 15.3835C14.5747 15.1228 14.2294 15.2026 14.0021 15.6215C13.7706 16.0476 13.7181 16.5193 13.6954 16.9942C13.6642 17.687 13.4568 17.8691 12.7676 17.9008C11.2947 17.9709 9.89691 17.7459 8.59838 16.9957C7.45355 16.3343 6.56579 15.4006 5.79308 14.3435C4.28861 12.2852 3.13649 10.0234 2.10101 7.6983C1.86793 7.17444 2.03838 6.89324 2.6108 6.88329C3.56132 6.86464 4.5117 6.86597 5.46334 6.88196C5.84966 6.88767 6.10541 7.11141 6.25458 7.47993C6.76884 8.75675 7.39809 9.97154 8.18794 11.0975C8.39829 11.3973 8.61277 11.6971 8.9182 11.9081C9.25609 12.1417 9.51335 12.0643 9.6723 11.6842C9.77317 11.4432 9.81733 11.1837 9.84007 10.9256C9.91537 10.0376 9.92529 9.15109 9.79321 8.26621C9.71213 7.71396 9.40407 7.35645 8.85833 7.25194C8.57985 7.19866 8.62131 7.09402 8.75615 6.93352C8.99035 6.65669 9.21061 6.48438 9.6497 6.48438H12.9426C13.461 6.58769 13.5761 6.82284 13.6471 7.34955L13.6499 11.0429C13.6442 11.2468 13.7508 11.8519 14.1145 11.9869C14.4056 12.0829 14.5975 11.8478 14.7721 11.6614C15.5605 10.8165 16.1232 9.81793 16.6259 8.78396C16.849 8.32931 17.0408 7.85714 17.2267 7.38538C17.3644 7.0353 17.5806 6.86305 17.9711 6.87068L21.1403 6.87353C21.2343 6.87353 21.3294 6.87493 21.4204 6.89065C21.9544 6.98255 22.1007 7.21452 21.9358 7.74109C21.6759 8.56725 21.1703 9.25572 20.6759 9.94738C20.1473 10.6858 19.5821 11.399 19.058 12.1418C18.5764 12.8201 18.6147 13.162 19.2129 13.7512Z" fill="#141414"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,50 @@
|
|||
.SocialNetworkInput {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
height: 54px;
|
||||
border: 2px solid var(--black-100);
|
||||
border-radius: 2px;
|
||||
|
||||
.icon {
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
padding: 16px;
|
||||
border-right: 2px solid var(--black-100);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.input {
|
||||
@include font-size(1.7rem);
|
||||
|
||||
margin: 0 16px;
|
||||
width: 100%;
|
||||
border: none;
|
||||
height: 1em;
|
||||
padding: 0;
|
||||
display: block;
|
||||
flex: 1;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
color: var(--black-300);
|
||||
}
|
||||
}
|
||||
|
||||
.remove {
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
padding: 16px;
|
||||
&:hover {
|
||||
background: var(--background-color-invert);
|
||||
img {
|
||||
filter: invert(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
import { clsx } from 'clsx'
|
||||
import styles from './SocialNetworkInput.module.scss'
|
||||
import { Icon } from '../Icon'
|
||||
import { onMount, Show } from 'solid-js'
|
||||
|
||||
type Props = {
|
||||
class?: string
|
||||
network?: string
|
||||
link?: string
|
||||
isExist: boolean
|
||||
handleChange: (value: string) => void
|
||||
handleDelete?: () => void
|
||||
slug?: string
|
||||
autofocus?: boolean
|
||||
}
|
||||
|
||||
export const SocialNetworkInput = (props: Props) => {
|
||||
const inputRef: { current: HTMLInputElement } = { current: null }
|
||||
onMount(() => {
|
||||
if (props.autofocus) {
|
||||
inputRef.current.focus()
|
||||
}
|
||||
})
|
||||
return (
|
||||
<div class={clsx(styles.SocialNetworkInput, props.class)}>
|
||||
<div class={styles.icon}>
|
||||
<Icon name={props.network ? `social-${props.network}` : 'user-link-default'} />
|
||||
</div>
|
||||
<input
|
||||
ref={(el) => (inputRef.current = el)}
|
||||
class={styles.input}
|
||||
type="text"
|
||||
value={props.isExist ? props.link : null}
|
||||
onChange={(event) => props.handleChange(event.currentTarget.value)}
|
||||
placeholder={props.autofocus ? null : `${props.link}${props.slug}`}
|
||||
/>
|
||||
<Show when={props.isExist}>
|
||||
<button type="button" onClick={props.handleDelete}>
|
||||
<Icon name="remove" class={styles.remove} />
|
||||
</button>
|
||||
</Show>
|
||||
</div>
|
||||
)
|
||||
}
|
1
src/components/_shared/SocialNetworkInput/index.ts
Normal file
1
src/components/_shared/SocialNetworkInput/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export { SocialNetworkInput } from './SocialNetworkInput'
|
|
@ -49,7 +49,7 @@ export const ArticleCardSwiper = (props: Props) => {
|
|||
speed={800}
|
||||
autoplay={{
|
||||
disableOnInteraction: false,
|
||||
delay: 3000,
|
||||
delay: 6000,
|
||||
pauseOnMouseEnter: true
|
||||
}}
|
||||
>
|
||||
|
|
|
@ -69,6 +69,10 @@ const useProfileForm = () => {
|
|||
})
|
||||
}
|
||||
}
|
||||
createEffect(() => {
|
||||
console.log('!!! FL:', form.links)
|
||||
})
|
||||
|
||||
return { form, submit, updateFormField, slugError }
|
||||
}
|
||||
|
||||
|
|
|
@ -215,3 +215,7 @@ h5 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.socialInput {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { PageLayout } from '../../components/_shared/PageLayout'
|
||||
import { Icon } from '../../components/_shared/Icon'
|
||||
import { ProfileSettingsNavigation } from '../../components/Nav/ProfileSettingsNavigation'
|
||||
import { For, createSignal, Show, onMount, onCleanup, createEffect } from 'solid-js'
|
||||
import deepEqual from 'fast-deep-equal'
|
||||
|
@ -19,11 +18,14 @@ import SimplifiedEditor from '../../components/Editor/SimplifiedEditor'
|
|||
import { GrowingTextarea } from '../../components/_shared/GrowingTextarea'
|
||||
import { AuthGuard } from '../../components/AuthGuard'
|
||||
import { handleImageUpload } from '../../utils/handleImageUpload'
|
||||
import { SocialNetworkInput } from '../../components/_shared/SocialNetworkInput'
|
||||
import { profileSocialLinks } from '../../utils/profileSocialLinks'
|
||||
|
||||
export const ProfileSettingsPage = () => {
|
||||
const { t } = useLocalize()
|
||||
const [addLinkForm, setAddLinkForm] = createSignal<boolean>(false)
|
||||
const [incorrectUrl, setIncorrectUrl] = createSignal<boolean>(false)
|
||||
|
||||
const [isUserpicUpdating, setIsUserpicUpdating] = createSignal(false)
|
||||
const [uploadError, setUploadError] = createSignal(false)
|
||||
const [isFloatingPanelVisible, setIsFloatingPanelVisible] = createSignal(false)
|
||||
|
@ -38,7 +40,7 @@ export const ProfileSettingsPage = () => {
|
|||
|
||||
const { form, updateFormField, submit, slugError } = useProfileForm()
|
||||
const [prevForm, setPrevForm] = createStore(clone(form))
|
||||
|
||||
const [social, setSocial] = createSignal(form.links)
|
||||
const handleChangeSocial = (value: string) => {
|
||||
if (validateUrl(value)) {
|
||||
updateFormField('links', value)
|
||||
|
@ -108,6 +110,14 @@ export const ProfileSettingsPage = () => {
|
|||
}
|
||||
})
|
||||
|
||||
const handleDeleteSocialLink = (link) => {
|
||||
updateFormField('links', link, true)
|
||||
}
|
||||
|
||||
createEffect(() => {
|
||||
setSocial(form.links)
|
||||
})
|
||||
|
||||
return (
|
||||
<PageLayout>
|
||||
<AuthGuard>
|
||||
|
@ -230,27 +240,26 @@ export const ProfileSettingsPage = () => {
|
|||
</button>
|
||||
</div>
|
||||
<Show when={addLinkForm()}>
|
||||
<div class={styles.multipleControlsItem}>
|
||||
<input
|
||||
autofocus={true}
|
||||
type="text"
|
||||
name="link"
|
||||
class="nolabel"
|
||||
onChange={(event) => handleChangeSocial(event.currentTarget.value)}
|
||||
/>
|
||||
</div>
|
||||
<SocialNetworkInput
|
||||
isExist={false}
|
||||
autofocus={true}
|
||||
handleChange={(value) => handleChangeSocial(value)}
|
||||
/>
|
||||
<Show when={incorrectUrl()}>
|
||||
<p class="form-message form-message--error">{t('It does not look like url')}</p>
|
||||
</Show>
|
||||
</Show>
|
||||
<For each={form.links}>
|
||||
{(link) => (
|
||||
<div class={styles.multipleControlsItem}>
|
||||
<input type="text" value={link} readonly={true} name="link" class="nolabel" />
|
||||
<button type="button" onClick={() => updateFormField('links', link, true)}>
|
||||
<Icon name="remove" class={styles.icon} />
|
||||
</button>
|
||||
</div>
|
||||
<For each={profileSocialLinks(social())}>
|
||||
{(network) => (
|
||||
<SocialNetworkInput
|
||||
class={styles.socialInput}
|
||||
link={network.link}
|
||||
network={network.name}
|
||||
handleChange={(value) => handleChangeSocial(value)}
|
||||
isExist={!network.isPlaceholder}
|
||||
slug={form.slug}
|
||||
handleDelete={() => handleDeleteSocialLink(network.link)}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
|
|
50
src/utils/profileSocialLinks.ts
Normal file
50
src/utils/profileSocialLinks.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
type Link = {
|
||||
link: string
|
||||
isPlaceholder: boolean
|
||||
name?: string
|
||||
}
|
||||
|
||||
const links: Link[] = [
|
||||
{ link: 'https://facebook.com/', name: 'facebook', isPlaceholder: true },
|
||||
{ link: 'https://linkedin.com/', name: 'linkedin', isPlaceholder: true },
|
||||
{ link: 'https://vk.com/', name: 'vk', isPlaceholder: true },
|
||||
{ link: 'https://instagram.com/', name: 'instagram', isPlaceholder: true },
|
||||
{ link: 'https://t.me/', name: 'telegram', isPlaceholder: true }
|
||||
]
|
||||
|
||||
const checkLink = (link: string, keyword: string): boolean => link.includes(keyword)
|
||||
|
||||
export const profileSocialLinks = (socialLinks: string[]): Link[] => {
|
||||
const processedLinks: Link[] = []
|
||||
let unmatchedLinks: string[] = [...socialLinks]
|
||||
|
||||
links.forEach((linkObj) => {
|
||||
let linkMatched = false
|
||||
|
||||
socialLinks.forEach((serverLink) => {
|
||||
if (checkLink(serverLink, new URL(linkObj.link).hostname.replace('www.', ''))) {
|
||||
processedLinks.push({ ...linkObj, link: serverLink, isPlaceholder: false })
|
||||
linkMatched = true
|
||||
unmatchedLinks = unmatchedLinks.filter((unmatchedLink) => unmatchedLink !== serverLink)
|
||||
}
|
||||
})
|
||||
|
||||
if (!linkMatched) {
|
||||
processedLinks.push({ ...linkObj, isPlaceholder: true })
|
||||
}
|
||||
})
|
||||
|
||||
unmatchedLinks.forEach((unmatchedLink) => {
|
||||
processedLinks.push({ link: unmatchedLink, isPlaceholder: false })
|
||||
})
|
||||
|
||||
return processedLinks.sort((a, b) => {
|
||||
if (a.isPlaceholder && !b.isPlaceholder) {
|
||||
return 1
|
||||
} else if (!a.isPlaceholder && b.isPlaceholder) {
|
||||
return -1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user