This commit is contained in:
GokaPek 2024-01-04 21:29:40 +04:00
parent 9e47ababe6
commit e37fc07485
6 changed files with 55 additions and 77 deletions

View File

@ -1,40 +1,23 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Button, Form } from 'react-bootstrap'; import { Button, Form } from 'react-bootstrap';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import useLinesItemForm from '../hooks/LinesItemFormHook';
import LinesItemForm from './LinesItemForm.jsx'; import LinesItemForm from './LinesItemForm.jsx';
const LinesForm = ({ id }) => { const LinesForm = ({ item }) => {
const navigate = useNavigate(); const navigate = useNavigate();
const {
item,
validated,
handleSubmit,
handleChange,
} = useLinesItemForm(id);
const onBack = () => { const onBack = () => {
navigate(-1); navigate(-1);
}; };
const onSubmit = async (event) => {
if (await handleSubmit(event)) {
onBack();
}
};
return ( return (
<> <>
<Form className='m-0 p-2' noValidate validated={validated} onSubmit={onSubmit}> <Form className='m-0 p-2'>
<LinesItemForm item={item} handleChange={handleChange} /> <LinesItemForm item={item} />
<Form.Group className='row justify-content-center m-0 mt-3'> <Form.Group className='row justify-content-center m-0 mt-3'>
<Button className='col-5 col-lg-2 m-0 me-2' variant='secondary' onClick={() => onBack()}> <Button className='col-5 col-lg-2 m-0 me-2' variant='secondary' onClick={() => onBack()}>
Back Back
</Button> </Button>
<Button className='col-5 col-lg-2 m-0 ms-2' type='submit' variant='primary'>
Save
</Button>
</Form.Group> </Form.Group>
</Form> </Form>
</> </>
@ -42,7 +25,7 @@ const LinesForm = ({ id }) => {
}; };
LinesForm.propTypes = { LinesForm.propTypes = {
id: PropTypes.string, item: PropTypes.object,
}; };
export default LinesForm; export default LinesForm;

View File

@ -1,32 +1,45 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import imgPlaceholder from '../../../assets/200.png'; import { FilePost } from 'react-bootstrap-icons';
import Input from '../../input/Input.jsx';
import Select from '../../input/Select.jsx';
import useTypes from '../../types/hooks/TypesHook';
import './LinesItemForm.css'; import './LinesItemForm.css';
const LinesItemForm = ({ item, handleChange }) => { const LinesItemForm = ({ item }) => {
const { types } = useTypes(); // Функция для конвертации base64 строки в Blob
const base64ToBlob = (base64) => {
// Кодируем строку base64 обратно в массив байтов
const byteCharacters = atob(base64.split(',')[1]);
const byteNumbers = Array.from(byteCharacters).map((char) => char.charCodeAt(0));
const byteArray = new Uint8Array(byteNumbers);
// Создаем Blob из типизированного массива байтов
return new Blob([byteArray], { type: 'application/pdf' });
};
const openFile = (base64) => {
const base64Prefix = 'data:application/pdf;base64,';
const content = base64.includes(base64Prefix) ? base64 : `${base64Prefix}${base64}`;
// Создаем Blob из base64 строки
const blob = base64ToBlob(content);
// Создаем URL для Blob
const fileURL = URL.createObjectURL(blob);
// Открываем URL в новой вкладке
window.open(fileURL);
// <a onClick={() => openFile(line.datafile)}></a>
};
return ( return (
<> <>
<div className='text-center'> <div className='text-center mt-5'>
<img id='image-preview' className='rounded' alt='placeholder' <img id='image-preview' className='rounded' alt='placeholder'
src={item.image || imgPlaceholder} /> src={item.image} />
</div> <div style={{ height: 300, overflow: 'auto' }}>
<div style={{ height: 300, overflow: 'auto' }}> <p>Name: {item.book_name}</p>
<Input name='book_name' label='Name' value={item.book_name} onChange={handleChange} <p>Author: {item.author_name}</p>
type='text' required /> <p>Price: {item.price}</p>
<Select values={types} name='typeId' label='Type' value={item.typeId} onChange={handleChange} <a onClick={() => openFile(item.datafile)}><FilePost /></a>
required /> </div>
<Input name='author_name' label='Author' value={item.author_name} onChange={handleChange}
type='text' required />
<Input name='price' label='Price' value={item.price} onChange={handleChange}
type='number' min='50.0' step='1.0' required />
<Input name='image' label='Image' onChange={handleChange}
type='file' accept='image/*' />
<Input name='datafile' label='file' onChange={handleChange}
type='file' accept='application/pdf/*' />
</div> </div>
</> </>
); );
@ -34,7 +47,6 @@ const LinesItemForm = ({ item, handleChange }) => {
LinesItemForm.propTypes = { LinesItemForm.propTypes = {
item: PropTypes.object, item: PropTypes.object,
handleChange: PropTypes.func,
}; };
export default LinesItemForm; export default LinesItemForm;

View File

@ -3,14 +3,12 @@ import LinesApiService from '../service/LinesApiService';
const useLinesItem = (id) => { const useLinesItem = (id) => {
const emptyItem = { const emptyItem = {
id: '', typeId: '',
book_name: '', book_name: '',
author_name: '', author_name: '',
typeId: '', price: '',
price: '0',
count: '0',
image: '', image: '',
data_file: '', datafile: '',
}; };
const [item, setItem] = useState({ ...emptyItem }); const [item, setItem] = useState({ ...emptyItem });

View File

@ -1,6 +1,7 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Carousel } from 'react-bootstrap'; import { Carousel } from 'react-bootstrap';
import { Heart } from 'react-bootstrap-icons'; import { Heart } from 'react-bootstrap-icons';
import { useNavigate } from 'react-router-dom';
import useCart from '../../cart/CartHook'; import useCart from '../../cart/CartHook';
import './LinesTableRow.css'; // Предполагается, что стили для карусели описаны здесь import './LinesTableRow.css'; // Предполагается, что стили для карусели описаны здесь
@ -12,38 +13,20 @@ const BookCarousel = ({
action(); action();
}; };
const navigate = useNavigate();
const handlePageClick = (event, path) => {
event.preventDefault();
navigate(path);
};
const { addToCart } = useCart(); const { addToCart } = useCart();
// Функция для конвертации base64 строки в Blob
const base64ToBlob = (base64) => {
// Кодируем строку base64 обратно в массив байтов
const byteCharacters = atob(base64.split(',')[1]);
const byteNumbers = Array.from(byteCharacters).map((char) => char.charCodeAt(0));
const byteArray = new Uint8Array(byteNumbers);
// Создаем Blob из типизированного массива байтов
return new Blob([byteArray], { type: 'application/pdf' });
};
const openFile = (base64) => {
const base64Prefix = 'data:application/pdf;base64,';
const content = base64.includes(base64Prefix) ? base64 : `${base64Prefix}${base64}`;
// Создаем Blob из base64 строки
const blob = base64ToBlob(content);
// Создаем URL для Blob
const fileURL = URL.createObjectURL(blob);
// Открываем URL в новой вкладке
window.open(fileURL);
};
return ( return (
<Carousel className="book-carousel container-fluid p-5 mt-5"> <Carousel className="book-carousel container-fluid p-5 mt-5">
{lines.map((line) => ( {lines.map((line) => (
<Carousel.Item key={line.id} className="book-carousel-item"> <Carousel.Item key={line.id} className="book-carousel-item">
<a onClick={() => openFile(line.datafile)}> <a onClick={(event) => handlePageClick(event, `/page-edit/${line.id}`)}>
<img <img
className="carimg" className="carimg"
src={line.image} src={line.image}

View File

@ -36,7 +36,7 @@ const routes = [
title: 'Comics', title: 'Comics',
}, },
{ {
path: '/page-edit', path: '/page-edit/:id',
element: <PageEdit />, element: <PageEdit />,
}, },
{ {

View File

@ -1,11 +1,13 @@
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import LinesForm from '../components/lines/form/LinesForm.jsx'; import LinesForm from '../components/lines/form/LinesForm.jsx';
import useLinesItem from '../components/lines/hooks/LinesItemHook';
const PageEdit = () => { const PageEdit = () => {
const { id } = useParams(); const { id } = useParams();
const { item } = useLinesItem(id);
return ( return (
<LinesForm id={id} /> <LinesForm item={item} />
); );
}; };