diff --git a/dev.html b/dev.html new file mode 100644 index 0000000..4434afc --- /dev/null +++ b/dev.html @@ -0,0 +1,178 @@ + + + + + Dashboard + + + + + +
+

+ Dashboard +

+ +
+
+ +
+
+ +
+ + +
+ +
+
+
+ +
+
+
+
+ +

+ OpenMediaVault +

+
+

+ OpenMediaVault +

+
+ +
+
+ +

+ Immich +

+
+

+ Immich +

+
+
+
+ +

+ Portainer +

+
+

+ Portainer +

+
+
+
+ +

+ Print Server +

+
+

+ Print Server +

+
+
+
+ + + + diff --git a/example.html b/example.html new file mode 100644 index 0000000..e61e665 --- /dev/null +++ b/example.html @@ -0,0 +1,77 @@ + + + + + + + Dashboard + + + + + +
+

Dashboard

+ +
+
+ +
+
+ +
+ + +
+ +
+
+
+ + + +
+
+
+ +
+

OpenMediaVault

+
+
+
+ +
+

Immich

+
+
+
+ +
+

Portainer

+
+
+
+ +
+

Print Server

+
+
+ + + + + \ No newline at end of file diff --git a/src/web/assets/script.js b/src/web/assets/script.js index 9361e64..6213ab3 100644 --- a/src/web/assets/script.js +++ b/src/web/assets/script.js @@ -4,6 +4,8 @@ if (searchInputEl) { // add an element with search suggestions after the search input const suggestionsEl = document.createElement("div"); suggestionsEl.id = "search-input-suggestions"; + suggestionsEl.classList = + "block w-full p-4 pl-10 text-sm border-2 text-gray-900 border rounded-lg bg-gray-50 ring-blue-500 border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:ring-blue-500 dark:border-blue-500 outline-none shadow-lg"; suggestionsEl.style.visibility = "hidden"; searchInputEl.insertAdjacentElement("afterend", suggestionsEl); @@ -30,7 +32,7 @@ if (searchInputEl) { nextQueryId++; const res = await fetch( - `/autocomplete?q=${encodeURIComponent(value)}` + `/autocomplete?q=${encodeURIComponent(value)}`, ).then((res) => res.json()); const options = res[1]; @@ -136,7 +138,7 @@ if (searchInputEl) { searchInputEl.focus(); searchInputEl.setSelectionRange( searchInputEl.value.length, - searchInputEl.value.length + searchInputEl.value.length, ); } // left arrow key focuses it at the beginning @@ -149,7 +151,7 @@ if (searchInputEl) { searchInputEl.focus(); searchInputEl.setSelectionRange( searchInputEl.value.length, - searchInputEl.value.length + searchInputEl.value.length, ); } }); @@ -202,3 +204,7 @@ if (customCssEl) { localStorage.setItem("custom-css-details-open", customCssDetailsEl.open); }); } + +function appLink(link) { + document.location.href = link; +} diff --git a/src/web/assets/style.css b/src/web/assets/style.css index 5576874..92bd749 100644 --- a/src/web/assets/style.css +++ b/src/web/assets/style.css @@ -1,18 +1,26 @@ :root { /* body background */ - --bg-1: #0b0e14; + /* --bg-1: #0b0e14; */ + --bg-1: #e5e7eb; /* background of the content */ - --bg-2: #0d1017; + /* --bg-2: #0d1017; */ + --bg-2: #e5e7eb; /* input suggestions background */ + /* --bg-3: #0f131a; */ --bg-3: #0f131a; /* mostly borders */ + /* --bg-4: #234; */ --bg-4: #234; /* main text color */ - --fg-1: #bfbdb6; + /* --fg-1: #bfbdb6; */ + --fg-1: #303030; /* 303030 */ + /* search result description */ - --fg-2: #bba; - --fg-3: #998; + /* --fg-2: #bba; */ + --fg-2: #5e5e5e; + /* --fg-3: #998; */ + --fg-3: #909090; /* focus outline */ --accent: #e6b450; @@ -69,7 +77,7 @@ body { word-break: break-word; } main { - max-width: 40rem; + /* max-width: 40rem; */ /* margin: 0 0 0 10rem; */ padding: 1rem 0.5rem; background-color: var(--bg-2); @@ -163,26 +171,31 @@ h1 { } /* header */ -.search-form { +/* .search-form { margin-bottom: 1rem; display: flex; gap: 0.5rem; -} -#search-input { +} */ +/* #search-input { flex: 1; } .main-container:not(.index-page) #search-input { max-width: 30em; -} +} */ #search-input-suggestions { - position: absolute; + /* position: absolute; text-align: left; margin-top: calc(1.9em + 1px); background: var(--bg-3); padding: 0.1em 0 0.3em 0; border: 1px solid var(--bg-4); border-top: transparent; - z-index: 10; + z-index: 10; */ + + position: absolute; + text-align: left; + margin-top: 0.5em; + padding: 0.1em 0 0.3em 0; } .search-input-suggestion { cursor: pointer; @@ -191,7 +204,8 @@ h1 { } .search-input-suggestion.focused, .search-input-suggestion:hover { - background: var(--bg-4); + /* background: var(--bg-4); */ + background: rgb(59 130 246); } /* search tabs (like images, if enabled) */ @@ -211,10 +225,12 @@ a.search-tab { /* search result */ .search-result { - padding-top: 1rem; - border-top: 1px solid var(--bg-4); + padding-top: 2.3rem; + /* border-top: 1px solid var(--bg-4); */ font-size: 1rem; + max-width: 40rem; } + .search-result-anchor { display: block; word-break: break-all; @@ -227,8 +243,15 @@ a.search-tab { .search-result-title { margin: 0; font-size: 1rem; + font-weight: bold; + text-overflow: ellipsis; + max-width: 40rem; + text-wrap: nowrap; + overflow: hidden; + color: rgb(26, 13, 171); } .search-result-description { + max-width: 40rem; margin: 0; font-size: 0.8em; color: var(--fg-2); @@ -249,6 +272,7 @@ a.search-tab { border: 1px solid var(--bg-4); padding: 0.5rem; font-size: 1.2rem; + max-width: 40rem; } .featured-snippet .search-result-description { margin-bottom: 1rem; @@ -460,7 +484,7 @@ h3.answer-thesaurus-category-title { border: 1px solid var(--bg-4); padding: 0.5rem; position: absolute; - top: 3.5rem; + top: 5.5rem; max-width: 30rem; margin-left: 42rem; } diff --git a/src/web/index.rs b/src/web/index.rs index 0856ee8..4d79d95 100644 --- a/src/web/index.rs +++ b/src/web/index.rs @@ -18,13 +18,72 @@ pub async fn get(Extension(config): Extension) -> impl IntoResponse { @if config.ui.show_settings_link { a.settings-link href="/settings" { "Settings" } } - div.main-container.index-page { - h1 { {(config.ui.site_name)} } - form.search-form action="/search" method="get" { - input type="text" name="q" placeholder="Search" id="search-input" autofocus onfocus="this.select()" autocomplete="off"; - input type="submit" value="Search"; + // div.main-container.index-page { + // h1 { {(config.ui.site_name)} } + // form.search-form action="/search" method="get" { + // input type="text" name="q" placeholder="Search" id="search-input" autofocus onfocus="this.select()" autocomplete="off"; + // input type="submit" value="Search"; + // } + // } + + div.fixed.w-full.text-center.z-50.flex.flex-col { + h1.z-50.w-full.text-center.m-0.mt-3.text-2xl.font-semibold { "Dashboard" } + div class="z-50 w-1/2 text-center self-center m-0 mt-20 text-2xl font-semibold" { + form.search-form action="/search" method="get" { + div.relative { + div.absolute.inset-y-0.left-0.flex.items-center.pl-3.pointer-events-none { + svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20" { + path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"; + } + } + input type="text" name="q" placeholder="Search" id="search-input" class="block w-full p-4 pl-10 text-sm border-2 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 outline-none shadow-lg focus:shadow-2xl" autofocus onfocus="this.select()" autocomplete="off"; + input type="submit" class="text-white absolute right-2.5 bottom-2.5 bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800" value="Search"; + } + } } } + + div class="h-svh w-screen grid grid-cols-1 grid-rows-1 place-items-end md:place-items-center" { + div class="max-w-3xl max-h-[65%] overflow-y-scroll md:overflow-y-visible flex h-fit w-full md:w-fit flex-col md:flex-row" { + div onclick="appLink('http://rotanclan.com:8080')" class="rounded-lg shadow-lg md:p-2 bg-white m-2 md:m-3 w-11/12 h-20 md:w-40 md:h-40 flex self-center flex-col cursor-pointer hover:shadow-2xl" { + div class="h-full flex items-left md:items-center content-left md:content-center justify-left md:justify-center md:m-2" { + img src="http://nas.local/assets/omv.png" class="md:h-auto md:w-2/3 rounded-md m-2 mr-0 md:mr-2"; + h1 class="text-center font-semibold mt-auto h-full content-center p-4 md:hidden" { "OpenMediaVault" } + } + h1 class="text-center font-semibold mt-auto hidden md:block" { "OpenMediaVault" } + } + + div onclick="appLink('http://rotanclan.com:2283')" class="rounded-lg shadow-lg md:p-2 bg-white m-2 md:m-3 w-11/12 h-20 md:w-40 md:h-40 flex self-center flex-col cursor-pointer hover:shadow-2xl" { + div class="h-full flex items-left md:items-center content-left md:content-center justify-left md:justify-center md:m-2" { + img src="http://nas.local/assets/immich.png" class="md:h-auto md:w-2/3 rounded-md m-2 mr-0 md:mr-2"; + h1 class="text-center font-semibold mt-auto h-full content-center p-4 md:hidden" { "Immich" } + } + h1 class="text-center font-semibold mt-auto hidden md:block" { "Immich" } + } + + div onclick="appLink('http://rotanclan.com:9000')" class="rounded-lg shadow-lg md:p-2 bg-white m-2 md:m-3 w-11/12 h-20 md:w-40 md:h-40 flex self-center flex-col cursor-pointer hover:shadow-2xl" { + div class="h-full flex items-left md:items-center content-left md:content-center justify-left md:justify-center md:m-2" { + img src="http://nas.local/assets/portainer.png" class="md:h-auto md:w-2/3 rounded-md m-2 mr-0 md:mr-2"; + h1 class="text-center font-semibold mt-auto h-full content-center p-4 md:hidden" { "Portainer" } + } + h1 class="text-center font-semibold mt-auto hidden md:block" { "Portainer" } + } + + div onclick="appLink('http://nas.local:631')" class="rounded-lg shadow-lg md:p-2 bg-white m-2 md:m-3 w-11/12 h-20 md:w-40 md:h-40 flex self-center flex-col cursor-pointer hover:shadow-2xl" { + div class="h-full flex items-left md:items-center content-left md:content-center justify-left md:justify-center md:m-2" { + img src="http://nas.local/assets/cups.png" class="md:h-auto md:w-2/3 rounded-md m-2 mr-0 md:mr-2"; + h1 class="text-center font-semibold mt-auto h-full content-center p-4 md:hidden" { "Print Server" } + } + h1 class="text-center font-semibold mt-auto hidden md:block" { "Print Server" } + } + + } + } + + + + + @if config.ui.show_version_info { span.version-info { @if COMMIT_HASH == "unknown" || COMMIT_HASH_SHORT == "unknown" { @@ -40,7 +99,7 @@ pub async fn get(Extension(config): Extension) -> impl IntoResponse { } } } - + } } .into_string(); diff --git a/src/web/mod.rs b/src/web/mod.rs index 5ce7ab5..54c2107 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -143,6 +143,7 @@ pub fn head_html(title: Option<&str>, config: &Config) -> Markup { style { (PreEscaped(html_escape::encode_style(&config.ui.stylesheet_str))) } } script src="/script.js" defer {} + script src="https://cdn.tailwindcss.com" {} link rel="search" type="application/opensearchdescription+xml" title="metasearch" href="/opensearch.xml"; } } diff --git a/src/web/search.rs b/src/web/search.rs index 85712ae..c612e75 100644 --- a/src/web/search.rs +++ b/src/web/search.rs @@ -25,13 +25,32 @@ use crate::{ fn render_beginning_of_html(search: &SearchQuery) -> String { let form_html = html! { - form.search-form action="/search" method="get" { - input #search-input type="text" name="q" placeholder="Search" value=(search.query) autofocus onfocus="this.select()" autocomplete="off"; - @if search.tab != SearchTab::default() { - input type="hidden" name="tab" value=(search.tab.to_string()); + + + + div.w-full.text-center.z-50.flex { + div class="z-50 w-full text-center self-center m-0 mb-4 text-2xl font-semibold" { + form.search-form action="/search" method="get" { + div.relative { + div.absolute.inset-y-0.left-0.flex.items-center.pl-3.pointer-events-none { + svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20" { + path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"; + } + } + input type="text" spellcheck="false" name="q" placeholder="Search" value=(search.query) id="search-input" class="block w-full p-4 pl-10 text-sm border-2 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 outline-none shadow-lg focus:shadow-2xl" onfocus="this.select()" autocomplete="off"; + input type="submit" class="text-white absolute right-2.5 bottom-2.5 bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800" value="Search"; + } + } } - input type="submit" value="Search"; } + + // form.search-form action="/search" method="get" { + // input #search-input type="text" name="q" placeholder="Search" value=(search.query) autofocus onfocus="this.select()" autocomplete="off"; + // @if search.tab != SearchTab::default() { + // input type="hidden" name="tab" value=(search.tab.to_string()); + // } + // input type="submit" value="Search"; + // } @if search.config.image_search.enabled { div.search-tabs { @if search.tab == SearchTab::All { span.search-tab.selected { "All" } }