webapp/src/components/Views/Edit.tsx

227 lines
8.0 KiB
TypeScript
Raw Normal View History

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'
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-05-03 16:13:48 +00:00
import { 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-05-03 16:13:48 +00:00
import { Panel } from '../Editor/Panel'
2023-02-11 09:32:52 +00:00
2023-03-23 17:15:50 +00:00
type ShoutForm = {
slug: string
title: string
subtitle: string
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-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-05-01 18:32:32 +00:00
const article = await apiClient.publishDraft()
2023-04-20 13:58:56 +00:00
openPage(router, 'article', { slug: article.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-20 13:58:56 +00:00
const handleSaveButtonClick = async (e) => {
e.preventDefault()
await apiClient.updateArticle({
slug: props.shout.slug,
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(router, 'drafts')
}
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-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}
2023-05-03 16:13:48 +00:00
initialContent={props.shout.body}
2023-04-11 13:57:48 +00:00
onChange={(body) => setForm('body', body)}
/>
2023-03-29 08:51:27 +00:00
</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">*/}
{/* Добавьте несколько тем, чтобы читатель знал, о&nbsp;чем ваш материал, и&nbsp;мог найти*/}
{/* его на&nbsp;страницах интересных ему тем. Темы можно менять местами, первая тема*/}
{/* становится заглавной*/}
{/*</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>Карточка материала на&nbsp;главной</h4>
<p class="description">
Выберите заглавное изображение для статьи, тут сразу можно увидеть как карточка будет
выглядеть на&nbsp;главной странице
</p>
<div class={styles.articlePreview} />
</div>
</div>
</div>
</div>
2023-04-06 21:40:34 +00:00
</form>
</div>
2023-05-03 16:13:48 +00:00
<Panel shoutSlug={props.shout.slug} />
2023-04-06 21:40:34 +00:00
</>
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