RSS Git Download  Clone
Raw Blame History
package Reporter::Routes;

use Reporter::Class; # provides Moo, Clone, Modern::Perl & Data::Printer::p
use Reporter;
use Dancer2;
use Dancer2::Plugin::Deferred;

use Reporter::Routes::AJAX;

my $app = Reporter->new(dbname => 'hilis4'); # contains model & db classes

hook before => sub {
    # all routes need login (except /login):
    unless ( session('user_profile') ) {
        redirect '/login' unless request->path_info =~ m!^/login!;
    }
    # sql query output to stdout:
    $app->enable_sql_trace if setting('enable_sql_trace'); # development env
};

hook before_template_render => sub {
    my $tokens = shift;
    $tokens->{symbolise} = sub { $app->symbolise(@_) };
};

# default route:
get '/' => sub {
    template load => { target => uri_for('/load') };
};

# login route:
get '/login' => sub { template 'login' };

# submitted user credentials:
post '/login' => sub {
    my $params = params; # p $params;

    # validate username/password
    if ( my $user = $app->model->authenticate_user($params) ) { # p $user;
        session user_profile => $user;
        redirect '/';
    }
    else { # p 'here';
        my $failed_logins = session('failed_logins') || 0;
        session failed_logins => $failed_logins + 1; # increment
        redirect '/login';
    }
};

get '/load' => sub {
    my $params = params; # p $params;

    # validate lab number format:
    my $validation = $app->model->validator->validate( search => $params );
        # p $validation;
    if ( $validation->{failed} ) { # p $result->{errors};
        return template load => $validation; # href containing dfv_errs key
    }
    my $lab_number = param('lab_number');
    my $session    = session('user_profile');
    { # get request for lab_number:
        my %h = (
            lab_number => $lab_number,
            user_id    => $session->{id},
        );
        my $data = $app->model->load_request(\%h); # p $data;
        if (! $data) {
            my $msg = 'request with lab number %s not found';
            deferred warning => sprintf $msg, $lab_number;
            redirect '/';
        }
        # store data in session for tt, and in case needed for re-display to report.tt:
        session request => $data;
    }
    { # get validation profile to configure required fields:
        my $profile = $app->model->get_validation_profile('report'); # p $profile;
        session validation_profile => $profile;
    }
    template report => {}; # gets data from session.request
};

post '/report/:request_id' => sub {
    my $params = params; # p $params;
    my $validation = $app->model->validator->validate( report => $params );
        # p $validation;
    if ( $validation->{failed} ) { # p $result->{errors};
        return template report => $validation; # href containing dfv_errs key
    }
    my $data = $validation->{valid}; # p $data;
    my $user = session('user_profile'); # p $user;

    # add user_id & request_id to $data:
    $data->{request_id} = param('request_id');
    $data->{user_id}    = $user->{id}; # p $data;

    my $result = $app->model->save_report($data);
    if ( my $err = $result->{error} ) { # p $result;
        return template report => { error => $err };
    } # p $params->{request_id};

    my $lab_number = $app->model->get_lab_number($params->{request_id}); # p $lab_number;
    redirect '/load?lab_number='.$lab_number;
};

# logout route:
get '/logout' => sub {
    app->destroy_session;
    redirect('/'); # should redirect to /login
};

# default Dancer2 app index page:
get '/index' => sub { template 'index', {}, { layout => 'index' } };

#===============================================================================
# http://blog.geekuni.com/2015/06/three-ways-to-implement-sessions.html
=begin
get '/count' => sub {
  if ( my $user = session('user') ) {
    session count => session('count') + 1;
    my $ordinal = $app->model->num2ordinal(session('count')); p $ordinal;
    return
        '<a href="/count">Click here</a> for the name of the eldest son of ' .
        '<b>Count von '. ucfirst $user.' the '. ucfirst $ordinal .'</b>';
  }
  return 'Cookie Monster!';
};

get '/do_login/:user' => sub {
    session user   => params->{user};
    session count  => 0;
    redirect '/count';
};
=cut
#===============================================================================

dance;