sight edit update
This commit is contained in:
@ -1,72 +1,196 @@
|
||||
import {Box, TextField, Typography, Paper} from '@mui/material'
|
||||
import {Create} from '@refinedev/mui'
|
||||
import {useForm} from '@refinedev/react-hook-form'
|
||||
import {Controller} from 'react-hook-form'
|
||||
import React, {useState, useEffect} from 'react'
|
||||
import ReactMarkdown from 'react-markdown'
|
||||
import { Box, TextField, Typography, Paper } from "@mui/material";
|
||||
import { Create } from "@refinedev/mui";
|
||||
import { useForm } from "@refinedev/react-hook-form";
|
||||
import { Controller } from "react-hook-form";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import Cookies from "js-cookie";
|
||||
import { MarkdownEditor } from "../../components/MarkdownEditor";
|
||||
import "easymde/dist/easymde.min.css";
|
||||
|
||||
import {MarkdownEditor} from '../../components/MarkdownEditor'
|
||||
import 'easymde/dist/easymde.min.css'
|
||||
|
||||
const MemoizedSimpleMDE = React.memo(MarkdownEditor)
|
||||
const MemoizedSimpleMDE = React.memo(MarkdownEditor);
|
||||
|
||||
export const ArticleCreate = () => {
|
||||
const [language, setLanguage] = useState(Cookies.get("lang")!);
|
||||
const [articleData, setArticleData] = useState<{
|
||||
ru: { heading: string; body: string };
|
||||
en: { heading: string; body: string };
|
||||
zh: { heading: string; body: string };
|
||||
}>({
|
||||
ru: { heading: "", body: "" },
|
||||
en: { heading: "", body: "" },
|
||||
zh: { heading: "", body: "" },
|
||||
});
|
||||
|
||||
const {
|
||||
saveButtonProps,
|
||||
refineCore: {formLoading},
|
||||
refineCore: { formLoading },
|
||||
register,
|
||||
control,
|
||||
watch,
|
||||
formState: {errors},
|
||||
formState: { errors },
|
||||
setValue,
|
||||
} = useForm({
|
||||
refineCoreProps: {
|
||||
resource: 'article/',
|
||||
resource: "article/",
|
||||
meta: {
|
||||
headers: {
|
||||
"Accept-Language": language,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
});
|
||||
|
||||
const [preview, setPreview] = useState('')
|
||||
const [headingPreview, setHeadingPreview] = useState('')
|
||||
useEffect(() => {
|
||||
const lang = Cookies.get("lang")!;
|
||||
Cookies.set("lang", language);
|
||||
return () => {
|
||||
Cookies.set("lang", lang);
|
||||
};
|
||||
}, [language]);
|
||||
|
||||
useEffect(() => {
|
||||
setValue(
|
||||
"heading",
|
||||
articleData[language as keyof typeof articleData]?.heading || ""
|
||||
);
|
||||
setValue(
|
||||
"body",
|
||||
articleData[language as keyof typeof articleData]?.body || ""
|
||||
);
|
||||
setPreview(articleData[language as keyof typeof articleData]?.body || "");
|
||||
setHeadingPreview(
|
||||
articleData[language as keyof typeof articleData]?.heading || ""
|
||||
);
|
||||
}, [language, articleData, setValue]);
|
||||
|
||||
const handleLanguageChange = (lang: string) => {
|
||||
setArticleData((prevData) => ({
|
||||
...prevData,
|
||||
[language]: {
|
||||
heading: watch("heading") || "",
|
||||
body: watch("body") || "",
|
||||
},
|
||||
}));
|
||||
setLanguage(lang);
|
||||
Cookies.set("lang", lang);
|
||||
};
|
||||
|
||||
const [preview, setPreview] = useState("");
|
||||
const [headingPreview, setHeadingPreview] = useState("");
|
||||
|
||||
// Следим за изменениями в полях body и heading
|
||||
const bodyContent = watch('body')
|
||||
const headingContent = watch('heading')
|
||||
const bodyContent = watch("body");
|
||||
const headingContent = watch("heading");
|
||||
|
||||
useEffect(() => {
|
||||
setPreview(bodyContent || '')
|
||||
}, [bodyContent])
|
||||
setPreview(bodyContent || "");
|
||||
}, [bodyContent]);
|
||||
|
||||
useEffect(() => {
|
||||
setHeadingPreview(headingContent || '')
|
||||
}, [headingContent])
|
||||
setHeadingPreview(headingContent || "");
|
||||
}, [headingContent]);
|
||||
|
||||
const simpleMDEOptions = React.useMemo(
|
||||
() => ({
|
||||
placeholder: 'Введите контент в формате Markdown...',
|
||||
placeholder: "Введите контент в формате Markdown...",
|
||||
spellChecker: false,
|
||||
}),
|
||||
[],
|
||||
)
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<Create isLoading={formLoading} saveButtonProps={saveButtonProps}>
|
||||
<Box sx={{display: 'flex', gap: 2}}>
|
||||
<Box sx={{ display: "flex", flex: 1, gap: 2 }}>
|
||||
{/* Форма создания */}
|
||||
<Box component="form" sx={{flex: 1, display: 'flex', flexDirection: 'column'}} autoComplete="off">
|
||||
<TextField
|
||||
{...register('heading', {
|
||||
required: 'Это поле является обязательным',
|
||||
})}
|
||||
error={!!(errors as any)?.heading}
|
||||
helperText={(errors as any)?.heading?.message}
|
||||
margin="normal"
|
||||
fullWidth
|
||||
InputLabelProps={{shrink: true}}
|
||||
type="text"
|
||||
label="Заголовок *"
|
||||
name="heading"
|
||||
/>
|
||||
<Box sx={{ display: "flex", flex: 1, flexDirection: "column", gap: 2 }}>
|
||||
<Box
|
||||
sx={{
|
||||
flex: 1,
|
||||
display: "flex",
|
||||
gap: 2,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
cursor: "pointer",
|
||||
flex: 1,
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
bgcolor: language === "ru" ? "primary.main" : "transparent",
|
||||
color: language === "ru" ? "white" : "inherit",
|
||||
p: 1,
|
||||
borderRadius: 1,
|
||||
}}
|
||||
onClick={() => handleLanguageChange("ru")}
|
||||
>
|
||||
RU
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
cursor: "pointer",
|
||||
flex: 1,
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
bgcolor: language === "en" ? "primary.main" : "transparent",
|
||||
color: language === "en" ? "white" : "inherit",
|
||||
p: 1,
|
||||
borderRadius: 1,
|
||||
}}
|
||||
onClick={() => handleLanguageChange("en")}
|
||||
>
|
||||
EN
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
cursor: "pointer",
|
||||
flex: 1,
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
bgcolor: language === "zh" ? "primary.main" : "transparent",
|
||||
color: language === "zh" ? "white" : "inherit",
|
||||
p: 1,
|
||||
borderRadius: 1,
|
||||
}}
|
||||
onClick={() => handleLanguageChange("zh")}
|
||||
>
|
||||
ZH
|
||||
</Box>
|
||||
</Box>
|
||||
<Box
|
||||
component="form"
|
||||
sx={{ flex: 1, display: "flex", flexDirection: "column" }}
|
||||
autoComplete="off"
|
||||
>
|
||||
<TextField
|
||||
{...register("heading", {
|
||||
required: "Это поле является обязательным",
|
||||
})}
|
||||
error={!!(errors as any)?.heading}
|
||||
helperText={(errors as any)?.heading?.message}
|
||||
margin="normal"
|
||||
fullWidth
|
||||
InputLabelProps={{ shrink: true }}
|
||||
type="text"
|
||||
label="Заголовок *"
|
||||
name="heading"
|
||||
/>
|
||||
|
||||
<Controller control={control} name="body" rules={{required: 'Это поле является обязательным'}} defaultValue="" render={({field: {onChange, value}}) => <MemoizedSimpleMDE value={value} onChange={onChange} options={simpleMDEOptions} className="my-markdown-editor" />} />
|
||||
<Controller
|
||||
control={control}
|
||||
name="body"
|
||||
rules={{ required: "Это поле является обязательным" }}
|
||||
defaultValue=""
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<MemoizedSimpleMDE
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
options={simpleMDEOptions}
|
||||
className="my-markdown-editor"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{/* Блок предпросмотра */}
|
||||
@ -74,14 +198,15 @@ export const ArticleCreate = () => {
|
||||
sx={{
|
||||
flex: 1,
|
||||
p: 2,
|
||||
maxHeight: 'calc(100vh - 200px)',
|
||||
overflowY: 'auto',
|
||||
position: 'sticky',
|
||||
maxHeight: "calc(100vh - 200px)",
|
||||
overflowY: "auto",
|
||||
position: "sticky",
|
||||
top: 16,
|
||||
borderRadius: 2,
|
||||
border: '1px solid',
|
||||
borderColor: 'primary.main',
|
||||
bgcolor: (theme) => (theme.palette.mode === 'dark' ? 'background.paper' : '#fff'),
|
||||
border: "1px solid",
|
||||
borderColor: "primary.main",
|
||||
bgcolor: (theme) =>
|
||||
theme.palette.mode === "dark" ? "background.paper" : "#fff",
|
||||
}}
|
||||
>
|
||||
<Typography variant="h6" gutterBottom color="primary">
|
||||
@ -93,7 +218,8 @@ export const ArticleCreate = () => {
|
||||
variant="h4"
|
||||
gutterBottom
|
||||
sx={{
|
||||
color: (theme) => (theme.palette.mode === 'dark' ? 'grey.300' : 'grey.800'),
|
||||
color: (theme) =>
|
||||
theme.palette.mode === "dark" ? "grey.300" : "grey.800",
|
||||
mb: 3,
|
||||
}}
|
||||
>
|
||||
@ -103,39 +229,41 @@ export const ArticleCreate = () => {
|
||||
{/* Markdown контент */}
|
||||
<Box
|
||||
sx={{
|
||||
'& img': {
|
||||
maxWidth: '100%',
|
||||
height: 'auto',
|
||||
"& img": {
|
||||
maxWidth: "100%",
|
||||
height: "auto",
|
||||
borderRadius: 1,
|
||||
},
|
||||
'& h1, & h2, & h3, & h4, & h5, & h6': {
|
||||
color: 'primary.main',
|
||||
"& h1, & h2, & h3, & h4, & h5, & h6": {
|
||||
color: "primary.main",
|
||||
mt: 2,
|
||||
mb: 1,
|
||||
},
|
||||
'& p': {
|
||||
"& p": {
|
||||
mb: 2,
|
||||
color: (theme) => (theme.palette.mode === 'dark' ? 'grey.300' : 'grey.800'),
|
||||
color: (theme) =>
|
||||
theme.palette.mode === "dark" ? "grey.300" : "grey.800",
|
||||
},
|
||||
'& a': {
|
||||
color: 'primary.main',
|
||||
textDecoration: 'none',
|
||||
'&:hover': {
|
||||
textDecoration: 'underline',
|
||||
"& a": {
|
||||
color: "primary.main",
|
||||
textDecoration: "none",
|
||||
"&:hover": {
|
||||
textDecoration: "underline",
|
||||
},
|
||||
},
|
||||
'& blockquote': {
|
||||
borderLeft: '4px solid',
|
||||
borderColor: 'primary.main',
|
||||
"& blockquote": {
|
||||
borderLeft: "4px solid",
|
||||
borderColor: "primary.main",
|
||||
pl: 2,
|
||||
my: 2,
|
||||
color: 'text.secondary',
|
||||
color: "text.secondary",
|
||||
},
|
||||
'& code': {
|
||||
bgcolor: (theme) => (theme.palette.mode === 'dark' ? 'grey.900' : 'grey.100'),
|
||||
"& code": {
|
||||
bgcolor: (theme) =>
|
||||
theme.palette.mode === "dark" ? "grey.900" : "grey.100",
|
||||
p: 0.5,
|
||||
borderRadius: 0.5,
|
||||
color: 'primary.main',
|
||||
color: "primary.main",
|
||||
},
|
||||
}}
|
||||
>
|
||||
@ -144,5 +272,5 @@ export const ArticleCreate = () => {
|
||||
</Paper>
|
||||
</Box>
|
||||
</Create>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
Reference in New Issue
Block a user