· 6 years ago · Jan 21, 2020, 09:50 AM
1import React, { Component } from 'react';
2import './App.css';
3import Book from './Book/Book';
4import styles from './App.module.css';
5import TextField from '@material-ui/core/TextField';
6import Button from '@material-ui/core/Button';
7import FilterResults from 'react-filter-search';
8import InputLabel from '@material-ui/core/InputLabel';
9import MenuItem from '@material-ui/core/MenuItem';
10import FormControl from '@material-ui/core/FormControl';
11import Select from '@material-ui/core/Select';
12import axios from 'axios';
13import Card from '@material-ui/core/Card';
14import CardActions from '@material-ui/core/CardActions';
15import CardContent from '@material-ui/core/CardContent';
16import SimpleReactValidator from 'simple-react-validator';
17import $ from 'jquery';
18import { makeStyles, ThemeProvider, useTheme, createMuiTheme } from '@material-ui/core/styles';
19import SearchIcon from '@material-ui/icons/Search';
20import { InputAdornment } from '@material-ui/core';
21import { green, purple } from '@material-ui/core/colors';
22//wyglad wyszukiwarki\
23//pozycja wyszukiwarki
24//walidacja pol w formularzu
25//api
26//naprawienie pol przy edycji jakiejs ksiazki bo sie te okienka nie robia wieksze i sie napisy zlewaja
27class App extends Component {
28 constructor(props) {
29 super(props);
30 this.validator = new SimpleReactValidator();
31 this.state = {
32 books : [],
33 authors : [],
34 showBooks : false,
35 updateButtonShow : false,
36 index : null,
37 searchTerm : '',
38 value : '',
39 data : [],
40 sort : ''
41 };
42 }
43 state = {
44 books : [
45 // {
46 // id : 'asdad213',
47 // title : 'wwwww',
48 // author : 'Mieszko I',
49 // publisher : 'publisher1',
50 // year : '1997',
51 // price : '200'
52 // },
53 // {
54 // id : 'asqwecz13',
55 // title : 'ccccc',
56 // author : 'Adam Solon',
57 // publisher : 'publisher2',
58 // year : '1992',
59 // price : '400'
60 // },
61 // {
62 // id : 'czxve',
63 // title : 'iiii',
64 // author : 'Kuba',
65 // publisher : 'publisher3',
66 // year : '1993',
67 // price : '100'
68 // },
69 // {
70 // id : 'aczbdd',
71 // title : 'bbbbb',
72 // author : 'Marios',
73 // publisher : 'kasztan',
74 // year : '1994',
75 // price : '300'
76 // }
77 ],
78 authors : [],
79 showBooks : true,
80 updateButtonShow : false,
81 index : null,
82 searchTerm : '',
83 value : '',
84 data : [],
85 sort : '',
86 title : '',
87 author : '',
88 publisher : '',
89 year : '',
90 price : '',
91 formErrors : {
92 title : '',
93 author : '',
94 publisher : '',
95 year : '',
96 price : ''
97 },
98 titleValid : false,
99 authorValid : false,
100 publisherValid : false,
101 yearValid : false,
102 priceValid : false,
103 formValid : false,
104 intervalId : 0
105 };
106
107 componentDidMount() {
108 // let one = 'http://localhost:3000/books';
109 // let two = 'http://localhost:3000/authors';
110 // const requestOne = axios.get(one);
111 // const requestTwo = axios.get(two);
112 // axios
113 // .all([ requestOne, requestTwo ])
114 // .then(
115 // axios.spread((...responses) => {
116 // console.log('>>>>>>>>>' + responses[0]);
117 // this.setState({ books: responses[0].data });
118 // this.setState({ authors: responses[1].data });
119 // })
120 // )
121 // .catch((error) => {
122 // console.log('nie udalo sie pobrac danych z api' + error);
123 // });
124 fetch('http://localhost:3000/authors').then((response) => response.json()).then(
125 (json) => {
126 this.setState({ authors: json });
127 console.log(this.state.authors);
128 },
129 (error) => {
130 console.log('nie udalo sie pobrac danych z api' + error);
131 }
132 );
133 fetch('http://localhost:3000/books').then((response) => response.json()).then(
134 (json) => {
135 this.setState({ books: json });
136 console.log(this.state.books);
137 },
138 (error) => {
139 console.log('nie udalo sie pobrac danych z api' + error);
140 }
141 );
142 }
143 $() {
144 $.fn.inputFilter = function(inputFilter) {
145 return this.on('input keydown keyup mousedown mouseup select contextmenu drop', function() {
146 if (inputFilter(this.value)) {
147 this.oldValue = this.value;
148 this.oldSelectionStart = this.selectionStart;
149 this.oldSelectionEnd = this.selectionEnd;
150 }
151 else if (this.hasOwnProperty('oldValue')) {
152 this.value = this.oldValue;
153 this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
154 }
155 });
156 };
157 }
158 $() {
159 $('#title').keypress(function(e) {
160 var txt = String.fromCharCode(e.which);
161 console.log(txt + ' : ' + e.which);
162 if (!txt.match(/[A-Za-z]/)) {
163 return false;
164 }
165 });
166 }
167 // $('#name').inputFilter(function(value) {
168 // return /^[a-z\u00c0-\u024f]*$/i.test(value);
169 // });
170 // $('#price, #count').inputFilter(function(value) {
171 // return /^\d*[.]?\d*$/.test(value);
172 // });
173 handleChangeFilter = (event) => {
174 const { value } = event.target;
175 this.setState({ value });
176 };
177 deleteArticleHandler = (articleIndex) => {
178 // const articles = this.state.articles.slice();
179 const books = [ ...this.state.books ];
180 axios.delete('http://localhost:3000/books/' + books[articleIndex].id).then((respone) => {
181 console.log(respone);
182 });
183 books.splice(articleIndex, 1);
184 this.setState({ books: books });
185 };
186 updateBookHandler = (bookIndex) => {
187 //window.scrollTo(0, 0);
188 this.scrollToTop();
189 const updateButtonVisible = this.state.updateButtonShow;
190 this.setState({ updateButtonShow: true });
191 const books = this.state.books;
192 this.setState({ index: bookIndex });
193 document.getElementById('title').value = books[bookIndex].title;
194 document.getElementById('author').value = books[bookIndex].author;
195 document.getElementById('publisher').value = books[bookIndex].publisher;
196 document.getElementById('year').value = books[bookIndex].year;
197 document.getElementById('price').value = books[bookIndex].price;
198 };
199
200 addBookToState = () => {
201 const title = document.getElementById('title').value;
202 const author = document.getElementById('author').value;
203 const publisher = document.getElementById('publisher').value;
204 const year = document.getElementById('year').value;
205 const price = document.getElementById('price').value;
206 const id = Math.floor(new Date() / 1000);
207 console.log(id);
208 const book = {
209 id : id,
210 title : title,
211 author : author,
212 publisher : publisher,
213 year : year,
214 price : price
215 };
216 const books = [ ...this.state.books ];
217 books.push(book);
218 this.setState({ books: books });
219
220 document.getElementById('title').value = '';
221 document.getElementById('author').value = '';
222 document.getElementById('publisher').value = '';
223 document.getElementById('year').value = '';
224 document.getElementById('price').value = '';
225 axios.post('http://localhost:3000/books', book).then((response) => {
226 console.log(response);
227 });
228 if (!this.checkIfAuthorExists(book.author)) {
229 const author = {
230 id : id,
231 name : book.author
232 };
233 const authors = [ ...this.state.authors ];
234 authors.push(author);
235 this.setState({ authors: authors });
236 axios.post('http://localhost:3000/authors', author).then((response) => {
237 console.log(response);
238 });
239 }
240 else {
241 console.log('Nie dodano autora ponieważ juz taki istnieje');
242 }
243 };
244 scrollStep() {
245 if (window.pageYOffset === 0) {
246 clearInterval(this.state.intervalId);
247 }
248 window.scroll(0, window.pageYOffset - this.props.scrollStepInPx);
249 }
250
251 scrollToTop() {
252 let intervalId = setInterval(this.scrollStep.bind(this), '0');
253 this.setState({ intervalId: intervalId });
254 }
255 checkIfAuthorExists = (authorName) => {
256 const authors = this.state.authors;
257 for (let i = 0; i < authors.length; i++) {
258 if (authors[i].name === authorName) return true;
259 }
260 return false;
261 };
262 updateBookToState = () => {
263 const index = this.state.index;
264 const books = [ ...this.state.books ];
265 const title = document.getElementById('title').value;
266 const author = document.getElementById('author').value;
267 const publisher = document.getElementById('publisher').value;
268 const year = document.getElementById('year').value;
269 const price = document.getElementById('price').value;
270 const book = {
271 id : books[index].id,
272 title : title,
273 author : author,
274 publisher : publisher,
275 year : year,
276 price : price
277 };
278 books.splice(index, 1, book);
279 this.setState({ books: books });
280 axios.put('http://localhost:3000/books/' + books[index].id, book).then((response) => {
281 console.log(response);
282 });
283 document.getElementById('title').value = '';
284 document.getElementById('author').value = '';
285 document.getElementById('publisher').value = '';
286 document.getElementById('year').value = '';
287 document.getElementById('price').value = '';
288 this.setState({
289 updateButtonShow : false
290 });
291 };
292 toggleBooksHandler = () => {
293 const doesShow = this.state.showBooks;
294 this.setState({ showBooks: !doesShow });
295 };
296 compareTitles(a, b) {
297 const titleA = a.title.toUpperCase();
298 const titleB = b.title.toUpperCase();
299 let comparison = 0;
300 if (titleA > titleB) {
301 comparison = 1;
302 }
303 else if (titleA < titleB) {
304 comparison = -1;
305 }
306 return comparison;
307 }
308 comparePricesAscending(a, b) {
309 const priceA = Number(a.price);
310 const priceB = Number(b.price);
311 let comparison = 0;
312 if (priceA > priceB) {
313 comparison = 1;
314 }
315 else if (priceA < priceB) {
316 comparison = -1;
317 }
318 return comparison;
319 }
320
321 comparePricesDescending(a, b) {
322 const priceA = Number(a.price);
323 const priceB = Number(b.price);
324 let comparison = 0;
325 if (priceA > priceB) {
326 comparison = 1;
327 }
328 else if (priceA < priceB) {
329 comparison = -1;
330 }
331 return comparison * -1;
332 }
333 compareAuthors(a, b) {
334 const authorA = a.author.toUpperCase();
335 const authorB = b.author.toUpperCase();
336 let comparison = 0;
337 if (authorA > authorB) {
338 comparison = 1;
339 }
340 else if (authorA < authorB) {
341 comparison = -1;
342 }
343 return comparison;
344 }
345 setSort = (value) => {
346 this.setState({ sort: value });
347 const originalBooks = [ ...this.state.books ];
348 let books = this.state.books;
349 if (this.state.value === 0) {
350 this.setState({ books: originalBooks });
351 }
352 else if (value === 1) {
353 books.sort(this.comparePricesAscending);
354 this.setState({ books: books });
355 console.log(this.state.sort);
356 }
357 else if (value === 2) {
358 books.sort(this.comparePricesDescending);
359 this.setState({ books: books });
360 }
361 else if (value === 3) {
362 books.sort(this.compareTitles);
363 this.setState({ books: books });
364 }
365 else if (value === 4) {
366 books.sort(this.compareAuthors);
367 this.setState({ books: books });
368 }
369 };
370 handleChange = (event) => {
371 this.setSort(event.target.value);
372 };
373 getAuthorName = (bookIndex) => {
374 // console.log(this.state.authors);
375 // const authors = this.state.authors.splice();
376 // console.log(authors);
377 // const author = authors.find((x) => x.id === author_id);
378 // return author.name;
379 const book = this.state.books[bookIndex];
380 const author_id = Number(book.author_id);
381 const authors = this.state.authors;
382 for (let i = 0; i < authors.length; i++) {
383 if (authors[i].id === author_id) return authors[i].name;
384 }
385 //const author = authors.find((x) => x.id === author_id);
386 return 'author.name';
387 };
388 getAuthorNameById = (authorId) => {
389 const authors = this.state.authors;
390 for (let i = 0; i < authors.length; i++) {
391 if (authors[i].id === authorId) {
392 return authors[i].name;
393 }
394 }
395 return null;
396 };
397 findObjectByKey(array, key, value) {
398 for (var i = 0; i < array.length; i++) {
399 if (array[i][key] === value) {
400 return array[i];
401 }
402 }
403 return null;
404 }
405 handleUserInput(e) {
406 const name = e.target.name;
407 const value = e.target.value;
408 this.setState({ [name]: value }, () => {
409 this.validateField(name, value);
410 });
411 }
412 validateField(fieldName, value) {
413 let fieldValidationErrors = this.state.formErrors;
414 let emailValid = this.state.emailValid;
415 let passwordValid = this.state.passwordValid;
416 let titleValid = this.state.titleValid;
417 const formValid = this.state.formValid;
418
419 switch (fieldName) {
420 case 'email':
421 emailValid = value.match(/^([\w.%+-]+)@([\w-]+\.)+([\w]{2,})$/i);
422 fieldValidationErrors.email = emailValid ? '' : ' is invalid';
423 break;
424 case 'password':
425 passwordValid = value.length >= 6;
426 fieldValidationErrors.password = passwordValid ? '' : ' is too short';
427 break;
428 case 'title':
429 if (titleValid > 2) {
430 this.setState({ formValid: true });
431 }
432 default:
433 break;
434 }
435 this.setState(
436 {
437 formErrors : fieldValidationErrors,
438 emailValid : emailValid,
439 passwordValid : passwordValid
440 },
441 this.validateForm
442 );
443 }
444
445 validateForm() {
446 this.setState({ formValid: this.state.emailValid && this.state.passwordValid });
447 }
448 render() {
449 const darkTheme = createMuiTheme({
450 palette : {
451 type : 'dark'
452 }
453 });
454 const { data, value } = this.state;
455 let books = null;
456 //let buttonStyles = [ styles.toggleButton ];
457 const searchResult = (
458 <FilterResults
459 value={value}
460 data={this.state.books}
461 renderResults={(results) => (
462 <div>
463 {results.map((el, index) => (
464 <div>
465 <Book
466 title={el.title}
467 author={el.author}
468 key={el.id}
469 publisher={el.publisher}
470 year={el.year}
471 price={el.price}
472 />
473 </div>
474 ))}
475 </div>
476 )}
477 />
478 );
479 let authors = this.state.authors;
480 if (authors.length > 0) {
481 //console.log(authors[0]);
482 }
483 books = this.state.books.map((book, index) => {
484 //console.log(this.state.books);
485 //console.log(this.state.authors);
486 //const authorName = this.state.authors.find((x) => x.id === book.author_id);
487 //const authorName = this.state.authors[1].id;
488 //console.log(authors[0]);
489 const authorName = JSON.parse(JSON.stringify(this.state.authors));
490 const authorIndex = authorName.findIndex((x) => x.id === book.author_id);
491 //console.log(authorIndex);
492 //console.log(authorName);
493 // if (this.state.authors.length > 0) {
494 // console.log(this.state.authors);
495 // authorName = this.state.authors;
496 // }
497 //findAuthor()
498 //if (this.state.showBooks) {
499 // if (this.state.authors > 0) {
500
501 return (
502 <Book
503 title={book.title}
504 author={book.author}
505 //author={authorName.find((x) => x.id === book.author_id).name}
506 //author={book.author_id}
507 deleteClick={() => this.deleteArticleHandler(index)}
508 updateClick={() => this.updateBookHandler(index)}
509 key={book.id}
510 publisher={book.publisher}
511 year={book.year}
512 price={book.price}
513 />
514 );
515 //}
516 //}
517 });
518 if (this.state.updateButtonShow) {
519 }
520 const articleStyles = [];
521
522 if (this.state.books.length === 1) {
523 articleStyles.push('OneArticle');
524 }
525
526 if (this.state.books.length >= 4) {
527 articleStyles.push('GreenArticles');
528 }
529 else {
530 articleStyles.push('OrangeArticles');
531 }
532 const theme2 = createMuiTheme({
533 palette : {
534 primary : green
535 }
536 });
537 const addButton = (
538 <ThemeProvider theme={theme2}>
539 <Button
540 style={{ margin: 10 }}
541 id="addButton"
542 onClick={this.addBookToState}
543 variant="contained"
544 color="primary"
545 >
546 Dodaj książkę
547 </Button>
548 </ThemeProvider>
549 );
550 const updateButton = (
551 <Button
552 style={{ margin: 10 }}
553 id="addButton"
554 onClick={this.updateBookToState}
555 variant="contained"
556 color="primary"
557 >
558 Aktualizuj książkę
559 </Button>
560 );
561 const theme = createMuiTheme();
562
563 return (
564 <div className={styles.App}>
565 <ThemeProvider theme={darkTheme}>
566 <div className={styles.form}>
567 <div className={styles.MyForm}>
568 <div className="container">
569 <form autoComplete="off">
570 <div>
571 <TextField
572 value={this.state.title}
573 required
574 style={{ margin: 8 }}
575 id="title"
576 label="Tytuł"
577 name="title"
578 InputLabelProps={{ shrink: true }}
579 />
580 </div>
581 <div>
582 <TextField
583 value={this.state.author}
584 required
585 style={{ margin: 8 }}
586 id="author"
587 label="Autor"
588 name="author"
589 InputLabelProps={{ shrink: true }}
590 />
591 </div>
592 <div>
593 <TextField
594 value={this.state.publisher}
595 required
596 style={{ margin: 8 }}
597 id="publisher"
598 label="Wydawnictwo"
599 name="publisher"
600 InputLabelProps={{ shrink: true }}
601 />
602 </div>
603 <div>
604 <TextField
605 value={this.state.year}
606 required
607 style={{ margin: 8 }}
608 id="year"
609 label="Rok wydania"
610 name="year"
611 InputLabelProps={{ shrink: true }}
612 />
613 </div>
614 <div>
615 <TextField
616 value={this.state.price}
617 required
618 style={{ margin: 8 }}
619 id="price"
620 label="Cena"
621 name="price"
622 InputLabelProps={{ shrink: true }}
623 />
624 </div>
625 </form>
626 </div>
627 {this.state.updateButtonShow ? updateButton : addButton}
628 <br />
629 </div>
630 {/* <button className={buttonStyles.join(' ')} onClick={this.toggleArticlesHandler}>
631 Dodaj książkę
632 </button> */}
633 {/* <div className={articleStyles.join(' ')}>{books}</div> */}
634 </div>
635 <div className={styles.mainCol}>
636 <div className={styles.sort}>
637 <FormControl variant="filled">
638 <InputLabel id="demo-simple-select-filled-label">Sortuj</InputLabel>
639 <Select
640 labelId="demo-simple-select-filled-label"
641 id="demo-simple-select-filled"
642 value={this.state.sort}
643 onChange={this.handleChange}
644 style={({ width: 14 + 'em' }, { minWidth: 200 + 'px' })}
645 >
646 <MenuItem value={0}>
647 <em>brak</em>
648 </MenuItem>
649 <MenuItem value={1}>Cena: od najniższej</MenuItem>
650 <MenuItem value={2}>Cena: od najwyższej</MenuItem>
651 <MenuItem value={3}>Tytuł: od A do Z</MenuItem>
652 <MenuItem value={4}>Autor: od A do Z</MenuItem>
653 </Select>
654 </FormControl>
655 </div>
656 <div>{this.state.value ? searchResult : books}</div>
657 </div>
658 <div>
659 {/* <h2>Filtruj: </h2>
660 <input type="text" value={value} onChange={this.handleChangeFilter} /> */}
661 <TextField
662 value={value}
663 margin="normal"
664 label="Filtruj"
665 onChange={this.handleChangeFilter}
666 InputProps={{
667 startAdornment : (
668 <InputAdornment position="start">
669 <SearchIcon />
670 </InputAdornment>
671 )
672 }}
673 />
674 </div>
675 </ThemeProvider>
676 </div>
677 );
678 }
679}
680
681export default App;