diff --git a/frontend/css/index.css b/frontend/css/index.css
index bf6e2f2..8ce2263 100644
--- a/frontend/css/index.css
+++ b/frontend/css/index.css
@@ -36,200 +36,3 @@ body {
overflow: auto; /* Enable scroll if needed */
background-color: #f1f1f1; /* Fallback color */
}
-/* The container
- needed to position the dropdown content */
-.dropdown {
- position: relative;
- display: inline-block;
-}
-
-/* Dropdown Content (Hidden by Default) */
-.dropdown-content {
- /* margin-top: 80px; Add a top margin to avoid content overlay */
- position: absolute;
- min-width: 160px;
- z-index: 1;
-}
-
-
-/* Float three header columns side by side */
-.header {
- position: fixed; /* Stay in place */
-/* overflow: hidden;*/
- z-index: 1; /* Sit on top */
- width: 100%;
- top: 0; /* Position the navbar at the top of the page */
- padding: 0 10px;
- background-color: #f1f1f1;
-}
-
-.main {
- margin-top: 50px; /* Add a top margin to avoid content overlay */
-}
-
-/* Float three header columns side by side */
-.header-button {
- float: left;
- width: 10%;
- padding: 0 10px;
-}
-
-/* Float three header columns side by side */
-.header-column {
- float: left;
- width: 36%;
- padding: 0 10px;
-}
-/* Float three header columns side by side */
-.header-page-column {
- float: right;
- margin-top: 0px;
- width: 15%;
- padding: 0 10px;
-}
-
-/* Float four columns side by side */
-.column {
- float: left;
- width: 25%;
- padding: 0 10px;
- margin-top: 10px;
- margin-bottom: 10px;
-}
-
-/* Remove extra left and right margins, due to padding in columns */
-.row {margin: 0 -5px;}
-
-/* Clear floats after the columns */
-.row:after {
- content: "";
- display: table;
- clear: both;
-}
-
-/* Style the counter cards */
-.card {
- box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); /* this adds the "card" effect */
- padding: 16px;
- text-align: left;
- height: 400px;
- overflow: hidden;
- text-overflow: ellipsis;
- background-color: #f1f1f1;
-}
-
-/* Style the counter cards */
-.card-openlibrary {
- box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); /* this adds the "card" effect */
- padding: 16px;
- text-align: left;
- height: 200px;
- overflow: hidden;
- text-overflow: ellipsis;
- background-color: #f1f1f1;
-}
-
-.card img {
- float: right;
- width: 100px;
- padding: 0 20px 20px 0;
-}
-
-.card-openlibrary img {
- float: right;
- width: 100px;
- padding: 0 20px 20px 0;
-}
-
-
-.card-title {
- padding: 16px;
- text-align: left;
- width: 60%;
- font-weight: bold;
- font-size: large;
-}
-
-.card-authors {
- padding: 16px;
- text-align: left;
- width: 60%;
- font-size: large;
-}
-
-.card-desc {
- padding: 2px;
- text-align: left;
- width: 100%;
-}
-
-
-.input-field {
- padding: 4px;
- float: left;
- text-align: left;
- width: 50%;
- font-size: large;
-}
-.input-field label {
- display: block;
- vertical-align: middle;
- min-width: 20%;
- max-width: 20%;
- width: 20%;
- padding: 4px;
-}
-.input-field textarea {
- vertical-align: middle;
- width: 80%;
-}
-.input-buttons {
- padding: 20px;
- float: left;
- text-align: left;
- width: 100%;
-}
-
-.more-info {
- width: 90%;
-}
-.more-info img {
- float: right;
- width: 200px;
- padding: 0 20px 20px 0;
-}
-
-.more-info label {
- display:inline-block;
- text-align: left;
- width: 20%;
- font-weight: bold;
- font-size: large;
-}
-
-.more-info-buttons {
- padding: 20px;
- text-align: left;
-}
-
-.page-input {
- width: 30px;
-}
-
-/* Responsive columns - one column layout (vertical) on small screens */
-@media screen and (max-width: 600px) {
- .column {
- width: 100%;
- display: block;
- margin-bottom: 20px;
- }
-}
-
-@media screen and (max-width: 800px) {
- .main {
- margin-top: 80px; /* Add a top margin to avoid content overlay */
- }
-
- .input-field {
- width: 100%;
- }
-}
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 2c103b4..745690b 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -5,6 +5,7 @@
"packages": {
"": {
"devDependencies": {
+ "@tailwindcss/forms": "^0.5.3",
"tailwindcss": "^3.2.4"
}
},
@@ -43,6 +44,18 @@
"node": ">= 8"
}
},
+ "node_modules/@tailwindcss/forms": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.3.tgz",
+ "integrity": "sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==",
+ "dev": true,
+ "dependencies": {
+ "mini-svg-data-uri": "^1.2.3"
+ },
+ "peerDependencies": {
+ "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1"
+ }
+ },
"node_modules/acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
@@ -397,6 +410,15 @@
"node": ">=8.6"
}
},
+ "node_modules/mini-svg-data-uri": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
+ "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
+ "dev": true,
+ "bin": {
+ "mini-svg-data-uri": "cli.js"
+ }
+ },
"node_modules/minimist": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
@@ -825,6 +847,15 @@
"fastq": "^1.6.0"
}
},
+ "@tailwindcss/forms": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.3.tgz",
+ "integrity": "sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==",
+ "dev": true,
+ "requires": {
+ "mini-svg-data-uri": "^1.2.3"
+ }
+ },
"acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
@@ -1087,6 +1118,12 @@
"picomatch": "^2.3.1"
}
},
+ "mini-svg-data-uri": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
+ "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
+ "dev": true
+ },
"minimist": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 34d20ba..c144606 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,5 +1,6 @@
{
"devDependencies": {
+ "@tailwindcss/forms": "^0.5.3",
"tailwindcss": "^3.2.4"
}
}
diff --git a/frontend/src/main.rs b/frontend/src/main.rs
index 7ca01f4..855b7bb 100644
--- a/frontend/src/main.rs
+++ b/frontend/src/main.rs
@@ -221,8 +221,8 @@ pub fn Header(cx: Scope) -> View {
let value2 = create_signal(cx, String::new());
let input_ref2 = create_node_ref(cx);
- let value3 = create_signal(cx, String::new());
- let input_ref3 = create_node_ref(cx);
+ //let value3 = create_signal(cx, String::new());
+ //let input_ref3 = create_node_ref(cx);
let completed = create_selector(cx, || *app_state.editmode.get());
let editchecked = create_signal(cx, false);
@@ -284,7 +284,7 @@ pub fn Header(cx: Scope) -> View {
};
- let handle_submit_addbulk = |event: Event| {
+ /*let handle_submit_addbulk = |event: Event| {
let event: KeyboardEvent = event.unchecked_into();
if event.key() == "Enter" {
@@ -298,7 +298,7 @@ pub fn Header(cx: Scope) -> View {
});
}
}
- };
+ };*/
let click_logout = |_| {
@@ -340,93 +340,123 @@ pub fn Header(cx: Scope) -> View {
view! { cx,
- header(class="header") {
- div(class="header-button"){
+ header(class="sticky top-0 z-50 flex bg-slate-400 gap-x-4") {
+ div(class="w-1/10 flex mb-2"){
(if *app_state.loggedin.get() == false {
view!{ cx,
- button(on:click=click_userscreen) { i(class="fa-solid fa-user") "Register / Login" }
+ button(on:click=click_userscreen, class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center w-full") { i(class="fa-solid fa-user") }
}
} else {
view!{cx,
- button(on:click=click_logout) { "Log Out" }
+ div(class="flex gap-x-1"){
+ button(on:click=click_logout, class="bg-gray-300 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center w-1/2") { i(class="fa-solid fa-right-from-bracket") }
+ label(class="inline-flex relative items-center cursor-pointer w-1/2"){
input(
- class="toggle",
+ class="sr-only peer",
type="checkbox",
on:input=toggle_editmode,
bind:checked=editchecked
- )("EDIT")
+ )
+ div(class="w-11 h-6 bg-gray-200 peer-focus:outline-none rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[5px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"){}
+ //p(class="ml-3 text-sm font-medium"){"EDIT"}
+ }
+ }
}
})
}
- div(class="header-column"){
+ div(class="w-1/10 flex mb-2"){
+ (if *app_state.editmode.get() == false {
+ view!{ cx,
+// button(class="bg-gray-300 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center ", on:click=dropdown_userselect) {
+ div(class="flex"){
+ select(class="bg-gray-300 hover:bg-gray-200 text-gray-800 font-bold rounded inline-flex items-center w-max", on:click=dropdown_userselect) {
+ option(disabled=true, selected=true, hidden=true, value="", class="w-max"){("?")}
+
+/* (if *app_state.userid.get() == 0 {
+
+ view!{ cx, ("SELECT")}
+ } else {
+ view!{cx, (*app_state.selectedusername.get())}
+ }
+ )*/
+ //}
+ // (if *app_state.dropdownselect.get() == true {
+ //view!{cx,
+ Keyed(
+ iterable=users,
+ view=move |cx, x| view! { cx,
+ DropDownUser(value=x)
+ },
+ key =|x| x.clone() )
+ //}
+ //} else {
+ // view!{cx, ""}
+ //})
+ }
+ }
+
+
+ } }
+ else {
+ view!{cx,
+ div(class="bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center"){(format!(" {} ", *app_state.selectedusername.get()))}
+ }
+ })
+}
+
+ div(class="w-2/5 flex mb-2"){
(if *app_state.userid.get() != 0 {
view!{ cx,
- (format!(" {} ", *app_state.selectedusername.get()))
- button(on:click=click_listall) { "All books" }
+ button(on:click=click_listall, class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center") { i(class="fa-solid fa-layer-group") span(class="inline-block"){"All" }}
+ div(class="min-w-40 inline-flex"){
input(ref=input_ref2,
- class="new-todo",
- placeholder="Search collection",
+ class = "inline-flex h-full m-0 p-1 w-full",
+ placeholder="🔍 Search",
bind:value=value2,
on:keyup=handle_submit_seachall,
- )
+ )}
}} else {
- view!{cx, "No Collection Selected"}
- })
- br{}
- (if *app_state.editmode.get() == false {
- view!{ cx,
- div(class="dropdown"){
-
- (if *app_state.dropdownselect.get() == true {
- view!{ cx,
- div(class="dropdown-content") {
- Keyed(
- iterable=users,
- view=move |cx, x| view! { cx,
- DropDownUser(value=x)
- },
- key =|x| x.clone() )
- }
- }
- } else {
- view!{cx, ""}
- })
- button(on:click=dropdown_userselect) { "Choose Collection" }
- }
- }} else {
view!{cx, ""}
- })
+ })
+
}
(if *app_state.editmode.get() == true {
view!{ cx,
-
- button(on:click=click_addbook) { "+ Add New" }
- input(ref=input_ref3,
- class="new-todo",
- placeholder="Add bulk ISBNs",
- bind:value=value3,
- on:keyup=handle_submit_addbulk,
- )
- br{}
- div(class="header-column"){
+ div(class="w-2/5 flex mb-2"){
+ button(on:click=click_addbook, class="bg-gray-300 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center") { i(class="fa-solid fa-circle-plus") }
+ //button(on:click=click_addbook) { "+ Add New" }
+ //input(ref=input_ref3,
+ // class="new-todo",
+ // placeholder="Add bulk ISBNs",
+ // bind:value=value3,
+ // on:keyup=handle_submit_addbulk,
+ //)
+ div(class="min-w-40 inline-flex"){
+ input(ref=input_ref,
+ class = "inline-flex h-full m-0 p-1 w-full",
+ placeholder="🔍 Internet",
+ bind:value=value,
+ on:keyup=handle_submit,
+ )}
+ /*
input(ref=input_ref,
class="new-todo",
placeholder="Search internet (openlibrary)",
bind:value=value,
on:keyup=handle_submit,
- )
+ )*/
}
}} else {
view!{cx, ""}
})
- div(class="header-page-column"){
+ div(){
PageBar{}
}
}
@@ -446,7 +476,8 @@ pub fn DropDownUser(cx: Scope, value: StringProp) -> View {
};
view! { cx,
- button(class="dropdown-item", on:click=handle_select_user){ (buttontext) }br{}
+ //div( class="py-1", role="none") {}
+ option(on:click=handle_select_user,class="w-max"){ (format!("{}",buttontext)) }
}
}
@@ -716,10 +747,9 @@ pub fn BookDB(cx: Scope, bookitem: BookUIProp) -> View {
div(class="card"){
div(class="card-buttons"){
-
- button(class="delete", on:click=handle_delete){ "DEL-" }
- button(class="update", on:click=handle_update){ "EDIT=" }
- button(class="info", on:click=handle_display){ "INFO+" }
+ button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 border-black-500 rounded inline-flex items-center", on:click=handle_display){ i(class="fa-solid fa-circle-info") }
+ button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 border-black-500 rounded inline-flex items-center", on:click=handle_update){ i(class="fa-solid fa-pen-to-square") }
+ button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 border-black-500 rounded inline-flex items-center", on:click=handle_delete){ i(class="fa-solid fa-trash") }
}
div(class="card-main",on:click=handle_display_div){
img(src=coverurl,width="100")
@@ -774,7 +804,8 @@ pub fn BookDB_View(cx: Scope, bookitem: BookUIProp) -> View {
div(class="card-buttons"){
- button(class="info", on:click=handle_display){ "INFO+" }
+ button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 border-black-500 rounded inline-flex items-center", on:click=handle_display){ i(class="fa-solid fa-circle-info") }
+
}
div(class="card-main", on:click=handle_display_div){
img(src=coverurl,width="100")
@@ -863,7 +894,8 @@ pub fn BookOL(cx: Scope, bookitem: BookUIProp) -> View {
view! { cx,
div(class="column"){
div(class="card-openlibrary",on:click=handle_add_div){
- button(class="add", on:click=handle_add){ "ADD+" }
+ button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 border-black-500 rounded inline-flex items-center", on:click=handle_add){ i(class="fa-solid fa-plus") }
+
div(class="card-main"){
img(src=coverurl,width="100")
@@ -1042,8 +1074,8 @@ info!("Adding book");
view!{ cx,
div(class="modal-content"){
div(class="input-buttons"){
- button(class="add", on:click=handle_add){ "Add/Update book to DB" }
- button(class="cancel", on:click=handle_cancel){ "Cancel" }
+ button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center", on:click=handle_add){ "Add/Update book to DB" }
+ button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center", on:click=handle_cancel){ "Cancel" }
}
p {
div(class="input-field"){
@@ -1231,9 +1263,11 @@ async fn SelectedUI(cx: Scope<'_>) -> View {
div(class="more-info"){
div(class="more-info-buttons"){
- button(class="close", on:click=handle_close){ "CLOSE" }
+
+ button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 border-black-500 rounded inline-flex items-center", on:click=handle_close){ i(class="fa-solid fa-xmark") }
(if *app_state.editmode.get() == true {
- view!{ cx,button(class="close", on:click=handle_edit){ "EDIT" }}
+ view!{ cx,
+ button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 border-black-500 rounded inline-flex items-center", on:click=handle_edit){ i(class="fa-solid fa-pen-to-square") }}
} else {
view!{cx, ""}
})
@@ -1327,19 +1361,21 @@ async fn PageBar(cx: Scope<'_>) -> View {
}
};
view! {cx,
- div {
+ div(class="w-1/10 flex mb-2 gap-x-1") {
(if (*app_state.openlibrary.get() == false || *app_state.internalsearch.get() == true) && !app_state.books.get().is_empty() {
view!{ cx,
- label{"PAGE "}
- input(ref=input_ref,bind:value=currpg,on:keyup=handle_submit,class="page-input")
- label{(format!(" / {}",*app_state.maxpage.get()))}
+ div(class="bg-gray-300 text-gray-800 font-bold px-1 rounded inline-flex items-center"){
+ i(class="fa-solid fa-file") span(class="hidden md:block-inline"){p{"#"}}
+ input(type="number", ref=input_ref,bind:value=currpg,on:keyup=handle_submit,class="page-input [appearance:textfield] mx-1 my-0 p-1 min-w-30 w-30")
+ label(class="block-inline"){(format!(" / {}",*app_state.maxpage.get()))}
+ }
(if *app_state.pagenum.get()>1 {
- view!{cx, button(class="page", on:click=handle_sub){ "-" }}
+ view!{cx, button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center", on:click=handle_sub){ "-" }}
} else {
view!{cx,""}
})
(if *app_state.pagenum.get()<*app_state.maxpage.get() {
- view!{cx, button(class="page", on:click=handle_add){ "+" }}
+ view!{cx, button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center", on:click=handle_add){ "+" }}
} else {
view!{cx,""}
})
@@ -1489,17 +1525,19 @@ async fn LoginScreenUI(cx: Scope<'_>) -> View {
(if *app_state.userscreen.get() == true {
view!{cx,
- div(class="modal-content"){
- label{"User name : "}
- input(ref=input_refU,bind:value=userval)
+ div(class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"){
+ label{"Username : "}
+ input(ref=input_refU,bind:value=userval, placeholder="Username", class="text-sm sm:text-base placeholder-gray-500 pl-10 pr-4 rounded-lg border border-gray-400 w-full py-2 focus:outline-none focus:border-blue-400")
br{}
- label{"Password : "}
- input(ref=input_refP,bind:value=passval,type="password",
- on:keyup=handle_submit_login)
+ label{"Password : "}
+ input(ref=input_refP,bind:value=passval,type="password", placeholder="*****",
+ on:keyup=handle_submit_login, class="text-sm sm:text-base placeholder-gray-500 pl-10 pr-4 rounded-lg border border-gray-400 w-full py-2 focus:outline-none focus:border-blue-400")
br{}
- button(on:click=handle_login){ "LOGIN" }
- button(on:click=handle_register){ "REGISTER" }
- button(class="close", on:click=handle_close){ "CLOSE" }
+ button( class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 inline-flex items-center border-b-4 border-blue-700 hover:border-blue-500 w-full",on:click=handle_login){ "LOGIN" }
+ br{}
+ button( class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 inline-flex items-center border-b-4 border-blue-700 hover:border-blue-500 w-full",on:click=handle_register){ "REGISTER" }
+ br{}
+ button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 border-black-500 rounded inline-flex items-center", on:click=handle_close){ i(class="fa-solid fa-xmark") }
br{}
(if *app_state.warningmsg.get() != "".to_string() {
view!{cx, (*app_state.warningmsg.get())}
@@ -1545,7 +1583,7 @@ fn App(cx: Scope) -> View {
loggedusername: create_rc_signal(String::new()),
useridloggedin: create_rc_signal(0),
userscreen: create_rc_signal(bool::default()),
- loggedin: create_rc_signal(bool::default()),
+ loggedin: create_rc_signal(true),
editmode: create_rc_signal(bool::default()),
dropdownselect: create_rc_signal(bool::default()),
scrolling: create_rc_signal(bool::default()),
@@ -1559,7 +1597,7 @@ fn App(cx: Scope) -> View {
cx,
div {
Header {}
- div(class="main"){
+ main(class="relative"){
LoginScreenUI{}
AddingUI{}
SelectedUI{}
diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js
index 5c4e142..b8fef04 100644
--- a/frontend/tailwind.config.js
+++ b/frontend/tailwind.config.js
@@ -6,6 +6,8 @@ module.exports = {
theme: {
extend: {},
},
- plugins: [],
+ plugins: [
+ require('@tailwindcss/forms'),
+ ],
}