mirror of
https://github.com/LeRoid-hub/Bookholder-WEB.git
synced 2025-01-31 03:14:57 +00:00
Some structure for the dashboard and correction to the README.md
This commit is contained in:
parent
080db44476
commit
fa7b37d0c3
@ -1,4 +1,4 @@
|
|||||||
# Bookholder APP
|
# Bookholder APP
|
||||||
|
|
||||||
## Build CSS
|
## Build CSS
|
||||||
npx tailwindcss -i ./public/css/input.css -o ./public/css/master.css --watch
|
npx tailwindcss -i ./assets/css/input.css -o ./assets/css/master.css --watch
|
2
assets/components/accounts.html
Normal file
2
assets/components/accounts.html
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<h1>Accounts</h1>
|
||||||
|
<p>This is the Accounts content.</p>
|
2
assets/components/entry.html
Normal file
2
assets/components/entry.html
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<h1>Entry</h1>
|
||||||
|
<p>This is the Entry content.</p>
|
2
assets/components/overview.html
Normal file
2
assets/components/overview.html
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<h1>Overview</h1>
|
||||||
|
<p>This is the Overview content.</p>
|
@ -554,22 +554,14 @@ video {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row-start-2 {
|
.m-4 {
|
||||||
grid-row-start: 2;
|
margin: 1rem;
|
||||||
}
|
|
||||||
|
|
||||||
.row-start-3 {
|
|
||||||
grid-row-start: 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mb-2 {
|
.mb-2 {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mb-3 {
|
|
||||||
margin-bottom: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mb-4 {
|
.mb-4 {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
@ -582,60 +574,67 @@ video {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.inline-block {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex {
|
.flex {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid {
|
.contents {
|
||||||
display: grid;
|
display: contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
.h-10 {
|
.hidden {
|
||||||
height: 2.5rem;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.h-screen {
|
.h-screen {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.min-h-screen {
|
.h-\[10\%\] {
|
||||||
min-height: 100vh;
|
height: 10%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-full {
|
.h-\[20\%\] {
|
||||||
width: 100%;
|
height: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-max {
|
||||||
|
height: -moz-max-content;
|
||||||
|
height: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-full {
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-80 {
|
.w-80 {
|
||||||
width: 20rem;
|
width: 20rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.max-w-xs {
|
.w-full {
|
||||||
max-width: 20rem;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.appearance-none {
|
.w-\[15\%\] {
|
||||||
-webkit-appearance: none;
|
width: 15%;
|
||||||
-moz-appearance: none;
|
|
||||||
appearance: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-rows-\[20px_1fr_20px\] {
|
.w-\[20\%\] {
|
||||||
grid-template-rows: 20px 1fr 20px;
|
width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-1 {
|
||||||
|
flex: 1 1 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cursor-pointer {
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-col {
|
.flex-col {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-wrap {
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.place-items-end {
|
.place-items-end {
|
||||||
place-items: end;
|
place-items: end;
|
||||||
}
|
}
|
||||||
@ -652,40 +651,18 @@ video {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.justify-items-center {
|
.justify-evenly {
|
||||||
justify-items: center;
|
justify-content: space-evenly;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gap-1 {
|
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
||||||
gap: 0.25rem;
|
--tw-space-x-reverse: 0;
|
||||||
|
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
||||||
|
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
||||||
}
|
}
|
||||||
|
|
||||||
.gap-16 {
|
.overflow-auto {
|
||||||
gap: 4rem;
|
overflow: auto;
|
||||||
}
|
|
||||||
|
|
||||||
.gap-2 {
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gap-4 {
|
|
||||||
gap: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gap-6 {
|
|
||||||
gap: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gap-8 {
|
|
||||||
gap: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rounded {
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rounded-full {
|
|
||||||
border-radius: 9999px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.rounded-lg {
|
.rounded-lg {
|
||||||
@ -696,21 +673,12 @@ video {
|
|||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.border-solid {
|
.border-b {
|
||||||
border-style: solid;
|
border-bottom-width: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.border-black\/\[\.08\] {
|
.border-b-2 {
|
||||||
border-color: rgb(0 0 0 / .08);
|
border-bottom-width: 2px;
|
||||||
}
|
|
||||||
|
|
||||||
.border-transparent {
|
|
||||||
border-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-red-500 {
|
|
||||||
--tw-border-opacity: 1;
|
|
||||||
border-color: rgb(239 68 68 / var(--tw-border-opacity, 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.border-black {
|
.border-black {
|
||||||
@ -718,18 +686,18 @@ video {
|
|||||||
border-color: rgb(0 0 0 / var(--tw-border-opacity, 1));
|
border-color: rgb(0 0 0 / var(--tw-border-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-foreground {
|
.border-gray-300 {
|
||||||
background-color: var(--foreground);
|
--tw-border-opacity: 1;
|
||||||
|
border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-blue-500 {
|
.border-transparent {
|
||||||
--tw-bg-opacity: 1;
|
border-color: transparent;
|
||||||
background-color: rgb(59 130 246 / var(--tw-bg-opacity, 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-white {
|
.border-blue-500 {
|
||||||
--tw-bg-opacity: 1;
|
--tw-border-opacity: 1;
|
||||||
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
|
border-color: rgb(59 130 246 / var(--tw-border-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-black {
|
.bg-black {
|
||||||
@ -742,14 +710,33 @@ video {
|
|||||||
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
|
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-8 {
|
.bg-white {
|
||||||
padding: 2rem;
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gray-200 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(229 231 235 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gray-300 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(209 213 219 / var(--tw-bg-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-6 {
|
.p-6 {
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-2 {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-4 {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.px-3 {
|
.px-3 {
|
||||||
padding-left: 0.75rem;
|
padding-left: 0.75rem;
|
||||||
padding-right: 0.75rem;
|
padding-right: 0.75rem;
|
||||||
@ -765,110 +752,57 @@ video {
|
|||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.px-8 {
|
|
||||||
padding-left: 2rem;
|
|
||||||
padding-right: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pb-20 {
|
|
||||||
padding-bottom: 5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pb-8 {
|
|
||||||
padding-bottom: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pt-6 {
|
|
||||||
padding-top: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-center {
|
.text-center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.align-baseline {
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font-\[family-name\:var\(--font-geist-sans\)\] {
|
|
||||||
font-family: var(--font-geist-sans);
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-3xl {
|
|
||||||
font-size: 1.875rem;
|
|
||||||
line-height: 2.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-sm {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
line-height: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-xs {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
line-height: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-2xl {
|
.text-2xl {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
line-height: 2rem;
|
line-height: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-3xl {
|
||||||
|
font-size: 1.875rem;
|
||||||
|
line-height: 2.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-4xl {
|
||||||
|
font-size: 2.25rem;
|
||||||
|
line-height: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.font-bold {
|
.font-bold {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.italic {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leading-tight {
|
|
||||||
line-height: 1.25;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-background {
|
|
||||||
color: var(--background);
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-black {
|
.text-black {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(0 0 0 / var(--tw-text-opacity, 1));
|
color: rgb(0 0 0 / var(--tw-text-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-blue-500 {
|
|
||||||
--tw-text-opacity: 1;
|
|
||||||
color: rgb(59 130 246 / var(--tw-text-opacity, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-gray-500 {
|
|
||||||
--tw-text-opacity: 1;
|
|
||||||
color: rgb(107 114 128 / var(--tw-text-opacity, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-gray-700 {
|
.text-gray-700 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(55 65 81 / var(--tw-text-opacity, 1));
|
color: rgb(55 65 81 / var(--tw-text-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-red-500 {
|
|
||||||
--tw-text-opacity: 1;
|
|
||||||
color: rgb(239 68 68 / var(--tw-text-opacity, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-white {
|
|
||||||
--tw-text-opacity: 1;
|
|
||||||
color: rgb(255 255 255 / var(--tw-text-opacity, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-gray-800 {
|
.text-gray-800 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(31 41 55 / var(--tw-text-opacity, 1));
|
color: rgb(31 41 55 / var(--tw-text-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.shadow {
|
.text-white {
|
||||||
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
--tw-text-opacity: 1;
|
||||||
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
|
color: rgb(255 255 255 / var(--tw-text-opacity, 1));
|
||||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
}
|
||||||
|
|
||||||
|
.text-red-500 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(239 68 68 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-400 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(156 163 175 / var(--tw-text-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.shadow-md {
|
.shadow-md {
|
||||||
@ -883,12 +817,6 @@ video {
|
|||||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.transition-colors {
|
|
||||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
|
|
||||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
transition-duration: 150ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--background: #ffffff;
|
--background: #ffffff;
|
||||||
--foreground: #171717;
|
--foreground: #171717;
|
||||||
@ -907,23 +835,9 @@ body {
|
|||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hover\:border-transparent:hover {
|
.focus-within\:border-blue-500:focus-within {
|
||||||
border-color: transparent;
|
--tw-border-opacity: 1;
|
||||||
}
|
border-color: rgb(59 130 246 / var(--tw-border-opacity, 1));
|
||||||
|
|
||||||
.hover\:bg-\[\#383838\]:hover {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(56 56 56 / var(--tw-bg-opacity, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
.hover\:bg-\[\#f2f2f2\]:hover {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(242 242 242 / var(--tw-bg-opacity, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
.hover\:bg-blue-700:hover {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.hover\:bg-gray-200:hover {
|
.hover\:bg-gray-200:hover {
|
||||||
@ -936,17 +850,19 @@ body {
|
|||||||
background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1));
|
background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.hover\:text-blue-800:hover {
|
.hover\:bg-gray-300:hover {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(209 213 219 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover\:text-red-500:hover {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(30 64 175 / var(--tw-text-opacity, 1));
|
color: rgb(239 68 68 / var(--tw-text-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.hover\:underline:hover {
|
.focus\:border-blue-500:focus {
|
||||||
text-decoration-line: underline;
|
--tw-border-opacity: 1;
|
||||||
}
|
border-color: rgb(59 130 246 / var(--tw-border-opacity, 1));
|
||||||
|
|
||||||
.hover\:underline-offset-4:hover {
|
|
||||||
text-underline-offset: 4px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.focus\:outline-none:focus {
|
.focus\:outline-none:focus {
|
||||||
@ -965,51 +881,3 @@ body {
|
|||||||
--tw-ring-color: rgb(0 0 0 / var(--tw-ring-opacity, 1));
|
--tw-ring-color: rgb(0 0 0 / var(--tw-ring-opacity, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
|
||||||
.sm\:h-12 {
|
|
||||||
height: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:min-w-44 {
|
|
||||||
min-width: 11rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:flex-row {
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:items-start {
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:p-20 {
|
|
||||||
padding: 5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:px-5 {
|
|
||||||
padding-left: 1.25rem;
|
|
||||||
padding-right: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:text-base {
|
|
||||||
font-size: 1rem;
|
|
||||||
line-height: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
.dark\:border-white\/\[\.145\] {
|
|
||||||
border-color: rgb(255 255 255 / .145);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark\:hover\:bg-\[\#1a1a1a\]:hover {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(26 26 26 / var(--tw-bg-opacity, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark\:hover\:bg-\[\#ccc\]:hover {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(204 204 204 / var(--tw-bg-opacity, 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
139
assets/scripts/dashboard.js
Normal file
139
assets/scripts/dashboard.js
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const navLinks = document.querySelectorAll('.nav-link');
|
||||||
|
const logoutButton = document.querySelector('.logout-button');
|
||||||
|
const tabHeader = document.getElementById('tab-header');
|
||||||
|
const tabContent = document.getElementById('tab-content');
|
||||||
|
const componentsDirectory = 'assets/components/';
|
||||||
|
|
||||||
|
// Track open tabs
|
||||||
|
const openTabs = new Map();
|
||||||
|
|
||||||
|
// Handle navigation links
|
||||||
|
navLinks.forEach((link) => {
|
||||||
|
link.addEventListener('click', async (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const fileName = link.dataset.file;
|
||||||
|
const tabName = fileName.replace('.html', '');
|
||||||
|
|
||||||
|
// Check if the tab is already open
|
||||||
|
if (openTabs.has(tabName)) {
|
||||||
|
// If the tab is already open, activate it
|
||||||
|
activateTab(tabName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove placeholder if it's the first tab
|
||||||
|
const placeholderTab = document.querySelector('.placeholder-tab');
|
||||||
|
const placeholderContent = document.querySelector('.placeholder-content');
|
||||||
|
if (placeholderTab) placeholderTab.remove();
|
||||||
|
if (placeholderContent) placeholderContent.remove();
|
||||||
|
|
||||||
|
// Create a new tab
|
||||||
|
const newTab = document.createElement('div');
|
||||||
|
newTab.className = 'flex items-center space-x-2 py-2 px-4 border-b-2 border-transparent cursor-pointer';
|
||||||
|
newTab.id = `tab-${tabName}`;
|
||||||
|
|
||||||
|
// Tab name (acts as a button)
|
||||||
|
const tabLabel = document.createElement('button');
|
||||||
|
tabLabel.className = 'focus:outline-none';
|
||||||
|
tabLabel.textContent = tabName;
|
||||||
|
|
||||||
|
// Switch to this tab when clicked
|
||||||
|
tabLabel.addEventListener('click', () => {
|
||||||
|
activateTab(tabName);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close button
|
||||||
|
const closeButton = document.createElement('button');
|
||||||
|
closeButton.className = 'text-gray-400 hover:text-red-500 focus:outline-none';
|
||||||
|
closeButton.textContent = 'X';
|
||||||
|
closeButton.title = 'Close Tab';
|
||||||
|
|
||||||
|
// Close tab logic
|
||||||
|
closeButton.addEventListener('click', () => {
|
||||||
|
// Remove tab and content
|
||||||
|
newTab.remove();
|
||||||
|
const relatedContent = document.getElementById(`content-${tabName}`);
|
||||||
|
if (relatedContent) relatedContent.remove();
|
||||||
|
|
||||||
|
// Remove from openTabs tracker
|
||||||
|
openTabs.delete(tabName);
|
||||||
|
|
||||||
|
// If no tabs are open, show placeholder
|
||||||
|
if (openTabs.size === 0) {
|
||||||
|
const placeholder = document.createElement('div');
|
||||||
|
placeholder.className = 'flex items-center space-x-2 placeholder-tab';
|
||||||
|
//placeholder.innerHTML = '<span class="py-2 px-4 text-center">Placeholder</span>';
|
||||||
|
tabHeader.appendChild(placeholder);
|
||||||
|
|
||||||
|
const placeholderContent = document.createElement('p');
|
||||||
|
placeholderContent.className = 'placeholder-content';
|
||||||
|
placeholderContent.textContent =
|
||||||
|
'This is the placeholder content. Click a link from the navbar to replace this content.';
|
||||||
|
tabContent.appendChild(placeholderContent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
newTab.appendChild(tabLabel);
|
||||||
|
newTab.appendChild(closeButton);
|
||||||
|
tabHeader.appendChild(newTab);
|
||||||
|
|
||||||
|
// Create content for the new tab
|
||||||
|
const newContent = document.createElement('div');
|
||||||
|
newContent.id = `content-${tabName}`;
|
||||||
|
newContent.className = 'tab-content-item hidden';
|
||||||
|
|
||||||
|
// Load content from the file
|
||||||
|
try {
|
||||||
|
const response = await fetch(componentsDirectory + fileName);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Failed to load ${fileName}`);
|
||||||
|
}
|
||||||
|
newContent.innerHTML = await response.text();
|
||||||
|
} catch (error) {
|
||||||
|
newContent.innerHTML = `<p class="text-red-500">Error loading content: ${error.message}</p>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
tabContent.appendChild(newContent);
|
||||||
|
|
||||||
|
// Hide other contents and show this one
|
||||||
|
activateTab(tabName);
|
||||||
|
|
||||||
|
// Track the open tab
|
||||||
|
openTabs.set(tabName, newTab);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Activate a tab and show its content
|
||||||
|
function activateTab(tabName) {
|
||||||
|
// Deactivate all tabs
|
||||||
|
document.querySelectorAll('#tab-header > div').forEach((tab) => {
|
||||||
|
tab.classList.remove('border-blue-500');
|
||||||
|
tab.classList.add('border-transparent');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Hide all content
|
||||||
|
document.querySelectorAll('.tab-content-item').forEach((content) => {
|
||||||
|
content.classList.add('hidden');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Activate the current tab
|
||||||
|
const activeTab = document.getElementById(`tab-${tabName}`);
|
||||||
|
const activeContent = document.getElementById(`content-${tabName}`);
|
||||||
|
if (activeTab && activeContent) {
|
||||||
|
activeTab.classList.add('border-blue-500');
|
||||||
|
activeTab.classList.remove('border-transparent');
|
||||||
|
activeContent.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle logout button separately
|
||||||
|
logoutButton.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
alert('You have been logged out.');
|
||||||
|
// Uncomment the following line to redirect to a login page
|
||||||
|
// window.location.href = '/login';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
10
assets/scripts/login.js
Normal file
10
assets/scripts/login.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
function login() {
|
||||||
|
const username = document.getElementById('username').value;
|
||||||
|
const password = document.getElementById('password').value;
|
||||||
|
|
||||||
|
if (username && password) {
|
||||||
|
alert(`Logging in with\nUsername: ${username}\nPassword: ${password}`);
|
||||||
|
} else {
|
||||||
|
alert('Please fill in both fields.');
|
||||||
|
}
|
||||||
|
}
|
42
views/dashboard.html
Normal file
42
views/dashboard.html
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Bookholder</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="assets/css/master.css">
|
||||||
|
<script src="assets/scripts/dashboard.js" defer></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="h-screen flex text-black">
|
||||||
|
<!-- Left Navigation Bar -->
|
||||||
|
<div class="w-[15%] bg-gray-200">
|
||||||
|
<h1 class="text-2xl text-center p-4">Bookholder</h1>
|
||||||
|
<div class="flex flex-col text-black h-full justify-evenly bg-gray-100">
|
||||||
|
<a href="" class="nav-link p-4 hover:bg-gray-300 text-center" data-file="overview.html">Overview</a>
|
||||||
|
<a href="" class="nav-link p-4 hover:bg-gray-300 text-center" data-file="entry.html">Entry</a>
|
||||||
|
<a href="" class="nav-link p-4 hover:bg-gray-300 text-center" data-file="accounts.html">Accounts</a>
|
||||||
|
<a href="" class="logout-button p-4 hover:bg-gray-300 text-center text-red-500">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Right Content Area -->
|
||||||
|
<div class="flex-1 flex flex-col bg-gray-100">
|
||||||
|
<!-- Tab Header -->
|
||||||
|
<div id="tab-header" class="flex bg-white border-b border-gray-300">
|
||||||
|
<div class="flex items-center space-x-2 placeholder-tab">
|
||||||
|
<!-- <span class="py-2 px-4 text-center">Placeholder</span> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tab Content Area -->
|
||||||
|
<div id="tab-content" class="flex-1 bg-white p-4 overflow-auto">
|
||||||
|
<p class="placeholder-content">This is the placeholder content. Click a link from the navbar to replace
|
||||||
|
this content.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -1,72 +1,47 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>Bookholder</title>
|
<title>Bookholder</title>
|
||||||
<link rel="stylesheet" type="text/css" href="assets/css/master.css">
|
<link rel="stylesheet" type="text/css" href="assets/css/master.css">
|
||||||
|
<link rel="reload" href="assets/scripts/dashboard.js"> as="script">
|
||||||
|
<script src="assets/scripts/login.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body class="flex items-center justify-center h-screen bg-gray-100">
|
|
||||||
|
<body class="flex items-center justify-center h-screen bg-gray-100">
|
||||||
<div class="bg-white p-6 rounded-lg shadow-md w-80">
|
<div class="bg-white p-6 rounded-lg shadow-md w-80">
|
||||||
<!-- Title -->
|
|
||||||
<h1 class="text-2xl font-bold text-center text-gray-800 mb-6">Bookholder</h1>
|
<h1 class="text-2xl font-bold text-center text-gray-800 mb-6">Bookholder</h1>
|
||||||
|
|
||||||
<form id="loginForm">
|
<form id="loginForm">
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label for="username" class="block text-gray-700 font-bold mb-2">Username</label>
|
<label for="username" class="block text-gray-700 font-bold mb-2">Username</label>
|
||||||
<input
|
<input type="text" id="username" name="username"
|
||||||
type="text"
|
|
||||||
id="username"
|
|
||||||
name="username"
|
|
||||||
class="w-full px-3 py-2 border rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-black"
|
class="w-full px-3 py-2 border rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-black"
|
||||||
placeholder="Enter your username"
|
placeholder="Enter your username" required />
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label for="password" class="block text-gray-700 font-bold mb-2">Password</label>
|
<label for="password" class="block text-gray-700 font-bold mb-2">Password</label>
|
||||||
<input
|
<input type="password" id="password" name="password"
|
||||||
type="password"
|
|
||||||
id="password"
|
|
||||||
name="password"
|
|
||||||
class="w-full px-3 py-2 border rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-black"
|
class="w-full px-3 py-2 border rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-black"
|
||||||
placeholder="Enter your password"
|
placeholder="Enter your password" required />
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<button
|
<button type="button" class="px-4 py-2 text-black border border-black rounded-lg hover:bg-gray-200"
|
||||||
type="button"
|
onclick="register()">
|
||||||
class="px-4 py-2 text-black border border-black rounded-lg hover:bg-gray-200"
|
|
||||||
onclick="register()"
|
|
||||||
>
|
|
||||||
Register
|
Register
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button type="button" class="px-4 py-2 text-white bg-black rounded-lg hover:bg-gray-800" onclick="login()">
|
||||||
type="button"
|
|
||||||
class="px-4 py-2 text-white bg-black rounded-lg hover:bg-gray-800"
|
|
||||||
onclick="login()"
|
|
||||||
>
|
|
||||||
Login
|
Login
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
// JavaScript Functions
|
|
||||||
function login() {
|
|
||||||
const username = document.getElementById('username').value;
|
|
||||||
const password = document.getElementById('password').value;
|
|
||||||
|
|
||||||
if (username && password) {
|
|
||||||
alert(`Logging in with\nUsername: ${username}\nPassword: ${password}`);
|
|
||||||
} else {
|
|
||||||
alert('Please fill in both fields.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function register() {
|
function register() {
|
||||||
window.location.href = '/register';
|
window.location.href = '/register';
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
Loading…
Reference in New Issue
Block a user