Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | 6x 4x 3x 3x 6x 6x 4x 6x 15x 3x | import { useEffect } from "react"; import { useQuery } from "react-query"; import { Row, Col } from "@canonical/react-components"; import { TopicCard, LoadingCard } from "@canonical/store-components"; type Topic = { topic_id: number; name: string; slug: string; description: string; categories: Array<string>; }; type Props = { topicsQuery: string | null; }; function Topics({ topicsQuery }: Props) { const getTopics = async () => { const response = await fetch(`/topics.json?q=${topicsQuery}`); const data = await response.json(); return { topics: data.topics.slice(0, 3), }; }; const { data, status, refetch, isFetching } = useQuery("topics", getTopics); useEffect(() => { refetch(); }, [topicsQuery]); return ( <> <h2 className="p-muted-heading">Top related topics</h2> <Row> {isFetching && [...Array(3)].map((_item, index) => ( <Col size={3} key={index}> <LoadingCard height={180} /> </Col> ))} {!isFetching && status === "success" && data.topics.length > 0 && data.topics.map((topic: Topic) => ( <TopicCard data={topic} truncateTitle truncateContent className="col-3 u-equal-height" key={topic.topic_id.toString()} /> ))} </Row> <p> <a href="/topics">See all topics ›</a> </p> </> ); } export default Topics; |