|
1 | 1 | import Footer from "./layouts/Footer";
|
2 | 2 | import Header from "./layouts/Header";
|
3 |
| -import SnippetList from "./components/SnippetList"; |
4 |
| -import Sidebar from "./layouts/Sidebar"; |
5 |
| -import { Navigate, useLocation } from "react-router-dom"; |
6 |
| -import SnippetModal from "./components/SnippetModal"; |
| 3 | +import Banner from "./layouts/Banner"; |
| 4 | +import { useState } from "react"; |
| 5 | +import Button from "./components/Button"; |
| 6 | +import { CopyIcon, ExpandIcon } from "./components/Icons"; |
| 7 | +import slugify from "./utils/slugify"; |
| 8 | +import { useLanguages } from "./hooks/useLanguages"; |
| 9 | +import { useCategories } from "./hooks/useCategories"; |
| 10 | +import { useSnippets } from "./hooks/useSnippets"; |
| 11 | + |
| 12 | +type LanguageType = { |
| 13 | + language: string; |
| 14 | + icon: string; |
| 15 | +}; |
| 16 | + |
| 17 | +type SnippetType = { |
| 18 | + title: string; |
| 19 | + description: string; |
| 20 | + code: string; |
| 21 | + tags: string[]; |
| 22 | + author: string; |
| 23 | +}; |
7 | 24 |
|
8 | 25 | const App = () => {
|
9 |
| - const location = useLocation(); |
| 26 | + const [language, setLanguage] = useState<LanguageType>({ |
| 27 | + language: "Sass", |
| 28 | + icon: "/icons/sass.svg", |
| 29 | + }); |
| 30 | + const [category, setCategory] = useState<string>(""); |
| 31 | + const [snippet, setSnippet] = useState<SnippetType>(); |
| 32 | + |
| 33 | + const { fetchedLanguages } = useLanguages(); |
| 34 | + const { fetchedCategories } = useCategories(language.language); |
| 35 | + const { fetchedSnippets } = useSnippets(language.language, category); |
10 | 36 |
|
11 |
| - if (location.pathname === "/") { |
12 |
| - return <Navigate to="/javascript/dom-manipulation" replace />; |
13 |
| - } |
| 37 | + const handleLanguageChange = ( |
| 38 | + event: React.ChangeEvent<HTMLSelectElement> |
| 39 | + ) => { |
| 40 | + const language = fetchedLanguages.find( |
| 41 | + (lan) => slugify(lan.language) === slugify(event.target.value) |
| 42 | + ); |
| 43 | + if (language) { |
| 44 | + setLanguage(language); |
| 45 | + } |
| 46 | + }; |
14 | 47 |
|
15 | 48 | return (
|
16 | 49 | <>
|
17 |
| - {/* Had to put the modal in App.tsx as well for it to work despite |
18 |
| - it's also being created in HTML with portal. |
19 |
| - If you know why it's that way, please let me know. */} |
20 |
| - <SnippetModal /> |
| 50 | + {/* <SnippetModal /> */} |
21 | 51 | <div className="container flow" data-flow-space="xl">
|
22 | 52 | <Header />
|
23 |
| - <div className="heading"> |
24 |
| - <h1 className="main-title"> |
25 |
| - Made to save your <span className="text-highlight">time.</span> |
26 |
| - </h1> |
27 |
| - <p> |
28 |
| - Find the necessary snippet in seconds, across multiple languages. |
29 |
| - Just search and copy! |
30 |
| - </p> |
31 |
| - </div> |
| 53 | + <Banner /> |
32 | 54 | <main className="main">
|
33 |
| - <Sidebar /> |
34 |
| - <SnippetList /> |
| 55 | + <aside className="sidebar flow"> |
| 56 | + <select |
| 57 | + id="languages" |
| 58 | + className="language-switcher" |
| 59 | + onChange={handleLanguageChange} |
| 60 | + > |
| 61 | + {fetchedLanguages.map(({ language }) => ( |
| 62 | + <option key={language} value={slugify(language)}> |
| 63 | + {language} |
| 64 | + </option> |
| 65 | + ))} |
| 66 | + </select> |
| 67 | + <ul role="list" className="categories"> |
| 68 | + {fetchedCategories.map((name) => ( |
| 69 | + <li className="category"> |
| 70 | + <button onClick={() => setCategory(name)}>{name}</button> |
| 71 | + </li> |
| 72 | + ))} |
| 73 | + </ul> |
| 74 | + </aside> |
| 75 | + <section className="flow"> |
| 76 | + <h2 className="section-title">{category}</h2> |
| 77 | + <ul role="list" className="snippets"> |
| 78 | + {fetchedSnippets.map((snippet) => ( |
| 79 | + <li className="snippet"> |
| 80 | + <div className="snippet__preview"> |
| 81 | + <img src={language.icon} alt={language.language} /> |
| 82 | + <Button isIcon={true} className="snippet__copy"> |
| 83 | + <CopyIcon /> |
| 84 | + </Button> |
| 85 | + </div> |
| 86 | + |
| 87 | + <div className="snippet__content"> |
| 88 | + <h3 className="snippet__title">{snippet.title}</h3> |
| 89 | + <Button isIcon={true}> |
| 90 | + <ExpandIcon /> |
| 91 | + </Button> |
| 92 | + </div> |
| 93 | + </li> |
| 94 | + ))} |
| 95 | + </ul> |
| 96 | + </section> |
35 | 97 | </main>
|
36 |
| - <hr className="divider" /> |
37 | 98 | <Footer />
|
38 | 99 | </div>
|
39 | 100 | </>
|
|
0 commit comments