feat: add base app

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
Kasper Juul Hermansen 2023-06-04 20:11:02 +02:00
parent c3b45d9eb6
commit 74a16b4d7c
Signed by: kjuulh
GPG Key ID: 57B6E1465221F912
13 changed files with 2675 additions and 528 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
COMO_GATEWAY_PAT="MjE3MDg4ODQ0NzMyODI1ODU3OjVXSEhVT0U4djhGSHNuTFNYRzkzRGJGYmhrUUhRMGpwWm5NLUM1VE56UVdJSzhUdnlfaVBKMGVtMHdJZzhwUWRXcVdkeFVF"

1256
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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"

View File

@ -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
View 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

File diff suppressed because it is too large Load Diff

2
src/api/mod.rs Normal file
View File

@ -0,0 +1,2 @@
#[cfg(feature = "ssr")]
pub fn register() {}

View File

@ -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
View 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}"),
)),
}
}
}}

View File

@ -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! {

View File

@ -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/> }
});
} }

View File

@ -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;