Fix log on flow; add page title
This commit is contained in:
parent
6dc1ad746c
commit
ade3430fb3
|
@ -8,13 +8,20 @@ open Giraffe
|
|||
open Giraffe.Htmx
|
||||
open MyPrayerJournal.Data.Extensions
|
||||
|
||||
/// Send a partial result if this is not a full page load
|
||||
let partialIfNotRefresh content : HttpHandler =
|
||||
let writeView view : HttpHandler =
|
||||
fun next ctx -> task {
|
||||
match ctx.Request.IsHtmx && not ctx.Request.IsHtmxRefresh with
|
||||
| true -> return! ctx.WriteHtmlViewAsync content
|
||||
| false -> return! Views.Layout.view content |> ctx.WriteHtmlViewAsync
|
||||
}
|
||||
return! ctx.WriteHtmlViewAsync view
|
||||
}
|
||||
|
||||
/// Send a partial result if this is not a full page load
|
||||
let partialIfNotRefresh (pageTitle : string) content : HttpHandler =
|
||||
fun next ctx ->
|
||||
(next, ctx)
|
||||
||> match ctx.Request.IsHtmx && not ctx.Request.IsHtmxRefresh with
|
||||
| true ->
|
||||
ctx.Response.Headers.["X-Page-Title"] <- Microsoft.Extensions.Primitives.StringValues pageTitle
|
||||
withHxTriggerAfterSettle "menu-refresh" >=> writeView content
|
||||
| false -> writeView (Views.Layout.view pageTitle content)
|
||||
|
||||
/// Handler to return Vue files
|
||||
module Vue =
|
||||
|
@ -22,7 +29,7 @@ module Vue =
|
|||
/// The application index page
|
||||
let app : HttpHandler =
|
||||
withHxTrigger "menu-refresh"
|
||||
>=> partialIfNotRefresh (ViewEngine.HtmlElements.str "It works")
|
||||
>=> partialIfNotRefresh "" (ViewEngine.HtmlElements.str "It works")
|
||||
|
||||
|
||||
open System
|
||||
|
@ -180,7 +187,11 @@ module Home =
|
|||
|
||||
// GET /
|
||||
let home : HttpHandler =
|
||||
withMenuRefresh >=> partialIfNotRefresh Views.Home.home
|
||||
withMenuRefresh >=> partialIfNotRefresh "Welcome!" Views.Home.home
|
||||
|
||||
// GET /user/log-on
|
||||
let logOn : HttpHandler =
|
||||
partialIfNotRefresh "Logging on..." Views.Home.logOn
|
||||
|
||||
|
||||
/// /journal URL
|
||||
|
@ -192,7 +203,7 @@ module Journal =
|
|||
>=> withMenuRefresh
|
||||
>=> fun next ctx -> task {
|
||||
let usr = ctx.Request.Headers.["X-Given-Name"].[0]
|
||||
return! partialIfNotRefresh (Views.Journal.journal usr) next ctx
|
||||
return! partialIfNotRefresh "Your Prayer Journal" (Views.Journal.journal usr) next ctx
|
||||
}
|
||||
|
||||
|
||||
|
@ -201,11 +212,11 @@ module Legal =
|
|||
|
||||
// GET /legal/privacy-policy
|
||||
let privacyPolicy : HttpHandler =
|
||||
withMenuRefresh >=> partialIfNotRefresh Views.Legal.privacyPolicy
|
||||
withMenuRefresh >=> partialIfNotRefresh "Privacy Policy" Views.Legal.privacyPolicy
|
||||
|
||||
// GET /legal/terms-of-service
|
||||
let termsOfService : HttpHandler =
|
||||
withMenuRefresh >=> partialIfNotRefresh Views.Legal.termsOfService
|
||||
withMenuRefresh >=> partialIfNotRefresh "Terms of Service" Views.Legal.termsOfService
|
||||
|
||||
|
||||
/// /api/request and /request(s) URLs
|
||||
|
@ -292,7 +303,7 @@ module Request =
|
|||
>=> withMenuRefresh
|
||||
>=> fun next ctx -> task {
|
||||
let! reqs = Data.journalByUserId (userId ctx) (db ctx)
|
||||
return! partialIfNotRefresh (Views.Request.active reqs) next ctx
|
||||
return! partialIfNotRefresh "Active Requests" (Views.Request.active reqs) next ctx
|
||||
}
|
||||
|
||||
/// GET /requests/answered
|
||||
|
@ -301,7 +312,7 @@ module Request =
|
|||
>=> withMenuRefresh
|
||||
>=> fun next ctx -> task {
|
||||
let! reqs = Data.answeredRequests (userId ctx) (db ctx)
|
||||
return! partialIfNotRefresh (Views.Request.answered reqs) next ctx
|
||||
return! partialIfNotRefresh "Answered Requests" (Views.Request.answered reqs) next ctx
|
||||
}
|
||||
|
||||
/// GET /api/request/[req-id]
|
||||
|
@ -319,7 +330,7 @@ module Request =
|
|||
>=> withMenuRefresh
|
||||
>=> fun next ctx -> task {
|
||||
match! Data.tryFullRequestById (toReqId requestId) (userId ctx) (db ctx) with
|
||||
| Some req -> return! partialIfNotRefresh (Views.Request.full req) next ctx
|
||||
| Some req -> return! partialIfNotRefresh "Full Prayer Request" (Views.Request.full req) next ctx
|
||||
| None -> return! Error.notFound next ctx
|
||||
}
|
||||
|
||||
|
@ -402,6 +413,7 @@ let routes =
|
|||
route "s/answered" Request.answered
|
||||
routef "/%s/full" Request.getFull
|
||||
]
|
||||
route "/user/log-on" Home.logOn
|
||||
subRoute "/api/" [
|
||||
GET [
|
||||
subRoute "request" [
|
||||
|
|
|
@ -32,7 +32,7 @@ module Helpers =
|
|||
span [ _title (date.ToString "f") ] [ Dates.formatDistance DateTime.Now date |> str ]
|
||||
|
||||
|
||||
/// View for home page
|
||||
/// Views for home and log on pages
|
||||
module Home =
|
||||
|
||||
/// The home page
|
||||
|
@ -49,6 +49,13 @@ module Home =
|
|||
rawText "learn more about the site at the “Docs” link, also above."
|
||||
]
|
||||
]
|
||||
|
||||
/// The log on page
|
||||
let logOn = article [ _class "container mt-3" ] [
|
||||
p [] [
|
||||
em [] [ str "Verifying..." ]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
/// Views for legal pages
|
||||
|
@ -406,8 +413,9 @@ module Request =
|
|||
/// Layout views
|
||||
module Layout =
|
||||
|
||||
let htmlHead =
|
||||
let htmlHead pageTitle =
|
||||
head [] [
|
||||
title [] [ str pageTitle; rawText " « myPrayerJournal" ]
|
||||
link [
|
||||
_href "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
|
||||
_rel "stylesheet"
|
||||
|
@ -451,12 +459,12 @@ module Layout =
|
|||
]
|
||||
|
||||
/// Create the full view of the page
|
||||
let view content =
|
||||
let view pageTitle content =
|
||||
html [ _lang "en" ] [
|
||||
htmlHead
|
||||
htmlHead pageTitle
|
||||
body [ _hxHeaders "" ] [
|
||||
Navigation.navBar
|
||||
main [] [ content ]
|
||||
main [ _hxTrigger "setTitle from:body" ] [ content ]
|
||||
htmlFoot
|
||||
]
|
||||
]
|
||||
|
|
|
@ -19,10 +19,12 @@ const mpj = {
|
|||
},
|
||||
/** Whether the user is currently authenticated */
|
||||
isAuthenticated: false,
|
||||
/** Whether we should redirect to the journal the next time the menu items are refreshed */
|
||||
redirToJournal: false,
|
||||
/** Process a log on request */
|
||||
logOn: async (e) => {
|
||||
e.preventDefault()
|
||||
await mpj.auth.auth0.loginWithRedirect({ redirect_uri: window.location.origin })
|
||||
await mpj.auth.auth0.loginWithRedirect({ redirect_uri: `${window.location.origin}/user/log-on` })
|
||||
},
|
||||
/** Log the user off */
|
||||
logOff: (e) => {
|
||||
|
@ -54,6 +56,27 @@ window.onload = async () => {
|
|||
if (query.includes("code=") && query.includes("state=")) {
|
||||
await mpj.auth.auth0.handleRedirectCallback()
|
||||
await establishAuth()
|
||||
window.history.replaceState({}, document.title, "/")
|
||||
if (window.location.pathname === "/user/log-on") {
|
||||
mpj.redirToJournal = true
|
||||
} else {
|
||||
window.history.replaceState({}, document.title, "/")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
htmx.on("htmx:afterOnLoad", function (evt) {
|
||||
// Set the page title if a header was in the response
|
||||
if (evt.detail.xhr.getAllResponseHeaders().indexOf("x-page-title") >= 0) {
|
||||
const title = document.querySelector("title")
|
||||
title.innerText = evt.detail.xhr.getResponseHeader("x-page-title")
|
||||
title.innerHTML += " « myPrayerJournal"
|
||||
}
|
||||
})
|
||||
htmx.on("htmx:afterSettle", function (evt) {
|
||||
// Redirect to the journal (once menu items load after log on)
|
||||
if (mpj.redirToJournal
|
||||
&& ([...evt.target.attributes].find(it => it.name === "hx-target")?.value ?? "") === ".navbar-nav") {
|
||||
mpj.redirToJournal = false
|
||||
document.querySelector(`a[href="/journal"]`).click()
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue
Block a user