summaryrefslogtreecommitdiff
path: root/examples/snowpack/src/components/PluginSearchPage.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'examples/snowpack/src/components/PluginSearchPage.jsx')
-rw-r--r--examples/snowpack/src/components/PluginSearchPage.jsx121
1 files changed, 121 insertions, 0 deletions
diff --git a/examples/snowpack/src/components/PluginSearchPage.jsx b/examples/snowpack/src/components/PluginSearchPage.jsx
new file mode 100644
index 000000000..51c7e6b0f
--- /dev/null
+++ b/examples/snowpack/src/components/PluginSearchPage.jsx
@@ -0,0 +1,121 @@
+import { h, Fragment } from 'preact';
+import { useEffect, useState } from 'preact/hooks';
+import Styles from './PluginSearchPage.module.css';
+
+async function searchPlugins(val) {
+ const params3 = new URLSearchParams([
+ ['q', 'snowpack plugin ' + (val || '')],
+ ['count', '100'],
+ ]);
+ const res = await fetch(
+ `https://api.skypack.dev/v1/search?${params3.toString()}`,
+ );
+ const jsonres = await res.json();
+ return jsonres.results;
+}
+
+function Card({ result }) {
+ const updatedAtFormatted = Intl.DateTimeFormat('en', {
+ month: 'long',
+ day: 'numeric',
+ year: 'numeric',
+ }).format(Date.parse(result.updatedAt));
+ return (
+ <li class={Styles.Card}>
+ <img class={Styles.Icon__Plugin} src="/img/plug-light.svg" />
+ <header class={Styles.CardHeader}>
+ <h3 class={Styles.CardName}>
+ <a href="https://www.npmjs.com/package/{result.name}" target="_blank">
+ <span itemprop="name">{result.name}</span>
+ </a>
+ </h3>
+ </header>
+ <p class={Styles.CardDesc} itemprop="description">
+ {result.description.split('. ')[0]}
+ </p>
+ <p class={Styles.CardSubtitle}>
+ Updated
+ <time class="" datetime={result.updatedAt}>
+ {updatedAtFormatted}
+ </time>
+ </p>
+ </li>
+ );
+}
+
+function PluginSearchPageLive() {
+ const searchParams = new URLSearchParams(window.location.search);
+ const [results, setResults] = useState(null);
+ const [searchQuery, setSearchQuery] = useState(searchParams.get('q'));
+ useEffect(() => {
+ (async () => {
+ setResults(await searchPlugins(searchParams.get('q')));
+ })();
+ }, []);
+
+ async function onFormSubmit(e) {
+ e.preventDefault();
+ const form = new FormData(e.target);
+ const formula = form.get('q');
+ // document.getElementById('loading-message').style.display = 'block';
+ const searchParams = new URLSearchParams(window.location.search);
+ searchParams.set('q', formula);
+ window.history.pushState(null, null, '?' + searchParams.toString());
+ setSearchQuery(formula);
+ setResults(await searchPlugins(formula));
+ return false;
+ }
+
+ return (
+ <>
+ <form
+ name="myform"
+ id="myform"
+ class={Styles.Form}
+ action="https://www.npmjs.com/search"
+ method="GET"
+ onSubmit={onFormSubmit}
+ >
+ <input
+ type="search"
+ name="q"
+ defaultValue={searchQuery}
+ placeholder="search Sass, sitemaps, image optimization..."
+ class={Styles.Input}
+ />
+ <button type="submit" class={Styles.Submit}>
+ Search
+ </button>
+ </form>
+ <div class={Styles.Count} id="total-result-count">
+ {!searchQuery &&
+ results &&
+ results.length > 50 &&
+ `${results.length}+ plugins available!`}
+ </div>
+ <section id="search-results" class={Styles.Results}>
+ {!results && (
+ <div id="loading-message" class={Styles.Loading}>
+ Loading...
+ </div>
+ )}
+ {results && results.length === 0 && (
+ <ul class={Styles.CardList}>
+ <li style="margin: 1rem; text-align: center;">No results found.</li>
+ </ul>
+ )}
+ {results && results.length > 0 && (
+ <ul class={Styles.CardList}>
+ {results.map((r) => (
+ <Card result={r} />
+ ))}
+ </ul>
+ )}
+ </section>
+ </>
+ );
+}
+
+export default function PluginSearchPage(props) {
+ return import.meta.env.astro ? <div>Loading...</div> : <PluginSearchPageLive {...props} />
+}