feat(routes): redirect to detail page after creating brews and cups
Update create_brew, create_cup, and submit_checkin to navigate to the new detail pages instead of reloading or redirecting to home.
This commit is contained in:
parent
b17aaab5f4
commit
eaf558a524
4 changed files with 34 additions and 14 deletions
|
|
@ -254,9 +254,11 @@ pub(crate) async fn create_brew(
|
|||
info!(brew_id = %enriched.brew.id, "brew created");
|
||||
state.stats_invalidator.invalidate();
|
||||
|
||||
let detail_url = format!("/brews/{}", enriched.brew.id);
|
||||
|
||||
if is_datastar_request(&headers) {
|
||||
// If the request came from a page that has #brew-list, return the updated fragment.
|
||||
// Otherwise (homepage, timeline, etc.), trigger a page reload instead.
|
||||
// Otherwise (homepage, add page, etc.), redirect to the brew detail page.
|
||||
let from_brew_page = headers
|
||||
.get("referer")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
|
|
@ -268,8 +270,8 @@ pub(crate) async fn create_brew(
|
|||
.map_err(ApiError::from)
|
||||
} else {
|
||||
use axum::http::header::HeaderValue;
|
||||
let mut response =
|
||||
axum::response::Html("<script>window.location.reload()</script>").into_response();
|
||||
let script = format!("<script>window.location.href='{detail_url}'</script>");
|
||||
let mut response = axum::response::Html(script).into_response();
|
||||
response
|
||||
.headers_mut()
|
||||
.insert("datastar-selector", HeaderValue::from_static("body"));
|
||||
|
|
@ -279,7 +281,7 @@ pub(crate) async fn create_brew(
|
|||
Ok(response)
|
||||
}
|
||||
} else if matches!(source, PayloadSource::Form) {
|
||||
Ok(Redirect::to("/").into_response())
|
||||
Ok(Redirect::to(&detail_url).into_response())
|
||||
} else {
|
||||
Ok((StatusCode::CREATED, Json(enriched)).into_response())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,10 +89,21 @@ pub(crate) async fn submit_checkin(
|
|||
.await
|
||||
.map_err(AppError::from)?;
|
||||
|
||||
let detail_url = format!("/cups/{}", cup.id);
|
||||
|
||||
if is_datastar_request(&headers) {
|
||||
crate::application::routes::support::render_signals_json(&[]).map_err(ApiError::from)
|
||||
use axum::http::header::HeaderValue;
|
||||
let script = format!("<script>window.location.href='{detail_url}'</script>");
|
||||
let mut response = axum::response::Html(script).into_response();
|
||||
response
|
||||
.headers_mut()
|
||||
.insert("datastar-selector", HeaderValue::from_static("body"));
|
||||
response
|
||||
.headers_mut()
|
||||
.insert("datastar-mode", HeaderValue::from_static("append"));
|
||||
Ok(response)
|
||||
} else if matches!(source, PayloadSource::Form) {
|
||||
Ok(Redirect::to("/").into_response())
|
||||
Ok(Redirect::to(&detail_url).into_response())
|
||||
} else {
|
||||
Ok((StatusCode::CREATED, Json(cup)).into_response())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ pub(crate) async fn create_cup(
|
|||
Query(query): Query<ListQuery>,
|
||||
payload: FlexiblePayload<NewCup>,
|
||||
) -> Result<Response, ApiError> {
|
||||
let (request, search) = query.into_request_and_search::<CupSortKey>();
|
||||
let (_request, _search) = query.into_request_and_search::<CupSortKey>();
|
||||
let (new_cup, source) = payload.into_parts();
|
||||
|
||||
let cup = state
|
||||
|
|
@ -64,14 +64,21 @@ pub(crate) async fn create_cup(
|
|||
info!(cup_id = %cup.id, "cup created");
|
||||
state.stats_invalidator.invalidate();
|
||||
|
||||
let detail_url = format!("/cups/{}", cup.id);
|
||||
|
||||
if is_datastar_request(&headers) {
|
||||
render_cup_list_fragment(state, request, search, true)
|
||||
.await
|
||||
.map_err(ApiError::from)
|
||||
use axum::http::header::HeaderValue;
|
||||
let script = format!("<script>window.location.href='{detail_url}'</script>");
|
||||
let mut response = axum::response::Html(script).into_response();
|
||||
response
|
||||
.headers_mut()
|
||||
.insert("datastar-selector", HeaderValue::from_static("body"));
|
||||
response
|
||||
.headers_mut()
|
||||
.insert("datastar-mode", HeaderValue::from_static("append"));
|
||||
Ok(response)
|
||||
} else if matches!(source, PayloadSource::Form) {
|
||||
let target =
|
||||
ListNavigator::new(CUP_PAGE_PATH, CUP_FRAGMENT_PATH, request, search).page_href(1);
|
||||
Ok(Redirect::to(&target).into_response())
|
||||
Ok(Redirect::to(&detail_url).into_response())
|
||||
} else {
|
||||
Ok((StatusCode::CREATED, Json(cup)).into_response())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ block title %}Brewlog · Check In{% endblock %} {% block head %}
|
|||
|
||||
<form
|
||||
data-on:submit="$_submitting = true; $_error = ''; @post('/api/v1/check-in', {contentType: 'form'})"
|
||||
data-on:datastar-fetch="if (!$_submitting) return; if (evt.detail.type === 'finished') { window.location.href = '/' } else if (evt.detail.type === 'error') { $_submitting = false; $_error = 'Check-in failed. Please try again.' }"
|
||||
data-on:datastar-fetch="if (!$_submitting) return; if (evt.detail.type === 'error') { $_submitting = false; $_error = 'Check-in failed. Please try again.' }"
|
||||
>
|
||||
<input type="hidden" name="cafe_id" data-attr:value="$_cafeId" />
|
||||
<input type="hidden" name="cafe_name" data-attr:value="$_cafeName" />
|
||||
|
|
|
|||
Loading…
Reference in a new issue