Skip to content

Instantly share code, notes, and snippets.

@EmmanuelDemey
Created January 30, 2024 16:25
Show Gist options
  • Save EmmanuelDemey/2ffba76078dce389e2d0003c8ab684af to your computer and use it in GitHub Desktop.
Save EmmanuelDemey/2ffba76078dce389e2d0003c8ab684af to your computer and use it in GitHub Desktop.
import "bulma/css/bulma.css";
import { useEffect, useState } from "react";
type Person = {
name: string;
height: string;
mass: string;
hair_color: string;
skin_color: string;
eye_color: string;
birth_year: string;
gender: string;
homeworld: string;
films: string[];
species: any[];
vehicles: string[];
starships: string[];
created: string;
edited: string;
url: string;
};
type People = Array<Person>;
type PeopleFilterProps = {
onFilterChange: (filter: string) => void;
};
const PeopleFilter = ({ onFilterChange }: PeopleFilterProps) => {
return (
<div className="field">
<div className="control">
<input className="input is-info" type="text" onChange={(e) => onFilterChange(e.target.value)} />
</div>
</div>
);
};
type PeopleTableProps = {
data: People;
};
const PeopleTable = ({ data }: PeopleTableProps) => {
return (
<table className="table is-fullwidth">
<thead>
<tr>
<th>Nom</th>
<th>Genre</th>
<th>Année de naissance</th>
</tr>
</thead>
<tbody>
{data.map((p) => {
return <PeopleItem person={p}></PeopleItem>;
})}
</tbody>
</table>
);
};
type PeopleItemProps = {
person: Person;
};
const PeopleItem = ({ person }: PeopleItemProps) => {
return (
<tr>
<td>{person.name}</td>
<td>{person.gender}</td>
<td>{person.birth_year}</td>
</tr>
);
};
function useFetch<DataType>(url: string) {
const [data, setData] = useState<DataType[]>([]);
const [filterValue, setFilterValue] = useState<string>("");
const [loading, setLoading] = useState<boolean>(false);
useEffect(() => {
setLoading(true);
fetch(url + "?search=" + filterValue)
.then((response) => response.json())
.then((body) => setData(body.results))
.finally(() => setLoading(false));
}, [filterValue, url]);
return {
data,
loading,
setFilterValue,
};
}
function App() {
const { loading, data: people, setFilterValue } = useFetch<Person>("https://swapi.dev/api/people");
return (
<>
<PeopleFilter onFilterChange={(value) => setFilterValue(value)}></PeopleFilter>
{loading ? (
<progress className="progress is-small is-primary" max="100"></progress>
) : (
<PeopleTable data={people}></PeopleTable>
)}
</>
);
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment