code.lukegrehan.com ril / master frontend / src / index.js
master

Tree @master (Download .tar.gz)

index.js @masterraw · history · blame

import React, {useState, useEffect} from 'react';
import ReactDOM from 'react-dom';
import { Nav, Navbar, Button, ListGroup, Container} from 'react-bootstrap';
import './index.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { BsCheckAll } from 'react-icons/bs';
import axios from 'axios';

const CheckAll = ({onClick}) => <Button variant="primary" onClick={onClick}><BsCheckAll size="2em"/></Button>

const openUrl = (url, remove) => () => {
  window.open(url, '_blank');
  remove();
}

const Item = ({title, url, rowId, remove}) => {
  const maybeUrl = (title === url) ? "" : <div className="text-muted"> {url} </div>

  return (
    <ListGroup.Item action style={{textAlign:"center"}} onClick={openUrl(url, remove)}>
      <h4>{title}</h4>
      {maybeUrl}
    </ListGroup.Item>
  )
};

const App = () => {
  const [state, setState] = useState({loaded: false, items: []});

  useEffect(() => {
    axios.get("/items")
      .then(resp => resp.data)
      .then(data => ({loaded: true, items:data}))
      .then(setState);
  }, []);

  const removeItem = (rowId) => () => {
    const filtered = state.items.filter(item => item.rowid !== rowId);
    const newState = {...state, items:filtered};
    axios.delete(`/items/${rowId}`)
      .then(() => {
        setState(newState);
      });
  };

  const removeAll = () => {
    axios.get("/popAllItems")
      .then(() => {
        setState({...state, items:[]});
      });
  }

  const body = (!state.loaded)
    ?  <h1> loading ... </h1>
    : (<ListGroup>
          { state.items.map((item) => <Item title={item.title} url={item.url} rowId={item.rowid} key={item.rowid} remove={removeItem(item.rowid)} />) }
       </ListGroup>
    );

  return (
    <>
      <Navbar bg="light" expand="lg">
        <Navbar.Brand href="#home">Read it later</Navbar.Brand>
        <Nav className="ml-auto">
          <CheckAll onClick={removeAll} />
        </Nav>
      </Navbar>
      <Container style={{marginTop: "2rem"}}>
        {body}
      </Container>
    </>
  );
};

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);