1
0
Переглянути джерело

[front] refactor, album list initial, filter

Innocenty Enikeew 7 роки тому
батько
коміт
d8b120846b
2 змінених файлів з 75 додано та 12 видалено
  1. 5 0
      front/src/App.css
  2. 70 12
      front/src/App.js

+ 5 - 0
front/src/App.css

@@ -34,3 +34,8 @@
 .category-list select {
   min-width: 150px;
 }
+
+.AlbumList {
+  clear: both;
+  padding-top: 15px;
+}

+ 70 - 12
front/src/App.js

@@ -27,26 +27,55 @@ function CategoryFlatList(props) {
   );
 }
 
-class App extends Component {
+function AlbumList(props) {
+  const { error, isLoaded, items } = props.state;
+
+  var content;
+  if (error) {
+    content = <div>Error: {error.message}</div>
+  } else if (!isLoaded) {
+    content = <div>Loading</div>
+  } else {
+    content = (
+        <ul>
+        {items.map(item => (
+            <li key={item.id}>{item.artist} - {item.year} - {item.album}</li>
+        ))}
+      </ul>
+    );
+  }
+  return (
+      <div className="AlbumList">
+      <h2>{props.title}</h2>
+      {content}
+    </div>
+  );
+}
+
+class Player extends Component {
+  stateLoading = {
+    error: null,
+    isLoaded: false,
+    items: []
+  };
   constructor(props) {
     super(props);
     this.categories = [{type: 'artist', title: 'Artists'},
                        {type: 'year', title: 'Years'},
+                       {type: 'genre', title: 'Genres'},
                        {type: 'publisher', title: 'Labels'},
                        {type: 'country', title: 'Countries'},
                        {type: 'type', title: 'Album types'},
                        {type: 'status', title: 'Album statuses'}];
     this.state = {};
     for (var {type} of this.categories) {
-      this.state[type] = {
-        error: null,
-        isLoaded: false,
-        items: []
-      };
+      this.state[type] = Object.assign({}, this.stateLoading);
     }
+    this.state.album = Object.assign({}, this.stateLoading);
+    this.filterTimeout = null;
   }
   fetchCategory(cat) {
-    const {restrictions} = this.state;
+    const {restrictions, filter} = this.state;
 
     function getQueryString(params) {
       var esc = encodeURIComponent;
@@ -54,7 +83,10 @@ class App extends Component {
         .map(k => esc(k) + '=' + esc(params[k]))
         .join('&');
     }
-    const params = Object.assign({}, restrictions, {offset:0, limit:100});
+    var params = Object.assign({}, restrictions, {offset:0, limit:100});
+    if (cat === 'album' && filter) {
+      params.filter = filter;
+    }
     const qs = getQueryString(params);
 
     fetch('/cat/' + cat + (qs ? ('?' + qs) : ''))
@@ -70,20 +102,25 @@ class App extends Component {
           isLoaded: true,
           error: error
         }});
-      })
+      });
+    this.setState({[cat]: Object.assign({}, this.stateLoading)});
   }
   fetchAll() {
     const {restrictions} = this.state;
     console.log(restrictions);
     this.categories.map(({type}) => !restrictions[type] && this.fetchCategory(type))
+    this.fetchCategory('album');
   }
   componentDidMount() {
     this.setState({restrictions: {}});
   }
   componentDidUpdate(prevProps, prevState) {
+    console.log('stateChange');
     if (this.state.restrictions !== prevState.restrictions) {
       // Reload category filters on restriction changes
       this.fetchAll();
+    } else if (this.state.filter !== prevState.filter) {
+      this.fetchCategory('album');
     }
   }
   handleCategoryChange(type, value) {
@@ -96,6 +133,29 @@ class App extends Component {
     }
     this.setState({restrictions: restrictions});
   }
+  handleFilterChange = (e) => {
+    if (this.filterTimeout) {
+      clearInterval(this.filterTimeout);
+    }
+    const value = e.target.value;
+    this.filterTimeout = setTimeout(() => this.setState({filter:value}), 500);
+  }
+  render() {
+    return (
+        <div>
+        <div className="PlayerFilters">
+        {this.categories.map(({type, title}) => (
+            <CategoryFlatList key={type} title={title} state={this.state[type]} onChange={e => this.handleCategoryChange(type, e.target.value)}/>
+          ))}
+      </div><div style={{clear:'both', paddingBottom:'20px'}}/>
+        <input type="text" placeholder="Search albums" onChange={this.handleFilterChange} size={150} />
+        <AlbumList title="Albums" state={this.state.album} />
+      </div>
+    );
+  }
+}
+
+class App extends Component {
   render() {
     return (
       <div className="App">
@@ -103,9 +163,7 @@ class App extends Component {
           <img src={logo} className="App-logo" alt="logo" />
           <h1 className="App-title">Chad Music</h1>
         </header>
-        {this.categories.map(({type, title}) => (
-            <CategoryFlatList key={type} title={title} state={this.state[type]} onChange={e => this.handleCategoryChange(type, e.target.value)}/>
-        ))}
+        <Player/>
       </div>
     );
   }