feat: add base app
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
c3b45d9eb6
commit
74a16b4d7c
1
.env
Normal file
1
.env
Normal file
@ -0,0 +1 @@
|
|||||||
|
COMO_GATEWAY_PAT="MjE3MDg4ODQ0NzMyODI1ODU3OjVXSEhVT0U4djhGSHNuTFNYRzkzRGJGYmhrUUhRMGpwWm5NLUM1VE56UVdJSzhUdnlfaVBKMGVtMHdJZzhwUWRXcVdkeFVF"
|
1256
Cargo.lock
generated
1256
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
58
Cargo.toml
58
Cargo.toml
@ -1,5 +1,13 @@
|
|||||||
|
[workspace]
|
||||||
|
|
||||||
|
[workspace.dependencies]
|
||||||
|
uuid = { version = "1.3.0", features = ["v4", "serde"] }
|
||||||
|
chrono = { version = "0.4.23", features = ["serde"] }
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "leptos_start"
|
name = "como_web"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
@ -7,31 +15,55 @@ edition = "2021"
|
|||||||
crate-type = ["cdylib", "rlib"]
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-files = { version = "0.6", optional = true }
|
|
||||||
actix-web = { version = "4", optional = true, features = ["macros"] }
|
|
||||||
console_error_panic_hook = "0.1"
|
console_error_panic_hook = "0.1"
|
||||||
|
console_log = "0.2"
|
||||||
cfg-if = "1"
|
cfg-if = "1"
|
||||||
leptos = { version = "0.3", default-features = false, features = ["serde"] }
|
lazy_static = "1"
|
||||||
leptos_meta = { version = "0.3", default-features = false }
|
leptos = { version = "*", default-features = false, features = ["serde"] }
|
||||||
leptos_actix = { version = "0.3", optional = true }
|
leptos_meta = { version = "*", default-features = false }
|
||||||
leptos_router = { version = "0.3", default-features = false }
|
leptos_axum = { version = "*", default-features = false, optional = true }
|
||||||
wasm-bindgen = "=0.2.84"
|
leptos_router = { version = "*", default-features = false }
|
||||||
|
log = "0.4"
|
||||||
|
simple_logger = "4"
|
||||||
|
thiserror = "1"
|
||||||
|
axum = { version = "0.6.1", optional = true }
|
||||||
|
tower = { version = "0.4.13", optional = true }
|
||||||
|
tower-http = { version = "0.3.4", features = ["fs"], optional = true }
|
||||||
|
tokio = { version = "1", features = ["time"], optional = true }
|
||||||
|
wasm-bindgen = "0.2"
|
||||||
|
tracing-subscriber = { version = "0.3.16", optional = true, features = [
|
||||||
|
"env-filter",
|
||||||
|
] }
|
||||||
|
tracing = { version = "0.1.37", features = ["log"], optional = true }
|
||||||
|
anyhow = { version = "1.0.71", optional = true }
|
||||||
|
|
||||||
|
serde = { workspace = true }
|
||||||
|
chrono = { workspace = true }
|
||||||
|
uuid = { workspace = true, features = ["v4", "wasm-bindgen", "js", "serde"] }
|
||||||
|
graphql_client = { version = "0.13.0", optional = true, features = ["reqwest"] }
|
||||||
|
reqwest = { version = "0.11.18", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
csr = ["leptos/csr", "leptos_meta/csr", "leptos_router/csr"]
|
|
||||||
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
|
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
|
||||||
ssr = [
|
ssr = [
|
||||||
"dep:actix-files",
|
"dep:axum",
|
||||||
"dep:actix-web",
|
"dep:tower",
|
||||||
"dep:leptos_actix",
|
"dep:tower-http",
|
||||||
|
"dep:tokio",
|
||||||
"leptos/ssr",
|
"leptos/ssr",
|
||||||
"leptos_meta/ssr",
|
"leptos_meta/ssr",
|
||||||
"leptos_router/ssr",
|
"leptos_router/ssr",
|
||||||
|
"dep:leptos_axum",
|
||||||
|
"dep:tracing-subscriber",
|
||||||
|
"dep:tracing",
|
||||||
|
"dep:graphql_client",
|
||||||
|
"dep:reqwest",
|
||||||
|
"dep:anyhow",
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata.leptos]
|
[package.metadata.leptos]
|
||||||
# The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name
|
# The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name
|
||||||
output-name = "leptos_start"
|
output-name = "como_web"
|
||||||
# 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.
|
# 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"
|
site-root = "target/site"
|
||||||
# The site-root relative folder where all compiled output (JS, WASM and CSS) is written
|
# The site-root relative folder where all compiled output (JS, WASM and CSS) is written
|
||||||
|
@ -46,12 +46,12 @@ After running a `cargo leptos build --release` the minimum files needed are:
|
|||||||
|
|
||||||
Copy these files to your remote server. The directory structure should be:
|
Copy these files to your remote server. The directory structure should be:
|
||||||
```text
|
```text
|
||||||
leptos_start
|
como_web
|
||||||
site/
|
site/
|
||||||
```
|
```
|
||||||
Set the following enviornment variables (updating for your project as needed):
|
Set the following enviornment variables (updating for your project as needed):
|
||||||
```text
|
```text
|
||||||
LEPTOS_OUTPUT_NAME="leptos_start"
|
LEPTOS_OUTPUT_NAME="como_web"
|
||||||
LEPTOS_SITE_ROOT="site"
|
LEPTOS_SITE_ROOT="site"
|
||||||
LEPTOS_SITE_PKG_DIR="pkg"
|
LEPTOS_SITE_PKG_DIR="pkg"
|
||||||
LEPTOS_SITE_ADDR="127.0.0.1:3000"
|
LEPTOS_SITE_ADDR="127.0.0.1:3000"
|
||||||
|
@ -23,3 +23,5 @@ scripts:
|
|||||||
type: "shell"
|
type: "shell"
|
||||||
"nodev":
|
"nodev":
|
||||||
type: "shell"
|
type: "shell"
|
||||||
|
"refresh:schema":
|
||||||
|
type: "shell"
|
||||||
|
16
scripts/refresh:schema.sh
Executable file
16
scripts/refresh:schema.sh
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
graphql-client introspect-schema \
|
||||||
|
http://localhost:3001/graphql \
|
||||||
|
--header "Authorization: Basic $COMO_GATEWAY_PAT" \
|
||||||
|
--output src/api/graphql/schema/schema.json
|
||||||
|
|
||||||
|
graphql-client generate \
|
||||||
|
--schema-path src/api/graphql/schema/schema.json \
|
||||||
|
src/api/graphql/schema/mutations.graphql \
|
||||||
|
--output-directory src/api/graphql/gen
|
||||||
|
|
||||||
|
graphql-client generate \
|
||||||
|
--schema-path src/api/graphql/schema/schema.json \
|
||||||
|
src/api/graphql/schema/queries.graphql \
|
||||||
|
--output-directory src/api/graphql/gen
|
1738
src/api/graphql/schema/schema.json
Normal file
1738
src/api/graphql/schema/schema.json
Normal file
File diff suppressed because it is too large
Load Diff
2
src/api/mod.rs
Normal file
2
src/api/mod.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#[cfg(feature = "ssr")]
|
||||||
|
pub fn register() {}
|
@ -12,7 +12,7 @@ pub fn App(cx: Scope) -> impl IntoView {
|
|||||||
|
|
||||||
// injects a stylesheet into the document <head>
|
// injects a stylesheet into the document <head>
|
||||||
// id=leptos means cargo-leptos will hot-reload this stylesheet
|
// id=leptos means cargo-leptos will hot-reload this stylesheet
|
||||||
<Stylesheet id="leptos" href="/pkg/leptos_start.css"/>
|
<Stylesheet id="leptos" href="/pkg/como_web.css"/>
|
||||||
|
|
||||||
// sets the document title
|
// sets the document title
|
||||||
<Title text="Welcome to Leptos"/>
|
<Title text="Welcome to Leptos"/>
|
||||||
|
45
src/fallback.rs
Normal file
45
src/fallback.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
use cfg_if::cfg_if;
|
||||||
|
|
||||||
|
cfg_if! { if #[cfg(feature = "ssr")] {
|
||||||
|
use axum::{
|
||||||
|
body::{boxed, Body, BoxBody},
|
||||||
|
extract::Extension,
|
||||||
|
response::IntoResponse,
|
||||||
|
http::{Request, Response, StatusCode, Uri},
|
||||||
|
};
|
||||||
|
use axum::response::Response as AxumResponse;
|
||||||
|
use tower::ServiceExt;
|
||||||
|
use tower_http::services::ServeDir;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use leptos::{LeptosOptions, Errors, view};
|
||||||
|
use crate::app::{App, AppProps};
|
||||||
|
|
||||||
|
pub async fn file_and_error_handler(uri: Uri, Extension(options): Extension<Arc<LeptosOptions>>, req: Request<Body>) -> AxumResponse {
|
||||||
|
let options = &*options;
|
||||||
|
let root = options.site_root.clone();
|
||||||
|
let res = get_static_file(uri.clone(), &root).await.unwrap();
|
||||||
|
|
||||||
|
if res.status() == StatusCode::OK {
|
||||||
|
res.into_response()
|
||||||
|
} else{
|
||||||
|
let handler = leptos_axum::render_app_to_stream(
|
||||||
|
options.to_owned(),
|
||||||
|
move |cx| view!{ cx, <App/> }
|
||||||
|
);
|
||||||
|
handler(req).await.into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_static_file(uri: Uri, root: &str) -> Result<Response<BoxBody>, (StatusCode, String)> {
|
||||||
|
let req = Request::builder().uri(uri.clone()).body(Body::empty()).unwrap();
|
||||||
|
// `ServeDir` implements `tower::Service` so we can call it with `tower::ServiceExt::oneshot`
|
||||||
|
// This path is relative to the cargo root
|
||||||
|
match ServeDir::new(root).oneshot(req).await {
|
||||||
|
Ok(res) => Ok(res.map(boxed)),
|
||||||
|
Err(err) => Err((
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Something went wrong: {err}"),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
@ -1,4 +1,6 @@
|
|||||||
|
pub mod api;
|
||||||
pub mod app;
|
pub mod app;
|
||||||
|
pub mod fallback;
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
|
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
|
73
src/main.rs
73
src/main.rs
@ -1,58 +1,45 @@
|
|||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
#[actix_web::main]
|
#[tokio::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() {
|
||||||
use actix_files::Files;
|
use axum::{extract::Extension, routing::post, Router};
|
||||||
use actix_web::*;
|
use como_web::app::*;
|
||||||
|
use como_web::fallback::file_and_error_handler;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_actix::{generate_route_list, LeptosRoutes};
|
use leptos_axum::{generate_route_list, LeptosRoutes};
|
||||||
use leptos_start::app::*;
|
use std::sync::Arc;
|
||||||
|
use tracing_subscriber::EnvFilter;
|
||||||
|
|
||||||
|
std::env::set_var("COMO_GATEWAY_URL", "https://api.como.i.kjuulh.io/graphql");
|
||||||
|
tracing_subscriber::fmt()
|
||||||
|
.with_env_filter(EnvFilter::from_default_env())
|
||||||
|
.init();
|
||||||
|
|
||||||
let conf = get_configuration(None).await.unwrap();
|
let conf = get_configuration(None).await.unwrap();
|
||||||
let addr = conf.leptos_options.site_addr;
|
let addr = conf.leptos_options.site_addr;
|
||||||
|
let leptos_options = conf.leptos_options;
|
||||||
// Generate the list of routes in your Leptos App
|
// Generate the list of routes in your Leptos App
|
||||||
let routes = generate_route_list(|cx| view! { cx, <App/> });
|
let routes = generate_route_list(|cx| view! { cx, <App/> }).await;
|
||||||
|
|
||||||
HttpServer::new(move || {
|
como_web::api::register();
|
||||||
let leptos_options = &conf.leptos_options;
|
|
||||||
let site_root = &leptos_options.site_root;
|
|
||||||
|
|
||||||
App::new()
|
let app = Router::new()
|
||||||
.route("/api/{tail:.*}", leptos_actix::handle_server_fns())
|
.route("/api/*fn_name", post(leptos_axum::handle_server_fns))
|
||||||
.leptos_routes(
|
.leptos_routes(leptos_options.clone(), routes, |cx| view! { cx, <App/> })
|
||||||
leptos_options.to_owned(),
|
.fallback(file_and_error_handler)
|
||||||
routes.to_owned(),
|
.layer(Extension(Arc::new(leptos_options)));
|
||||||
|cx| view! { cx, <App/> },
|
|
||||||
)
|
// run our app with hyper
|
||||||
.service(Files::new("/", site_root))
|
// `axum::Server` is a re-export of `hyper::Server`
|
||||||
//.wrap(middleware::Compress::default())
|
log!("listening on http://{}", &addr);
|
||||||
})
|
axum::Server::bind(&addr)
|
||||||
.bind(&addr)?
|
.serve(app.into_make_service())
|
||||||
.run()
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(feature = "ssr", feature = "csr")))]
|
#[cfg(not(feature = "ssr"))]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
// no client-side main function
|
// no client-side main function
|
||||||
// unless we want this to work with e.g., Trunk for pure client-side testing
|
// unless we want this to work with e.g., Trunk for pure client-side testing
|
||||||
// see lib.rs for hydration function instead
|
// see lib.rs for hydration function instead
|
||||||
// see optional feature `ssg` instead
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(not(feature = "ssr"), feature = "csr"))]
|
|
||||||
pub fn main() {
|
|
||||||
// a client-side main function is required for using `trunk serve`
|
|
||||||
// prefer using `cargo leptos serve` instead
|
|
||||||
// to run: `trunk serve --open --features ssg`
|
|
||||||
use leptos::*;
|
|
||||||
use leptos_start::app::*;
|
|
||||||
use wasm_bindgen::prelude::wasm_bindgen;
|
|
||||||
|
|
||||||
console_error_panic_hook::set_once();
|
|
||||||
|
|
||||||
leptos::mount_to_body(move |cx| {
|
|
||||||
// note: for testing it may be preferrable to replace this with a
|
|
||||||
// more specific component, although leptos_router should still work
|
|
||||||
view! {cx, <App/> }
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
@ -522,6 +522,10 @@ video {
|
|||||||
--tw-backdrop-sepia: ;
|
--tw-backdrop-sepia: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.relative {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.text-xl {
|
.text-xl {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
line-height: 1.75rem;
|
line-height: 1.75rem;
|
||||||
|
Loading…
Reference in New Issue
Block a user