Skip to content

Instantly share code, notes, and snippets.

@mauricedb
Created November 14, 2017 12:12
Show Gist options
  • Save mauricedb/62d37298150a9080f9867d13d97aa059 to your computer and use it in GitHub Desktop.
Save mauricedb/62d37298150a9080f9867d13d97aa059 to your computer and use it in GitHub Desktop.
Add a route to view/edit movie details
import { h, Component } from "preact";
import { Router } from "preact-router";
import Header from "./header";
import Home from "../routes/home";
import Movies from "../routes/movies";
import Movie from "../routes/movie";
export default class App extends Component {
/** Gets fired when the route changes.
* @param {Object} event "change" event from [preact-router](http://git.io/preact-router)
* @param {string} event.url The newly routed URL
*/
handleRoute = e => {
this.currentUrl = e.url;
};
render() {
return (
<div id="app" class="container">
<Header />
<Router onChange={this.handleRoute}>
<Home path="/" />
<Movies path="/movies" />
<Movie path="/movie/:id" />
</Router>
</div>
);
}
}
import { h } from "preact";
export default ({ value, name, children, onChange }) => (
<div class="form-group">
<label for={name}>{children}</label>
<input
type="text"
class="form-control"
id={name}
value={value}
onChange={e => onChange(e.target.value, name)}
/>
</div>
);
import { h } from "preact";
import { Link } from "preact-router";
import style from "./style";
export default ({ movie }) => (
<div class={["card", style.movieCard].join(" ")}>
<img class="card-img-top" src={movie.image} alt="Card image cap" />
<div class="card-body">
<h4 class="card-title">{movie.title}</h4>
<Link href={`/movie/${movie.id}`}>Edit</Link>
<p class="card-text">{movie.overview}</p>
</div>
<div class="card-footer text-cente">
{movie.genres.map(genre => (
<span
class={["badge", "badge-pill", "badge-info", style.genreBadge].join(
" "
)}
>
{genre}
</span>
))}
</div>
</div>
);
import { h } from "preact";
export default ({ value, name, children, onChange }) => (
<div class="form-group">
<label for={name}>{children}</label>
<textarea
type="text"
class="form-control"
id={name}
value={value}
rows="5"
onChange={e => onChange(e.target.value, name)}
/>
</div>
);
export default from "./movie-container";
import { h, Component } from "preact";
import MoviePresentation from "./movie-presentation";
export default class MovieContainer extends Component {
state = { movie: null };
onChange = (value, name) => {
const movie = { ...this.state.movie, [name]: value };
this.setState({ movie });
};
onSave = () => {
alert("Saving " + this.state.movie.title);
};
componentDidMount() {
const id = +this.props.id;
fetch("/api/movies.json")
.then(rsp => rsp.json())
.then(movies => movies.find(m => m.id === id))
.then(movie => this.setState({ movie }));
}
render(props, { movie }) {
if (!movie) return null;
return (
<MoviePresentation
movie={movie}
onChange={this.onChange}
onSave={this.onSave}
/>
);
}
}
import { h } from "preact";
import { Link } from "preact-router";
import Input from "../../components/input";
import TextArea from "../../components/textarea";
export default ({ movie, onChange, onSave }) => (
<form>
<Input value={movie.title} name="title" onChange={onChange}>
Title
</Input>
<TextArea value={movie.overview} name="overview" onChange={onChange}>
Overview
</TextArea>
<div class="btn-group">
<button type="button" className="btn btn-primary" onClick={onSave}>
Save changes
</button>
<Link className="btn btn-warning" href="/movies">
Cancel
</Link>
</div>
</form>
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment