diff --git a/style.css b/style.css index d505d70..09e42e8 100644 --- a/style.css +++ b/style.css @@ -63,3 +63,12 @@ main { .cart__price { width: 65px; } + +.login__reason { + padding: 8px 8px; + margin: 16px 0; + border-radius: 2px; + border: 1px solid #bee5eb; + background: #d1ecf1; + color: #0c5460; +} diff --git a/views/login.pl b/views/login.pl index 6b9b34c..e5b3876 100644 --- a/views/login.pl +++ b/views/login.pl @@ -1,6 +1,16 @@ :- http_handler(root(login), login_view(Method), [method(Method), methods([get, post])]). +:- http_handler(root(logout), logout_view, []). :- http_handler(root('style.css'), http_reply_file('style.css', []), []). + +login_reason --> + { + http_session_data(reason(Reason)), + http_session_retract(reason(_)) + }, !, + html(div(class=login__reason, Reason)). +login_reason --> []. + login_view(get, _Request) :- reply_html_page( [ @@ -13,6 +23,7 @@ login_view(get, _Request) :- ], [ h1('Login'), + \login_reason, form([method=post], [ div([ label(for=username, 'Username'), @@ -20,7 +31,9 @@ login_view(get, _Request) :- type=text, placeholder='Username', name=username, - id=username + id=username, + autofocus, + required ]) ]), @@ -30,7 +43,8 @@ login_view(get, _Request) :- type=password, placeholder='Username', name=password, - id=password + id=password, + required ]) ]), @@ -46,19 +60,40 @@ login_view(get, _Request) :- login_view(post, Request) :- http_read_data(Request, [username=Username, password=Password], []), - handle_login(Username, Password, Reply), - reply_prolog(Reply). + handle_login(Username, Password, Request). + + +create_user(Username, _) :- + user(Username, _), !, + format("User already exists.~n"), + false. + +create_user(Username, Password) :- + crypto_password_hash(Password, Hash), + assert_user(Username, Hash). % Handles logging in, returning the correct Json in Reply. -handle_login(Username, Password, Reply) :- +handle_login(Username, Password, Request) :- user(Username, Hash), crypto_password_hash(Password, Hash), !, - assert_session(Username, Token), - Reply = true. + http_session_assert(user(Username)), + (http_session_retract(from(From)); From = .), + http_redirect(see_other, root(From), Request). -handle_login(Username, _, Reply) :- +handle_login(Username, _, Request) :- user(Username, _), !, - Reply = incorrect_password. + http_session_assert(reason('Invalid password.')), + http_redirect(see_other, root(login), Request). -handle_login(_, _, incorrect_user). +handle_login(_, _, Request) :- + http_session_assert(reason('Unknown username.')), + http_redirect(see_other, root(login), Request). + + +logout_view(Request) :- + http_session_retract(user(_)), + http_redirect(see_other, root(.), Request). + +logout_view(Request) :- + http_redirect(see_other, root(.), Request). diff --git a/views/products.pl b/views/products.pl index 6fa150b..1b1bf88 100644 --- a/views/products.pl +++ b/views/products.pl @@ -1,10 +1,44 @@ -:- http_handler(root(.), products_view, []). +:- http_handler(root(.), products_view(Method), [method(Method), methods([get, post])]). :- http_handler(root('style.css'), http_reply_file('style.css', []), []). price_str(Price, PriceStr) :- Euro is Price / 100, format(atom(PriceStr), '€ ~2f', Euro). +products_add --> + {http_session_data(user(_))}, !, % Check if we're logged in + html( + div([ + h2('Add product'), + form([method=post], [ + div([ + label(for=name, 'Name'), + input([ + type=text, + placeholder='Name', + name=name, + id=name, + required + ]) + ]), + + div([ + label(for=price, 'Price'), + input([ + type=text, + placeholder='Price', + name=price, + id=price, + required + ]) + ]), + + div(input(type=submit)) + ]) + ]) + ). +products_add --> []. % If not, do not show + products_list([]) --> []. products_list([product(Name, Price)|Products]) --> {price_str(Price, PriceStr)}, @@ -34,7 +68,16 @@ cart([Name|Items]) --> ]), cart(Items). -products_view(_Request) :- +account --> + {http_session_data(user(Username))}, !, + html([ + div(['Hello ', Username, '!']), + a(href('/logout'), 'Log out') + ]). +account --> + html(a(href('/login'), 'Log in')). + +products_view(get, _Request) :- http_session_id(SessionId), (bagof(product(X, Y), product(X, Y), Products); Products = []), (bagof(Name, cart_entry(SessionId, Name), CartEntries); CartEntries = []), @@ -52,6 +95,23 @@ products_view(_Request) :- main([ div(class(products), \products_list(Products)), div(class(cart), \cart(CartEntries)) - ]) + ]), + \products_add, + h2('Account'), + \account ] ). + +products_view(post, Request) :- + % Check if we're logged in + \+ http_session_data(user(_)), !, + http_session_assert(reason('You need to be logged in to do this.')), + http_redirect(see_other, root(login), Request). + +products_view(post, Request) :- + http_read_data(Request, [name=Name, price=Price], []), + atom_number(Price, PriceNumber), + Cents is round(PriceNumber * 100), + retractall_product(Name, _), + assert_product(Name, Cents), + http_redirect(see_other, root(.), Request).