Merge branch 'editor_settings/upload_cover_image' into 'dev'
Editor settings/upload cover image See merge request discoursio/discoursio-webapp!74
This commit is contained in:
commit
2c252b8dce
|
@ -3,6 +3,8 @@
|
||||||
"About myself": "About myself",
|
"About myself": "About myself",
|
||||||
"About the project": "About the project",
|
"About the project": "About the project",
|
||||||
"Add comment": "Comment",
|
"Add comment": "Comment",
|
||||||
|
"Add image": "Add image",
|
||||||
|
"Add another image": "Add another image",
|
||||||
"Address on Discourse": "Address on Discourse",
|
"Address on Discourse": "Address on Discourse",
|
||||||
"All": "All",
|
"All": "All",
|
||||||
"All authors": "All authors",
|
"All authors": "All authors",
|
||||||
|
@ -32,6 +34,7 @@
|
||||||
"By views": "By views",
|
"By views": "By views",
|
||||||
"Characters": "Знаков",
|
"Characters": "Знаков",
|
||||||
"Chat Title": "Chat Title",
|
"Chat Title": "Chat Title",
|
||||||
|
"Choose a title image for the article. You can immediately see how the publication card will look like.": "Choose a title image for the article. You can immediately see how the publication card will look like.",
|
||||||
"Choose who you want to write to": "Choose who you want to write to",
|
"Choose who you want to write to": "Choose who you want to write to",
|
||||||
"Collaborate": "Help Edit",
|
"Collaborate": "Help Edit",
|
||||||
"Comments": "Comments",
|
"Comments": "Comments",
|
||||||
|
@ -119,6 +122,7 @@
|
||||||
"Logout": "Logout",
|
"Logout": "Logout",
|
||||||
"Manifest": "Manifest",
|
"Manifest": "Manifest",
|
||||||
"Many files, choose only one": "Many files, choose only one",
|
"Many files, choose only one": "Many files, choose only one",
|
||||||
|
"Material card": "Material card",
|
||||||
"More": "More",
|
"More": "More",
|
||||||
"Most commented": "Commented",
|
"Most commented": "Commented",
|
||||||
"Most read": "Readable",
|
"Most read": "Readable",
|
||||||
|
@ -162,6 +166,7 @@
|
||||||
"Recent": "Fresh",
|
"Recent": "Fresh",
|
||||||
"Reply": "Reply",
|
"Reply": "Reply",
|
||||||
"Report": "Complain",
|
"Report": "Complain",
|
||||||
|
"Required": "Required",
|
||||||
"Resend code": "Send confirmation",
|
"Resend code": "Send confirmation",
|
||||||
"Restore password": "Restore password",
|
"Restore password": "Restore password",
|
||||||
"Save draft": "Save draft",
|
"Save draft": "Save draft",
|
||||||
|
@ -272,6 +277,6 @@
|
||||||
"user already exist": "user already exists",
|
"user already exist": "user already exists",
|
||||||
"view": "view",
|
"view": "view",
|
||||||
"zine": "zine",
|
"zine": "zine",
|
||||||
"Required": "Required",
|
"Unnamed draft": "Unnamed draft",
|
||||||
"Unnamed draft": "Unnamed draft"
|
"Publish Settings": "Publish Settings"
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
"About myself": "О себе",
|
"About myself": "О себе",
|
||||||
"About the project": "О проекте",
|
"About the project": "О проекте",
|
||||||
"Add comment": "Комментировать",
|
"Add comment": "Комментировать",
|
||||||
|
"Add image": "Добавить изображение",
|
||||||
|
"Add another image": "Добавить другое изображение",
|
||||||
"Add to bookmarks": "Добавить в закладки",
|
"Add to bookmarks": "Добавить в закладки",
|
||||||
"Address on Discourse": "Адрес на Дискурсе",
|
"Address on Discourse": "Адрес на Дискурсе",
|
||||||
"All": "Все",
|
"All": "Все",
|
||||||
|
@ -34,6 +36,7 @@
|
||||||
"By views": "По просмотрам",
|
"By views": "По просмотрам",
|
||||||
"Characters": "Знаков",
|
"Characters": "Знаков",
|
||||||
"Chat Title": "Тема дискурса",
|
"Chat Title": "Тема дискурса",
|
||||||
|
"Choose a title image for the article. You can immediately see how the publication card will look like.": "Выберите заглавное изображение для статьи. Тут же сразу можно увидеть как будет выглядеть карточка публикации.",
|
||||||
"Choose who you want to write to": "Выберите кому хотите написать",
|
"Choose who you want to write to": "Выберите кому хотите написать",
|
||||||
"Collaborate": "Помочь редактировать",
|
"Collaborate": "Помочь редактировать",
|
||||||
"Comments": "Комментарии",
|
"Comments": "Комментарии",
|
||||||
|
@ -126,6 +129,7 @@
|
||||||
"Logout": "Выход",
|
"Logout": "Выход",
|
||||||
"Manifest": "Манифест",
|
"Manifest": "Манифест",
|
||||||
"Many files, choose only one": "Много файлов, выберете один",
|
"Many files, choose only one": "Много файлов, выберете один",
|
||||||
|
"Material card": "Карточка материала",
|
||||||
"More": "Ещё",
|
"More": "Ещё",
|
||||||
"Most commented": "Комментируемое",
|
"Most commented": "Комментируемое",
|
||||||
"Most read": "Читаемое",
|
"Most read": "Читаемое",
|
||||||
|
@ -173,11 +177,13 @@
|
||||||
"Recent": "Свежее",
|
"Recent": "Свежее",
|
||||||
"Reply": "Ответить",
|
"Reply": "Ответить",
|
||||||
"Report": "Пожаловаться",
|
"Report": "Пожаловаться",
|
||||||
|
"Required": "Поле обязательно для заполнения",
|
||||||
"Resend code": "Выслать подтверждение",
|
"Resend code": "Выслать подтверждение",
|
||||||
"Restore password": "Восстановить пароль",
|
"Restore password": "Восстановить пароль",
|
||||||
"Save": "Сохранить",
|
"Save": "Сохранить",
|
||||||
"Save draft": "Сохранить черновик",
|
"Save draft": "Сохранить черновик",
|
||||||
"Save settings": "Сохранить настройки",
|
"Save settings": "Сохранить настройки",
|
||||||
|
"Scroll up": "Наверх",
|
||||||
"Search": "Поиск",
|
"Search": "Поиск",
|
||||||
"Search author": "Поиск автора",
|
"Search author": "Поиск автора",
|
||||||
"Search topic": "Поиск темы",
|
"Search topic": "Поиск темы",
|
||||||
|
@ -187,7 +193,6 @@
|
||||||
"Send": "Отправить",
|
"Send": "Отправить",
|
||||||
"Send link again": "Прислать ссылку ещё раз",
|
"Send link again": "Прислать ссылку ещё раз",
|
||||||
"Settings": "Настройки",
|
"Settings": "Настройки",
|
||||||
"Scroll up": "Наверх",
|
|
||||||
"Share": "Поделиться",
|
"Share": "Поделиться",
|
||||||
"Short opening": "Небольшое вступление, чтобы заинтересовать читателя",
|
"Short opening": "Небольшое вступление, чтобы заинтересовать читателя",
|
||||||
"Show": "Показать",
|
"Show": "Показать",
|
||||||
|
@ -293,6 +298,6 @@
|
||||||
"user already exist": "пользователь уже существует",
|
"user already exist": "пользователь уже существует",
|
||||||
"view": "просмотр",
|
"view": "просмотр",
|
||||||
"zine": "журнал",
|
"zine": "журнал",
|
||||||
"Required": "Поле обязательно для заполнения",
|
"Publish Settings": "Настройки публикации",
|
||||||
"Unnamed draft": "Unnamed draft"
|
"Unnamed draft": "Unnamed draft"
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,10 @@ import { useLocalize } from '../../../context/localize'
|
||||||
import { Modal } from '../../Nav/Modal'
|
import { Modal } from '../../Nav/Modal'
|
||||||
import { Menu } from './Menu'
|
import { Menu } from './Menu'
|
||||||
import type { MenuItem } from './Menu/Menu'
|
import type { MenuItem } from './Menu/Menu'
|
||||||
import { showModal } from '../../../stores/ui'
|
import { hideModal, showModal } from '../../../stores/ui'
|
||||||
import { UploadModalContent } from '../UploadModal'
|
import { UploadModalContent } from '../UploadModalContent'
|
||||||
import { useOutsideClickHandler } from '../../../utils/useOutsideClickHandler'
|
import { useOutsideClickHandler } from '../../../utils/useOutsideClickHandler'
|
||||||
|
import { imageProxy } from '../../../utils/imageProxy'
|
||||||
|
|
||||||
type FloatingMenuProps = {
|
type FloatingMenuProps = {
|
||||||
editor: Editor
|
editor: Editor
|
||||||
|
@ -35,6 +36,7 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const [selectedMenuItem, setSelectedMenuItem] = createSignal<MenuItem | undefined>()
|
const [selectedMenuItem, setSelectedMenuItem] = createSignal<MenuItem | undefined>()
|
||||||
const [menuOpen, setMenuOpen] = createSignal<boolean>(false)
|
const [menuOpen, setMenuOpen] = createSignal<boolean>(false)
|
||||||
|
const menuRef: { current: HTMLDivElement } = { current: null }
|
||||||
const handleEmbedFormSubmit = async (value: string) => {
|
const handleEmbedFormSubmit = async (value: string) => {
|
||||||
// TODO: add support instagram embed (blockquote)
|
// TODO: add support instagram embed (blockquote)
|
||||||
const emb = await embedData(value)
|
const emb = await embedData(value)
|
||||||
|
@ -58,8 +60,6 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => {
|
||||||
setMenuOpen(false)
|
setMenuOpen(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const menuRef: { current: HTMLDivElement } = { current: null }
|
|
||||||
|
|
||||||
useOutsideClickHandler({
|
useOutsideClickHandler({
|
||||||
containerRef: menuRef,
|
containerRef: menuRef,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
|
@ -69,6 +69,15 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const renderImage = (src: string) => {
|
||||||
|
props.editor
|
||||||
|
.chain()
|
||||||
|
.focus()
|
||||||
|
.setImage({ src: imageProxy(src) })
|
||||||
|
.run()
|
||||||
|
hideModal()
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div ref={props.ref} class={styles.editorFloatingMenu}>
|
<div ref={props.ref} class={styles.editorFloatingMenu}>
|
||||||
|
@ -100,7 +109,12 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => {
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
<Modal variant="narrow" name="uploadImage" onClose={closeUploadModalHandler}>
|
<Modal variant="narrow" name="uploadImage" onClose={closeUploadModalHandler}>
|
||||||
<UploadModalContent closeCallback={() => setSelectedMenuItem()} editor={props.editor} />
|
<UploadModalContent
|
||||||
|
onClose={(value) => {
|
||||||
|
renderImage(value)
|
||||||
|
setSelectedMenuItem()
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
|
@ -33,6 +33,9 @@ export const InlineForm = (props: Props) => {
|
||||||
} else {
|
} else {
|
||||||
setFormValueError(props.errorMessage)
|
setFormValueError(props.errorMessage)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
props.onSubmit(formValue())
|
||||||
|
props.onClose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
src/components/Editor/TopicSelect/index.ts
Normal file
1
src/components/Editor/TopicSelect/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export { TopicSelect } from './TopicSelect'
|
|
@ -8,14 +8,11 @@ import { hideModal } from '../../../stores/ui'
|
||||||
import { createDropzone, createFileUploader, UploadFile } from '@solid-primitives/upload'
|
import { createDropzone, createFileUploader, UploadFile } from '@solid-primitives/upload'
|
||||||
import { handleFileUpload } from '../../../utils/handleFileUpload'
|
import { handleFileUpload } from '../../../utils/handleFileUpload'
|
||||||
import { useLocalize } from '../../../context/localize'
|
import { useLocalize } from '../../../context/localize'
|
||||||
import { Editor } from '@tiptap/core'
|
|
||||||
import { Loading } from '../../_shared/Loading'
|
import { Loading } from '../../_shared/Loading'
|
||||||
import { verifyImg } from '../../../utils/verifyImg'
|
import { verifyImg } from '../../../utils/verifyImg'
|
||||||
import { imageProxy } from '../../../utils/imageProxy'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
editor: Editor
|
onClose: (imgUrl?: string) => void
|
||||||
closeCallback: () => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const UploadModalContent = (props: Props) => {
|
export const UploadModalContent = (props: Props) => {
|
||||||
|
@ -25,27 +22,17 @@ export const UploadModalContent = (props: Props) => {
|
||||||
const [dragActive, setDragActive] = createSignal(false)
|
const [dragActive, setDragActive] = createSignal(false)
|
||||||
const [dragError, setDragError] = createSignal<string | undefined>()
|
const [dragError, setDragError] = createSignal<string | undefined>()
|
||||||
|
|
||||||
const renderImage = (src: string) => {
|
|
||||||
props.editor
|
|
||||||
.chain()
|
|
||||||
.focus()
|
|
||||||
.setImage({ src: imageProxy(src) })
|
|
||||||
.run()
|
|
||||||
hideModal()
|
|
||||||
}
|
|
||||||
|
|
||||||
const { selectFiles } = createFileUploader({ multiple: false, accept: 'image/*' })
|
const { selectFiles } = createFileUploader({ multiple: false, accept: 'image/*' })
|
||||||
const runUpload = async (file) => {
|
const runUpload = async (file) => {
|
||||||
try {
|
try {
|
||||||
setIsUploading(true)
|
setIsUploading(true)
|
||||||
const fileUrl = await handleFileUpload(file)
|
const fileUrl = await handleFileUpload(file)
|
||||||
setIsUploading(false)
|
setIsUploading(false)
|
||||||
props.closeCallback()
|
props.onClose(fileUrl)
|
||||||
renderImage(fileUrl)
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[upload image] error', error)
|
|
||||||
setIsUploading(false)
|
setIsUploading(false)
|
||||||
setUploadError(t('Error'))
|
setUploadError(t('Error'))
|
||||||
|
console.error('[runUpload]', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +40,7 @@ export const UploadModalContent = (props: Props) => {
|
||||||
try {
|
try {
|
||||||
const data = await fetch(value)
|
const data = await fetch(value)
|
||||||
const blob = await data.blob()
|
const blob = await data.blob()
|
||||||
const file = new File([blob], 'convertedFromUrl', { type: data.headers.get('Content-Type') })
|
const file = await new File([blob], 'convertedFromUrl', { type: data.headers.get('Content-Type') })
|
||||||
const fileToUpload: UploadFile = {
|
const fileToUpload: UploadFile = {
|
||||||
source: blob.toString(),
|
source: blob.toString(),
|
||||||
name: file.name,
|
name: file.name,
|
||||||
|
@ -124,7 +111,7 @@ export const UploadModalContent = (props: Props) => {
|
||||||
showInput={true}
|
showInput={true}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
hideModal()
|
hideModal()
|
||||||
props.closeCallback()
|
props.onClose()
|
||||||
}}
|
}}
|
||||||
validate={(value) => verifyImg(value)}
|
validate={(value) => verifyImg(value)}
|
||||||
onSubmit={handleImageFormSubmit}
|
onSubmit={handleImageFormSubmit}
|
4
src/components/Editor/index.ts
Normal file
4
src/components/Editor/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
export { Editor } from './Editor'
|
||||||
|
export { Panel } from './Panel'
|
||||||
|
export { TopicSelect } from './TopicSelect'
|
||||||
|
export { UploadModalContent } from './UploadModalContent'
|
|
@ -4,8 +4,62 @@
|
||||||
|
|
||||||
.articlePreview {
|
.articlePreview {
|
||||||
border: 2px solid #e8e8e8;
|
border: 2px solid #e8e8e8;
|
||||||
min-height: 10em;
|
|
||||||
padding: 1rem 1.2rem;
|
padding: 1rem 1.2rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 300px;
|
||||||
|
align-items: flex-start;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.shoutCardCoverContainer {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
.shoutCardCover {
|
||||||
|
height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
margin: 1.6rem 0;
|
||||||
|
padding-bottom: 56.2%;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
position: absolute;
|
||||||
|
transform-origin: 50% 50%;
|
||||||
|
transition: transform 1s ease-in-out;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover img {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.shoutCardTitle {
|
||||||
|
@include font-size(2.2rem);
|
||||||
|
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.25;
|
||||||
|
margin: auto 0 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shoutCardSubtitle {
|
||||||
|
@include font-size(1.7rem);
|
||||||
|
|
||||||
|
color: #696969;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.3;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
transition: color 0.2s, background-color 0.2s, box-shadow 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shoutAuthor {
|
||||||
|
@include font-size(1.2rem);
|
||||||
|
|
||||||
|
margin-right: 1.6rem;
|
||||||
|
color: rgb(0 0 0 / 70%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.formHolder {
|
.formHolder {
|
||||||
|
@ -60,7 +114,7 @@
|
||||||
|
|
||||||
.close {
|
.close {
|
||||||
filter: invert(1);
|
filter: invert(1);
|
||||||
margin: -1.6rem 0 0 -1.6rem;
|
margin: -1.6rem 0 0 -2.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
section {
|
section {
|
||||||
|
|
|
@ -1,34 +1,43 @@
|
||||||
import { createSignal, onCleanup, onMount, Show } from 'solid-js'
|
import { createSignal, onCleanup, onMount, Show } from 'solid-js'
|
||||||
import { useLocalize } from '../../context/localize'
|
import { useLocalize } from '../../context/localize'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
import styles from './Edit.module.scss'
|
|
||||||
import { Title } from '@solidjs/meta'
|
import { Title } from '@solidjs/meta'
|
||||||
import type { Shout, Topic } from '../../graphql/types.gen'
|
import type { Shout, Topic } from '../../graphql/types.gen'
|
||||||
import { apiClient } from '../../utils/apiClient'
|
import { apiClient } from '../../utils/apiClient'
|
||||||
import { TopicSelect } from '../Editor/TopicSelect/TopicSelect'
|
|
||||||
import { useRouter } from '../../stores/router'
|
import { useRouter } from '../../stores/router'
|
||||||
import { Editor } from '../Editor/Editor'
|
|
||||||
import { Panel } from '../Editor/Panel'
|
|
||||||
import { useEditorContext } from '../../context/editor'
|
import { useEditorContext } from '../../context/editor'
|
||||||
|
import { Editor, Panel, TopicSelect, UploadModalContent } from '../Editor'
|
||||||
import { Icon } from '../_shared/Icon'
|
import { Icon } from '../_shared/Icon'
|
||||||
|
import { Button } from '../_shared/Button'
|
||||||
|
import styles from './Edit.module.scss'
|
||||||
|
import { useSession } from '../../context/session'
|
||||||
|
import { Modal } from '../Nav/Modal'
|
||||||
|
import { hideModal, showModal } from '../../stores/ui'
|
||||||
|
|
||||||
type EditViewProps = {
|
type EditViewProps = {
|
||||||
shout: Shout
|
shout: Shout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const scrollTop = () => {
|
||||||
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
behavior: 'smooth'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const EditView = (props: EditViewProps) => {
|
export const EditView = (props: EditViewProps) => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
|
const { user } = useSession()
|
||||||
|
|
||||||
const [isScrolled, setIsScrolled] = createSignal(false)
|
const [isScrolled, setIsScrolled] = createSignal(false)
|
||||||
const [topics, setTopics] = createSignal<Topic[]>(null)
|
const [topics, setTopics] = createSignal<Topic[]>(null)
|
||||||
|
const [coverImage, setCoverImage] = createSignal<string>(null)
|
||||||
const { page } = useRouter()
|
const { page } = useRouter()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
form,
|
form,
|
||||||
formErrors,
|
formErrors,
|
||||||
actions: { setForm, setFormErrors }
|
actions: { setForm, setFormErrors }
|
||||||
} = useEditorContext()
|
} = useEditorContext()
|
||||||
|
|
||||||
const [isSlugChanged, setIsSlugChanged] = createSignal(false)
|
const [isSlugChanged, setIsSlugChanged] = createSignal(false)
|
||||||
|
|
||||||
setForm({
|
setForm({
|
||||||
|
@ -76,11 +85,10 @@ export const EditView = (props: EditViewProps) => {
|
||||||
setForm('slug', slug)
|
setForm('slug', slug)
|
||||||
}
|
}
|
||||||
|
|
||||||
const scrollTop = () => {
|
const handleUploadModalContentCloseSetCover = (imgUrl: string) => {
|
||||||
window.scrollTo({
|
hideModal()
|
||||||
top: 0,
|
setCoverImage(imgUrl)
|
||||||
behavior: 'smooth'
|
setForm('coverImageUrl', imgUrl)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -112,7 +120,7 @@ export const EditView = (props: EditViewProps) => {
|
||||||
type="text"
|
type="text"
|
||||||
name="title"
|
name="title"
|
||||||
id="title"
|
id="title"
|
||||||
placeholder="Заголовок"
|
placeholder={t('Header')}
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
value={form.title}
|
value={form.title}
|
||||||
onInput={handleTitleInputChange}
|
onInput={handleTitleInputChange}
|
||||||
|
@ -128,7 +136,7 @@ export const EditView = (props: EditViewProps) => {
|
||||||
name="subtitle"
|
name="subtitle"
|
||||||
id="subtitle"
|
id="subtitle"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
placeholder="Подзаголовок"
|
placeholder={t('Subheader')}
|
||||||
value={form.subtitle}
|
value={form.subtitle}
|
||||||
onChange={(e) => setForm('subtitle', e.currentTarget.value)}
|
onChange={(e) => setForm('subtitle', e.currentTarget.value)}
|
||||||
/>
|
/>
|
||||||
|
@ -143,7 +151,7 @@ export const EditView = (props: EditViewProps) => {
|
||||||
[styles.visible]: page().route === 'editSettings'
|
[styles.visible]: page().route === 'editSettings'
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<h1>Настройки публикации</h1>
|
<h1>{t('Publish Settings')}</h1>
|
||||||
|
|
||||||
<h4>Slug</h4>
|
<h4>Slug</h4>
|
||||||
<div class="pretty-form__item">
|
<div class="pretty-form__item">
|
||||||
|
@ -209,18 +217,38 @@ export const EditView = (props: EditViewProps) => {
|
||||||
{/* </div>*/}
|
{/* </div>*/}
|
||||||
{/*</div>*/}
|
{/*</div>*/}
|
||||||
|
|
||||||
<h4>Карточка материала на главной</h4>
|
<h4>{t('Material card')}</h4>
|
||||||
<p class="description">
|
<p class="description">
|
||||||
Выберите заглавное изображение для статьи, тут сразу можно увидеть как карточка будет
|
{t(
|
||||||
выглядеть на главной странице
|
'Choose a title image for the article. You can immediately see how the publication card will look like.'
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
<div class={styles.articlePreview} />
|
<div class={styles.articlePreview}>
|
||||||
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
onClick={() => showModal('uploadImage')}
|
||||||
|
value={coverImage() ? t('Add another image') : t('Add image')}
|
||||||
|
/>
|
||||||
|
<Show when={coverImage() ?? form.coverImageUrl}>
|
||||||
|
<div class={styles.shoutCardCoverContainer}>
|
||||||
|
<div class={styles.shoutCardCover}>
|
||||||
|
<img src={coverImage() || form.coverImageUrl} alt={form.title} loading="lazy" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
<div class={styles.shoutCardTitle}>{form.title}</div>
|
||||||
|
<div class={styles.shoutCardSubtitle}>{form.subtitle}</div>
|
||||||
|
<div class={styles.shoutAuthor}>{user().name}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<Modal variant="narrow" name="uploadImage">
|
||||||
|
<UploadModalContent onClose={(value) => handleUploadModalContentCloseSetCover(value)} />
|
||||||
|
</Modal>
|
||||||
<Panel shoutId={props.shout.id} />
|
<Panel shoutId={props.shout.id} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user