RSS Git Download  Clone
Raw Blame History
package Routes::Moongate;
use Dancer2 appname => 'DocsLib';

use v5.34.0;
use Data::Printer;

use App::Model; # D2 plugin, provides 'model' keyword
use Dancer2::Plugin::Deferred;
use Dancer2::Plugin::Auth::Tiny;

my $PREFIX = 'moongate'; 
prefix "/$PREFIX";

my $docs_path = path( config->{appdir}, 'documents', $PREFIX ); # debug $docs_path;

hook before_template_render => sub {
    my $tokens = shift; # need to have unique token name across all route files 
    my %h = (
        home     => '/' . $PREFIX . '/',
        new      => '/' . $PREFIX . '/service_record',
        edit     => '/' . $PREFIX . '/edit',
        search   => '/' . $PREFIX . '/search',
        update   => '/' . $PREFIX . '/update',
        summary  => '/' . $PREFIX . '/summary',
        all_docs => '/' . $PREFIX . '/all_docs',
        document => '/' . $PREFIX . '/id',
        download => '/' . $PREFIX . '/download',
    );
    $tokens->{uri_for_section}->{$PREFIX}->{$_} = uri_for($h{$_}) for keys %h; # p $tokens;
};

# cannot use method 'any' with route names: "Route with this name ($name) already exists"
#   probably when route name is registered for GET, then for POST/HEAD/etc
# cannot use uri_for_route in any template loaded after forward (data is deleted)
get  'moongate_home'            => '/'
                                => needs login => \&home; 
post 'edit_moongate_entry_post' => '/edit/:id[Int]'
                                => needs login => \&edit_document;
get  'edit_moongate_entry_get'  => '/edit/:id[Int]' # required for GET request, needs unique route name
                                => needs login => \&edit_document;
post 'new_moongate_entry'       => '/service_record'
                                => needs login => \&service_record;
post 'update_moongate_entry'    => '/update/:id[Int]'
                                => needs login => \&update_document;

get  'moongate_summary'            => '/summary'      => \&summary;
get  'download_moongate_document'  => '/download/:id[Str]' => \&download;
get  'get_moongate_entry'          => '/id/:id[Int]'  => \&get_document;
get  'all_moongate_entries'        => '/all_docs'     => \&all_documents;
post 'find_moongate_entries'       => '/search'       => \&search;

# ==============================================================================

sub flash { deferred @_ }

sub home {
    template $PREFIX.'/home.tt', { records => query_parameters->get('records') };
};

sub get_document {
    my $id = route_parameters->get('id');
    my $rec = model->moongate->get_document($id); # p $rec; # AoH
    template $PREFIX.'/home.tt', { records => $rec };
};

sub all_documents {
	my $rec = model->moongate->get_all_documents; # p $rec; # AoH
	template $PREFIX.'/home.tt', { records => $rec };
};

sub summary {
    my $rec = model->moongate->get_all_documents; # p $rec; # AoH
    template $PREFIX.'/summary.tt',  => { records => $rec };
};

sub search {
	my $str = body_parameters->get('search') =~ s{\s+}{}gr;
	my $rec = model->moongate->find_documents($str); # p $rec; # AoH
    my $tt = @$rec ? 'summary.tt' : 'home.tt';
	template path( $PREFIX, $tt ),  { records => $rec };
};

sub edit_document {
	var is_edit => 1;
    my $route = '/'.$PREFIX.'/id/'.route_parameters->get('id');
	forward $route, {}, { method => 'GET' };
};

sub update_document { # just captures document_id & forwards:
	forward '/'.$PREFIX.'/service_record', { id => route_parameters->get('id') };
};

sub service_record {
    my $params = request->parameters->as_hashref; # p $params;
    # get upload data - new entry only, passed as param if edit:
    my $data_file = upload('filename'); # p $data_file;
    if ( $data_file ) {
        # capture filename, replace spaces with underscores, non-destructive
        my $filename = $data_file->filename =~ s{\s}{_}gr;
        # generate $filepath from docs_path & filename, create var of same name:
        my $filepath = var filepath => path($docs_path, $filename); # p $filepath;
        # check if it exists and bail if it does:
        if ( -e $filepath ) {
            var input_error => qq!file "$filename" already exists!;
            forward '/'.$PREFIX.'/', { records => [$params] },
                { method => 'GET' }; # tt needs AoH
        }
        # add filename to params:
        $params->{filename} = $filename; # say vars->{filepath};
    } # p $params;

    my $res = model->moongate->save_document($params); # p $res;
	if ( $res->{error} ) {
		var input_error => $res->{error};
		forward '/'.$PREFIX.'/', { records => [$params] }, { method => 'GET' };
    }
	else {
		flash ( input_success => 1 ); # doesn't need message
        # upload file to docs dir if uploaded:
        $data_file->copy_to( vars->{filepath} ) if $data_file;
		redirect uri_for_route( 'get_moongate_entry', { id => $res->{id} } );
	}
};

sub download {
    my $document = route_parameters->get('id');
    my $file = join '/', $docs_path, $document; debug $file;
    send_file $file, system_path => 1;
};

true;