v8.4 #53
74
src/PrayerTracker.UI/Help.fs
Normal file
74
src/PrayerTracker.UI/Help.fs
Normal file
|
@ -0,0 +1,74 @@
|
|||
/// Help content for PrayerTracker
|
||||
module PrayerTracker.Views.Help
|
||||
|
||||
open System.IO
|
||||
open Giraffe.ViewEngine
|
||||
|
||||
/// The help index page
|
||||
let index () =
|
||||
let s = I18N.localizer.Force()
|
||||
let l = I18N.forView "Help/Index"
|
||||
use sw = new StringWriter()
|
||||
let raw = rawLocText sw
|
||||
[ p [] [
|
||||
raw l["Throughout PrayerTracker, you'll see an icon (a question mark in a circle) next to the title on each page."]; space
|
||||
raw l["Clicking this will open a new, small window with directions on using that page."]; space
|
||||
raw l["If you are looking for a quick overview of PrayerTracker, start with the “Add / Edit a Request” and “Change Preferences” entries."] ]
|
||||
hr []
|
||||
p [ _class "pt-center-text" ] [ strong [] [ locStr s["Help Topics"] ] ]
|
||||
p [] [ a [ _href "/help/small-group/preferences" ] [ locStr s["Change Preferences"] ] ]
|
||||
p [] [ a [ _href "/help/small-group/announcement" ] [ locStr s["Send Announcement"] ] ]
|
||||
p [] [ a [ _href "/help/small-group/members" ] [ locStr s["Maintain Group Members"] ] ]
|
||||
p [] [ a [ _href "/help/requests/edit" ] [ locStr s["Add / Edit a Request"] ] ]
|
||||
p [] [ a [ _href "/help/requests/maintain" ] [ locStr s["Maintain Requests"] ] ]
|
||||
p [] [ a [ _href "/help/requests/view" ] [ locStr s["View Request List"] ] ]
|
||||
p [] [ a [ _href "/help/user/log-on" ] [ locStr s["Log On"] ] ]
|
||||
p [] [ a [ _href "/help/user/password" ] [ locStr s["Change Your Password"] ] ] ]
|
||||
|
||||
|
||||
/// Help for prayer requests
|
||||
module Requests =
|
||||
|
||||
/// Add / Edit a Request
|
||||
let edit () =
|
||||
let s = I18N.localizer.Force()
|
||||
let l = I18N.forView "Help/Requests/Edit"
|
||||
use sw = new StringWriter()
|
||||
let raw = rawLocText sw
|
||||
[ p [] [ raw l["This page allows you to enter or update a new prayer request."] ]
|
||||
h2 [] [ locStr s["Request Type"] ]
|
||||
p [] [
|
||||
raw l["There are 5 request types in PrayerTracker."]; space
|
||||
raw l["“Current Requests” are your regular requests that people may have regarding things happening over the next week or so."]; space
|
||||
raw l["“Long-Term Requests” are requests that may occur repeatedly or continue indefinitely."]; space
|
||||
raw l["“Praise Reports” are like “Current Requests”, but they are answers to prayer to share with your group."]; space
|
||||
raw l["“Expecting” is for those who are pregnant."]; space
|
||||
raw l["“Announcements” are like “Current Requests”, but instead of a request, they are simply passing information along about something coming up."] ]
|
||||
p [] [
|
||||
raw l["The order above is the order in which the request types appear on the list."]; space
|
||||
raw l["“Long-Term Requests” and “Expecting” are not subject to the automatic expiration (set on the “Change Preferences” page) that the other requests are."] ]
|
||||
h2 [] [ locStr s["Date"] ]
|
||||
p [] [
|
||||
raw l["For new requests, this is a box with a calendar date picker."]; space
|
||||
raw l["Click or tab into the box to display the calendar, which will be preselected to today's date."]; space
|
||||
raw l["For existing requests, there will be a check box labeled “Check to not update the date”."]; space
|
||||
raw l["This can be used if you are correcting spelling or punctuation, and do not have an actual update to make to the request."]
|
||||
]
|
||||
h2 [] [ locStr s["Requestor / Subject"] ]
|
||||
p [] [
|
||||
raw l["For requests or praises, this field is for the name of the person who made the request or offered the praise report."]; space
|
||||
raw l["For announcements, this should contain the subject of the announcement."]; space
|
||||
raw l["For all types, it is optional; I used to have an announcement with no subject that ran every week, telling where to send requests and updates."] ]
|
||||
h2 [] [ locStr s["Expiration"] ]
|
||||
p [] [
|
||||
raw l["“Expire Normally” means that the request is subject to the expiration days in the group preferences."]; space
|
||||
raw l["“Request Never Expires” can be used to make a request never expire (note that this is redundant for “Long-Term Requests” and “Expecting”)."]; space
|
||||
raw l["If you are editing an existing request, a third option appears."]; space
|
||||
raw l["“Expire Immediately” will make the request expire when it is saved."]; space
|
||||
raw l["Apart from the icons on the request maintenance page, this is the only way to expire “Long-Term Requests” and “Expecting” requests, but it can be used for any request type."] ]
|
||||
h2 [] [ locStr s["Request"] ]
|
||||
p [] [
|
||||
raw l["This is the text of the request."]; space
|
||||
raw l["The editor provides many formatting capabilities, including “Spell Check as you Type” (enabled by default), “Paste from Word”, and “Paste Plain”, as well as “Source” view, if you want to edit the HTML yourself."]; space
|
||||
raw l["It also supports undo and redo, and the editor supports full-screen mode. Hover over each icon to see what each button does."] ] ]
|
||||
|
|
@ -15,130 +15,93 @@ module Navigation =
|
|||
|
||||
/// Top navigation bar
|
||||
let top m =
|
||||
let s = I18N.localizer.Force ()
|
||||
let s = I18N.localizer.Force()
|
||||
let menuSpacer = rawText " "
|
||||
let _dropdown = _class "dropdown-btn"
|
||||
let leftLinks = [
|
||||
match m.User with
|
||||
| Some u ->
|
||||
li [ _class "dropdown" ] [
|
||||
a [ _dropdown; _ariaLabel s["Requests"].Value; _title s["Requests"].Value; _roleButton ] [
|
||||
icon "question_answer"; space; locStr s["Requests"]; space; icon "keyboard_arrow_down"
|
||||
]
|
||||
div [ _class "dropdown-content"; _roleMenuBar ] [
|
||||
a [ _href "/prayer-requests"; _roleMenuItem ] [
|
||||
icon "compare_arrows"; menuSpacer; locStr s["Maintain"]
|
||||
]
|
||||
a [ _href "/prayer-requests/view"; _roleMenuItem ] [
|
||||
icon "list"; menuSpacer; locStr s["View List"]
|
||||
]
|
||||
]
|
||||
]
|
||||
li [ _class "dropdown" ] [
|
||||
a [ _dropdown; _ariaLabel s["Group"].Value; _title s["Group"].Value; _roleButton ] [
|
||||
icon "group"; space; locStr s["Group"]; space; icon "keyboard_arrow_down"
|
||||
]
|
||||
div [ _class "dropdown-content"; _roleMenuBar ] [
|
||||
a [ _href "/small-group/members"; _roleMenuItem ] [
|
||||
icon "email"; menuSpacer; locStr s["Maintain Group Members"]
|
||||
]
|
||||
a [ _href "/small-group/announcement"; _roleMenuItem ] [
|
||||
icon "send"; menuSpacer; locStr s["Send Announcement"]
|
||||
]
|
||||
a [ _href "/small-group/preferences"; _roleMenuItem ] [
|
||||
icon "build"; menuSpacer; locStr s["Change Preferences"]
|
||||
]
|
||||
]
|
||||
]
|
||||
if u.IsAdmin then
|
||||
li [ _class "dropdown" ] [
|
||||
a [ _dropdown
|
||||
_ariaLabel s["Administration"].Value
|
||||
_title s["Administration"].Value
|
||||
_roleButton ] [
|
||||
icon "settings"; space; locStr s["Administration"]; space; icon "keyboard_arrow_down"
|
||||
]
|
||||
div [ _class "dropdown-content"; _roleMenuBar ] [
|
||||
a [ _href "/churches"; _roleMenuItem ] [ icon "home"; menuSpacer; locStr s["Churches"] ]
|
||||
a [ _href "/small-groups"; _roleMenuItem ] [ icon "send"; menuSpacer; locStr s["Groups"] ]
|
||||
a [ _href "/users"; _roleMenuItem ] [ icon "build"; menuSpacer; locStr s["Users"] ]
|
||||
]
|
||||
]
|
||||
| None ->
|
||||
match m.Group with
|
||||
| Some _ ->
|
||||
li [] [
|
||||
a [ _href "/prayer-requests/view"
|
||||
_ariaLabel s["View Request List"].Value
|
||||
_title s["View Request List"].Value ] [
|
||||
icon "list"; space; locStr s["View Request List"]
|
||||
]
|
||||
]
|
||||
| None ->
|
||||
li [ _class "dropdown" ] [
|
||||
a [ _dropdown; _ariaLabel s["Log On"].Value; _title s["Log On"].Value; _roleButton ] [
|
||||
icon "security"; space; locStr s["Log On"]; space; icon "keyboard_arrow_down"
|
||||
]
|
||||
div [ _class "dropdown-content"; _roleMenuBar ] [
|
||||
a [ _href "/user/log-on"; _roleMenuItem ] [ icon "person"; menuSpacer; locStr s["User"] ]
|
||||
a [ _href "/small-group/log-on"; _roleMenuItem ] [
|
||||
icon "group"; menuSpacer; locStr s["Group"]
|
||||
]
|
||||
]
|
||||
]
|
||||
li [] [
|
||||
a [ _href "/prayer-requests/lists"
|
||||
_ariaLabel s["View Request List"].Value
|
||||
_title s["View Request List"].Value ] [
|
||||
icon "list"; space; locStr s["View Request List"]
|
||||
]
|
||||
]
|
||||
li [] [
|
||||
a [ _href $"https://docs.prayer.bitbadger.solutions/{langCode ()}"
|
||||
_ariaLabel s["Help"].Value
|
||||
_title s["View Help"].Value
|
||||
_target "_blank"
|
||||
_relNoOpener ] [
|
||||
icon "help"; space; locStr s["Help"]
|
||||
]
|
||||
]
|
||||
]
|
||||
let leftLinks =
|
||||
[ match m.User with
|
||||
| Some u ->
|
||||
li [ _class "dropdown" ] [
|
||||
a [ _dropdown; _ariaLabel s["Requests"].Value; _title s["Requests"].Value; _roleButton ] [
|
||||
icon "question_answer"; space; locStr s["Requests"]; space; icon "keyboard_arrow_down" ]
|
||||
div [ _class "dropdown-content"; _roleMenuBar ] [
|
||||
a [ _href "/prayer-requests"; _roleMenuItem ] [
|
||||
icon "compare_arrows"; menuSpacer; locStr s["Maintain"] ]
|
||||
a [ _href "/prayer-requests/view"; _roleMenuItem ] [
|
||||
icon "list"; menuSpacer; locStr s["View List"] ] ] ]
|
||||
li [ _class "dropdown" ] [
|
||||
a [ _dropdown; _ariaLabel s["Group"].Value; _title s["Group"].Value; _roleButton ] [
|
||||
icon "group"; space; locStr s["Group"]; space; icon "keyboard_arrow_down" ]
|
||||
div [ _class "dropdown-content"; _roleMenuBar ] [
|
||||
a [ _href "/small-group/members"; _roleMenuItem ] [
|
||||
icon "email"; menuSpacer; locStr s["Maintain Group Members"] ]
|
||||
a [ _href "/small-group/announcement"; _roleMenuItem ] [
|
||||
icon "send"; menuSpacer; locStr s["Send Announcement"] ]
|
||||
a [ _href "/small-group/preferences"; _roleMenuItem ] [
|
||||
icon "build"; menuSpacer; locStr s["Change Preferences"] ] ] ]
|
||||
if u.IsAdmin then
|
||||
li [ _class "dropdown" ] [
|
||||
a [ _dropdown
|
||||
_ariaLabel s["Administration"].Value
|
||||
_title s["Administration"].Value
|
||||
_roleButton ] [
|
||||
icon "settings"; space; locStr s["Administration"]; space; icon "keyboard_arrow_down" ]
|
||||
div [ _class "dropdown-content"; _roleMenuBar ] [
|
||||
a [ _href "/churches"; _roleMenuItem ] [ icon "home"; menuSpacer; locStr s["Churches"] ]
|
||||
a [ _href "/small-groups"; _roleMenuItem ] [
|
||||
icon "send"; menuSpacer; locStr s["Groups"] ]
|
||||
a [ _href "/users"; _roleMenuItem ] [ icon "build"; menuSpacer; locStr s["Users"] ] ] ]
|
||||
| None ->
|
||||
match m.Group with
|
||||
| Some _ ->
|
||||
li [] [
|
||||
a [ _href "/prayer-requests/view"
|
||||
_ariaLabel s["View Request List"].Value
|
||||
_title s["View Request List"].Value ] [
|
||||
icon "list"; space; locStr s["View Request List"] ] ]
|
||||
| None ->
|
||||
li [ _class "dropdown" ] [
|
||||
a [ _dropdown; _ariaLabel s["Log On"].Value; _title s["Log On"].Value; _roleButton ] [
|
||||
icon "security"; space; locStr s["Log On"]; space; icon "keyboard_arrow_down" ]
|
||||
div [ _class "dropdown-content"; _roleMenuBar ] [
|
||||
a [ _href "/user/log-on"; _roleMenuItem ] [ icon "person"; menuSpacer; locStr s["User"] ]
|
||||
a [ _href "/small-group/log-on"; _roleMenuItem ] [
|
||||
icon "group"; menuSpacer; locStr s["Group"] ] ] ]
|
||||
li [] [
|
||||
a [ _href "/prayer-requests/lists"
|
||||
_ariaLabel s["View Request List"].Value
|
||||
_title s["View Request List"].Value ] [
|
||||
icon "list"; space; locStr s["View Request List"] ] ]
|
||||
li [] [
|
||||
a [ _href "/help"; _ariaLabel s["Help"].Value; _title s["View Help"].Value; _target "_blank" ] [
|
||||
icon "help"; space; locStr s["Help"] ] ] ]
|
||||
let rightLinks =
|
||||
match m.Group with
|
||||
| Some _ ->
|
||||
[ match m.User with
|
||||
| Some _ ->
|
||||
li [] [
|
||||
a [ _href "/user/password"
|
||||
_ariaLabel s["Change Your Password"].Value
|
||||
_title s["Change Your Password"].Value ] [
|
||||
icon "lock"; space; locStr s["Change Your Password"]
|
||||
]
|
||||
]
|
||||
| None -> ()
|
||||
li [] [
|
||||
a [ _href "/log-off"; _ariaLabel s["Log Off"].Value; _title s["Log Off"].Value; Target.body ] [
|
||||
icon "power_settings_new"; space; locStr s["Log Off"]
|
||||
]
|
||||
]
|
||||
]
|
||||
[ match m.User with
|
||||
| Some _ ->
|
||||
li [] [
|
||||
a [ _href "/user/password"
|
||||
_ariaLabel s["Change Your Password"].Value
|
||||
_title s["Change Your Password"].Value ] [
|
||||
icon "lock"; space; locStr s["Change Your Password"] ] ]
|
||||
| None -> ()
|
||||
li [] [
|
||||
a [ _href "/log-off"; _ariaLabel s["Log Off"].Value; _title s["Log Off"].Value; Target.body ] [
|
||||
icon "power_settings_new"; space; locStr s["Log Off"] ] ] ]
|
||||
| None -> []
|
||||
header [ _class "pt-title-bar"; Target.content ] [
|
||||
section [ _class "pt-title-bar-left"; _ariaLabel "Left side of top menu" ] [
|
||||
span [ _class "pt-title-bar-home" ] [
|
||||
a [ _href "/"; _title s["Home"].Value ] [ locStr s["PrayerTracker"] ]
|
||||
]
|
||||
ul [] leftLinks
|
||||
]
|
||||
a [ _href "/"; _title s["Home"].Value ] [ locStr s["PrayerTracker"] ] ]
|
||||
ul [] leftLinks ]
|
||||
section [ _class "pt-title-bar-center"; _ariaLabel "Empty center space in top menu" ] []
|
||||
section [ _class "pt-title-bar-right"; _roleToolBar; _ariaLabel "Right side of top menu" ] [
|
||||
ul [] rightLinks
|
||||
]
|
||||
]
|
||||
ul [] rightLinks ] ]
|
||||
|
||||
/// Identity bar (below top nav)
|
||||
let identity m =
|
||||
let s = I18N.localizer.Force ()
|
||||
let s = I18N.localizer.Force()
|
||||
header [ _id "pt-language"; Target.body ] [
|
||||
div [] [
|
||||
span [ _title s["Language"].Value ] [ icon "record_voice_over"; space ]
|
||||
|
@ -150,29 +113,26 @@ module Navigation =
|
|||
| _ ->
|
||||
strong [] [ locStr s["English"] ]
|
||||
rawText " "
|
||||
a [ _href "/language/es" ] [ locStr s["Cambie a Español"] ]
|
||||
]
|
||||
a [ _href "/language/es" ] [ locStr s["Cambie a Español"] ] ]
|
||||
match m.Group with
|
||||
| Some g ->
|
||||
[ match m.User with
|
||||
| Some u ->
|
||||
span [ _class "u" ] [ locStr s["Currently Logged On"] ]
|
||||
rawText " "
|
||||
icon "person"
|
||||
strong [] [ str u.Name ]
|
||||
rawText " "
|
||||
| None ->
|
||||
locStr s["Logged On as a Member of"]
|
||||
rawText " "
|
||||
icon "group"
|
||||
space
|
||||
match m.User with
|
||||
| Some _ -> a [ _href "/small-group"; Target.content ] [ strong [] [ str g.Name ] ]
|
||||
| None -> strong [] [ str g.Name ]
|
||||
]
|
||||
[ match m.User with
|
||||
| Some u ->
|
||||
span [ _class "u" ] [ locStr s["Currently Logged On"] ]
|
||||
rawText " "
|
||||
icon "person"
|
||||
strong [] [ str u.Name ]
|
||||
rawText " "
|
||||
| None ->
|
||||
locStr s["Logged On as a Member of"]
|
||||
rawText " "
|
||||
icon "group"
|
||||
space
|
||||
match m.User with
|
||||
| Some _ -> a [ _href "/small-group"; Target.content ] [ strong [] [ str g.Name ] ]
|
||||
| None -> strong [] [ str g.Name ] ]
|
||||
| None -> []
|
||||
|> div []
|
||||
]
|
||||
|> div [] ]
|
||||
|
||||
|
||||
/// Content layouts
|
||||
|
@ -198,7 +158,7 @@ let private commonHead = [
|
|||
|
||||
/// Render the <head> portion of the page
|
||||
let private htmlHead viewInfo pgTitle =
|
||||
let s = I18N.localizer.Force ()
|
||||
let s = I18N.localizer.Force()
|
||||
head [] [
|
||||
meta [ _charset "UTF-8" ]
|
||||
title [] [ locStr pgTitle; titleSep; locStr s["PrayerTracker"] ]
|
||||
|
@ -212,7 +172,7 @@ open Giraffe.ViewEngine.Htmx
|
|||
|
||||
/// Render a link to the help page for the current page
|
||||
let private helpLink link =
|
||||
let s = I18N.localizer.Force ()
|
||||
let s = I18N.localizer.Force()
|
||||
sup [ _class "pt-help-link" ] [
|
||||
a [ _href link
|
||||
_title s["Click for Help on This Page"].Value
|
||||
|
@ -233,7 +193,7 @@ let private renderPageTitle viewInfo pgTitle =
|
|||
|
||||
/// Render the messages that may need to be displayed to the user
|
||||
let private messages viewInfo =
|
||||
let s = I18N.localizer.Force ()
|
||||
let s = I18N.localizer.Force()
|
||||
if List.isEmpty viewInfo.Messages then []
|
||||
else
|
||||
viewInfo.Messages
|
||||
|
@ -259,70 +219,61 @@ open NodaTime
|
|||
|
||||
/// Render the <footer> at the bottom of the page
|
||||
let private htmlFooter viewInfo =
|
||||
let s = I18N.localizer.Force ()
|
||||
let s = I18N.localizer.Force()
|
||||
let imgText = $"""%O{s["PrayerTracker"]} %O{s["from Bit Badger Solutions"]}"""
|
||||
let resultTime = (SystemClock.Instance.GetCurrentInstant () - viewInfo.RequestStart).TotalSeconds
|
||||
let resultTime = (SystemClock.Instance.GetCurrentInstant() - viewInfo.RequestStart).TotalSeconds
|
||||
footer [ _class "pt-footer" ] [
|
||||
div [ _id "pt-legal" ] [
|
||||
a [ _href "/legal/privacy-policy" ] [ locStr s["Privacy Policy"] ]
|
||||
rawText " "
|
||||
a [ _href "/legal/terms-of-service" ] [ locStr s["Terms of Service"] ]
|
||||
rawText " "
|
||||
a [ _href "https://github.com/bit-badger/PrayerTracker"
|
||||
a [ _href "https://git.bitbadger.solutions/bit-badger/PrayerTracker"
|
||||
_title s["View source code and get technical support"].Value
|
||||
_target "_blank"
|
||||
_relNoOpener ] [
|
||||
locStr s["Source & Support"]
|
||||
]
|
||||
]
|
||||
locStr s["Source & Support"] ] ]
|
||||
div [ _id "pt-footer" ] [
|
||||
a [ _href "/"; _style "line-height:28px;" ] [
|
||||
img [ _src $"""/img/%O{s["footer_en"]}.png"""
|
||||
_alt imgText
|
||||
_title imgText
|
||||
_width "331"; _height "28" ]
|
||||
]
|
||||
_width "331"; _height "28" ] ]
|
||||
span [ _id "pt-version" ] [ str viewInfo.Version ]
|
||||
space
|
||||
i [ _title s["This page loaded in {0:N3} seconds", resultTime].Value; _class "material-icons md-18" ] [
|
||||
str "schedule"
|
||||
]
|
||||
]
|
||||
]
|
||||
str "schedule" ] ] ]
|
||||
|
||||
/// The content portion of the PrayerTracker layout
|
||||
let private contentSection viewInfo pgTitle (content : XmlNode) = [
|
||||
Navigation.identity viewInfo
|
||||
renderPageTitle viewInfo pgTitle
|
||||
yield! messages viewInfo
|
||||
match viewInfo.ScopedStyle with
|
||||
| [] -> ()
|
||||
| styles -> style [] [ rawText (styles |> String.concat " ") ]
|
||||
content
|
||||
htmlFooter viewInfo
|
||||
match viewInfo.OnLoadScript with
|
||||
| Some onLoad ->
|
||||
let doCall = if onLoad.EndsWith ")" then "" else "()"
|
||||
script [] [
|
||||
rawText $"
|
||||
window.doOnLoad = () => {{
|
||||
if (window.PT) {{
|
||||
{onLoad}{doCall}
|
||||
delete window.doOnLoad
|
||||
}} else {{ setTimeout(window.doOnLoad, 500) }}
|
||||
}}
|
||||
window.doOnLoad()"
|
||||
]
|
||||
| None -> ()
|
||||
]
|
||||
let private contentSection viewInfo pgTitle (content: XmlNode) =
|
||||
[ Navigation.identity viewInfo
|
||||
renderPageTitle viewInfo pgTitle
|
||||
yield! messages viewInfo
|
||||
match viewInfo.ScopedStyle with
|
||||
| [] -> ()
|
||||
| styles -> style [] [ rawText (styles |> String.concat " ") ]
|
||||
content
|
||||
htmlFooter viewInfo
|
||||
match viewInfo.OnLoadScript with
|
||||
| Some onLoad ->
|
||||
let doCall = if onLoad.EndsWith ")" then "" else "()"
|
||||
script [] [
|
||||
rawText $"
|
||||
window.doOnLoad = () => {{
|
||||
if (window.PT) {{
|
||||
{onLoad}{doCall}
|
||||
delete window.doOnLoad
|
||||
}} else {{ setTimeout(window.doOnLoad, 500) }}
|
||||
}}
|
||||
window.doOnLoad()" ]
|
||||
| None -> () ]
|
||||
|
||||
/// The HTML head element for partial responses
|
||||
let private partialHead pgTitle =
|
||||
let s = I18N.localizer.Force ()
|
||||
let s = I18N.localizer.Force()
|
||||
head [] [
|
||||
meta [ _charset "UTF-8" ]
|
||||
title [] [ locStr pgTitle; titleSep; locStr s["PrayerTracker"] ]
|
||||
]
|
||||
title [] [ locStr pgTitle; titleSep; locStr s["PrayerTracker"] ] ]
|
||||
|
||||
open Giraffe.Htmx.Common
|
||||
|
||||
|
@ -337,12 +288,11 @@ let private pageLayout viewInfo pgTitle content =
|
|||
Script.minified
|
||||
script [ _src "/js/ckeditor/ckeditor.js" ] []
|
||||
script [ _src "/js/app.js" ] []
|
||||
| _ -> ()
|
||||
]
|
||||
| _ -> () ]
|
||||
|
||||
/// The standard layout(s) for PrayerTracker
|
||||
let standard viewInfo pageTitle content =
|
||||
let s = I18N.localizer.Force ()
|
||||
let s = I18N.localizer.Force()
|
||||
let pgTitle = s[pageTitle]
|
||||
html [ _lang (langCode ()) ] [
|
||||
match viewInfo.Layout with
|
||||
|
@ -354,13 +304,46 @@ let standard viewInfo pageTitle content =
|
|||
pageLayout viewInfo pgTitle content
|
||||
| ContentOnly ->
|
||||
partialHead pgTitle
|
||||
body [] (contentSection viewInfo pgTitle content)
|
||||
]
|
||||
body [] (contentSection viewInfo pgTitle content) ]
|
||||
|
||||
/// A layout with nothing but a title and content
|
||||
let bare pageTitle content =
|
||||
let s = I18N.localizer.Force ()
|
||||
let s = I18N.localizer.Force()
|
||||
html [ _lang (langCode ()) ] [
|
||||
partialHead s[pageTitle]
|
||||
body [] [ content ]
|
||||
]
|
||||
body [] [ content ] ]
|
||||
|
||||
/// Help page layout
|
||||
let help pageTitle isHome content =
|
||||
let s = I18N.localizer.Force()
|
||||
let pgTitle = s[pageTitle]
|
||||
html [ _lang (langCode ()) ] [
|
||||
head [] [
|
||||
meta [ _charset "UTF-8" ]
|
||||
meta [ _name "viewport"; _content "width=device-width, initial-scale=1" ]
|
||||
title [] [ locStr pgTitle; titleSep; locStr s["PrayerTracker Help"] ]
|
||||
link [ _href "https://fonts.googleapis.com/icon?family=Material+Icons"; _rel "stylesheet" ]
|
||||
link [ _href "/css/app.css"; _rel "stylesheet" ]
|
||||
link [ _href "/css/help.css"; _rel "stylesheet" ] ]
|
||||
body [] [
|
||||
header [ _class "pt-title-bar" ] [
|
||||
section [ _class "pt-title-bar-left" ] [
|
||||
span [ _class "pt-title-bar-home" ] [
|
||||
a [ _href "/help"; _title "Home" ] [ locStr s["PrayerTracker"] ] ] ]
|
||||
section [ _class "pt-title-bar-right" ] [ locStr s["Help"] ] ]
|
||||
div [ _id "pt-body" ] [
|
||||
h2 [ _id "pt-page-title" ] [ locStr pgTitle ]
|
||||
div [ _class "pt-content" ] [
|
||||
yield! content
|
||||
div [ _class "pt-close-window" ] [
|
||||
p [ _class "pt-center-text" ] [
|
||||
a [ _href "#"; _title s["Click to Close This Window"].Value
|
||||
_onclick "window.close(); return false" ] [
|
||||
i [ _class "material-icons"] [ rawText "cancel" ]
|
||||
space; locStr s["Close Window"] ] ] ]
|
||||
if not isHome then
|
||||
div [ _class "pt-help-index" ] [
|
||||
p [ _class "pt-center-text" ] [
|
||||
a [ _href "/help"; _title s["Help Index"].Value ] [
|
||||
rawText "« "; locStr s["Back to Help Index"] ] ] ] ] ] ] ]
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
<Compile Include="PrayerRequest.fs" />
|
||||
<Compile Include="SmallGroup.fs" />
|
||||
<Compile Include="User.fs" />
|
||||
<Compile Include="Help.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -33,6 +34,12 @@
|
|||
<EmbeddedResource Update="Resources\Common.es.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\Help\Index.es.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\Help\Requests\Edit.es.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\Views\Home\Error.es.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
|
|
|
@ -882,4 +882,22 @@
|
|||
<data name="This User Is a {0} Administrator" xml:space="preserve">
|
||||
<value>Este Usuario Es un Administrador de {0}</value>
|
||||
</data>
|
||||
<data name="PrayerTracker Help" xml:space="preserve">
|
||||
<value>Ayuda de SeguidorOración</value>
|
||||
</data>
|
||||
<data name="Click to Close This Window" xml:space="preserve">
|
||||
<value>Haga Clic para Cerrar Esta Ventana</value>
|
||||
</data>
|
||||
<data name="Close Window" xml:space="preserve">
|
||||
<value>Cerrar Esta Ventana</value>
|
||||
</data>
|
||||
<data name="Help Index" xml:space="preserve">
|
||||
<value>Índice de Ayuda</value>
|
||||
</data>
|
||||
<data name="Back to Help Index" xml:space="preserve">
|
||||
<value>Volver al Índice de Ayuda</value>
|
||||
</data>
|
||||
<data name="Add / Edit a Request" xml:space="preserve">
|
||||
<value>Agregar o Editar una Petición</value>
|
||||
</data>
|
||||
</root>
|
70
src/PrayerTracker.UI/Resources/Views/Help/Index.es.resx
Normal file
70
src/PrayerTracker.UI/Resources/Views/Help/Index.es.resx
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Throughout PrayerTracker, you'll see an icon (a question mark in a circle) next to the title on each page." xml:space="preserve">
|
||||
<value>En todo el sistema, verá un icono (un signo de interrogación en un círculo) junto al título de cada página.</value>
|
||||
</data>
|
||||
<data name="Clicking this will open a new, small window with directions on using that page." xml:space="preserve">
|
||||
<value>Al hacer clic en esta opción, se abrirá una nueva y pequeña ventana con instrucciones sobre cómo usar esa página.</value>
|
||||
</data>
|
||||
<data name="If you are looking for a quick overview of PrayerTracker, start with the “Add / Edit a Request” and “Change Preferences” entries." xml:space="preserve">
|
||||
<value>Si está buscando una descripción rápida de SeguidorOración, comience con las entradas “Agregar o Editar una Petición” y “Cambiar las Preferencias”.</value>
|
||||
</data>
|
||||
</root>
|
133
src/PrayerTracker.UI/Resources/Views/Help/Requests/Edit.es.resx
Normal file
133
src/PrayerTracker.UI/Resources/Views/Help/Requests/Edit.es.resx
Normal file
|
@ -0,0 +1,133 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="This page allows you to enter or update a new prayer request." xml:space="preserve">
|
||||
<value>Esta página le permite introducir o actualizar una petición de oración nueva.</value>
|
||||
</data>
|
||||
<data name="There are 5 request types in PrayerTracker." xml:space="preserve">
|
||||
<value>Hay 5 tipos de peticiones en SeguidorOración.</value>
|
||||
</data>
|
||||
<data name="“Current Requests” are your regular requests that people may have regarding things happening over the next week or so." xml:space="preserve">
|
||||
<value>“Peticiones Actuales” son sus peticiones habituales que la gente pueda tener acerca de las cosas que suceden durante la próxima semana o así.</value>
|
||||
</data>
|
||||
<data name="“Long-Term Requests” are requests that may occur repeatedly or continue indefinitely." xml:space="preserve">
|
||||
<value>“Peticiones a Largo Plazo” son peticiones que pueden ocurrir varias veces, o continuar indefinidamente.</value>
|
||||
</data>
|
||||
<data name="“Praise Reports” are like “Current Requests”, but they are answers to prayer to share with your group." xml:space="preserve">
|
||||
<value>“Informes de Alabanza” son como “Peticiones Actuales”, pero son respuestas a la oración para compartir con su grupo.</value>
|
||||
</data>
|
||||
<data name="“Expecting” is for those who are pregnant." xml:space="preserve">
|
||||
<value>“Embarazada” es para aquellos que están embarazadas.</value>
|
||||
</data>
|
||||
<data name="“Announcements” are like “Current Requests”, but instead of a request, they are simply passing information along about something coming up." xml:space="preserve">
|
||||
<value>“Anuncios” son como “Peticiones Actuales”, pero en lugar de una petición, simplemente se pasa la información a lo largo de algo por venir.</value>
|
||||
</data>
|
||||
<data name="The order above is the order in which the request types appear on the list." xml:space="preserve">
|
||||
<value>El orden anterior es el orden en que los tipos de peticiones aparecen en la lista.</value>
|
||||
</data>
|
||||
<data name="“Long-Term Requests” and “Expecting” are not subject to the automatic expiration (set on the “Change Preferences” page) that the other requests are." xml:space="preserve">
|
||||
<value>“Peticiones a Largo Plazo” y “Embarazada” no están sujetos a la caducidad automática (establecida en el “Cambiar las Preferencias” de la página) que las peticiones son otros.</value>
|
||||
</data>
|
||||
<data name="For new requests, this is a box with a calendar date picker." xml:space="preserve">
|
||||
<value>Para nuevas peticiones, se trata de una caja con un selector de fechas del calendario.</value>
|
||||
</data>
|
||||
<data name="Click or tab into the box to display the calendar, which will be preselected to today's date." xml:space="preserve">
|
||||
<value>Haga clic en la pestaña o en la caja para mostrar el calendario, que será preseleccionada para la fecha de hoy.</value>
|
||||
</data>
|
||||
<data name="For existing requests, there will be a check box labeled “Check to not update the date”." xml:space="preserve">
|
||||
<value>Para peticiones existentes, habrá una casilla de verificación “Seleccionar para no actualizar la fecha”.</value>
|
||||
</data>
|
||||
<data name="This can be used if you are correcting spelling or punctuation, and do not have an actual update to make to the request." xml:space="preserve">
|
||||
<value>Esto puede ser usado si corrige la ortografía ni la puntuacion, y no tienen una actualización real de hacer la petición.</value>
|
||||
</data>
|
||||
<data name="For requests or praises, this field is for the name of the person who made the request or offered the praise report." xml:space="preserve">
|
||||
<value>Para las peticiones o alabanzas, este campo es el nombre de la persona que hizo la petición o que ofrece el informe de alabanza.</value>
|
||||
</data>
|
||||
<data name="For announcements, this should contain the subject of the announcement." xml:space="preserve">
|
||||
<value>Para los anuncios, este debe contener el objeto del anuncio.</value>
|
||||
</data>
|
||||
<data name="For all types, it is optional; I used to have an announcement with no subject that ran every week, telling where to send requests and updates." xml:space="preserve">
|
||||
<value>Para todos los tipos, es opcional, yo solía tener un anuncio con ningún tema que iba todas las semanas, diciendo a dónde enviar peticiones y actualizaciones.</value>
|
||||
</data>
|
||||
<data name="“Expire Normally” means that the request is subject to the expiration days in the group preferences." xml:space="preserve">
|
||||
<value>“Expirará Normalmente” significa que la petición está sujeta a los días de vencimiento de las preferencias del grupo.</value>
|
||||
</data>
|
||||
<data name="“Request Never Expires” can be used to make a request never expire (note that this is redundant for “Long-Term Requests” and “Expecting”)." xml:space="preserve">
|
||||
<value>“Petición no Expira Nunca” se puede utilizar para hacer una petición que no caduque nunca (nótese que esto es redundante para los tipos “Peticiones a Largo Plazo” y “Embarazada”).</value>
|
||||
</data>
|
||||
<data name="If you are editing an existing request, a third option appears." xml:space="preserve">
|
||||
<value>Si está editando una petición existente, aparece una tercera opción.</value>
|
||||
</data>
|
||||
<data name="“Expire Immediately” will make the request expire when it is saved." xml:space="preserve">
|
||||
<value>“Expirará Inmediatamente” hará que la petición expirará cuando se guarda.</value>
|
||||
</data>
|
||||
<data name="Apart from the icons on the request maintenance page, this is the only way to expire “Long-Term Requests” and “Expecting” requests, but it can be used for any request type." xml:space="preserve">
|
||||
<value>Aparte de los iconos de la página de mantenimiento de las peticiones, ésta es la única otra forma de expirar peticiones del tipos “Peticiones a Largo Plazo” y “Embarazada”, pero puede ser utilizada para cualquier tipo de petición.</value>
|
||||
</data>
|
||||
<data name="This is the text of the request." xml:space="preserve">
|
||||
<value>Este es el texto de la petición.</value>
|
||||
</data>
|
||||
<data name="The editor provides many formatting capabilities, including “Spell Check as you Type” (enabled by default), “Paste from Word”, and “Paste Plain”, as well as “Source” view, if you want to edit the HTML yourself." xml:space="preserve">
|
||||
<value>El editor ofrece muchas capacidades de formato, como "El Corrector Ortográfico al Escribir" (habilitado predeterminado), "Pegar desde Word" y "Pegar sin formato", así como "Código Fuente" punto de vista, si quieres editar el código HTML usted mismo.</value>
|
||||
</data>
|
||||
<data name="It also supports undo and redo, and the editor supports full-screen mode. Hover over each icon to see what each button does." xml:space="preserve">
|
||||
<value>También es compatible con deshacer y rehacer, y el editor soporta modo de pantalla completa. Pase el ratón sobre cada icono para ver qué hace cada botón.</value>
|
||||
</data>
|
||||
</root>
|
|
@ -98,6 +98,12 @@ module Configure =
|
|||
]
|
||||
route "/class/logon" (redirectTo true "/small-group/log-on")
|
||||
routef "/error/%s" Handlers.Home.error
|
||||
subRoute "/help" [
|
||||
route "" Handlers.Help.index
|
||||
subRoute "/requests" [
|
||||
route "/edit" Handlers.Help.Requests.edit
|
||||
]
|
||||
]
|
||||
routef "/language/%s" Handlers.Home.language
|
||||
subRoute "/legal" [
|
||||
route "/privacy-policy" Handlers.Home.privacyPolicy
|
||||
|
|
24
src/PrayerTracker/Help.fs
Normal file
24
src/PrayerTracker/Help.fs
Normal file
|
@ -0,0 +1,24 @@
|
|||
/// Handlers for /help routes
|
||||
module PrayerTracker.Handlers.Help
|
||||
|
||||
open Giraffe
|
||||
open PrayerTracker
|
||||
|
||||
// GET: /help
|
||||
let index : HttpHandler = fun next ctx -> task {
|
||||
return!
|
||||
Views.Help.index ()
|
||||
|> Views.Layout.help ctx.Strings["Help Index"].Value true
|
||||
|> renderHtml next ctx
|
||||
}
|
||||
|
||||
/// Handlers for /help/requests routes
|
||||
module Requests =
|
||||
|
||||
// GET: /help/requests/edit
|
||||
let edit : HttpHandler = fun next ctx -> task {
|
||||
return!
|
||||
Views.Help.Requests.edit ()
|
||||
|> Views.Layout.help ctx.Strings["Add / Edit a Request"].Value false
|
||||
|> renderHtml next ctx
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
<Compile Include="Email.fs" />
|
||||
<Compile Include="CommonFunctions.fs" />
|
||||
<Compile Include="Church.fs" />
|
||||
<Compile Include="Help.fs" />
|
||||
<Compile Include="Home.fs" />
|
||||
<Compile Include="PrayerRequest.fs" />
|
||||
<Compile Include="SmallGroup.fs" />
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
background-color: white;
|
||||
padding: 0 .25em;
|
||||
}
|
||||
.pt-title-bar-home {
|
||||
height: 2rem;
|
||||
}
|
||||
.pt-title-bar-left {
|
||||
color: white;
|
||||
font-size: 1.25rem;
|
||||
|
@ -17,9 +20,24 @@
|
|||
font-size: 1.1rem;
|
||||
font-variant: small-caps;
|
||||
margin-right: 1rem;
|
||||
align-self: center;
|
||||
}
|
||||
h2 {
|
||||
margin-top: 0;
|
||||
padding-left: .5rem;
|
||||
border-bottom: solid 1px #444;
|
||||
}
|
||||
.pt-close-window, .pt-help-index {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
.pt-help-index {
|
||||
display: none;
|
||||
}
|
||||
@media screen and (min-width:451px) {
|
||||
.pt-close-window {
|
||||
display: none;
|
||||
}
|
||||
.pt-help-index {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user