open Dream_html open Page_kit open Page_shell (* The authenticated application feedback page. It keeps writing and reviewing feedback in separate tabs, while both tabs remain plain links for no-script use and progressive enhancement. *) let app_feedback_form request ?error () = let error_block = match error with None -> [] | Some message -> [ alert message ] in tag "form" [ action Routes.submit_app_feedback; post_form; class_ "app-feedback-form"; Dream_html.attr "data-hito-app-form"; ] (Dream_html.csrf_tag request :: tag "label" [ Dream_html.string_attr "for" "app-feedback-message" ] [ txt "Your feedback" ] :: tag "textarea" [ name "message"; id "app-feedback-message"; Dream_html.string_attr "rows" "8"; required; Dream_html.string_attr "placeholder" "Tell us what works well or what needs attention."; ] [] :: error_block @ [ void "input" [ type_ "submit"; value "Submit feedback" ] ]) let app_feedback_vote_form request (report : View_model.App_feedback.t) = if report.viewer_owns then tag "p" [ class_ "app-feedback-own" ] [ txt "Your feedback" ] else let label = if report.viewer_upvoted then "Upvoted" else Printf.sprintf "Upvote (%d)" report.upvotes in let attrs = [ action Routes.upvote_app_feedback report.id; post_form; class_ "app-feedback-vote"; Dream_html.attr "data-hito-app-form"; ] in let attrs = if report.viewer_upvoted then Dream_html.attr "disabled" :: attrs else attrs in tag "form" attrs [ Dream_html.csrf_tag request; void "input" [ type_ "submit"; Dream_html.string_attr "value" "%s" label ]; ] let app_feedback_edit_form request (report : View_model.App_feedback.t) = tag "form" [ action Routes.edit_app_feedback report.id; post_form; class_ "app-feedback-edit-form"; Dream_html.attr "data-hito-app-form"; ] [ Dream_html.csrf_tag request; tag "label" [ Dream_html.string_attr "for" "app-feedback-edit-%s" report.id ] [ txt "Edit feedback" ]; tag "textarea" [ name "message"; Dream_html.string_attr "id" "app-feedback-edit-%s" report.id; Dream_html.string_attr "rows" "4"; required; ] [ txt "%s" report.message ]; void "input" [ type_ "submit"; value "Save edit" ]; ] let app_feedback_remove_form request (report : View_model.App_feedback.t) = tag "form" [ action Routes.remove_app_feedback report.id; post_form; class_ "app-feedback-remove-form"; Dream_html.attr "data-hito-app-form"; ] [ Dream_html.csrf_tag request; void "input" [ type_ "submit"; value "Remove feedback" ]; ] let app_feedback_actions request (report : View_model.App_feedback.t) = if report.viewer_owns then tag "div" [ class_ "app-feedback-actions" ] [ app_feedback_edit_form request report; app_feedback_remove_form request report; ] else tag "div" [ class_ "app-feedback-actions" ] [ app_feedback_vote_form request report ] let app_feedback request ?workout_started ~viewer ?(tab = `Write) ?error reports = let panel = match tab with | `Write -> [ tag "h2" [] [ txt "Write feedback" ]; tag "p" [] [ txt "Tell us about your experience using the application." ]; app_feedback_form request ?error (); ] | `Submitted -> [ tag "h2" [] [ txt "Submitted feedback" ]; (if reports = [] then tag "p" [] [ txt "You have not submitted any application feedback." ] else tag "ul" [ class_ "app-feedback-list" ] (List.map (fun (report : View_model.App_feedback.t) -> tag "li" [] [ tag "p" [ class_ "app-feedback-author" ] [ txt "%s — %d contributions" report.author report.contributions; ]; tag "time" [ class_ "app-feedback-time"; Dream_html.string_attr "datetime" "%s" report.submitted_at; ] [ txt "%s" report.submitted_at ]; tag "p" [ class_ "app-feedback-message" ] [ txt "%s" report.message ]; tag "p" [ class_ "app-feedback-upvotes" ] [ txt "Upvotes: %d" report.upvotes ]; app_feedback_actions request report; ]) reports)); ] in html_page ~viewer ~request ~active:"app-feedback" ?workout_started "App Feedback" ([ tag "h1" [] [ txt "App Feedback" ]; tag "p" [] [ txt "Help us improve hito by sharing your experience." ]; link_tabs ~aria_label:"App feedback views" ~active: (match tab with `Write -> "write" | `Submitted -> "submitted") [ ("write", "Write feedback", "/app-feedback?tab=write"); ("submitted", "Submitted feedback", "/app-feedback?tab=submitted"); ]; ] @ panel)