feat: enable dynamic routes on frontend

This commit is contained in:
Valerio Ageno
2024-06-02 20:32:53 +02:00
parent 7557df10f3
commit 7cfaf94146
4 changed files with 36 additions and 16 deletions
@@ -20,10 +20,11 @@ pub const AXUM_ENTRY_POINT: &str = r##"
// File automatically generated
// Do not manually change it
use axum::extract::Request;
use axum::extract::{Path, Request};
use axum::response::Html;
use axum::{routing::get, Router};
use tower_http::services::ServeDir;
use std::collections::HashMap;
use tuono_lib::{ssr, Ssr};
use reqwest::Client;
@@ -44,11 +45,11 @@ async fn main() {
axum::serve(listener, app).await.unwrap();
}
async fn catch_all(request: Request) -> Html<String> {
async fn catch_all(Path(params): Path<HashMap<String, String>>, request: Request) -> Html<String> {
let pathname = &request.uri();
let headers = &request.headers();
let req = tuono_lib::Request::new(pathname, headers);
let req = tuono_lib::Request::new(pathname, headers, params);
// TODO: remove unwrap
+12 -3
View File
@@ -3,10 +3,11 @@ use std::collections::HashMap;
use axum::http::{HeaderMap, Uri};
#[derive(Debug, Copy, Clone)]
#[derive(Debug, Clone)]
pub struct Request<'a> {
uri: &'a Uri,
headers: &'a HeaderMap,
pub params: HashMap<String, String>,
}
/// Location must match client side interface
@@ -21,8 +22,16 @@ pub struct Location<'a> {
}
impl<'a> Request<'a> {
pub fn new(uri: &'a Uri, headers: &'a HeaderMap) -> Request<'a> {
Request { uri, headers }
pub fn new(
uri: &'a Uri,
headers: &'a HeaderMap,
params: HashMap<String, String>,
) -> Request<'a> {
Request {
uri,
headers,
params,
}
}
pub fn location(&self) -> Location<'a> {
+14 -5
View File
@@ -9,16 +9,21 @@ pub fn handler_core(_args: TokenStream, item: TokenStream) -> TokenStream {
quote! {
use axum::response::{Html, IntoResponse};
use axum::extract::State;
use std::collections::HashMap;
use axum::extract::{State, Path};
use reqwest::Client;
#item
pub async fn route(State(client): State<Client>, request: axum::extract::Request) -> Html<String> {
pub async fn route(
Path(params): Path<HashMap<String, String>>,
State(client): State<Client>,
request: axum::extract::Request
) -> Html<String> {
let pathname = &request.uri();
let headers = &request.headers();
let req = tuono_lib::Request::new(pathname, headers);
let req = tuono_lib::Request::new(pathname, headers, params);
let local_response = #fn_name(req.clone(), client).await;
@@ -40,11 +45,15 @@ pub fn handler_core(_args: TokenStream, item: TokenStream) -> TokenStream {
}
}
pub async fn api(State(client): State<Client>, request: axum::extract::Request) -> axum::response::Response {
pub async fn api(
Path(params): Path<HashMap<String, String>>,
State(client): State<Client>,
request: axum::extract::Request
) -> axum::response::Response {
let pathname = &request.uri();
let headers = &request.headers();
let req = tuono_lib::Request::new(pathname, headers);
let req = tuono_lib::Request::new(pathname, headers, params);
let local_response = #fn_name(req.clone(), client).await;
@@ -1,5 +1,6 @@
import { useState, useEffect, useRef } from 'react'
import type { Route } from '../route'
import { useRouterStore } from './useRouterStore'
const isServer = typeof document === 'undefined'
@@ -20,6 +21,7 @@ export function useServerSideProps(
serverSideProps: any,
): UseServerSidePropsReturn {
const isFirstRendering = useRef<boolean>(true)
const location = useRouterStore((st) => st.location)
const [isLoading, setIsLoading] = useState<boolean>(
// Force loading if has handler
route.options.hasHandler &&
@@ -41,15 +43,14 @@ export function useServerSideProps(
return
}
// After client side routing load again the remote data
if (route.options.hasHandler && !data) {
if (route.options.hasHandler) {
;(async (): Promise<void> => {
setIsLoading(true)
try {
const path = route.path === '/' ? '' : route.path
const res = await fetch(`/__tuono/data/${path}`)
const res = await fetch(`/__tuono/data${location.pathname}`)
setData(await res.json())
} catch (error) {
// Handle here error
throw Error('Failed loading Server Side Data', { cause: error })
} finally {
setIsLoading(false)
}
@@ -60,7 +61,7 @@ export function useServerSideProps(
return (): void => {
setData(undefined)
}
}, [route.path])
}, [location.pathname])
return { isLoading, data }
}