Update profile post

This commit is contained in:
ilya-bkv 2022-12-01 20:16:14 +03:00
parent 7b0bac4eca
commit 22ede100e5
4 changed files with 147 additions and 68 deletions

View File

@ -3,34 +3,25 @@ import { t } from '../../../utils/intl'
import type { PageProps } from '../../types' import type { PageProps } from '../../types'
import { Icon } from '../../_shared/Icon' import { Icon } from '../../_shared/Icon'
import ProfileSettingsNavigation from '../../Discours/ProfileSettingsNavigation' import ProfileSettingsNavigation from '../../Discours/ProfileSettingsNavigation'
import { useSession } from '../../../context/session' import { For, createSignal, Show } from 'solid-js'
import { createMemo, For, createSignal, Show, createEffect } from 'solid-js'
import { loadAuthor, useAuthorsStore } from '../../../stores/zine/authors'
import type { Author } from '../../../graphql/types.gen'
import { clsx } from 'clsx' import { clsx } from 'clsx'
import styles from './Settings.module.scss' import styles from './Settings.module.scss'
import { useProfileForm } from '../../../context/profile'
export const ProfileSettingsPage = (props: PageProps) => { export const ProfileSettingsPage = (props: PageProps) => {
const [author, setAuthor] = createSignal<Author>(null) const [addLinkForm, setAddLinkForm] = createSignal<boolean>(false)
const { session } = useSession() const { form, updateFormField, submit } = useProfileForm()
const currentSlug = createMemo(() => session()?.user?.slug) const handleChangeSocial = (value) => {
const { authorEntities } = useAuthorsStore({ authors: [] }) updateFormField('links', value)
const currentAuthor = createMemo(() => authorEntities()[currentSlug()]) setAddLinkForm(false)
}
createEffect(async () => { const handleSubmit = (event: Event): void => {
if (!currentSlug()) return event.preventDefault()
try { submit(form)
await loadAuthor({ slug: currentSlug() })
setAuthor(currentAuthor())
console.log('!!! currentAuthor:', currentAuthor())
} catch (error) {
console.error(error)
} }
})
return ( return (
<PageWrap> <PageWrap>
<Show when={author()}> <Show when={form}>
<div class="wide-container"> <div class="wide-container">
<div class="shift-content"> <div class="shift-content">
<div class="left-col"> <div class="left-col">
@ -42,11 +33,11 @@ export const ProfileSettingsPage = (props: PageProps) => {
<div class="col-md-10 col-lg-9 col-xl-8"> <div class="col-md-10 col-lg-9 col-xl-8">
<h1>{t('Profile settings')}</h1> <h1>{t('Profile settings')}</h1>
<p class="description">{t('Here you can customize your profile the way you want.')}</p> <p class="description">{t('Here you can customize your profile the way you want.')}</p>
<form> <form onSubmit={handleSubmit}>
<h4>{t('Userpic')}</h4> <h4>{t('Userpic')}</h4>
<div class="pretty-form__item"> <div class="pretty-form__item">
<div class={styles.avatarContainer}> <div class={styles.avatarContainer}>
<img class={styles.avatar} src={author().userpic} /> <img class={styles.avatar} src={form.userpic} alt={form.name} />
<input <input
type="file" type="file"
name="avatar" name="avatar"
@ -55,7 +46,6 @@ export const ProfileSettingsPage = (props: PageProps) => {
/> />
</div> </div>
</div> </div>
<h4>{t('Name')}</h4> <h4>{t('Name')}</h4>
<p class="description"> <p class="description">
{t( {t(
@ -67,8 +57,9 @@ export const ProfileSettingsPage = (props: PageProps) => {
type="text" type="text"
name="username" name="username"
id="username" id="username"
placeholder="Имя" placeholder={t('Name')}
value={author().name} onChange={(event) => updateFormField('name', event.currentTarget.value)}
value={form.name}
/> />
<label for="username">Имя</label> <label for="username">Имя</label>
</div> </div>
@ -82,7 +73,8 @@ export const ProfileSettingsPage = (props: PageProps) => {
type="text" type="text"
name="user-address" name="user-address"
id="user-address" id="user-address"
value={currentSlug()} onChange={(event) => updateFormField('slug', event.currentTarget.value)}
value={form.slug}
class="nolabel" class="nolabel"
/> />
<p class="form-message form-message--error"> <p class="form-message form-message--error">
@ -92,52 +84,70 @@ export const ProfileSettingsPage = (props: PageProps) => {
</div> </div>
</div> </div>
<h4>{t('Introduce')}</h4> {/*Нет реализации полей на бэке*/}
<div class="pretty-form__item"> {/*<h4>{t('Introduce')}</h4>*/}
<textarea name="presentation" id="presentation" placeholder="Представление" /> {/*<div class="pretty-form__item">*/}
<label for="presentation">{t('Introduce')}</label> {/* <textarea name="presentation" id="presentation" placeholder={t('Introduce')} />*/}
</div> {/* <label for="presentation">{t('Introduce')}</label>*/}
{/*</div>*/}
<h4>{t('About myself')}</h4> <h4>{t('About myself')}</h4>
<div class="pretty-form__item"> <div class="pretty-form__item">
<textarea name="about" id="about" placeholder="О себе"> <textarea
{author().bio} name="about"
</textarea> id="about"
placeholder={t('About myself')}
value={form.bio}
onChange={(event) => updateFormField('bio', event.currentTarget.value)}
/>
<label for="about">{t('About myself')}</label> <label for="about">{t('About myself')}</label>
</div> </div>
<h4>{t('How can I help/skills')}</h4> {/*Нет реализации полей на бэке*/}
<div class="pretty-form__item"> {/*<h4>{t('How can I help/skills')}</h4>*/}
<input type="text" name="skills" id="skills" /> {/*<div class="pretty-form__item">*/}
</div> {/* <input type="text" name="skills" id="skills" />*/}
{/*</div>*/}
{/*<h4>{t('Where')}</h4>*/}
{/*<div class="pretty-form__item">*/}
{/* <input type="text" name="location" id="location" placeholder="Откуда" />*/}
{/* <label for="location">{t('Where')}</label>*/}
{/*</div>*/}
<h4>{t('Where')}</h4> {/*<h4>{t('Date of Birth')}</h4>*/}
<div class="pretty-form__item"> {/*<div class="pretty-form__item">*/}
<input type="text" name="location" id="location" placeholder="Откуда" /> {/* <input*/}
<label for="location">{t('Where')}</label> {/* type="date"*/}
</div> {/* name="birthdate"*/}
{/* id="birthdate"*/}
<h4>{t('Date of Birth')}</h4> {/* placeholder="Дата рождения"*/}
<div class="pretty-form__item"> {/* class="nolabel"*/}
<input {/* />*/}
type="date" {/*</div>*/}
name="birthdate"
id="birthdate"
placeholder="Дата рождения"
class="nolabel"
/>
</div>
<div class={clsx(styles.multipleControls, 'pretty-form__item')}> <div class={clsx(styles.multipleControls, 'pretty-form__item')}>
<div class={styles.multipleControlsHeader}> <div class={styles.multipleControlsHeader}>
<h4>{t('Social networks')}</h4> <h4>{t('Social networks')}</h4>
<button class="button">+</button> <button type="button" class="button" onClick={() => setAddLinkForm(!addLinkForm())}>
+
</button>
</div> </div>
<For each={author().links}> <Show when={addLinkForm()}>
<div class={styles.multipleControlsItem}>
<input
autofocus={true}
type="text"
name="link"
class="nolabel"
onChange={(event) => handleChangeSocial(event.currentTarget.value)}
/>
</div>
</Show>
<For each={form.links}>
{(link) => ( {(link) => (
<div class={styles.multipleControlsItem}> <div class={styles.multipleControlsItem}>
<input type="text" value={link} name="social1" class="nolabel" /> <input type="text" value={link} readonly={true} name="link" class="nolabel" />
<button> <button type="button" onClick={() => updateFormField('links', link, true)}>
<Icon name="remove" class={styles.icon} /> <Icon name="remove" class={styles.icon} />
</button> </button>
</div> </div>
@ -147,12 +157,15 @@ export const ProfileSettingsPage = (props: PageProps) => {
<br /> <br />
<p> <p>
<button class="button button--submit">{t('Save settings')}</button> <button type="submit" class="button button--submit">
{t('Save settings')}
</button>
</p> </p>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
<pre>{JSON.stringify(form, null, 2)}</pre>
</div> </div>
</Show> </Show>
</PageWrap> </PageWrap>

61
src/context/profile.tsx Normal file
View File

@ -0,0 +1,61 @@
import { createEffect, createMemo } from 'solid-js'
import { createStore } from 'solid-js/store'
import { useSession } from './session'
import { loadAuthor, useAuthorsStore } from '../stores/zine/authors'
import { apiClient } from '../utils/apiClient'
import type { ProfileInput } from '../graphql/types.gen'
const submit = async (profile: ProfileInput) => {
try {
await apiClient.updateProfile(profile)
} catch (error) {
console.error(error)
}
}
const useProfileForm = () => {
const { session } = useSession()
const currentSlug = createMemo(() => session()?.user?.slug)
const { authorEntities } = useAuthorsStore({ authors: [] })
const currentAuthor = createMemo(() => authorEntities()[currentSlug()])
const [form, setForm] = createStore<ProfileInput>({
name: '',
bio: '',
userpic: '',
links: []
})
createEffect(async () => {
if (!currentSlug()) return
try {
await loadAuthor({ slug: currentSlug() })
setForm({
name: currentAuthor()?.name,
bio: currentAuthor()?.bio,
userpic: currentAuthor()?.userpic,
links: currentAuthor()?.links
})
} catch (error) {
console.error(error)
}
})
const updateFormField = (fieldName: string, value: string, remove?: boolean) => {
if (fieldName === 'links') {
if (remove) {
setForm((prev) => ({ ...prev, links: [...prev?.links.filter((item) => item !== value)] }))
} else {
setForm((prev) => ({ ...prev, links: [...prev?.links, value] }))
}
} else {
setForm({
[fieldName]: value
})
}
}
return { form, submit, updateFormField }
}
export { useProfileForm }

View File

@ -2,17 +2,15 @@ import { gql } from '@urql/core'
// WARNING: need Auth header // WARNING: need Auth header
export default gql` export default gql`
mutation ProfileUpdateMutation($user: User!) { mutation ProfileUpdateMutation($profile: ProfileInput!) {
profileUpdate(user: $user) { updateProfile(profile: $profile) {
error error
token author {
user {
_id: slug
name name
slug slug
userpic userpic
bio bio
# links links
} }
} }
} }

View File

@ -10,7 +10,9 @@ import type {
QueryLoadMessagesByArgs, QueryLoadMessagesByArgs,
MutationCreateChatArgs, MutationCreateChatArgs,
MutationCreateMessageArgs, MutationCreateMessageArgs,
QueryLoadRecipientsArgs QueryLoadRecipientsArgs,
User,
ProfileInput
} from '../graphql/types.gen' } from '../graphql/types.gen'
import { publicGraphQLClient } from '../graphql/publicGraphQLClient' import { publicGraphQLClient } from '../graphql/publicGraphQLClient'
import { getToken, privateGraphQLClient } from '../graphql/privateGraphQLClient' import { getToken, privateGraphQLClient } from '../graphql/privateGraphQLClient'
@ -42,6 +44,7 @@ import shoutsLoadBy from '../graphql/query/articles-load-by'
import shoutLoad from '../graphql/query/article-load' import shoutLoad from '../graphql/query/article-load'
import loadRecipients from '../graphql/query/chat-recipients' import loadRecipients from '../graphql/query/chat-recipients'
import createMessage from '../graphql/mutation/create-chat-message' import createMessage from '../graphql/mutation/create-chat-message'
import updateProfile from '../graphql/mutation/update-profile'
type ApiErrorCode = type ApiErrorCode =
| 'unknown' | 'unknown'
@ -213,6 +216,10 @@ export const apiClient = {
console.debug('getAuthor', response) console.debug('getAuthor', response)
return response.data.getAuthor return response.data.getAuthor
}, },
updateProfile: async (options: ProfileInput) => {
const response = await privateGraphQLClient.mutation(updateProfile, options).toPromise()
console.debug('updateProfile', response)
},
getTopic: async ({ slug }: { slug: string }): Promise<Topic> => { getTopic: async ({ slug }: { slug: string }): Promise<Topic> => {
const response = await publicGraphQLClient.query(topicBySlug, { slug }).toPromise() const response = await publicGraphQLClient.query(topicBySlug, { slug }).toPromise()
return response.data.getTopic return response.data.getTopic