diff options
| author | Daniel Friesel <derf@finalrewind.org> | 2019-04-07 18:44:33 +0200 | 
|---|---|---|
| committer | Daniel Friesel <derf@finalrewind.org> | 2019-04-07 18:44:33 +0200 | 
| commit | ffee7177ac26f4e79227cdf0abcd83f80f34faa4 (patch) | |
| tree | 9232d785b19f5e10239be0c20ca55bcc60062700 | |
| parent | 828dd54266dfaf2b58c0498b7ced6c06d6e104ef (diff) | |
Refactor history template, add yearly stats
| -rwxr-xr-x | lib/Travelynx.pm | 4 | ||||
| -rwxr-xr-x | lib/Travelynx/Controller/Traveling.pm | 71 | ||||
| -rw-r--r-- | templates/_history_months.html.ep | 12 | ||||
| -rw-r--r-- | templates/_history_stats.html.ep | 33 | ||||
| -rw-r--r-- | templates/_history_trains.html.ep | 51 | ||||
| -rw-r--r-- | templates/_history_years.html.ep | 12 | ||||
| -rw-r--r-- | templates/cancelled.html.ep | 16 | ||||
| -rw-r--r-- | templates/history.html.ep | 133 | ||||
| -rw-r--r-- | templates/history_by_month.html.ep | 13 | ||||
| -rw-r--r-- | templates/history_by_year.html.ep | 13 | ||||
| -rw-r--r-- | templates/landingpage.html.ep | 33 | 
11 files changed, 229 insertions, 162 deletions
| diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm index 20f885b..7cab531 100755 --- a/lib/Travelynx.pm +++ b/lib/Travelynx.pm @@ -1468,11 +1468,13 @@ qq{select * from pending_mails where email = ? and num_tries > 1;}  	);  	$authed_r->get('/account')->to('account#account'); +	$authed_r->get('/cancelled')->to('traveling#cancelled');  	$authed_r->get('/change_password')->to('account#password_form');  	$authed_r->get('/export.json')->to('account#json_export'); +	$authed_r->get('/history.json')->to('traveling#json_history');  	$authed_r->get('/history')->to('traveling#history'); +	$authed_r->get('/history/:year')->to('traveling#yearly_history');  	$authed_r->get('/history/:year/:month')->to('traveling#monthly_history'); -	$authed_r->get('/history.json')->to('traveling#json_history');  	$authed_r->get('/journey/:id')->to('traveling#journey_details');  	$authed_r->get('/s/*station')->to('traveling#station');  	$authed_r->post('/change_password')->to('account#change_password'); diff --git a/lib/Travelynx/Controller/Traveling.pm b/lib/Travelynx/Controller/Traveling.pm index dee69a6..bbbc214 100755 --- a/lib/Travelynx/Controller/Traveling.pm +++ b/lib/Travelynx/Controller/Traveling.pm @@ -250,34 +250,79 @@ sub redirect_to_station {  	$self->redirect_to("/s/${station}");  } -sub history { +sub cancelled {  	my ($self) = @_; -	my $cancelled = $self->param('cancelled') ? 1 : 0; - -	my @journeys = $self->get_user_travels( cancelled => $cancelled ); +	my @journeys = $self->get_user_travels( cancelled => 1 );  	$self->respond_to(  		json => { json => [@journeys] },  		any  => { -			template => 'history', +			template => 'cancelled',  			journeys => [@journeys]  		}  	);  } +sub history { +	my ($self) = @_; + +	$self->render( template => 'history' ); +} +  sub json_history {  	my ($self) = @_; -	my $cancelled = $self->param('cancelled') ? 1 : 0; -	$self->render( -		json => [ $self->get_user_travels( cancelled => $cancelled ) ] ); +	$self->render( json => [ $self->get_user_travels ] ); +} + +sub yearly_history { +	my ($self) = @_; +	my $year = $self->stash('year'); +	my @journeys; +	my $stats; + +	if ( not $year =~ m{ ^ [0-9]{4} $ }x ) { +		@journeys = $self->get_user_travels; +	} +	else { +		my $interval_start = DateTime->new( +			time_zone => 'Europe/Berlin', +			year      => $year, +			month     => 1, +			day       => 1, +			hour      => 0, +			minute    => 0, +			second    => 0, +		); +		my $interval_end = $interval_start->clone->add( years => 1 ); +		@journeys = $self->get_user_travels( +			after  => $interval_start, +			before => $interval_end +		); +		$stats = $self->get_journey_stats( year => $year ); +	} + +	$self->respond_to( +		json => { +			json => { +				journeys   => [@journeys], +				statistics => $stats +			} +		}, +		any => { +			template   => 'history_by_year', +			journeys   => [@journeys], +			year       => $year, +			statistics => $stats +		} +	); +  }  sub monthly_history {  	my ($self) = @_;  	my $year   = $self->stash('year');  	my $month  = $self->stash('month'); -	my $cancelled = $self->param('cancelled') ? 1 : 0;  	my @journeys;  	my $stats;  	my @months @@ -285,11 +330,9 @@ sub monthly_history {  		qw(Januar Februar März April Mai Juni Juli August September Oktober November Dezember)  	  ); -	if ( $cancelled -		or -		not( $year =~ m{ ^ [0-9]{4} $ }x and $month =~ m{ ^ [0-9]{1,2} $ }x ) ) +	if ( not( $year =~ m{ ^ [0-9]{4} $ }x and $month =~ m{ ^ [0-9]{1,2} $ }x ) )  	{ -		@journeys = $self->get_user_travels( cancelled => $cancelled ); +		@journeys = $self->get_user_travels;  	}  	else {  		my $interval_start = DateTime->new( @@ -320,7 +363,7 @@ sub monthly_history {  			}  		},  		any => { -			template   => 'history', +			template   => 'history_by_month',  			journeys   => [@journeys],  			year       => $year,  			month      => $month, diff --git a/templates/_history_months.html.ep b/templates/_history_months.html.ep new file mode 100644 index 0000000..465a159 --- /dev/null +++ b/templates/_history_months.html.ep @@ -0,0 +1,12 @@ +<div class="row"> +	<div class="col s12"> +		<ul class="pagination"> +			% while ($since < $now) { +				% my $link_to = $since->strftime('%Y/%m'); +				% my $class = $link_to eq $current ? 'active' : 'waves-effect'; +				<li class="<%= $class %>"><a href="/history/<%= $link_to %>"><%= $since->strftime('%m.%Y') %></a></li> +				% $since->add(months => 1)->set(day => 1, hour => 0, minute => 0, second => 0); +			% } +		</ul> +	</div> +</div> diff --git a/templates/_history_stats.html.ep b/templates/_history_stats.html.ep new file mode 100644 index 0000000..f203631 --- /dev/null +++ b/templates/_history_stats.html.ep @@ -0,0 +1,33 @@ +<div class="row"> +	<div class="col s12"> +		<table class="striped"> +			<tr> +				<th scope="row">Fahrten</th> +				<td><%= $stats->{num_journeys} %></td> +			</tr> +			<tr> +				<th scope="row">Züge</th> +				<td><%= $stats->{num_trains} %></td> +			</tr> +			<tr> +				<th scope="row">Entfernung</th> +				<td>ca. <%= sprintf('%.f', $stats->{km_route}) %> km +					(Luftlinie: <%= sprintf('%.f', $stats->{km_beeline}) %> km)</td> +			</tr> +			<tr> +				<th scope="row">Fahrtzeit</th> +				<td><%= sprintf('%02d:%02d', $stats->{min_travel_real} / 60, $stats->{min_travel_real} % 60) %> Stunden +					(nach Fahrplan: <%= sprintf('%02d:%02d', $stats->{min_travel_sched} / 60, $stats->{min_travel_sched} % 60) %>)<td> +			</tr> +			<tr> +				<th scope="row">Wartezeit (nur Umstiege)</th> +				<td><%= sprintf('%02d:%02d', $stats->{min_interchange_real} / 60, $stats->{min_interchange_real} % 60) %> Stunden +			</tr> +			<tr> +				<th scope="row">Kumulierte Verspätung</th> +				<td>Bei Abfahrt: <%= sprintf('%02d:%02d', $stats->{delay_dep} / 60, $stats->{delay_dep} % 60) %> Stunden<br/> +					Bei Ankunft: <%= sprintf('%02d:%02d', $stats->{delay_arr} / 60, $stats->{delay_arr} % 60) %> Stunden</td> +			</tr> +		</table> +	</div> +</div> diff --git a/templates/_history_trains.html.ep b/templates/_history_trains.html.ep new file mode 100644 index 0000000..2044f7b --- /dev/null +++ b/templates/_history_trains.html.ep @@ -0,0 +1,51 @@ +<div class="row"> +	<div class="col s12"> +		<table class="striped"> +			<thead> +				<tr> +					<th>Datum</th> +					<th>Zeit</th> +					<th>Zug</th> +					<th>Strecke</th> +				</tr> +			</thead> +			<tbody> +				% for my $travel (@{$journeys}) { +					% if ($travel->{completed}) { +						% my $detail_link = '/journey/' . current_user()->{id} . '-' . $travel->{ids}->[1]; +						<tr> +							<td><%= $travel->{sched_departure}->strftime('%d.%m.%Y') %></td> +							<td> +							% if (param('cancelled') and $travel->{sched_arrival}->epoch != 0) { +								%= $travel->{sched_arrival}->strftime('%H:%M') +							% } +							% else { +								% if ($travel->{rt_arrival}->epoch == 0 and $travel->{sched_arrival}->epoch == 0) { +									<i class="material-icons">timer_off</i> +								% } else { +									%= $travel->{rt_arrival}->strftime('%H:%M'); +									% if ($travel->{sched_arrival} != $travel->{rt_arrival}) { +										(<%= sprintf('%+d', ($travel->{rt_arrival}->epoch - $travel->{sched_arrival}->epoch) / 60) %>) +									% } +								% } +							% } +							<br/> +							% if (param('cancelled')) { +								%= $travel->{sched_departure}->strftime('%H:%M') +							% } +							% else { +								<%= $travel->{rt_departure}->strftime('%H:%M') %> +								% if ($travel->{sched_departure} != $travel->{rt_departure}) { +									(<%= sprintf('%+d', ($travel->{rt_departure}->epoch - $travel->{sched_departure}->epoch) / 60) %>) +								% } +							% } +							</td> +							<td><a href="<%= $detail_link %>"><%= $travel->{type} %> <%= $travel->{line} // '' %> <%= $travel->{no} %></a></td> +							<td><a href="<%= $detail_link %>"><%= $travel->{from_name} %> → <%= $travel->{to_name} %></a></td> +						</tr> +					% } +				% } +			</tbody> +		</table> +	</div> +</div> diff --git a/templates/_history_years.html.ep b/templates/_history_years.html.ep new file mode 100644 index 0000000..02bb70d --- /dev/null +++ b/templates/_history_years.html.ep @@ -0,0 +1,12 @@ +<div class="row"> +	<div class="col s12"> +		<ul class="pagination"> +			% while ($since < $now) { +				% my $link_to = $since->strftime('%Y'); +				% my $class = $link_to eq $current ? 'active' : 'waves-effect'; +				<li class="<%= $class %>"><a href="/history/<%= $link_to %>"><%= $since->strftime('%Y') %></a></li> +				% $since->add(years => 1)->set(month => 1, day => 1, hour => 0, minute => 0, second => 0); +			% } +		</ul> +	</div> +</div> diff --git a/templates/cancelled.html.ep b/templates/cancelled.html.ep new file mode 100644 index 0000000..ff5ba1e --- /dev/null +++ b/templates/cancelled.html.ep @@ -0,0 +1,16 @@ +<h1>Zugausfälle</h1> +<div class="row"> +	<div class="col s12"> +		Die folgenden Zugfahrten haben nicht stattgefunden. +	</div> +</div> +<div class="row"> +	<div class="col s12"> +		<ul> +			<li><a href="/cancelled.json">JSON-Export</a> (Das Datenlayout ist noch nicht final)</li> +			<li><a href="/history">Reguläre Zugfahrten</a></li> +		</ul> +	</div> +</div> + +%= include '_history_trains', journeys => stash('journeys'); diff --git a/templates/history.html.ep b/templates/history.html.ep index e65d31f..10cc596 100644 --- a/templates/history.html.ep +++ b/templates/history.html.ep @@ -1,126 +1,29 @@ -% my $since = get_user_data()->{registered_at}; -% my $now = DateTime->now(time_zone => 'Europe/Berlin'); -<div class="row"> -	<div class="col s12"> -		<ul class="pagination"> -			<!--<li class="disabled"><a href="#!"><i class="material-icons">chevron_left</i></a></li>--> -			% my $ref = stash('year') ? stash('year') . '/' . stash('month') : ''; -			% while ($since < $now) { -				% my $link_to = $since->strftime('%Y/%m'); -				% my $class = $link_to eq $ref ? 'active' : 'waves-effect'; -				<li class="<%= $class %>"><a href="/history/<%= $link_to %>"><%= $since->strftime('%m.%Y') %></a></li> -				% $since->add(months => 1)->set(day => 1, hour => 0, minute => 0, second => 0); -			% } -			<!--<li class="disabled"><a href="#!"><i class="material-icons">chevron_right</i></a></li>--> -		</ul> -	</div> -</div> -% if (my $stats = stash('statistics')) { -<h1><%= stash('month_name') %> <%= stash('year') %></h1> -	<div class="row"> -		<div class="col s12"> -			<table class="striped"> -				<tr> -					<th scope="row">Fahrten</th> -					<td><%= $stats->{num_journeys} %></td> -				</tr> -				<tr> -					<th scope="row">Züge</th> -					<td><%= $stats->{num_trains} %></td> -				</tr> -				<tr> -					<th scope="row">Entfernung</th> -					<td>ca. <%= sprintf('%.f', $stats->{km_route}) %> km -						(Luftlinie: <%= sprintf('%.f', $stats->{km_beeline}) %> km)</td> -				</tr> -				<tr> -					<th scope="row">Fahrtzeit</th> -					<td><%= sprintf('%02d:%02d', $stats->{min_travel_real} / 60, $stats->{min_travel_real} % 60) %> Stunden -						(nach Fahrplan: <%= sprintf('%02d:%02d', $stats->{min_travel_sched} / 60, $stats->{min_travel_sched} % 60) %>)<td> -				</tr> -				<tr> -					<th scope="row">Wartezeit (nur Umstiege)</th> -					<td><%= sprintf('%02d:%02d', $stats->{min_interchange_real} / 60, $stats->{min_interchange_real} % 60) %> Stunden -				</tr> -				<tr> -					<th scope="row">Kumulierte Verspätung</th> -					<td>Bei Abfahrt: <%= sprintf('%02d:%02d', $stats->{delay_dep} / 60, $stats->{delay_dep} % 60) %> Stunden<br/> -						Bei Ankunft: <%= sprintf('%02d:%02d', $stats->{delay_arr} / 60, $stats->{delay_arr} % 60) %> Stunden</td> -				</tr> -			</table> -		</div> -	</div> -% } -% elsif (param('cancelled')) { -<h1>Ausgefallene Fahrten</h1> +<h1>Fahrten</h1> +  <div class="row">  	<div class="col s12"> -		<ul> -			<li><a href="/history.json?cancelled=1">JSON-Export</a> (Das Datenlayout ist noch nicht final)</li> -			<li><a href="/history">Reguläre Zugfahrten</a></li> -		</ul> +		Hier finden sich alle bisherigen Zugfahrten und Statistiken für jedes +		Jahr und jeden Monat.  	</div>  </div> -% } -% else { -<h1>Fahrten</h1> +  <div class="row">  	<div class="col s12">  		<ul> -			<li><a href="/history.json">JSON-Export</a> (Das Datenlayout ist noch nicht final)</li> -			<li><a href="/history?cancelled=1">Ausgefallene Züge</a></li> +			<li><a href="/history.json">JSON-Export aller Zugfahrten</a> (Das Datenlayout ist noch nicht final)</li> +			<li><a href="/cancelled">Ausgefallene Züge</a></li>  		</ul>  	</div>  </div> + +<h2>Nach Jahr</h2> +% my $since = get_user_data()->{registered_at}; +% my $now = DateTime->now(time_zone => 'Europe/Berlin'); +%= include '_history_years', current => '', since => $since->clone, now => $now; + +<h2>Nach Monat</h2> +%= include '_history_months', current => '', since => $since->clone, now => $now; + +% if (stash('statistics')) { +	%= include '_history_stats', stats => stash('statistics');  % } -<div class="row"> -	<div class="col s12"> -		<table class="striped"> -			<thead> -				<tr> -					<th>Datum</th> -					<th>Zeit</th> -					<th>Zug</th> -					<th>Strecke</th> -				</tr> -			</thead> -			<tbody> -				% for my $travel (@{$journeys}) { -					% if ($travel->{completed}) { -						% my $detail_link = '/journey/' . current_user()->{id} . '-' . $travel->{ids}->[1]; -						<tr> -							<td><%= $travel->{sched_departure}->strftime('%d.%m.%Y') %></td> -							<td> -							% if (param('cancelled') and $travel->{sched_arrival}->epoch != 0) { -								%= $travel->{sched_arrival}->strftime('%H:%M') -							% } -							% else { -								% if ($travel->{rt_arrival}->epoch == 0 and $travel->{sched_arrival}->epoch == 0) { -									<i class="material-icons">timer_off</i> -								% } else { -									%= $travel->{rt_arrival}->strftime('%H:%M'); -									% if ($travel->{sched_arrival} != $travel->{rt_arrival}) { -										(<%= sprintf('%+d', ($travel->{rt_arrival}->epoch - $travel->{sched_arrival}->epoch) / 60) %>) -									% } -								% } -							% } -							<br/> -							% if (param('cancelled')) { -								%= $travel->{sched_departure}->strftime('%H:%M') -							% } -							% else { -								<%= $travel->{rt_departure}->strftime('%H:%M') %> -								% if ($travel->{sched_departure} != $travel->{rt_departure}) { -									(<%= sprintf('%+d', ($travel->{rt_departure}->epoch - $travel->{sched_departure}->epoch) / 60) %>) -								% } -							% } -							</td> -							<td><a href="<%= $detail_link %>"><%= $travel->{type} %> <%= $travel->{line} // '' %> <%= $travel->{no} %></a></td> -							<td><a href="<%= $detail_link %>"><%= $travel->{from_name} %> → <%= $travel->{to_name} %></a></td> -						</tr> -					% } -				% } -			</tbody> -		</table> -	</div> -</div> diff --git a/templates/history_by_month.html.ep b/templates/history_by_month.html.ep new file mode 100644 index 0000000..3794858 --- /dev/null +++ b/templates/history_by_month.html.ep @@ -0,0 +1,13 @@ +% my $since = get_user_data()->{registered_at}; +% my $now = DateTime->now(time_zone => 'Europe/Berlin'); +%= include '_history_months', current => "${year}/${month}", since => $since, now => $now; + +<h1><%= stash('month_name') %> <%= stash('year') %></h1> + +% if (stash('statistics')) { +	%= include '_history_stats', stats => stash('statistics'); +% } + +% if (stash('journeys')) { +	%= include '_history_trains', journeys => stash('journeys'); +% } diff --git a/templates/history_by_year.html.ep b/templates/history_by_year.html.ep new file mode 100644 index 0000000..97c223f --- /dev/null +++ b/templates/history_by_year.html.ep @@ -0,0 +1,13 @@ +% my $since = get_user_data()->{registered_at}; +% my $now = DateTime->now(time_zone => 'Europe/Berlin'); +%= include '_history_years', current => $year, since => $since, now => $now; + +<h1>Jahresrückblick <%= $year %></h1> + +% if (stash('statistics')) { +	%= include '_history_stats', stats => stash('statistics'); +% } + +% if (stash('journeys')) { +	%= include '_history_trains', journeys => stash('journeys'); +% } diff --git a/templates/landingpage.html.ep b/templates/landingpage.html.ep index b01896d..5d06dbf 100644 --- a/templates/landingpage.html.ep +++ b/templates/landingpage.html.ep @@ -91,38 +91,7 @@  		</div>  	</div>  	<h1>Letzte Fahrten</h1> -	<div class="row"> -		<table class="striped"> -			<thead> -				<tr> -					<th>Datum</th> -					<th>Zug</th> -					<th>Strecke</th> -					<th>Dauer</th> -				</tr> -			</thead> -			<tbody> -				% for my $travel (get_user_travels(limit => 1)) { -					% if ($travel->{completed}) { -						<tr> -							% my $detail_link = '/journey/' . current_user()->{id} . '-' . $travel->{ids}->[1]; -							<td><%= $travel->{sched_departure}->strftime('%d.%m.%Y') %></td> -							<td><a href="<%= $detail_link %>"><%= $travel->{type} %> <%= $travel->{line} // $travel->{no} %></a></td> -							<td><a href="<%= $detail_link %>"><%= $travel->{from_name} %> → <%= $travel->{to_name} %></a></td> -							% if ($travel->{rt_arrival}->epoch and $travel->{rt_departure}->epoch) { -								<td><%= ($travel->{rt_arrival}->epoch - $travel->{rt_departure}->epoch) / 60 %> min -								</td> -							% } else { -								<td><%= sprintf('%.f', $self->get_travel_distance($travel->{from_name}, $travel->{to_name}, $travel->{route})) %>km -									<i class="material-icons">timer_off</i> -								</td> -							% } -						</tr> -					% } -				% } -			</tbody> -		</tabel> -	</div> +	%= include '_history_trains', journeys => [get_user_travels(limit => 1)];  % }  % else {  	<div class="row"> | 
