2023-04-11 13:57:48 +00:00
|
|
|
|
import { createSignal, onMount, Show } from 'solid-js'
|
2023-02-17 09:21:02 +00:00
|
|
|
|
import { useLocalize } from '../../context/localize'
|
2023-03-12 20:16:20 +00:00
|
|
|
|
import { clsx } from 'clsx'
|
2023-04-11 13:57:48 +00:00
|
|
|
|
import styles from './Edit.module.scss'
|
2023-03-13 12:26:25 +00:00
|
|
|
|
import { Title } from '@solidjs/meta'
|
2023-03-23 17:15:50 +00:00
|
|
|
|
import { createStore } from 'solid-js/store'
|
2023-04-11 13:57:48 +00:00
|
|
|
|
import type { Shout, Topic } from '../../graphql/types.gen'
|
2023-03-23 17:15:50 +00:00
|
|
|
|
import { apiClient } from '../../utils/apiClient'
|
|
|
|
|
import { TopicSelect } from '../Editor/TopicSelect/TopicSelect'
|
2023-03-26 18:31:34 +00:00
|
|
|
|
import { router, useRouter } from '../../stores/router'
|
2023-04-11 13:57:48 +00:00
|
|
|
|
import { getPagePath, openPage } from '@nanostores/router'
|
2023-03-26 18:31:34 +00:00
|
|
|
|
import { translit } from '../../utils/ru2en'
|
2023-03-29 08:51:27 +00:00
|
|
|
|
import { Editor } from '../Editor/Editor'
|
2023-04-06 21:40:34 +00:00
|
|
|
|
import { Button } from '../_shared/Button'
|
|
|
|
|
import { Icon } from '../_shared/Icon'
|
2023-02-11 09:32:52 +00:00
|
|
|
|
|
2023-03-23 17:15:50 +00:00
|
|
|
|
type ShoutForm = {
|
|
|
|
|
slug: string
|
|
|
|
|
title: string
|
|
|
|
|
subtitle: string
|
2023-03-23 17:47:36 +00:00
|
|
|
|
selectedTopics: Topic[]
|
2023-04-11 13:57:48 +00:00
|
|
|
|
mainTopic: string
|
2023-03-23 17:15:50 +00:00
|
|
|
|
body: string
|
|
|
|
|
coverImageUrl: string
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-11 13:57:48 +00:00
|
|
|
|
type EditViewProps = {
|
|
|
|
|
shout: Shout
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const EditView = (props: EditViewProps) => {
|
2023-02-17 09:21:02 +00:00
|
|
|
|
const { t } = useLocalize()
|
|
|
|
|
|
2023-03-23 17:15:50 +00:00
|
|
|
|
const [topics, setTopics] = createSignal<Topic[]>(null)
|
2023-03-26 18:31:34 +00:00
|
|
|
|
const { page } = useRouter()
|
|
|
|
|
|
|
|
|
|
const [isSlugChanged, setIsSlugChanged] = createSignal(false)
|
2023-04-06 21:40:34 +00:00
|
|
|
|
const [isEditorPanelOPened, setIsEditorPanelOPened] = createSignal(false)
|
2023-03-23 17:15:50 +00:00
|
|
|
|
|
|
|
|
|
const [form, setForm] = createStore<ShoutForm>({
|
2023-04-11 13:57:48 +00:00
|
|
|
|
slug: props.shout.slug,
|
|
|
|
|
title: props.shout.title,
|
|
|
|
|
subtitle: props.shout.subtitle,
|
|
|
|
|
selectedTopics: props.shout.topics,
|
|
|
|
|
mainTopic: props.shout.mainTopic,
|
|
|
|
|
body: props.shout.body,
|
|
|
|
|
coverImageUrl: props.shout.cover
|
2023-03-23 17:15:50 +00:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
onMount(async () => {
|
|
|
|
|
const allTopics = await apiClient.getAllTopics()
|
|
|
|
|
setTopics(allTopics)
|
|
|
|
|
})
|
|
|
|
|
|
2023-03-27 14:45:07 +00:00
|
|
|
|
const handleFormSubmit = async (e) => {
|
2023-03-23 17:15:50 +00:00
|
|
|
|
e.preventDefault()
|
2023-03-27 14:45:07 +00:00
|
|
|
|
|
2023-04-11 13:57:48 +00:00
|
|
|
|
// const newShout = await apiClient.updateArticle({
|
|
|
|
|
// article: {
|
|
|
|
|
// slug: form.slug,
|
|
|
|
|
// title: form.title,
|
|
|
|
|
// subtitle: form.subtitle,
|
|
|
|
|
// body: form.body,
|
|
|
|
|
// topics: form.selectedTopics.map((topic) => topic.slug),
|
|
|
|
|
// mainTopic: form.selectedTopics[0].slug
|
|
|
|
|
// }
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
|
|
// openPage(getPagePath(router, 'article', { slug: newShout.slug }))
|
2023-03-23 17:15:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-26 18:31:34 +00:00
|
|
|
|
const handleTitleInputChange = (e) => {
|
|
|
|
|
const title = e.currentTarget.value
|
|
|
|
|
setForm('title', title)
|
|
|
|
|
|
|
|
|
|
if (!isSlugChanged()) {
|
|
|
|
|
const slug = translit(title).replaceAll(' ', '-')
|
|
|
|
|
setForm('slug', slug)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleSlugInputChange = (e) => {
|
|
|
|
|
const slug = e.currentTarget.value
|
|
|
|
|
|
|
|
|
|
if (slug !== form.slug) {
|
|
|
|
|
setIsSlugChanged(true)
|
|
|
|
|
}
|
|
|
|
|
setForm('slug', slug)
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-06 21:40:34 +00:00
|
|
|
|
const toggleEditorPanel = () => {
|
|
|
|
|
setIsEditorPanelOPened(!isEditorPanelOPened())
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 11:53:35 +00:00
|
|
|
|
return (
|
2023-04-06 21:40:34 +00:00
|
|
|
|
<>
|
|
|
|
|
<div class={styles.container}>
|
|
|
|
|
<Title>{t('Write an article')}</Title>
|
2023-03-12 20:16:20 +00:00
|
|
|
|
|
2023-04-06 21:40:34 +00:00
|
|
|
|
<form onSubmit={handleFormSubmit}>
|
|
|
|
|
<div class="wide-container">
|
2023-03-29 08:51:27 +00:00
|
|
|
|
<div class="row">
|
2023-04-06 21:40:34 +00:00
|
|
|
|
<div class="col-md-19 col-lg-18 col-xl-16 offset-md-5">
|
2023-03-29 08:51:27 +00:00
|
|
|
|
<div
|
2023-04-11 13:57:48 +00:00
|
|
|
|
class={clsx(styles.edit, {
|
|
|
|
|
[styles.visible]: page().route === 'edit'
|
2023-03-29 08:51:27 +00:00
|
|
|
|
})}
|
|
|
|
|
>
|
|
|
|
|
<input
|
|
|
|
|
class={styles.titleInput}
|
|
|
|
|
type="text"
|
|
|
|
|
name="title"
|
|
|
|
|
id="title"
|
|
|
|
|
placeholder="Заголовок"
|
|
|
|
|
value={form.title}
|
|
|
|
|
onChange={handleTitleInputChange}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<input
|
|
|
|
|
class={styles.subtitleInput}
|
|
|
|
|
type="text"
|
|
|
|
|
name="subtitle"
|
|
|
|
|
id="subtitle"
|
|
|
|
|
placeholder="Подзаголовок"
|
|
|
|
|
value={form.subtitle}
|
|
|
|
|
onChange={(e) => setForm('subtitle', e.currentTarget.value)}
|
|
|
|
|
/>
|
|
|
|
|
|
2023-04-11 13:57:48 +00:00
|
|
|
|
<Editor
|
|
|
|
|
shoutSlug={props.shout.slug}
|
|
|
|
|
initialContent={form.body}
|
|
|
|
|
onChange={(body) => setForm('body', body)}
|
|
|
|
|
/>
|
2023-03-29 08:51:27 +00:00
|
|
|
|
|
|
|
|
|
<div class={styles.saveBlock}>
|
|
|
|
|
{/*<button class={clsx('button button--outline', styles.button)}>Сохранить</button>*/}
|
2023-04-11 13:57:48 +00:00
|
|
|
|
<a href={getPagePath(router, 'editSettings', { shoutSlug: props.shout.slug })}>
|
|
|
|
|
Настройки
|
|
|
|
|
</a>
|
2023-03-29 08:51:27 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
2023-04-11 13:57:48 +00:00
|
|
|
|
class={clsx(styles.editSettings, {
|
|
|
|
|
[styles.visible]: page().route === 'editSettings'
|
2023-03-29 08:51:27 +00:00
|
|
|
|
})}
|
|
|
|
|
>
|
|
|
|
|
<h1>Настройки публикации</h1>
|
|
|
|
|
|
|
|
|
|
<h4>Slug</h4>
|
|
|
|
|
<div class="pretty-form__item">
|
2023-03-23 17:15:50 +00:00
|
|
|
|
<input
|
|
|
|
|
type="text"
|
2023-03-29 08:51:27 +00:00
|
|
|
|
name="slug"
|
|
|
|
|
id="slug"
|
|
|
|
|
value={form.slug}
|
|
|
|
|
onChange={handleSlugInputChange}
|
2023-03-23 17:15:50 +00:00
|
|
|
|
/>
|
2023-03-29 08:51:27 +00:00
|
|
|
|
<label for="slug">Slug</label>
|
2023-03-26 18:31:34 +00:00
|
|
|
|
</div>
|
2023-03-29 08:51:27 +00:00
|
|
|
|
|
|
|
|
|
{/*<h4>Лид</h4>*/}
|
|
|
|
|
{/*<div class="pretty-form__item">*/}
|
|
|
|
|
{/* <textarea name="lead" id="lead" placeholder="Лид"></textarea>*/}
|
|
|
|
|
{/* <label for="lead">Лид</label>*/}
|
|
|
|
|
{/*</div>*/}
|
|
|
|
|
|
|
|
|
|
{/*<h4>Выбор сообщества</h4>*/}
|
|
|
|
|
{/*<p class="description">Сообщества можно перечислить через запятую</p>*/}
|
|
|
|
|
{/*<div class="pretty-form__item">*/}
|
|
|
|
|
{/* <input*/}
|
|
|
|
|
{/* type="text"*/}
|
|
|
|
|
{/* name="community"*/}
|
|
|
|
|
{/* id="community"*/}
|
|
|
|
|
{/* placeholder="Сообщества"*/}
|
|
|
|
|
{/* class="nolabel"*/}
|
|
|
|
|
{/* />*/}
|
|
|
|
|
{/*</div>*/}
|
|
|
|
|
|
|
|
|
|
<h4>Темы</h4>
|
|
|
|
|
{/*<p class="description">*/}
|
|
|
|
|
{/* Добавьте несколько тем, чтобы читатель знал, о чем ваш материал, и мог найти*/}
|
|
|
|
|
{/* его на страницах интересных ему тем. Темы можно менять местами, первая тема*/}
|
|
|
|
|
{/* становится заглавной*/}
|
|
|
|
|
{/*</p>*/}
|
|
|
|
|
<div class="pretty-form__item">
|
|
|
|
|
<Show when={topics()}>
|
|
|
|
|
<TopicSelect
|
|
|
|
|
topics={topics()}
|
|
|
|
|
onChange={(newSelectedTopics) => setForm('selectedTopics', newSelectedTopics)}
|
|
|
|
|
selectedTopics={form.selectedTopics}
|
2023-03-26 18:31:34 +00:00
|
|
|
|
/>
|
2023-03-29 08:51:27 +00:00
|
|
|
|
</Show>
|
|
|
|
|
{/*<input type="text" name="topics" id="topics" placeholder="Темы" class="nolabel" />*/}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/*<h4>Соавторы</h4>*/}
|
|
|
|
|
{/*<p class="description">У каждого соавтора можно добавить роль</p>*/}
|
|
|
|
|
{/*<div class="pretty-form__item--with-button">*/}
|
|
|
|
|
{/* <div class="pretty-form__item">*/}
|
|
|
|
|
{/* <input type="text" name="authors" id="authors" placeholder="Введите имя или e-mail" />*/}
|
|
|
|
|
{/* <label for="authors">Введите имя или e-mail</label>*/}
|
|
|
|
|
{/* </div>*/}
|
|
|
|
|
{/* <button class="button button--submit">Добавить</button>*/}
|
|
|
|
|
{/*</div>*/}
|
|
|
|
|
|
|
|
|
|
{/*<div class="row">*/}
|
|
|
|
|
{/* <div class="col-md-6">Михаил Драбкин</div>*/}
|
|
|
|
|
{/* <div class="col-md-6">*/}
|
|
|
|
|
{/* <input type="text" name="coauthor" id="coauthor1" class="nolabel" />*/}
|
|
|
|
|
{/* </div>*/}
|
|
|
|
|
{/*</div>*/}
|
|
|
|
|
|
|
|
|
|
<h4>Карточка материала на главной</h4>
|
|
|
|
|
<p class="description">
|
|
|
|
|
Выберите заглавное изображение для статьи, тут сразу можно увидеть как карточка будет
|
|
|
|
|
выглядеть на главной странице
|
|
|
|
|
</p>
|
|
|
|
|
<div class={styles.articlePreview} />
|
|
|
|
|
|
|
|
|
|
<div class={styles.saveBlock}>
|
|
|
|
|
<p>
|
|
|
|
|
Проверьте ещё раз введённые данные, если всё верно, вы можете сохранить или
|
|
|
|
|
опубликовать ваш текст
|
2023-03-13 12:26:25 +00:00
|
|
|
|
</p>
|
2023-04-11 13:57:48 +00:00
|
|
|
|
<button class={clsx('button button--outline', styles.button)}>Сохранить</button>
|
|
|
|
|
<a href={getPagePath(router, 'edit', { shoutSlug: props.shout.slug })}>Назад</a>
|
2023-03-29 08:51:27 +00:00
|
|
|
|
<button type="submit" class={clsx('button button--submit', styles.button)}>
|
|
|
|
|
Опубликовать
|
|
|
|
|
</button>
|
2023-03-13 12:26:25 +00:00
|
|
|
|
</div>
|
2023-03-12 20:16:20 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2023-04-06 21:40:34 +00:00
|
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<aside
|
|
|
|
|
class={clsx('col-md-6', styles.asidePanel, { [styles.asidePanelHidden]: !isEditorPanelOPened() })}
|
|
|
|
|
>
|
|
|
|
|
<div>
|
|
|
|
|
<Button
|
|
|
|
|
value={<Icon name="close" />}
|
|
|
|
|
variant={'inline'}
|
|
|
|
|
class={styles.close}
|
|
|
|
|
onClick={toggleEditorPanel}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<section>
|
|
|
|
|
<Button value={t('Publish')} variant={'inline'} class={styles.button} />
|
|
|
|
|
<Button value={t('Save draft')} variant={'inline'} class={styles.button} />
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section>
|
|
|
|
|
<Button
|
|
|
|
|
value={
|
|
|
|
|
<>
|
|
|
|
|
<Icon name="eye" class={styles.icon} />
|
|
|
|
|
{t('Preview')}
|
|
|
|
|
</>
|
|
|
|
|
}
|
|
|
|
|
variant={'inline'}
|
|
|
|
|
class={clsx(styles.button, styles.buttonWithIcon)}
|
|
|
|
|
/>
|
|
|
|
|
<Button
|
|
|
|
|
value={
|
|
|
|
|
<>
|
|
|
|
|
<Icon name="pencil-outline" class={styles.icon} />
|
|
|
|
|
{t('Editing')}
|
|
|
|
|
</>
|
|
|
|
|
}
|
|
|
|
|
variant={'inline'}
|
|
|
|
|
class={clsx(styles.button, styles.buttonWithIcon)}
|
|
|
|
|
/>
|
|
|
|
|
<Button
|
|
|
|
|
value={
|
|
|
|
|
<>
|
|
|
|
|
<Icon name="feed-discussion" class={styles.icon} />
|
|
|
|
|
{t('FAQ')}
|
|
|
|
|
</>
|
|
|
|
|
}
|
|
|
|
|
variant={'inline'}
|
|
|
|
|
class={clsx(styles.button, styles.buttonWithIcon)}
|
|
|
|
|
/>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section>
|
|
|
|
|
<Button value={t('Invite co-authors')} variant={'inline'} class={styles.button} />
|
|
|
|
|
<Button value={t('Publication settings')} variant={'inline'} class={styles.button} />
|
|
|
|
|
<Button value={t('Corrections history')} variant={'inline'} class={styles.button} />
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section>
|
|
|
|
|
<p>
|
|
|
|
|
<a href="/how-to-write-a-good-article">Как написать хорошую статью</a>
|
|
|
|
|
</p>
|
|
|
|
|
<p>
|
|
|
|
|
<a href="#">Горячие клавиши</a>
|
|
|
|
|
</p>
|
|
|
|
|
<p>
|
|
|
|
|
<a href="#">Помощь</a>
|
|
|
|
|
</p>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<div class={styles.stats}>
|
|
|
|
|
<div>
|
|
|
|
|
Знаков: <em>2345</em>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
Слов: <em>215</em>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
Абзацев: <em>300</em>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
Посл. изм.: <em>22.03.22 в 18:20</em>
|
|
|
|
|
</div>
|
2023-03-29 08:51:27 +00:00
|
|
|
|
</div>
|
2023-04-06 21:40:34 +00:00
|
|
|
|
</aside>
|
|
|
|
|
</>
|
2022-09-09 11:53:35 +00:00
|
|
|
|
)
|
|
|
|
|
}
|
2022-11-01 19:27:43 +00:00
|
|
|
|
|
2023-04-11 13:57:48 +00:00
|
|
|
|
export default EditView
|