Owows so many new files
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
/target
|
||||
/config.toml
|
||||
/node_modules
|
||||
1833
Cargo.lock
generated
1833
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
74
Cargo.toml
74
Cargo.toml
@@ -17,12 +17,14 @@ chrono = { version = "0.4.45", features = ["serde"] }
|
||||
console_error_panic_hook = "0.1.7"
|
||||
diesel = { version = "2.3.13", features = ["postgres", "uuid", "chrono", "r2d2"] }
|
||||
diesel_migrations = "2.3.2"
|
||||
leptos = "0.8.20"
|
||||
leptos_axum = "0.8.10"
|
||||
leptos = { version = "0.8.20", features = ["hydration"] }
|
||||
leptos_axum = { version = "0.8.10", features = ["tracing", "wasm"]}
|
||||
leptos_meta = "0.8.6"
|
||||
leptos_router = { version = "0.8.15", features = ["tracing"] }
|
||||
serde = { version = "1.0.229", features = ["derive"] }
|
||||
serde_json = "1.0.151"
|
||||
thiserror = "2.0.20"
|
||||
tokio = { version = "1.53.1", features = ["full"] }
|
||||
tokio = { version = "1.53.1", features = ["rt-multi-thread","macros"] }
|
||||
tracing = "0.1.44"
|
||||
tracing-subscriber = { version = "0.3.23", features = ["env-filter"] }
|
||||
uuid = { version = "1.26.0", features = ["v4", "serde"] }
|
||||
@@ -32,3 +34,69 @@ toml = "1.1.5"
|
||||
camino = { version = "1.2.5", features = ["serde1"]}
|
||||
humantime = "2.4.0"
|
||||
humantime-serde = "1.1.1"
|
||||
any_spawner = { version = "0.3", features = ["tokio"] }
|
||||
|
||||
|
||||
[profile.wasm-release]
|
||||
inherits = "release"
|
||||
opt-level = 'z'
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
panic = "abort"
|
||||
|
||||
[[workspace.metadata.leptos]]
|
||||
name="erplt"
|
||||
bin-package="erplt"
|
||||
lib-package="erplt"
|
||||
# The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name
|
||||
output-name = "erplt"
|
||||
# The site root folder is where cargo-leptos generate all output. WARNING: all content of this folder will be erased on a rebuild. Use it in your server setup.
|
||||
site-root = "target/site"
|
||||
# The site-root relative folder where all compiled output (JS, WASM and CSS) is written
|
||||
# Defaults to pkg
|
||||
site-pkg-dir = "pkg"
|
||||
# The tailwind input file.
|
||||
#
|
||||
# Optional, Activates the tailwind build
|
||||
tailwind-input-file = "crates/erplt-api/style/tailwind.css"
|
||||
|
||||
# [Optional] Files in the asset-dir will be copied to the site-root directory
|
||||
assets-dir = "public"
|
||||
# The port to use for automatic reload monitoring
|
||||
site-addr = "0.0.0.0:8080"
|
||||
reload-port = 8081
|
||||
|
||||
# [Optional] Command to use when running end2end tests. It will run in the end2end dir.
|
||||
# [Windows] for non-WSL use "npx.cmd playwright test"
|
||||
# This binary name can be checked in Powershell with Get-Command npx
|
||||
end2end-cmd = "npx playwright test"
|
||||
end2end-dir = "end2end"
|
||||
|
||||
# The browserlist query used for optimizing the CSS.
|
||||
browserquery = "defaults"
|
||||
|
||||
# Set by cargo-leptos watch when building with that tool. Controls whether autoreload JS will be included in the head
|
||||
watch = false
|
||||
|
||||
# The environment Leptos will run in, usually either "DEV" or "PROD"
|
||||
env = "DEV"
|
||||
|
||||
# The features to use when compiling the bin target
|
||||
#
|
||||
# Optional. Can be over-ridden with the command line parameter --bin-features
|
||||
bin-features = ["ssr"]
|
||||
|
||||
# If the --no-default-features flag should be used when compiling the bin target
|
||||
#
|
||||
# Optional. Defaults to false.
|
||||
bin-default-features = false
|
||||
|
||||
# The features to use when compiling the lib target
|
||||
#
|
||||
# Optional. Can be over-ridden with the command line parameter --lib-features
|
||||
lib-features = ["hydrate"]
|
||||
|
||||
# If the --no-default-features flag should be used when compiling the lib target
|
||||
#
|
||||
# Optional. Defaults to false.
|
||||
lib-default-features = false
|
||||
@@ -3,10 +3,40 @@ name = "erplt-api"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
|
||||
[features]
|
||||
hydrate=["leptos/hydrate"]
|
||||
ssr=[
|
||||
"dep:erplt-db",
|
||||
"dep:erplt-config",
|
||||
"dep:leptos_axum",
|
||||
"dep:tokio",
|
||||
"dep:anyhow",
|
||||
"dep:any_spawner",
|
||||
"dep:tracing",
|
||||
"dep:axum",
|
||||
]
|
||||
|
||||
|
||||
[dependencies]
|
||||
erplt-db.path="../erplt-db"
|
||||
erplt-config.path = "../erplt-config"
|
||||
anyhow.workspace = true
|
||||
axum.workspace = true
|
||||
tokio.workspace = true
|
||||
tracing.workspace = true
|
||||
leptos.workspace = true
|
||||
leptos_meta.workspace = true
|
||||
leptos_router.workspace = true
|
||||
console_error_panic_hook.workspace = true
|
||||
wasm-bindgen.workspace = true
|
||||
|
||||
axum = { workspace = true, optional = true }
|
||||
erplt-db = { path = "../erplt-db", optional = true }
|
||||
erplt-config = { path = "../erplt-config", optional = true }
|
||||
leptos_axum = { workspace = true, optional = true }
|
||||
tokio = { workspace = true, optional = true }
|
||||
anyhow = { workspace = true, optional = true }
|
||||
any_spawner = { workspace = true, optional = true }
|
||||
tracing = { workspace = true, optional = true }
|
||||
|
||||
[package.metadata.cargo-all-features]
|
||||
denylist = ["axum", "tokio", "tower", "tower-http", "leptos_axum"]
|
||||
skip_feature_sets = [["ssr", "hydrate"], []]
|
||||
@@ -1,5 +1,21 @@
|
||||
mod routes;
|
||||
#[cfg(feature="ssr")]
|
||||
mod state;
|
||||
#[cfg(feature="ssr")]
|
||||
mod server;
|
||||
|
||||
#[cfg(feature="ssr")]
|
||||
pub use server::start;
|
||||
|
||||
#[cfg(feature="ssr")]
|
||||
use leptos::config::LeptosOptions;
|
||||
|
||||
#[cfg(feature="ssr")]
|
||||
type Router = axum::Router<LeptosOptions>;
|
||||
|
||||
#[cfg(feature = "hydrate")]
|
||||
#[wasm_bindgen::prelude::wasm_bindgen]
|
||||
pub fn hydrate() {
|
||||
use routes::pages::App;
|
||||
console_error_panic_hook::set_once();
|
||||
leptos::mount::hydrate_body(App);
|
||||
}
|
||||
8
crates/erplt-api/src/routes/api/mod.rs
Normal file
8
crates/erplt-api/src/routes/api/mod.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
mod v1;
|
||||
|
||||
|
||||
pub fn router() -> crate::Router {
|
||||
crate::Router::new()
|
||||
.merge(v1::router())
|
||||
.nest("/v1", v1::router())
|
||||
}
|
||||
9
crates/erplt-api/src/routes/api/v1/mod.rs
Normal file
9
crates/erplt-api/src/routes/api/v1/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use axum::routing::get;
|
||||
|
||||
mod health;
|
||||
|
||||
|
||||
pub fn router() -> crate::Router {
|
||||
crate::Router::new()
|
||||
.route("/health", get(health::get))
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
use axum::{routing::get, Router};
|
||||
pub mod pages;
|
||||
|
||||
mod health;
|
||||
#[cfg(feature="ssr")]
|
||||
mod api;
|
||||
|
||||
pub fn router() -> Router {
|
||||
Router::new()
|
||||
.route("/health", get(health::get))
|
||||
#[cfg(feature="ssr")]
|
||||
pub fn router() -> crate::Router {
|
||||
crate::Router::new()
|
||||
.nest("/api", api::router())
|
||||
}
|
||||
11
crates/erplt-api/src/routes/pages/home.rs
Normal file
11
crates/erplt-api/src/routes/pages/home.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
use leptos::prelude::*;
|
||||
|
||||
#[component]
|
||||
pub fn HomePage() -> impl IntoView {
|
||||
view! {
|
||||
<main>
|
||||
<h1>"ERPLT"</h1>
|
||||
<p>"Welcome to ERPLT."</p>
|
||||
</main>
|
||||
}
|
||||
}
|
||||
32
crates/erplt-api/src/routes/pages/layout.rs
Normal file
32
crates/erplt-api/src/routes/pages/layout.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
use leptos::prelude::*;
|
||||
|
||||
#[component]
|
||||
pub fn Layout(children: Children) -> impl IntoView {
|
||||
view! {
|
||||
<div class="flex min-h-screen">
|
||||
<aside class="w-64 border-r p-4">
|
||||
<h1 class="mb-6 text-xl font-bold">
|
||||
"ERPLT"
|
||||
</h1>
|
||||
|
||||
<nav class="space-y-2">
|
||||
<a href="/">"Dashboard"</a>
|
||||
<a href="/sales">"Sales"</a>
|
||||
<a href="/purchases">"Purchases"</a>
|
||||
<a href="/inventory">"Inventory"</a>
|
||||
<a href="/accounting">"Accounting"</a>
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
<div class="flex flex-1 flex-col">
|
||||
<header class="border-b p-4">
|
||||
"ERPLT"
|
||||
</header>
|
||||
|
||||
<main class="flex-1 p-6">
|
||||
{children()}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
50
crates/erplt-api/src/routes/pages/mod.rs
Normal file
50
crates/erplt-api/src/routes/pages/mod.rs
Normal file
@@ -0,0 +1,50 @@
|
||||
use leptos::prelude::*;
|
||||
use leptos_meta::*;
|
||||
use leptos_router::{
|
||||
SsrMode, StaticSegment, components::{FlatRoutes, Route, Router},
|
||||
};
|
||||
|
||||
mod home;
|
||||
mod layout;
|
||||
|
||||
#[cfg(feature="ssr")]
|
||||
pub fn shell(options: LeptosOptions) -> impl IntoView {
|
||||
view! {
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<AutoReload options=options.clone() />
|
||||
<HydrationScripts options/>
|
||||
<link rel="stylesheet" id="leptos" href="/pkg/erplt.css"/>
|
||||
<link rel="shortcut icon" type="image/ico" href="/favicon.ico"/>
|
||||
<MetaTags/>
|
||||
</head>
|
||||
<body>
|
||||
<App/>
|
||||
</body>
|
||||
</html>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn App() -> impl IntoView {
|
||||
provide_meta_context();
|
||||
|
||||
view! {
|
||||
<Router>
|
||||
<FlatRoutes fallback=|| "Page not found.">
|
||||
<Route
|
||||
path=StaticSegment("")
|
||||
view=|| view! {
|
||||
<layout::Layout>
|
||||
<home::HomePage/>
|
||||
</layout::Layout>
|
||||
}
|
||||
ssr=SsrMode::Async
|
||||
/>
|
||||
</FlatRoutes>
|
||||
</Router>
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,41 @@
|
||||
use std::{net::{Ipv4Addr, SocketAddr, SocketAddrV4}, str::FromStr};
|
||||
|
||||
use anyhow::Context;
|
||||
use axum::http::StatusCode;
|
||||
use leptos::prelude::*;
|
||||
use leptos_axum::{LeptosRoutes, generate_route_list};
|
||||
|
||||
use erplt_db::DbPool;
|
||||
|
||||
#[axum::debug_handler]
|
||||
async fn fallback() -> (StatusCode, &'static str) {
|
||||
(StatusCode::NOT_FOUND, "Not Found")
|
||||
}
|
||||
use crate::routes;
|
||||
|
||||
|
||||
|
||||
pub async fn start(db: DbPool) -> anyhow::Result<()> {
|
||||
let config = erplt_config::get();
|
||||
|
||||
// Need this because tokio has threading panics otherwise
|
||||
any_spawner::Executor::init_tokio().unwrap();
|
||||
|
||||
let leptos_options = LeptosOptions::builder()
|
||||
.output_name("erplt")
|
||||
.site_root("target/site")
|
||||
.site_pkg_dir("pkg")
|
||||
.reload_external_port(Some((config.web.port+1) as u32))
|
||||
.site_addr(SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::from_str(&config.web.host)?, config.web.port)))
|
||||
.build();
|
||||
|
||||
let routes = generate_route_list(routes::pages::App);
|
||||
|
||||
let app = axum::Router::new()
|
||||
.merge(crate::routes::router())
|
||||
.fallback(fallback);
|
||||
//.merge(crate::routes::router())
|
||||
.merge(routes::router())
|
||||
.leptos_routes(&leptos_options, routes, {
|
||||
let leptos_options = leptos_options.clone();
|
||||
move || routes::pages::shell(leptos_options.clone())
|
||||
})
|
||||
.fallback(leptos_axum::file_and_error_handler(routes::pages::shell))
|
||||
.with_state(leptos_options)
|
||||
.with_state(db);
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +46,7 @@ pub async fn start(db: DbPool) -> anyhow::Result<()> {
|
||||
|
||||
tracing::info!("Web server listening on http://{}", listener.local_addr()?);
|
||||
|
||||
axum::serve(listener, app)
|
||||
axum::serve(listener, app.into_make_service())
|
||||
.await
|
||||
.context("Web server stopped unexpectedly")?;
|
||||
|
||||
|
||||
1
crates/erplt-api/style/tailwind.css
Normal file
1
crates/erplt-api/style/tailwind.css
Normal file
@@ -0,0 +1 @@
|
||||
@import "tailwindcss";
|
||||
@@ -2,7 +2,6 @@ use std::time::Duration;
|
||||
|
||||
use anyhow::Context;
|
||||
use camino::Utf8PathBuf;
|
||||
use serde::de;
|
||||
|
||||
pub mod cli;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use anyhow::Context;
|
||||
use diesel::r2d2::ConnectionManager;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub type DbBackend = diesel::pg::Pg;
|
||||
pub type DbConnection = diesel::PgConnection;
|
||||
pub type DbPool = diesel::r2d2::Pool<
|
||||
@@ -25,6 +26,8 @@ pub fn connect(url: &str) -> anyhow::Result<DbPool> {
|
||||
|
||||
pool.get()
|
||||
.context("Failed to connect to PostgreSQL")?;
|
||||
|
||||
tracing::info!("Connected to database");
|
||||
// crate::migrations::run_migrations(&pool)?;
|
||||
Ok(pool)
|
||||
}
|
||||
@@ -3,17 +3,39 @@ name = "erplt"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[features]
|
||||
default = ["ssr", "erplt-api/ssr"]
|
||||
hydrate=["erplt-api/hydrate"]
|
||||
ssr=[
|
||||
"erplt-api/ssr",
|
||||
"dep:erplt-db",
|
||||
"dep:erplt-config",
|
||||
"dep:camino",
|
||||
"dep:clap",
|
||||
"dep:serde",
|
||||
"dep:toml",
|
||||
"dep:anyhow",
|
||||
"dep:tracing",
|
||||
"dep:tracing-subscriber",
|
||||
"dep:humantime",
|
||||
"dep:humantime-serde",
|
||||
"dep:tokio",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
erplt-db.path="../erplt-db"
|
||||
erplt-api.path="../erplt-api"
|
||||
erplt-config.path="../erplt-config"
|
||||
camino.workspace = true
|
||||
clap.workspace = true
|
||||
serde.workspace = true
|
||||
toml.workspace = true
|
||||
anyhow.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
tracing.workspace = true
|
||||
humantime.workspace = true
|
||||
humantime-serde.workspace = true
|
||||
tokio.workspace = true
|
||||
erplt-db = { path="../erplt-db", optional = true }
|
||||
erplt-config = { path="../erplt-config", optional = true }
|
||||
camino = { workspace = true, optional = true }
|
||||
clap = { workspace = true, optional = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
toml = { workspace = true, optional = true }
|
||||
anyhow = { workspace = true, optional = true }
|
||||
tracing-subscriber = { workspace = true, optional = true }
|
||||
tracing = { workspace = true, optional = true }
|
||||
humantime = { workspace = true, optional = true }
|
||||
humantime-serde = { workspace = true, optional = true }
|
||||
tokio = { workspace = true, optional = true }
|
||||
|
||||
2
crates/erplt/src/lib.rs
Normal file
2
crates/erplt/src/lib.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
#[cfg(feature = "hydrate")]
|
||||
pub use erplt_api::hydrate;
|
||||
1103
package-lock.json
generated
Normal file
1103
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
6
package.json
Normal file
6
package.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@tailwindcss/cli": "^4.3.3",
|
||||
"tailwindcss": "^4.3.3"
|
||||
}
|
||||
}
|
||||
2
scripts/cloc.sh
Normal file
2
scripts/cloc.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/bash
|
||||
cloc . --fullpath --not-match-d="\.hemttout|\.hemtt/presets|target|node_modules" --not-match-f="package-lock.json"
|
||||
Reference in New Issue
Block a user