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)