diff options
| -rwxr-xr-x | index.pl | 446 | ||||
| -rw-r--r-- | public/static/js/geolocation.js | 4 | ||||
| -rw-r--r-- | public/static/js/geolocation.min.js | 2 | ||||
| -rw-r--r-- | public/static/js/travelynx-actions.js | 2 | ||||
| -rw-r--r-- | public/static/js/travelynx-actions.min.js | 2 | ||||
| l--------- | public/static/v1 | 1 | ||||
| -rw-r--r-- | templates/account.html.ep | 2 | ||||
| -rw-r--r-- | templates/landingpage.html.ep | 137 | ||||
| -rw-r--r-- | templates/layouts/default.html.ep | 23 | ||||
| -rw-r--r-- | templates/login.html.ep | 4 | ||||
| -rw-r--r-- | templates/register.html.ep | 4 | 
11 files changed, 286 insertions, 341 deletions
| @@ -44,13 +44,10 @@ app->plugin(  	authentication => {  		autoload_user => 1,  		session_key   => 'foodor', +		fail_render   => { template => 'login' },  		load_user     => sub {  			my ( $self, $uid ) = @_; -			my $data = $self->get_user_data($uid); -			if ($data) { -				return { name => $data->{name} }; -			} -			return undef; +			return $self->get_user_data($uid);  		},  		validate_user => sub {  			my ( $self, $username, $password, $extradata ) = @_; @@ -68,6 +65,7 @@ app->plugin(  		},  	}  ); +app->sessions->default_expiration( 60 * 60 * 24 * 180 );  app->defaults( layout => 'default' ); @@ -427,7 +425,7 @@ helper 'checkin' => sub {  			}  			my $success = $self->app->checkin_query->execute( -				$self->get_user_id, +				$self->current_user->{id},  				$self->get_station_id(  					ds100 => $status->{station_ds100},  					name  => $status->{station_name} @@ -457,7 +455,7 @@ helper 'checkin' => sub {  helper 'undo' => sub {  	my ($self) = @_; -	my $uid = $self->get_user_id; +	my $uid = $self->current_user->{id};  	$self->app->get_last_actions_query->execute($uid);  	my $rows = $self->app->get_last_actions_query->fetchall_arrayref; @@ -469,10 +467,10 @@ helper 'undo' => sub {  		return 'Repeated undo is not supported';  	} -	my $success -	  = $self->app->undo_query->execute( $self->get_user_id, +	my $success = $self->app->undo_query->execute( +		$self->current_user->{id},  		DateTime->now( time_zone => 'Europe/Berlin' )->epoch, -	  ); +	);  	if ( defined $success ) {  		return; @@ -501,7 +499,7 @@ helper 'checkout' => sub {  	if ( not defined $train ) {  		if ($force) {  			my $success = $self->app->checkout_query->execute( -				$self->get_user_id, +				$self->current_user->{id},  				$self->get_station_id(  					ds100 => $status->{station_ds100},  					name  => $status->{station_name} @@ -523,7 +521,7 @@ helper 'checkout' => sub {  	}  	else {  		my $success = $self->app->checkout_query->execute( -			$self->get_user_id, +			$self->current_user->{id},  			$self->get_station_id(  				ds100 => $status->{station_ds100},  				name  => $status->{station_name} @@ -580,7 +578,7 @@ helper 'get_user_token' => sub {  helper 'get_user_data' => sub {  	my ( $self, $uid ) = @_; -	$uid //= $self->get_user_id; +	$uid //= $self->current_user->{id};  	my $query = $self->app->get_user_query;  	$query->execute($uid);  	my $rows = $query->fetchall_arrayref; @@ -603,7 +601,7 @@ helper 'get_user_data' => sub {  			deletion_requested => $row[7]  		};  	} -	return; +	return undef;  };  helper 'get_user_password' => sub { @@ -623,80 +621,9 @@ helper 'get_user_password' => sub {  	return;  }; -helper 'get_user_name' => sub { -	my ($self) = @_; - -	my $user = $self->req->headers->header('X-Remote-User') // 'dev'; - -	return $user; -}; - -helper 'get_user_id' => sub { +helper 'add_user' => sub {  	my ( $self, $user_name, $email, $token, $password ) = @_; -	$user_name //= $self->get_user_name; - -	if ( not -e $dbname ) { -		$self->app->dbh->begin_work; -		$self->app->dbh->do( -			qq{ -			create table schema_version ( -				version integer primary key -			); -		} -		); -		$self->app->dbh->do( -			qq{ -			create table users ( -				id integer primary key, -				name char(64) not null unique, -				status int not null, -				public_level bool not null, -				email char(256), -				token char(80), -				password text, -				registered_at datetime not null, -				last_login datetime not null, -				deletion_requested datetime -			) -		} -		); -		$self->app->dbh->do( -			qq{ -			create table stations ( -				id integer primary key, -				ds100 char(16) not null unique, -				name char(64) not null unique -			) -		} -		); -		$self->app->dbh->do( -			qq{ -			create table user_actions ( -				user_id int not null, -				action_id int not null, -				station_id int, -				action_time int not null, -				train_type char(16), -				train_line char(16), -				train_no char(16), -				train_id char(128), -				sched_time int, -				real_time int, -				route text, -				messages text, -				primary key (user_id, action_time) -			) -		} -		); -		$self->app->dbh->do( -			qq{ -			insert into schema_version (version) values (1); -		} -		); -		$self->app->dbh->commit; -	} -  	$self->app->get_userid_query->execute($user_name);  	my $rows = $self->app->get_userid_query->fetchall_arrayref; @@ -737,7 +664,7 @@ helper 'check_if_user_name_exists' => sub {  helper 'get_user_travels' => sub {  	my ( $self, $limit ) = @_; -	my $uid   = $self->get_user_id; +	my $uid   = $self->current_user->{id};  	my $query = $self->app->get_all_actions_query;  	if ($limit) {  		$query = $self->app->get_last_actions_query; @@ -800,7 +727,7 @@ helper 'get_user_travels' => sub {  helper 'get_user_status' => sub {  	my ($self) = @_; -	my $uid = $self->get_user_id; +	my $uid = $self->current_user->{id};  	$self->app->get_last_actions_query->execute($uid);  	my $rows = $self->app->get_last_actions_query->fetchall_arrayref; @@ -886,176 +813,33 @@ helper 'navbar_class' => sub {  get '/' => sub {  	my ($self) = @_; -	$self->render( 'landingpage', with_geolocation => 1 ); -}; - -post '/action' => sub { -	my ($self) = @_; -	my $params = $self->req->json; - -	if ( not exists $params->{action} ) { -		$params = $self->req->params->to_hash; -	} - -	if ( not $params->{action} ) { -		$self->render( -			json => { -				success => 0, -				error   => 'Missing action value', -			}, -			status => 400, -		); -		return; -	} - -	my $station = $params->{station}; - -	if ( $params->{action} eq 'checkin' ) { - -		my ( $train, $error ) -		  = $self->checkin( $params->{station}, $params->{train}, ); - -		if ($error) { -			$self->render( -				json => { -					success => 0, -					error   => $error, -				}, -			); -		} -		else { -			$self->render( -				json => { -					success => 1, -				}, -			); -		} -	} -	elsif ( $params->{action} eq 'checkout' ) { -		my $error = $self->checkout( $params->{station}, $params->{force}, ); - -		if ($error) { -			$self->render( -				json => { -					success => 0, -					error   => $error, -				}, -			); -		} -		else { -			$self->render( -				json => { -					success => 1, -				}, -			); -		} -	} -	elsif ( $params->{action} eq 'undo' ) { -		my $error = $self->undo; -		if ($error) { -			$self->render( -				json => { -					success => 0, -					error   => $error, -				}, -			); -		} -		else { -			$self->render( -				json => { -					success => 1, -				}, -			); -		} +	if ( $self->is_user_authenticated ) { +		$self->render( 'landingpage', with_geolocation => 1 );  	}  	else { -		$self->render( -			json => { -				success => 0, -				error   => 'invalid action value', -			}, -			status => 400, -		); -	} -}; - -get '/a/account' => sub { -	my ($self) = @_; - -	$self->render('account'); -}; - -get '/a/export.json' => sub { -	my ($self) = @_; -	my $uid    = $self->get_user_id; -	my $query  = $self->app->get_all_actions_query; - -	$query->execute($uid); - -	my @entries; - -	while ( my @row = $query->fetchrow_array ) { -		my ( -			$action,       $raw_ts,      $ds100,     $name, -			$train_type,   $train_line,  $train_no,  $train_id, -			$raw_sched_ts, $raw_real_ts, $raw_route, $raw_messages -		) = @row; - -		$name         = decode( 'UTF-8', $name ); -		$raw_route    = decode( 'UTF-8', $raw_route ); -		$raw_messages = decode( 'UTF-8', $raw_messages ); -		push( -			@entries, -			{ -				action        => $action_types[ $action - 1 ], -				action_ts     => $raw_ts, -				station_ds100 => $ds100, -				station_name  => $name, -				train_type    => $train_type, -				train_line    => $train_line, -				train_no      => $train_no, -				train_id      => $train_id, -				scheduled_ts  => $raw_sched_ts, -				realtime_ts   => $raw_real_ts, -				messages      => $raw_messages -				? [ map { [ split(qr{:}) ] } split( qr{[|]}, $raw_messages ) ] -				: undef, -				route => $raw_route ? [ split( qr{[|]}, $raw_route ) ] -				: undef, -			} -		); +		$self->render( 'landingpage', intro => 1 );  	} - -	$self->render( -		json => [@entries], -	);  }; -get '/a/history' => sub { -	my ($self) = @_; - -	$self->render('history'); -}; - -get '/x/about' => sub { +get '/about' => sub {  	my ($self) = @_;  	$self->render( 'about', version => $VERSION );  }; -get '/x/impressum' => sub { +get '/impressum' => sub {  	my ($self) = @_;  	$self->render('imprint');  }; -get '/x/imprint' => sub { +get '/imprint' => sub {  	my ($self) = @_;  	$self->render('imprint');  }; -post '/x/geolocation' => sub { +post '/geolocation' => sub {  	my ($self) = @_;  	my $lon = $self->param('lon'); @@ -1085,12 +869,12 @@ post '/x/geolocation' => sub {  }; -get '/x/login' => sub { +get '/login' => sub {  	my ($self) = @_;  	$self->render('login');  }; -post '/x/login' => sub { +post '/login' => sub {  	my ($self)   = @_;  	my $user     = $self->req->param('user');  	my $password = $self->req->param('password'); @@ -1114,18 +898,12 @@ post '/x/login' => sub {  	}  }; -get '/x/logout' => sub { -	my ($self) = @_; -	$self->logout; -	$self->redirect_to('/x/login'); -}; - -get '/x/register' => sub { +get '/register' => sub {  	my ($self) = @_;  	$self->render('register');  }; -post '/x/register' => sub { +post '/register' => sub {  	my ($self)    = @_;  	my $user      = $self->req->param('user');  	my $email     = $self->req->param('email'); @@ -1163,8 +941,7 @@ post '/x/register' => sub {  		return;  	} -	#if ( $self->check_if_user_name_exists($user) or $user eq 'dev' ) { -	if ( $user ne $self->get_user_name ) { +	if ( $self->check_if_user_name_exists($user) ) {  		$self->render( 'register', invalid => 'user_collision' );  		return;  	} @@ -1181,14 +958,14 @@ post '/x/register' => sub {  	my $token   = make_token();  	my $pw_hash = hash_password($password); -	my $user_id = $self->get_user_id( $user, $email, $token, $pw_hash ); +	my $user_id = $self->add_user( $user, $email, $token, $pw_hash );  	my $body = "Hallo, ${user}!\n\n";  	$body .= "Mit deiner E-Mail-Adresse (${email}) wurde ein Account auf\n";  	$body .= "travelynx.finalrewind.org angelegt.\n\n";  	$body  	  .= "Falls die Registrierung von dir ausging, kannst du den Account unter\n"; -	$body .= "https://travelynx.finalrewind.org/x/reg/${user_id}/${token}\n"; +	$body .= "https://travelynx.finalrewind.org/reg/${user_id}/${token}\n";  	$body .= "freischalten.\n\n";  	$body  	  .= "Falls nicht, ignoriere diese Mail bitte. Nach 48 Stunden wird deine\n"; @@ -1200,7 +977,7 @@ post '/x/register' => sub {  	$body .= " * Datum: ${date}\n";  	$body .= " * Verwendete IP: ${ip}\n";  	$body .= " * Verwendeter Browser gemäß User Agent: ${ua}\n\n\n"; -	$body .= "Impressum: https://travelynx.finalrewind.org/x/impressum\n"; +	$body .= "Impressum: https://travelynx.finalrewind.org/impressum\n";  	my $reg_mail = Email::Simple->create(  		header => [ @@ -1221,7 +998,7 @@ post '/x/register' => sub {  	}  }; -get '/x/reg/:id/:token' => sub { +get '/reg/:id/:token' => sub {  	my ($self) = @_;  	my $id    = $self->stash('id'); @@ -1244,7 +1021,166 @@ get '/x/reg/:id/:token' => sub {  	$self->render( 'login', from => 'verification' );  }; -get '/*station' => sub { +under sub { +	my ($self) = @_; +	return $self->is_user_authenticated; +}; + +post '/action' => sub { +	my ($self) = @_; +	my $params = $self->req->json; + +	if ( not exists $params->{action} ) { +		$params = $self->req->params->to_hash; +	} + +	if ( not $params->{action} ) { +		$self->render( +			json => { +				success => 0, +				error   => 'Missing action value', +			}, +			status => 400, +		); +		return; +	} + +	my $station = $params->{station}; + +	if ( $params->{action} eq 'checkin' ) { + +		my ( $train, $error ) +		  = $self->checkin( $params->{station}, $params->{train}, ); + +		if ($error) { +			$self->render( +				json => { +					success => 0, +					error   => $error, +				}, +			); +		} +		else { +			$self->render( +				json => { +					success => 1, +				}, +			); +		} +	} +	elsif ( $params->{action} eq 'checkout' ) { +		my $error = $self->checkout( $params->{station}, $params->{force}, ); + +		if ($error) { +			$self->render( +				json => { +					success => 0, +					error   => $error, +				}, +			); +		} +		else { +			$self->render( +				json => { +					success => 1, +				}, +			); +		} +	} +	elsif ( $params->{action} eq 'undo' ) { +		my $error = $self->undo; +		if ($error) { +			$self->render( +				json => { +					success => 0, +					error   => $error, +				}, +			); +		} +		else { +			$self->render( +				json => { +					success => 1, +				}, +			); +		} +	} +	else { +		$self->render( +			json => { +				success => 0, +				error   => 'invalid action value', +			}, +			status => 400, +		); +	} +}; + +get '/account' => sub { +	my ($self) = @_; + +	$self->render('account'); +}; + +get '/history' => sub { +	my ($self) = @_; + +	$self->render('history'); +}; + +get '/export.json' => sub { +	my ($self) = @_; +	my $uid    = $self->current_user->{id}; +	my $query  = $self->app->get_all_actions_query; + +	$query->execute($uid); + +	my @entries; + +	while ( my @row = $query->fetchrow_array ) { +		my ( +			$action,       $raw_ts,      $ds100,     $name, +			$train_type,   $train_line,  $train_no,  $train_id, +			$raw_sched_ts, $raw_real_ts, $raw_route, $raw_messages +		) = @row; + +		$name         = decode( 'UTF-8', $name ); +		$raw_route    = decode( 'UTF-8', $raw_route ); +		$raw_messages = decode( 'UTF-8', $raw_messages ); +		push( +			@entries, +			{ +				action        => $action_types[ $action - 1 ], +				action_ts     => $raw_ts, +				station_ds100 => $ds100, +				station_name  => $name, +				train_type    => $train_type, +				train_line    => $train_line, +				train_no      => $train_no, +				train_id      => $train_id, +				scheduled_ts  => $raw_sched_ts, +				realtime_ts   => $raw_real_ts, +				messages      => $raw_messages +				? [ map { [ split(qr{:}) ] } split( qr{[|]}, $raw_messages ) ] +				: undef, +				route => $raw_route ? [ split( qr{[|]}, $raw_route ) ] +				: undef, +			} +		); +	} + +	$self->render( +		json => [@entries], +	); +}; + +post '/logout' => sub { +	my ($self) = @_; +	$self->logout; +	$self->redirect_to('/login'); +}; + +get '/s/*station' => sub {  	my ($self) = @_;  	my $station = $self->stash('station'); diff --git a/public/static/js/geolocation.js b/public/static/js/geolocation.js index 1c881e2..caf2a2a 100644 --- a/public/static/js/geolocation.js +++ b/public/static/js/geolocation.js @@ -25,14 +25,14 @@ $(document).ready(function() {  				stationlink.attr('href', ds100);  				stationlink.text(name); -				resultBody.append('<tr><td><a href="/' + ds100 + '">' + name + '</a></td></tr>'); +				resultBody.append('<tr><td><a href="/s/' + ds100 + '">' + name + '</a></td></tr>');  			});  			placeholder.replaceWith(resultTable);  		}  	};  	var processLocation = function(loc) { -		$.post('/x/geolocation', {lon: loc.coords.longitude, lat: loc.coords.latitude}, processResult); +		$.post('/geolocation', {lon: loc.coords.longitude, lat: loc.coords.latitude}, processResult);  	};  	var processError = function(error) { diff --git a/public/static/js/geolocation.min.js b/public/static/js/geolocation.min.js index 50cd010..1bd2c77 100644 --- a/public/static/js/geolocation.min.js +++ b/public/static/js/geolocation.min.js @@ -1 +1 @@ -$(document).ready(function(){var e=$("p.geolocationhint"),t=$("div.geolocation div.progress"),o=function(o,a,n){e.remove(),t.remove()},a=function(e){e.error?o(0,e.error):0==e.candidates.length?o():(resultTable=$("<table><tbody></tbody></table>"),resultBody=resultTable.children(),$.each(e.candidates,function(e,t){var o=t.ds100,a=t.name,n=t.distance;n=n.toFixed(1);var r=$(document.createElement("a"));r.attr("href",o),r.text(a),resultBody.append('<tr><td><a href="/'+o+'">'+a+"</a></td></tr>")}),t.replaceWith(resultTable))},n=function(e){$.post("/x/geolocation",{lon:e.coords.longitude,lat:e.coords.latitude},a)},r=function(e){e.code==e.PERMISSION_DENIED?o():e.code==e.POSITION_UNAVAILABLE?o():(e.code,e.TIMEOUT,o())};navigator.geolocation?navigator.geolocation.getCurrentPosition(n,r):o()}); +$(document).ready(function(){var a=$("p.geolocationhint"),n=$("div.geolocation div.progress"),t=function(e,t,o){a.remove(),n.remove()},o=function(e){e.error?t(0,e.error):0==e.candidates.length?t():(resultTable=$("<table><tbody></tbody></table>"),resultBody=resultTable.children(),$.each(e.candidates,function(e,t){var o=t.ds100,a=t.name,n=t.distance;n=n.toFixed(1);var r=$(document.createElement("a"));r.attr("href",o),r.text(a),resultBody.append('<tr><td><a href="/s/'+o+'">'+a+"</a></td></tr>")}),n.replaceWith(resultTable))};navigator.geolocation?navigator.geolocation.getCurrentPosition(function(e){$.post("/geolocation",{lon:e.coords.longitude,lat:e.coords.latitude},o)},function(e){e.code==e.PERMISSION_DENIED||e.code==e.POSITION_UNAVAILABLE||(e.code,e.TIMEOUT),t()}):t()}); diff --git a/public/static/js/travelynx-actions.js b/public/static/js/travelynx-actions.js index d758a1a..0a3d092 100644 --- a/public/static/js/travelynx-actions.js +++ b/public/static/js/travelynx-actions.js @@ -34,7 +34,7 @@ $(document).ready(function() {  			station: link.data('station'),  			force: link.data('force'),  		}; -		tvly_run(link, req, '/' + req.station, function() { +		tvly_run(link, req, '/s/' + req.station, function() {  			link.append(' – Ohne Echtzeitdaten auschecken?')  			link.data('force', true);  		}); diff --git a/public/static/js/travelynx-actions.min.js b/public/static/js/travelynx-actions.min.js index 156c458..9c37d8d 100644 --- a/public/static/js/travelynx-actions.min.js +++ b/public/static/js/travelynx-actions.min.js @@ -1 +1 @@ -function tvly_run(n,t,i,a){var c='<i class="material-icons">error</i>',o=$('<div class="progress"><div class="indeterminate"></div></div>');n.hide(),n.after(o),$.post("/action",t,function(t){t.success?$(location).attr("href",i):(M.toast({html:c+" "+t.error}),o.remove(),a&&a(),n.append(" "+c),n.show())})}$(document).ready(function(){$(".action-checkin").click(function(){var t=$(this);tvly_run(t,{action:"checkin",station:t.data("station"),train:t.data("train")},"/")}),$(".action-checkout").click(function(){var t=$(this),n={action:"checkout",station:t.data("station"),force:t.data("force")};tvly_run(t,n,"/"+n.station,function(){t.append(" – Ohne Echtzeitdaten auschecken?"),t.data("force",!0)})}),$(".action-undo").click(function(){tvly_run($(this),{action:"undo"},window.location.href)})}); +function tvly_run(n,t,i,a){var c='<i class="material-icons">error</i>',o=$('<div class="progress"><div class="indeterminate"></div></div>');n.hide(),n.after(o),$.post("/action",t,function(t){t.success?$(location).attr("href",i):(M.toast({html:c+" "+t.error}),o.remove(),a&&a(),n.append(" "+c),n.show())})}$(document).ready(function(){$(".action-checkin").click(function(){var t=$(this);tvly_run(t,{action:"checkin",station:t.data("station"),train:t.data("train")},"/")}),$(".action-checkout").click(function(){var t=$(this),n={action:"checkout",station:t.data("station"),force:t.data("force")};tvly_run(t,n,"/s/"+n.station,function(){t.append(" – Ohne Echtzeitdaten auschecken?"),t.data("force",!0)})}),$(".action-undo").click(function(){tvly_run($(this),{action:"undo"},window.location.href)})}); diff --git a/public/static/v1 b/public/static/v1 new file mode 120000 index 0000000..945c9b4 --- /dev/null +++ b/public/static/v1 @@ -0,0 +1 @@ +.
\ No newline at end of file diff --git a/templates/account.html.ep b/templates/account.html.ep index 9c3a435..c3f24f8 100644 --- a/templates/account.html.ep +++ b/templates/account.html.ep @@ -22,7 +22,7 @@  <div class="row">  	<div class="col s12">  		<ul> -			<li><a href="/a/export.json">Rohdaten</a> (Kein API-Ersatz, das Format kann sich jederzeit ändern)</li> +			<li><a href="/export.json">Rohdaten</a> (Kein API-Ersatz, das Format kann sich jederzeit ändern)</li>  		</ul>  	</div>  </div> diff --git a/templates/landingpage.html.ep b/templates/landingpage.html.ep index 00a67cc..4c6a8f2 100644 --- a/templates/landingpage.html.ep +++ b/templates/landingpage.html.ep @@ -1,72 +1,77 @@ -<div class="row"> -	<div class="col s12"> -		% my $status = $self->get_user_status; -		% if ($status->{checked_in}) { -			<div class="card green darken-4"> -				<div class="card-content white-text"> -					<span class="card-title">Hallo, <%= $self->get_user_name %>!</span> -					<p>Du bist gerade eingecheckt in -						<%= $status->{train_type} %> <%= $status->{train_no} %> -						ab <%= $status->{station_name} %>. -						% if ($status->{timestamp_delta} < 3600) { -							<a class="action-undo"><i class="material-icons">undo</i> Rückgängig</a> -						% } -						</p> -					<p>Auschecken?</p> -					<table> -						<tbody> -							% my $is_after = 0; -							% for my $station (@{$status->{route_after}}) { -								<tr><td><a class="action-checkout" data-station="<%= $station %>"><%= $station %></a></td></tr> +% if (is_user_authenticated()) { +	<div class="row"> +		<div class="col s12"> +			% my $status = get_user_status(); +			% if ($status->{checked_in}) { +				<div class="card green darken-4"> +					<div class="card-content white-text"> +						<span class="card-title">Hallo, <%= current_user()->{name} %>!</span> +						<p>Du bist gerade eingecheckt in +							<%= $status->{train_type} %> <%= $status->{train_no} %> +							ab <%= $status->{station_name} %>. +							% if ($status->{timestamp_delta} < 3600) { +								<a class="action-undo"><i class="material-icons">undo</i> Rückgängig</a>  							% } -						</tbody> -					</table> +							</p> +						<p>Auschecken?</p> +						<table> +							<tbody> +								% my $is_after = 0; +								% for my $station (@{$status->{route_after}}) { +									<tr><td><a class="action-checkout" data-station="<%= $station %>"><%= $station %></a></td></tr> +								% } +							</tbody> +						</table> +					</div>  				</div> -			</div> -		% } -		% else { -			<div class="card grey darken-4"> -				<div class="card-content white-text"> -					<span class="card-title">Hallo, <%= $self->get_user_name %>!</span> -					<p>Du bist gerade nicht eingecheckt.</p> -					<p class="geolocationhint">Stationen in der Umgebung:</p> -					<div class="geolocation"> -						<div class="progress"><div class="indeterminate"></div></div> +			% } +			% else { +				<div class="card grey darken-4"> +					<div class="card-content white-text"> +						<span class="card-title">Hallo, <%= current_user()->{name} %>!</span> +						<p>Du bist gerade nicht eingecheckt.</p> +						<p class="geolocationhint">Stationen in der Umgebung:</p> +						<div class="geolocation"> +							<div class="progress"><div class="indeterminate"></div></div> +						</div>  					</div>  				</div> -			</div> -		% } +			% } +		</div>  	</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(1)) { -				% if ($travel->{completed}) { -					<tr> -						<td><%= $travel->{sched_departure}->strftime('%d.%m.%Y') %></td> -						<td><%= $travel->{type} %> <%= $travel->{line} // $travel->{no} %></td> -						<td><%= $travel->{from_name} %> → <%= $travel->{to_name} %></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> +	<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(1)) { +					% if ($travel->{completed}) { +						<tr> +							<td><%= $travel->{sched_departure}->strftime('%d.%m.%Y') %></td> +							<td><%= $travel->{type} %> <%= $travel->{line} // $travel->{no} %></td> +							<td><%= $travel->{from_name} %> → <%= $travel->{to_name} %></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> +			</tbody> +		</tabel> +	</div> +% } +% else { +Huhu! +% } diff --git a/templates/layouts/default.html.ep b/templates/layouts/default.html.ep index cbe06e3..3fdb075 100644 --- a/templates/layouts/default.html.ep +++ b/templates/layouts/default.html.ep @@ -5,14 +5,15 @@  	<meta charset="utf-8">  	<meta name="viewport" content="width=device-width, initial-scale=1.0">  	<meta name="theme-color" content="#673ab7"> -	%= stylesheet '/static/css/materialize.min.css' -	%= stylesheet '/static/css/material-icons.css' -	%= stylesheet '/static/css/local.css' -	%= javascript '/static/js/jquery-2.2.4.min.js' -	%= javascript '/static/js/materialize.min.js' -	%= javascript '/static/js/travelynx-actions.min.js' +	% my $av = 'v1'; # asset version +	%= stylesheet "/static/${av}/css/materialize.min.css" +	%= stylesheet "/static/${av}/css/material-icons.css" +	%= stylesheet "/static/${av}/css/local.css" +	%= javascript "/static/${av}/js/jquery-2.2.4.min.js" +	%= javascript "/static/${av}/js/materialize.min.js" +	%= javascript "/static/${av}/js/travelynx-actions.min.js"  	% if (stash('with_geolocation')) { -		%= javascript '/static/js/geolocation.min.js' +		%= javascript "/static/${av}/js/geolocation.min.js"  	% }  </head>  <body> @@ -21,9 +22,11 @@  	<div class="nav-wrapper container">  		<a href="/" class="brand-logo left">travelynx</a>  		<ul id="nav-mobile" class="right"> -			<li class="<%= navbar_class('/a/history') %>"><a href='/a/history' title="History"><i class="material-icons">history</i></a></li> -			<li class="<%= navbar_class('/a/account') %>"><a href="/a/account" title="Account"><i class="material-icons">account_circle</i></a></li> -			<li class="<%= navbar_class('/x/about') %>"><a href='/x/about' title="About"><i class="material-icons">info_outline</i></a></li> +			% if (is_user_authenticated()) { +				<li class="<%= navbar_class('/history') %>"><a href='/history' title="History"><i class="material-icons">history</i></a></li> +				<li class="<%= navbar_class('/account') %>"><a href="/account" title="Account"><i class="material-icons">account_circle</i></a></li> +			% } +			<li class="<%= navbar_class('/about') %>"><a href='/about' title="About"><i class="material-icons">info_outline</i></a></li>  		</ul>  	</div>  </nav> diff --git a/templates/login.html.ep b/templates/login.html.ep index 37afacc..f85ba91 100644 --- a/templates/login.html.ep +++ b/templates/login.html.ep @@ -7,7 +7,7 @@  					<p>  						Du bist bereits angemeldet. Falls du mehrere Accounts hast  						und auf einen anderen wechseln möchtest, musst du dich -						vorher <a href="/x/logout">abmelden</a>. +						vorher <a href="/logout">abmelden</a>.  					</p>  				</div>  			</div> @@ -64,7 +64,7 @@  	</div>  % }  <div class="row"> -	%= form_for '/x/login' => (class => 'col s12', method => 'POST') => begin +	%= form_for '/login' => (class => 'col s12', method => 'POST') => begin  		%= csrf_field  		<div class="row">  			<div class="input-field col s12"> diff --git a/templates/register.html.ep b/templates/register.html.ep index a227e6f..d1e189d 100644 --- a/templates/register.html.ep +++ b/templates/register.html.ep @@ -59,7 +59,7 @@  	</div>  % }  <div class="row"> -	%= form_for '/x/register' => (class => 'col s12', method => 'POST') => begin +	%= form_for '/register' => (class => 'col s12', method => 'POST') => begin  		%= csrf_field  		<div class="row">  			<div class="input-field col l6 m12 s12"> @@ -103,7 +103,7 @@  			Die Mail-Adresse wird ausschließlich zur Bestätigung der Anmeldung  			und für die "Passwort vergessen"-Funktionalität verwendet und nicht  			an Dritte weitergegeben.  Die <a -			href="/x/impressum">Datenschutzerklärung</a> beschreibt weitere +			href="/impressum">Datenschutzerklärung</a> beschreibt weitere  			erhobene Daten sowie deren Zweck und Speicherfristen.  			Accounts werden nach einem Jahr ohne Nutzung automatisch gelöscht.  		</p> | 
