From 3cfbf0e5f200573798c5a467e0f768fbe67b259b Mon Sep 17 00:00:00 2001 From: alban Date: Sat, 8 Apr 2023 05:05:20 -0400 Subject: [PATCH] Fix some things (#32) Fixes the issue with the background color not taking up the whole screen. This was noticeable when the page was loading in dark mode, the user would get a white flash. Fixes the docker build with axum that was never tested with the axum integration PR. Removed useless dependencies at the workspace level. Rustywind has done some tailwind classes sorting here and there where files were saved. Co-authored-by: Miroito Reviewed-on: https://git.albv.org/alban/fast-insiders/pulls/32 --- Cargo.lock | 4 - Cargo.toml | 5 - client/src/components/the_header.rs | 4 +- client/src/templates/index.rs | 16 +- client/src/templates/transactions.rs | 45 +- client/static/style.css | 17 + client/static/tailwind.css | 929 +-------------------------- docker-compose.yml | 8 +- makefile | 2 +- server/Dockerfile | 15 +- server/src/env.rs | 20 + server/src/main.rs | 5 +- 12 files changed, 94 insertions(+), 976 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 416e047..374be4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -971,10 +971,6 @@ dependencies = [ [[package]] name = "fast-insiders" version = "0.1.0" -dependencies = [ - "client", - "server", -] [[package]] name = "fastrand" diff --git a/Cargo.toml b/Cargo.toml index dc89f2f..ee00988 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,10 +5,6 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[dependencies] -server = { version = "0.1.0", path = "./server" } -client = { version = "0.1.0", path = "./client" } - [workspace] members = ["server", "client"] @@ -18,4 +14,3 @@ serde = { version = "1.0.152", features = ["derive"] } dotenvy = "0.15.6" envy = "0.4.2" serde_json = "1.0.91" -# chrono = { workspace = true, features = ["serde"] } diff --git a/client/src/components/the_header.rs b/client/src/components/the_header.rs index a3ec62a..bd489ca 100644 --- a/client/src/components/the_header.rs +++ b/client/src/components/the_header.rs @@ -33,13 +33,13 @@ pub fn TheHeader<'a, G: Html>(cx: Scope<'a>) -> View { "Fast Insiders" } } - div (class="grow text-left") { + div (class="text-left grow") { a (id="header-all-transactions", href="/transactions", class="hover:underline") { "All transactions" } } div (class="flex-none") { - button (on:click=toggle_dark_mode, class="mx-1 py-1 px-2 bg-slate-200 dark:bg-slate-800 rounded-full") + button (on:click=toggle_dark_mode, class="py-1 px-2 mx-1 rounded-full bg-slate-200 dark:bg-slate-800") { "Toggle dark mode" } } } diff --git a/client/src/templates/index.rs b/client/src/templates/index.rs index 87d7239..909ebe5 100644 --- a/client/src/templates/index.rs +++ b/client/src/templates/index.rs @@ -35,10 +35,18 @@ fn index_page(cx: Scope) -> View { table_class: table_classes, }; + let dark_mode_class = create_memo(cx, || { + if *global_state.dark_mode.get() { + "dark" + } else { + "" + } + }); + view! {cx, - main (class=if *global_state.dark_mode.get() { "dark" } else { "" }) { - div (class="bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-100 font-sans") { - TheHeader() + main (class=format!("{} flex flex-1", dark_mode_class)) { + div (class="flex-1 font-sans bg-slate-200 text-slate-700 dark:bg-slate-700 dark:text-slate-100") { + TheHeader() MainContentContainer(useless_prop=1) { div(class="flex flex-wrap gap-4 justify-around") { div (class="flex-grow") { @@ -55,9 +63,9 @@ fn index_page(cx: Scope) -> View { } } } + } } } - } } pub fn get_template() -> Template { diff --git a/client/src/templates/transactions.rs b/client/src/templates/transactions.rs index 04b633b..4ae610b 100644 --- a/client/src/templates/transactions.rs +++ b/client/src/templates/transactions.rs @@ -25,7 +25,6 @@ pub struct TransactionsPageState { #[auto_scope] fn transactions_page(cx: Scope, state: &TransactionsPageStateRx) -> View { let global_state = Reactor::::from_cx(cx).get_global_state::(cx); - let dark_mode = &global_state.dark_mode; let expand = create_signal(cx, false); let filter_expand = BaseButtonStateRx { @@ -73,33 +72,41 @@ fn transactions_page(cx: Scope, state: &TransactionsPageStateRx) -> Vie } }); + let dark_mode_class = create_memo(cx, || { + if *global_state.dark_mode.get() { + "dark" + } else { + "" + } + }); + view! {cx, - main (class=if *dark_mode.get() { "dark" } else { "" }) { - div (class="bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-100 font-sans") { + main (class=format!("{} flex flex-1", dark_mode_class)) { + div (class="flex-1 font-sans bg-slate-200 text-slate-700 dark:bg-slate-700 dark:text-slate-100") { TheHeader() - MainContentContainer(useless_prop=1) { - a (class="hover:underline", href="/transactions") { - h1 ( - class="text-center text-lg" - ) { - "Insider Transactions published by the AMF" - } + MainContentContainer(useless_prop=1) { + a (class="hover:underline", href="/transactions") { + h1 ( + class="text-lg text-center" + ) { + "Insider Transactions published by the AMF" } - BaseButton(filter_expand) - div (id="filters", - class=format!("p-2 border rounded-lg border-slate-200 dark:border-slate-800 bg-slate-200 dark:bg-slate-700 transition-all ease-in {}", - if *expand.get() { "h-40 visible" } else { "h-0 collapse" }, - ) - ) - { + } + BaseButton(filter_expand) + div (id="filters", + class=format!("p-2 border rounded-lg border-slate-200 dark:border-slate-800 bg-slate-200 dark:bg-slate-700 transition-all ease-in {}", + if *expand.get() { "h-40 visible" } else { "h-0 collapse" }, + ) + ) + { div (class="w-80") { p () {"Search for a company:"} BaseAsyncSelect(async_select_prop) BaseButton(search_button) } } - PaginatedTable(paginated_table_state) - } + PaginatedTable(paginated_table_state) + } } } } diff --git a/client/static/style.css b/client/static/style.css index b5c61c9..18b30fb 100644 --- a/client/static/style.css +++ b/client/static/style.css @@ -1,3 +1,20 @@ @tailwind base; @tailwind components; @tailwind utilities; + +html { + height: 100%; + width: 100%; +} + +body { + min-height: 100%; + display: flex; + flex-direction: column; +} + +div#root { + flex: 1; + display: flex; + flex-direction: column; +} diff --git a/client/static/tailwind.css b/client/static/tailwind.css index db599bf..0e75b59 100644 --- a/client/static/tailwind.css +++ b/client/static/tailwind.css @@ -1,928 +1 @@ -/* -! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com -*/ - -/* -1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) -2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) -*/ - -*, -::before, -::after { - box-sizing: border-box; - /* 1 */ - border-width: 0; - /* 2 */ - border-style: solid; - /* 2 */ - border-color: #e5e7eb; - /* 2 */ -} - -::before, -::after { - --tw-content: ''; -} - -/* -1. Use a consistent sensible line-height in all browsers. -2. Prevent adjustments of font size after orientation changes in iOS. -3. Use a more readable tab size. -4. Use the user's configured `sans` font-family by default. -5. Use the user's configured `sans` font-feature-settings by default. -*/ - -html { - line-height: 1.5; - /* 1 */ - -webkit-text-size-adjust: 100%; - /* 2 */ - -moz-tab-size: 4; - /* 3 */ - -o-tab-size: 4; - tab-size: 4; - /* 3 */ - font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - /* 4 */ - font-feature-settings: normal; - /* 5 */ -} - -/* -1. Remove the margin in all browsers. -2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. -*/ - -body { - margin: 0; - /* 1 */ - line-height: inherit; - /* 2 */ -} - -/* -1. Add the correct height in Firefox. -2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) -3. Ensure horizontal rules are visible by default. -*/ - -hr { - height: 0; - /* 1 */ - color: inherit; - /* 2 */ - border-top-width: 1px; - /* 3 */ -} - -/* -Add the correct text decoration in Chrome, Edge, and Safari. -*/ - -abbr:where([title]) { - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; -} - -/* -Remove the default font size and weight for headings. -*/ - -h1, -h2, -h3, -h4, -h5, -h6 { - font-size: inherit; - font-weight: inherit; -} - -/* -Reset links to optimize for opt-in styling instead of opt-out. -*/ - -a { - color: inherit; - text-decoration: inherit; -} - -/* -Add the correct font weight in Edge and Safari. -*/ - -b, -strong { - font-weight: bolder; -} - -/* -1. Use the user's configured `mono` font family by default. -2. Correct the odd `em` font sizing in all browsers. -*/ - -code, -kbd, -samp, -pre { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - /* 1 */ - font-size: 1em; - /* 2 */ -} - -/* -Add the correct font size in all browsers. -*/ - -small { - font-size: 80%; -} - -/* -Prevent `sub` and `sup` elements from affecting the line height in all browsers. -*/ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - -/* -1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) -2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) -3. Remove gaps between table borders by default. -*/ - -table { - text-indent: 0; - /* 1 */ - border-color: inherit; - /* 2 */ - border-collapse: collapse; - /* 3 */ -} - -/* -1. Change the font styles in all browsers. -2. Remove the margin in Firefox and Safari. -3. Remove default padding in all browsers. -*/ - -button, -input, -optgroup, -select, -textarea { - font-family: inherit; - /* 1 */ - font-size: 100%; - /* 1 */ - font-weight: inherit; - /* 1 */ - line-height: inherit; - /* 1 */ - color: inherit; - /* 1 */ - margin: 0; - /* 2 */ - padding: 0; - /* 3 */ -} - -/* -Remove the inheritance of text transform in Edge and Firefox. -*/ - -button, -select { - text-transform: none; -} - -/* -1. Correct the inability to style clickable types in iOS and Safari. -2. Remove default button styles. -*/ - -button, -[type='button'], -[type='reset'], -[type='submit'] { - -webkit-appearance: button; - /* 1 */ - background-color: transparent; - /* 2 */ - background-image: none; - /* 2 */ -} - -/* -Use the modern Firefox focus style for all focusable elements. -*/ - -:-moz-focusring { - outline: auto; -} - -/* -Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) -*/ - -:-moz-ui-invalid { - box-shadow: none; -} - -/* -Add the correct vertical alignment in Chrome and Firefox. -*/ - -progress { - vertical-align: baseline; -} - -/* -Correct the cursor style of increment and decrement buttons in Safari. -*/ - -::-webkit-inner-spin-button, -::-webkit-outer-spin-button { - height: auto; -} - -/* -1. Correct the odd appearance in Chrome and Safari. -2. Correct the outline style in Safari. -*/ - -[type='search'] { - -webkit-appearance: textfield; - /* 1 */ - outline-offset: -2px; - /* 2 */ -} - -/* -Remove the inner padding in Chrome and Safari on macOS. -*/ - -::-webkit-search-decoration { - -webkit-appearance: none; -} - -/* -1. Correct the inability to style clickable types in iOS and Safari. -2. Change font properties to `inherit` in Safari. -*/ - -::-webkit-file-upload-button { - -webkit-appearance: button; - /* 1 */ - font: inherit; - /* 2 */ -} - -/* -Add the correct display in Chrome and Safari. -*/ - -summary { - display: list-item; -} - -/* -Removes the default spacing and border for appropriate elements. -*/ - -blockquote, -dl, -dd, -h1, -h2, -h3, -h4, -h5, -h6, -hr, -figure, -p, -pre { - margin: 0; -} - -fieldset { - margin: 0; - padding: 0; -} - -legend { - padding: 0; -} - -ol, -ul, -menu { - list-style: none; - margin: 0; - padding: 0; -} - -/* -Prevent resizing textareas horizontally by default. -*/ - -textarea { - resize: vertical; -} - -/* -1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) -2. Set the default placeholder color to the user's configured gray 400 color. -*/ - -input::-moz-placeholder, textarea::-moz-placeholder { - opacity: 1; - /* 1 */ - color: #9ca3af; - /* 2 */ -} - -input::placeholder, -textarea::placeholder { - opacity: 1; - /* 1 */ - color: #9ca3af; - /* 2 */ -} - -/* -Set the default cursor for buttons. -*/ - -button, -[role="button"] { - cursor: pointer; -} - -/* -Make sure disabled buttons don't get the pointer cursor. -*/ - -:disabled { - cursor: default; -} - -/* -1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) -2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) - This can trigger a poorly considered lint error in some tools but is included by design. -*/ - -img, -svg, -video, -canvas, -audio, -iframe, -embed, -object { - display: block; - /* 1 */ - vertical-align: middle; - /* 2 */ -} - -/* -Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) -*/ - -img, -video { - max-width: 100%; - height: auto; -} - -/* Make elements with the HTML hidden attribute stay hidden by default */ - -[hidden] { - display: none; -} - -*, ::before, ::after { - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-rotate: 0; - --tw-skew-x: 0; - --tw-skew-y: 0; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; - --tw-scroll-snap-strictness: proximity; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: rgb(59 130 246 / 0.5); - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; -} - -::backdrop { - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-rotate: 0; - --tw-skew-x: 0; - --tw-skew-y: 0; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; - --tw-scroll-snap-strictness: proximity; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: rgb(59 130 246 / 0.5); - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; -} - -.visible { - visibility: visible; -} - -.collapse { - visibility: collapse; -} - -.static { - position: static; -} - -.absolute { - position: absolute; -} - -.relative { - position: relative; -} - -.-top-1 { - top: -0.25rem; -} - -.z-0 { - z-index: 0; -} - -.m-2 { - margin: 0.5rem; -} - -.m-10 { - margin: 2.5rem; -} - -.m-1 { - margin: 0.25rem; -} - -.my-2 { - margin-top: 0.5rem; - margin-bottom: 0.5rem; -} - -.mx-auto { - margin-left: auto; - margin-right: auto; -} - -.mx-1 { - margin-left: 0.25rem; - margin-right: 0.25rem; -} - -.mr-12 { - margin-right: 3rem; -} - -.mb-1 { - margin-bottom: 0.25rem; -} - -.flex { - display: flex; -} - -.table { - display: table; -} - -.grid { - display: grid; -} - -.contents { - display: contents; -} - -.h-11 { - height: 2.75rem; -} - -.h-40 { - height: 10rem; -} - -.h-0 { - height: 0px; -} - -.w-full { - width: 100%; -} - -.w-80 { - width: 20rem; -} - -.w-4\/5 { - width: 80%; -} - -.w-32 { - width: 8rem; -} - -.w-60 { - width: 15rem; -} - -.w-max { - width: -moz-max-content; - width: max-content; -} - -.w-fit { - width: -moz-fit-content; - width: fit-content; -} - -.w-5\/12 { - width: 41.666667%; -} - -.flex-none { - flex: none; -} - -.flex-grow { - flex-grow: 1; -} - -.grow { - flex-grow: 1; -} - -.table-auto { - table-layout: auto; -} - -.transform { - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - -.cursor-pointer { - cursor: pointer; -} - -.auto-cols-max { - grid-auto-columns: max-content; -} - -.grid-flow-row { - grid-auto-flow: row; -} - -.grid-flow-col { - grid-auto-flow: column; -} - -.auto-rows-max { - grid-auto-rows: max-content; -} - -.flex-row { - flex-direction: row; -} - -.flex-col { - flex-direction: column; -} - -.flex-wrap { - flex-wrap: wrap; -} - -.items-center { - align-items: center; -} - -.justify-end { - justify-content: flex-end; -} - -.justify-center { - justify-content: center; -} - -.justify-between { - justify-content: space-between; -} - -.justify-around { - justify-content: space-around; -} - -.gap-4 { - gap: 1rem; -} - -.rounded-md { - border-radius: 0.375rem; -} - -.rounded-lg { - border-radius: 0.5rem; -} - -.rounded-full { - border-radius: 9999px; -} - -.rounded-b-md { - border-bottom-right-radius: 0.375rem; - border-bottom-left-radius: 0.375rem; -} - -.border { - border-width: 1px; -} - -.border-x { - border-left-width: 1px; - border-right-width: 1px; -} - -.border-b-2 { - border-bottom-width: 2px; -} - -.border-dashed { - border-style: dashed; -} - -.border-slate-500 { - --tw-border-opacity: 1; - border-color: rgb(100 116 139 / var(--tw-border-opacity)); -} - -.border-slate-200 { - --tw-border-opacity: 1; - border-color: rgb(226 232 240 / var(--tw-border-opacity)); -} - -.bg-slate-300 { - --tw-bg-opacity: 1; - background-color: rgb(203 213 225 / var(--tw-bg-opacity)); -} - -.bg-slate-200 { - --tw-bg-opacity: 1; - background-color: rgb(226 232 240 / var(--tw-bg-opacity)); -} - -.bg-slate-100 { - --tw-bg-opacity: 1; - background-color: rgb(241 245 249 / var(--tw-bg-opacity)); -} - -.bg-gray-100 { - --tw-bg-opacity: 1; - background-color: rgb(243 244 246 / var(--tw-bg-opacity)); -} - -.p-2 { - padding: 0.5rem; -} - -.p-3 { - padding: 0.75rem; -} - -.py-1 { - padding-top: 0.25rem; - padding-bottom: 0.25rem; -} - -.px-2 { - padding-left: 0.5rem; - padding-right: 0.5rem; -} - -.text-left { - text-align: left; -} - -.text-center { - text-align: center; -} - -.text-right { - text-align: right; -} - -.align-middle { - vertical-align: middle; -} - -.font-sans { - font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; -} - -.text-lg { - font-size: 1.125rem; - line-height: 1.75rem; -} - -.text-slate-700 { - --tw-text-opacity: 1; - color: rgb(51 65 85 / var(--tw-text-opacity)); -} - -.text-indigo-800 { - --tw-text-opacity: 1; - color: rgb(55 48 163 / var(--tw-text-opacity)); -} - -.shadow-md { - --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.filter { - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); -} - -.backdrop-blur-lg { - --tw-backdrop-blur: blur(16px); - -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); -} - -.transition-all { - transition-property: all; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; -} - -.ease-in { - transition-timing-function: cubic-bezier(0.4, 0, 1, 1); -} - -.hover\:cursor-pointer:hover { - cursor: pointer; -} - -.hover\:bg-slate-400:hover { - --tw-bg-opacity: 1; - background-color: rgb(148 163 184 / var(--tw-bg-opacity)); -} - -.hover\:font-bold:hover { - font-weight: 700; -} - -.hover\:text-indigo-500:hover { - --tw-text-opacity: 1; - color: rgb(99 102 241 / var(--tw-text-opacity)); -} - -.hover\:underline:hover { - text-decoration-line: underline; -} - -.disabled\:cursor-not-allowed:disabled { - cursor: not-allowed; -} - -.dark .dark\:border-slate-800 { - --tw-border-opacity: 1; - border-color: rgb(30 41 59 / var(--tw-border-opacity)); -} - -.dark .dark\:bg-slate-800 { - --tw-bg-opacity: 1; - background-color: rgb(30 41 59 / var(--tw-bg-opacity)); -} - -.dark .dark\:bg-slate-600 { - --tw-bg-opacity: 1; - background-color: rgb(71 85 105 / var(--tw-bg-opacity)); -} - -.dark .dark\:bg-slate-500\/30 { - background-color: rgb(100 116 139 / 0.3); -} - -.dark .dark\:bg-slate-700 { - --tw-bg-opacity: 1; - background-color: rgb(51 65 85 / var(--tw-bg-opacity)); -} - -.dark .dark\:text-slate-100 { - --tw-text-opacity: 1; - color: rgb(241 245 249 / var(--tw-text-opacity)); -} - -.dark .dark\:text-indigo-300 { - --tw-text-opacity: 1; - color: rgb(165 180 252 / var(--tw-text-opacity)); -} - -.dark .dark\:hover\:bg-slate-900:hover { - --tw-bg-opacity: 1; - background-color: rgb(15 23 42 / var(--tw-bg-opacity)); -} - -.dark .dark\:hover\:text-indigo-600:hover { - --tw-text-opacity: 1; - color: rgb(79 70 229 / var(--tw-text-opacity)); -} +/*! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.visible{visibility:visible}.collapse{visibility:collapse}.static{position:static}.absolute{position:absolute}.relative{position:relative}.-top-1{top:-.25rem}.z-0{z-index:0}.m-2{margin:.5rem}.m-10{margin:2.5rem}.m-1{margin:.25rem}.my-2{margin-bottom:.5rem;margin-top:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.mx-1{margin-left:.25rem;margin-right:.25rem}.mr-12{margin-right:3rem}.mb-1{margin-bottom:.25rem}.flex{display:flex}.table{display:table}.contents{display:contents}.h-11{height:2.75rem}.h-40{height:10rem}.h-0{height:0}.w-full{width:100%}.w-80{width:20rem}.w-4\/5{width:80%}.flex-none{flex:none}.flex-1{flex:1 1 0%}.flex-grow,.grow{flex-grow:1}.table-auto{table-layout:auto}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.gap-4{gap:1rem}.rounded-md{border-radius:.375rem}.rounded-lg{border-radius:.5rem}.rounded-full{border-radius:9999px}.rounded-b-md{border-bottom-left-radius:.375rem;border-bottom-right-radius:.375rem}.border{border-width:1px}.border-x{border-left-width:1px;border-right-width:1px}.border-b-2{border-bottom-width:2px}.border-dashed{border-style:dashed}.border-slate-500{--tw-border-opacity:1;border-color:rgb(100 116 139/var(--tw-border-opacity))}.border-slate-200{--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity))}.bg-slate-300{--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity))}.bg-slate-200{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.p-2{padding:.5rem}.p-3{padding:.75rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-sans{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-slate-700{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity))}.text-indigo-800{--tw-text-opacity:1;color:rgb(55 48 163/var(--tw-text-opacity))}.shadow-md{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-lg{--tw-backdrop-blur:blur(16px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-all{transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}html{height:100%;width:100%}body{display:flex;flex-direction:column;min-height:100%}div#root{display:flex;flex:1;flex-direction:column}.hover\:cursor-pointer:hover{cursor:pointer}.hover\:bg-slate-400:hover{--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity))}.hover\:font-bold:hover{font-weight:700}.hover\:text-indigo-500:hover{--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity))}.hover\:underline:hover{text-decoration-line:underline}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.dark .dark\:border-slate-800{--tw-border-opacity:1;border-color:rgb(30 41 59/var(--tw-border-opacity))}.dark .dark\:bg-slate-800{--tw-bg-opacity:1;background-color:rgb(30 41 59/var(--tw-bg-opacity))}.dark .dark\:bg-slate-600{--tw-bg-opacity:1;background-color:rgb(71 85 105/var(--tw-bg-opacity))}.dark .dark\:bg-slate-500\/30{background-color:#64748b4d}.dark .dark\:bg-slate-700{--tw-bg-opacity:1;background-color:rgb(51 65 85/var(--tw-bg-opacity))}.dark .dark\:text-slate-100{--tw-text-opacity:1;color:rgb(241 245 249/var(--tw-text-opacity))}.dark .dark\:text-indigo-300{--tw-text-opacity:1;color:rgb(165 180 252/var(--tw-text-opacity))}.dark .dark\:hover\:bg-slate-900:hover{--tw-bg-opacity:1;background-color:rgb(15 23 42/var(--tw-bg-opacity))}.dark .dark\:hover\:text-indigo-600:hover{--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity))} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index c03b3a1..af547ba 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -version: '3' +version: "3" services: client: container_name: fast-insiders-client @@ -6,7 +6,7 @@ services: build: context: . args: - API_URL: http://localhost:8000/v1/ + API_URL: http://localhost:8000/ dockerfile: ./client/Dockerfile restart: always ports: @@ -19,7 +19,7 @@ services: build: context: . args: - API_URL: http://localhost:8000/v1/ + API_URL: http://localhost:8000/ dockerfile: ./server/Dockerfile restart: always ports: @@ -44,9 +44,7 @@ services: - MYSQL_DATABASE=fast_insiders - MYSQL_USER=fiuser - volumes: fi-data: driver: local db: - diff --git a/makefile b/makefile index 5dad3f0..0d15cdc 100644 --- a/makefile +++ b/makefile @@ -13,7 +13,7 @@ server-dev: tailwind: cd client && \ - tailwindcss -i static/style.css -o static/tailwind.css -w + tailwindcss -i static/style.css -o static/tailwind.css -w --minify serve: cd client && \ diff --git a/server/Dockerfile b/server/Dockerfile index c58beec..2b27ca4 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -1,8 +1,8 @@ FROM rust:1.66-slim as build # Install build dependencies -RUN apt update \ - && apt install -y --no-install-recommends lsb-release apt-transport-https \ +RUN apt-get update \ + && apt-get install -y --no-install-recommends lsb-release apt-transport-https \ build-essential curl wget pkg-config libssl-dev # Root of the project @@ -21,20 +21,23 @@ RUN rustup default nightly ARG API_URL ENV API_URL=$API_URL +# go to src dir +WORKDIR /app/server + # Build the final binary -RUN cargo build --release --bin server +RUN cargo build --release # prepare deployment image FROM debian:stable-slim # For tls to work -RUN apt-get update && apt-get -y install ca-certificates libssl-dev && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get -y --no-install-recommends install ca-certificates libssl-dev && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY --from=build /app/target/release/server /app/ -ENV ROCKET_ADDRESS=0.0.0.0 +ENV HOST=0.0.0.0 -CMD ./server +CMD ["./server"] diff --git a/server/src/env.rs b/server/src/env.rs index ac0d351..98fda18 100644 --- a/server/src/env.rs +++ b/server/src/env.rs @@ -1,7 +1,13 @@ +use std::net::SocketAddr; + use serde::Deserialize; #[derive(Deserialize, Debug)] pub struct Env { + #[serde(default = "host_default")] + pub host: String, + #[serde(default = "port_default")] + pub port: String, pub mysql_user: String, pub mysql_password: String, pub mysql_host: String, @@ -31,6 +37,14 @@ pub struct Env { pub get_amf_transaction_interval: u64, } +fn host_default() -> String { + "127.0.0.1".to_string() +} + +fn port_default() -> String { + "8000".to_string() +} + fn mysql_port_default() -> String { "3306".to_string() } @@ -92,6 +106,7 @@ impl Env { #[derive(Debug)] pub struct Config { + pub server_address: SocketAddr, pub database_url: String, pub max_connections: u32, pub min_connections: u32, @@ -113,7 +128,12 @@ impl Config { env.mysql_user, env.mysql_password, env.mysql_host, env.mysql_port, env.mysql_database ); + let server_address = format!("{}:{}", env.host, env.port) + .parse() + .expect("Could not parse host and port combination into a valid server address"); + let mut config = Config { + server_address, database_url, max_connections: env.max_connections, min_connections: env.min_connections, diff --git a/server/src/main.rs b/server/src/main.rs index 8407c56..acf6b65 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -16,7 +16,7 @@ use axum::{ Router, }; use sea_orm::DatabaseConnection; -use std::{net::SocketAddr, time::Duration}; +use std::time::Duration; use tokio::signal; use tower_http::{classify::ServerErrorsFailureClass, cors::CorsLayer, trace::TraceLayer}; use tracing::{info, info_span, Span}; @@ -136,7 +136,8 @@ pub async fn main() -> Result<(), Box> { // Run tasks tokio::task::spawn(async move { run_tasks(&shared_state.db).await }); - let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); + let addr = CONFIG.server_address; + info!("Server will start listening on {}", addr); axum::Server::bind(&addr) .serve(app.into_make_service()) .with_graceful_shutdown(shutdown_signal())