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");
|
info!(brew_id = %enriched.brew.id, "brew created");
|
||||||
state.stats_invalidator.invalidate();
|
state.stats_invalidator.invalidate();
|
||||||
|
|
||||||
|
let detail_url = format!("/brews/{}", enriched.brew.id);
|
||||||
|
|
||||||
if is_datastar_request(&headers) {
|
if is_datastar_request(&headers) {
|
||||||
// If the request came from a page that has #brew-list, return the updated fragment.
|
// 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
|
let from_brew_page = headers
|
||||||
.get("referer")
|
.get("referer")
|
||||||
.and_then(|v| v.to_str().ok())
|
.and_then(|v| v.to_str().ok())
|
||||||
|
|
@ -268,8 +270,8 @@ pub(crate) async fn create_brew(
|
||||||
.map_err(ApiError::from)
|
.map_err(ApiError::from)
|
||||||
} else {
|
} else {
|
||||||
use axum::http::header::HeaderValue;
|
use axum::http::header::HeaderValue;
|
||||||
let mut response =
|
let script = format!("<script>window.location.href='{detail_url}'</script>");
|
||||||
axum::response::Html("<script>window.location.reload()</script>").into_response();
|
let mut response = axum::response::Html(script).into_response();
|
||||||
response
|
response
|
||||||
.headers_mut()
|
.headers_mut()
|
||||||
.insert("datastar-selector", HeaderValue::from_static("body"));
|
.insert("datastar-selector", HeaderValue::from_static("body"));
|
||||||
|
|
@ -279,7 +281,7 @@ pub(crate) async fn create_brew(
|
||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
} else if matches!(source, PayloadSource::Form) {
|
} else if matches!(source, PayloadSource::Form) {
|
||||||
Ok(Redirect::to("/").into_response())
|
Ok(Redirect::to(&detail_url).into_response())
|
||||||
} else {
|
} else {
|
||||||
Ok((StatusCode::CREATED, Json(enriched)).into_response())
|
Ok((StatusCode::CREATED, Json(enriched)).into_response())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,10 +89,21 @@ pub(crate) async fn submit_checkin(
|
||||||
.await
|
.await
|
||||||
.map_err(AppError::from)?;
|
.map_err(AppError::from)?;
|
||||||
|
|
||||||
|
let detail_url = format!("/cups/{}", cup.id);
|
||||||
|
|
||||||
if is_datastar_request(&headers) {
|
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) {
|
} else if matches!(source, PayloadSource::Form) {
|
||||||
Ok(Redirect::to("/").into_response())
|
Ok(Redirect::to(&detail_url).into_response())
|
||||||
} else {
|
} else {
|
||||||
Ok((StatusCode::CREATED, Json(cup)).into_response())
|
Ok((StatusCode::CREATED, Json(cup)).into_response())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ pub(crate) async fn create_cup(
|
||||||
Query(query): Query<ListQuery>,
|
Query(query): Query<ListQuery>,
|
||||||
payload: FlexiblePayload<NewCup>,
|
payload: FlexiblePayload<NewCup>,
|
||||||
) -> Result<Response, ApiError> {
|
) -> 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 (new_cup, source) = payload.into_parts();
|
||||||
|
|
||||||
let cup = state
|
let cup = state
|
||||||
|
|
@ -64,14 +64,21 @@ pub(crate) async fn create_cup(
|
||||||
info!(cup_id = %cup.id, "cup created");
|
info!(cup_id = %cup.id, "cup created");
|
||||||
state.stats_invalidator.invalidate();
|
state.stats_invalidator.invalidate();
|
||||||
|
|
||||||
|
let detail_url = format!("/cups/{}", cup.id);
|
||||||
|
|
||||||
if is_datastar_request(&headers) {
|
if is_datastar_request(&headers) {
|
||||||
render_cup_list_fragment(state, request, search, true)
|
use axum::http::header::HeaderValue;
|
||||||
.await
|
let script = format!("<script>window.location.href='{detail_url}'</script>");
|
||||||
.map_err(ApiError::from)
|
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) {
|
} else if matches!(source, PayloadSource::Form) {
|
||||||
let target =
|
Ok(Redirect::to(&detail_url).into_response())
|
||||||
ListNavigator::new(CUP_PAGE_PATH, CUP_FRAGMENT_PATH, request, search).page_href(1);
|
|
||||||
Ok(Redirect::to(&target).into_response())
|
|
||||||
} else {
|
} else {
|
||||||
Ok((StatusCode::CREATED, Json(cup)).into_response())
|
Ok((StatusCode::CREATED, Json(cup)).into_response())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -304,7 +304,7 @@ block title %}Brewlog · Check In{% endblock %} {% block head %}
|
||||||
|
|
||||||
<form
|
<form
|
||||||
data-on:submit="$_submitting = true; $_error = ''; @post('/api/v1/check-in', {contentType: '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_id" data-attr:value="$_cafeId" />
|
||||||
<input type="hidden" name="cafe_name" data-attr:value="$_cafeName" />
|
<input type="hidden" name="cafe_name" data-attr:value="$_cafeName" />
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue