Remove references to old tour but include code for new tour.

This commit is contained in:
James Cole 2017-07-15 21:40:42 +02:00
parent accbdea942
commit 8a38ce1964
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
18 changed files with 139 additions and 214 deletions

View File

@ -18,6 +18,7 @@ use FireflyIII\Models\AccountType;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Support\Facades\Preferences;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
@ -25,6 +26,7 @@ use Illuminate\Routing\Controller as BaseController;
use Session;
use URL;
use View;
use Route;
/**
* Class Controller
@ -63,6 +65,12 @@ class Controller extends BaseController
$this->monthAndDayFormat = (string)trans('config.month_and_day');
$this->dateTimeFormat = (string)trans('config.date_time');
// get shown-intro-preference:
$key = 'shown_demo_' . Route::currentRouteName();
$shownDemo = Preferences::get($key, false)->data;
View::share('shownDemo', $shownDemo);
View::share('current_route_name', Route::currentRouteName());
return $next($request);
}
);

View File

@ -21,9 +21,11 @@ use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use Illuminate\Http\Request;
use Illuminate\Routing\Route;
use Illuminate\Support\Collection;
use Log;
use Preferences;
use Route as RouteFacade;
use Session;
use View;
@ -120,7 +122,6 @@ class HomeController extends Controller
$start = session('start', Carbon::now()->startOfMonth());
/** @var Carbon $end */
$end = session('end', Carbon::now()->endOfMonth());
$showTour = Preferences::get('tour', true)->data;
$accounts = $repository->getAccountsById($frontPage->data);
$showDepositsFrontpage = Preferences::get('showDepositsFrontpage', false)->data;
@ -137,10 +138,34 @@ class HomeController extends Controller
}
return view(
'index', compact('count', 'showTour', 'title', 'subTitle', 'mainTitleIcon', 'transactions', 'showDepositsFrontpage', 'billCount')
'index', compact('count', 'title', 'subTitle', 'mainTitleIcon', 'transactions', 'showDepositsFrontpage', 'billCount')
);
}
public function routes()
{
$set = RouteFacade::getRoutes();
$ignore = ['chart.','javascript.','json.','report-data.','popup.','debugbar.'];
/** @var Route $route */
foreach ($set as $route) {
$name = $route->getName();
if (!is_null($name) && in_array('GET', $route->methods()) && strlen($name) > 0) {
$found = false;
foreach ($ignore as $string) {
if (strpos($name, $string) !== false) {
$found = true;
}
}
if (!$found) {
echo 'touch '.$route->getName() . '.md;';
}
}
}
return ' ';
}
/**
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/

View File

@ -237,16 +237,6 @@ class JsonController extends Controller
return Response::json($return);
}
/**
* @return \Illuminate\Http\JsonResponse
*/
public function endTour()
{
Preferences::set('tour', false);
return Response::json('true');
}
/**
* Returns a JSON list of all beneficiaries.
*
@ -293,34 +283,6 @@ class JsonController extends Controller
}
/**
*
*/
public function tour()
{
$pref = Preferences::get('tour', true);
if (!$pref) {
throw new FireflyException('Cannot find preference for tour. Exit.'); // @codeCoverageIgnore
}
$headers = ['main-content', 'sidebar-toggle', 'account-menu', 'budget-menu', 'report-menu', 'transaction-menu', 'option-menu', 'main-content-end'];
$steps = [];
foreach ($headers as $header) {
$steps[] = [
'element' => '#' . $header,
'title' => trans('help.' . $header . '-title'),
'content' => trans('help.' . $header . '-text'),
];
}
$steps[0]['orphan'] = true;// orphan and backdrop for first element.
$steps[0]['backdrop'] = true;
$steps[1]['placement'] = 'left';// sidebar position left:
$steps[7]['orphan'] = true; // final in the center again.
$steps[7]['backdrop'] = true;
$template = view('json.tour')->render();
return Response::json(['steps' => $steps, 'template' => $template]);
}
/**
* @param JournalCollectorInterface $collector
* @param string $what

View File

@ -54,7 +54,6 @@ class NewUserController extends Controller
View::share('title', trans('firefly.welcome'));
View::share('mainTitleIcon', 'fa-fire');
$types = config('firefly.accountTypesByIdentifier.asset');
$count = $repository->count($types);
@ -74,30 +73,13 @@ class NewUserController extends Controller
*/
public function submit(NewUserFormRequest $request, AccountRepositoryInterface $repository)
{
$count = 1;
// create normal asset account:
$this->createAssetAccount($request, $repository);
// create savings account
$savingBalance = strval($request->get('savings_balance')) === '' ? '0' : strval($request->get('savings_balance'));
if (bccomp($savingBalance, '0') !== 0) {
$this->createSavingsAccount($request, $repository);
$count++;
}
$this->createSavingsAccount($request, $repository);
// create credit card.
$limit = strval($request->get('credit_card_limit')) === '' ? '0' : strval($request->get('credit_card_limit'));
if (bccomp($limit, '0') !== 0) {
$this->storeCreditCard($request, $repository);
$count++;
}
$message = strval(trans('firefly.stored_new_accounts_new_user'));
if ($count === 1) {
$message = strval(trans('firefly.stored_new_account_new_user'));
}
Session::flash('success', $message);
Session::flash('success', strval(trans('firefly.stored_new_accounts_new_user')));
Preferences::mark();
return redirect(route('index'));
@ -152,29 +134,4 @@ class NewUserController extends Controller
return true;
}
/**
* @param NewUserFormRequest $request
* @param AccountRepositoryInterface $repository
*
* @return bool
*/
private function storeCreditCard(NewUserFormRequest $request, AccountRepositoryInterface $repository): bool
{
$creditAccount = [
'name' => 'Credit card',
'iban' => null,
'accountType' => 'asset',
'virtualBalance' => round($request->get('credit_card_limit'), 12),
'active' => true,
'accountRole' => 'ccAsset',
'openingBalance' => null,
'openingBalanceDate' => null,
'openingBalanceCurrency' => intval($request->input('amount_currency_id_credit_card_limit')),
'ccType' => 'monthlyFull',
'ccMonthlyPaymentDate' => Carbon::now()->year . '-01-01',
];
$repository->store($creditAccount);
return true;
}
}

View File

@ -311,6 +311,9 @@ class Amount
$coloured = false;
$format = '<span class="text-info">%s</span>';
}
if($transaction->transaction_type_type === TransactionType::OPENING_BALANCE) {
$amount = strval($transaction->transaction_amount);
}
$currency = new TransactionCurrency;
$currency->symbol = $transaction->transaction_currency_symbol;

View File

@ -1,22 +0,0 @@
/* ========================================================================
* bootstrap-tour - v0.10.3
* http://bootstraptour.com
* ========================================================================
* Copyright 2012-2015 Ulrich Sossou
*
* ========================================================================
* Licensed under the MIT License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================================
*/
.tour-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1100;background-color:#000;opacity:.8;filter:alpha(opacity=80)}.tour-step-backdrop{position:relative;z-index:1101}.tour-step-backdrop>td{position:relative;z-index:1101}.tour-step-background{position:absolute!important;z-index:1100;background:inherit;border-radius:6px}.popover[class*=tour-]{z-index:1102}.popover[class*=tour-] .popover-navigation{padding:9px 14px;overflow:hidden}.popover[class*=tour-] .popover-navigation [data-role=end]{float:right}.popover[class*=tour-] .popover-navigation [data-role=prev],.popover[class*=tour-] .popover-navigation [data-role=next],.popover[class*=tour-] .popover-navigation [data-role=end]{cursor:pointer}.popover[class*=tour-] .popover-navigation [data-role=prev].disabled,.popover[class*=tour-] .popover-navigation [data-role=next].disabled,.popover[class*=tour-] .popover-navigation [data-role=end].disabled{cursor:default}.popover[class*=tour-].orphan{position:fixed;margin-top:0}.popover[class*=tour-].orphan .arrow{display:none}

View File

@ -8,36 +8,15 @@
* See the LICENSE file for details.
*/
/** global: Tour, showTour, accountFrontpageUri, token, billCount, accountExpenseUri, accountRevenueUri */
/** global: accountFrontpageUri, token, billCount, accountExpenseUri, accountRevenueUri */
$(function () {
"use strict";
// do chart JS stuff.
drawChart();
if (showTour === true) {
$.getJSON('json/tour').done(function (data) {
var tour = new Tour(
{
steps: data.steps,
template: data.template,
onEnd: endTheTour
});
// Initialize the tour
tour.init();
// Start the tour
tour.start();
});
}
});
function endTheTour() {
"use strict";
$.post('json/end-tour', {_token: token});
}
function drawChart() {
"use strict";
lineChart(accountFrontpageUri, 'accounts-chart');

View File

@ -0,0 +1,14 @@
/*
* intro.js
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
/** global: route_for_tour */
$(function () {
"use strict";
alert('show user intro for ' + route_for_tour);
});

File diff suppressed because one or more lines are too long

49
public/lib/intro/intro.min.js vendored Executable file
View File

@ -0,0 +1,49 @@
(function(C,n){"object"===typeof exports?n(exports):"function"===typeof define&&define.amd?define(["exports"],n):n(C)})(this,function(C){function n(a){this._targetElement=a;this._introItems=[];this._options={nextLabel:"Next &rarr;",prevLabel:"&larr; Back",skipLabel:"Skip",doneLabel:"Done",hidePrev:!1,hideNext:!1,tooltipPosition:"bottom",tooltipClass:"",highlightClass:"",exitOnEsc:!0,exitOnOverlayClick:!0,showStepNumbers:!0,keyboardNavigation:!0,showButtons:!0,showBullets:!0,showProgress:!1,scrollToElement:!0,
overlayOpacity:0.8,scrollPadding:30,positionPrecedence:["bottom","top","right","left"],disableInteraction:!1,hintPosition:"top-middle",hintButtonLabel:"Got it",hintAnimation:!0}}function V(a){var b=[],c=this;if(this._options.steps)for(var d=0,e=this._options.steps.length;d<e;d++){var f=y(this._options.steps[d]);f.step=b.length+1;"string"===typeof f.element&&(f.element=document.querySelector(f.element));if("undefined"===typeof f.element||null==f.element){var g=document.querySelector(".introjsFloatingElement");
null==g&&(g=document.createElement("div"),g.className="introjsFloatingElement",document.body.appendChild(g));f.element=g;f.position="floating"}null!=f.element&&b.push(f)}else{e=a.querySelectorAll("*[data-intro]");if(1>e.length)return!1;d=0;for(f=e.length;d<f;d++)if(g=e[d],"none"!=g.style.display){var k=parseInt(g.getAttribute("data-step"),10);0<k&&(b[k-1]={element:g,intro:g.getAttribute("data-intro"),step:parseInt(g.getAttribute("data-step"),10),tooltipClass:g.getAttribute("data-tooltipClass"),highlightClass:g.getAttribute("data-highlightClass"),
position:g.getAttribute("data-position")||this._options.tooltipPosition})}d=k=0;for(f=e.length;d<f;d++)if(g=e[d],null==g.getAttribute("data-step")){for(;"undefined"!=typeof b[k];)k++;b[k]={element:g,intro:g.getAttribute("data-intro"),step:k+1,tooltipClass:g.getAttribute("data-tooltipClass"),highlightClass:g.getAttribute("data-highlightClass"),position:g.getAttribute("data-position")||this._options.tooltipPosition}}}d=[];for(e=0;e<b.length;e++)b[e]&&d.push(b[e]);b=d;b.sort(function(a,b){return a.step-
b.step});c._introItems=b;W.call(c,a)&&(x.call(c),a.querySelector(".introjs-skipbutton"),a.querySelector(".introjs-nextbutton"),c._onKeyDown=function(b){if(27===b.keyCode&&!0==c._options.exitOnEsc)z.call(c,a);else if(37===b.keyCode)E.call(c);else if(39===b.keyCode)x.call(c);else if(13===b.keyCode){var d=b.target||b.srcElement;d&&0<d.className.indexOf("introjs-prevbutton")?E.call(c):d&&0<d.className.indexOf("introjs-skipbutton")?(c._introItems.length-1==c._currentStep&&"function"===typeof c._introCompleteCallback&&
c._introCompleteCallback.call(c),z.call(c,a)):x.call(c);b.preventDefault?b.preventDefault():b.returnValue=!1}},c._onResize=function(a){t.call(c,document.querySelector(".introjs-helperLayer"));t.call(c,document.querySelector(".introjs-tooltipReferenceLayer"))},window.addEventListener?(this._options.keyboardNavigation&&window.addEventListener("keydown",c._onKeyDown,!0),window.addEventListener("resize",c._onResize,!0)):document.attachEvent&&(this._options.keyboardNavigation&&document.attachEvent("onkeydown",
c._onKeyDown),document.attachEvent("onresize",c._onResize)));return!1}function y(a){if(null==a||"object"!=typeof a||"undefined"!=typeof a.nodeType)return a;var b={},c;for(c in a)b[c]="undefined"!=typeof jQuery&&a[c]instanceof jQuery?a[c]:y(a[c]);return b}function x(){this._direction="forward";if("undefined"!==typeof this._currentStepNumber)for(var a=0,b=this._introItems.length;a<b;a++)this._introItems[a].step===this._currentStepNumber&&(this._currentStep=a-1,this._currentStepNumber=void 0);"undefined"===
typeof this._currentStep?this._currentStep=0:++this._currentStep;this._introItems.length<=this._currentStep?("function"===typeof this._introCompleteCallback&&this._introCompleteCallback.call(this),z.call(this,this._targetElement)):(a=this._introItems[this._currentStep],"undefined"!==typeof this._introBeforeChangeCallback&&this._introBeforeChangeCallback.call(this,a.element),N.call(this,a))}function E(){this._direction="backward";if(0===this._currentStep)return!1;var a=this._introItems[--this._currentStep];
"undefined"!==typeof this._introBeforeChangeCallback&&this._introBeforeChangeCallback.call(this,a.element);N.call(this,a)}function z(a){var b=a.querySelectorAll(".introjs-overlay");if(b&&0<b.length)for(var c=b.length-1;0<=c;c--){var d=b[c];d.style.opacity=0;setTimeout(function(){this.parentNode&&this.parentNode.removeChild(this)}.bind(d),500)}(c=a.querySelector(".introjs-helperLayer"))&&c.parentNode.removeChild(c);(c=a.querySelector(".introjs-tooltipReferenceLayer"))&&c.parentNode.removeChild(c);
(a=a.querySelector(".introjs-disableInteraction"))&&a.parentNode.removeChild(a);(a=document.querySelector(".introjsFloatingElement"))&&a.parentNode.removeChild(a);O();if((a=document.querySelectorAll(".introjs-fixParent"))&&0<a.length)for(c=a.length-1;0<=c;c--)a[c].className=a[c].className.replace(/introjs-fixParent/g,"").replace(/^\s+|\s+$/g,"");window.removeEventListener?window.removeEventListener("keydown",this._onKeyDown,!0):document.detachEvent&&document.detachEvent("onkeydown",this._onKeyDown);
void 0!=this._introExitCallback&&this._introExitCallback.call(self);this._currentStep=void 0}function F(a,b,c,d,e){var f="",g,k;e=e||!1;b.style.top=null;b.style.right=null;b.style.bottom=null;b.style.left=null;b.style.marginLeft=null;b.style.marginTop=null;c.style.display="inherit";"undefined"!=typeof d&&null!=d&&(d.style.top=null,d.style.left=null);if(this._introItems[this._currentStep]){f=this._introItems[this._currentStep];f="string"===typeof f.tooltipClass?f.tooltipClass:this._options.tooltipClass;
b.className=("introjs-tooltip "+f).replace(/^\s+|\s+$/g,"");k=this._introItems[this._currentStep].position;if(("auto"==k||"auto"==this._options.tooltipPosition)&&"floating"!=k){f=k;g=this._options.positionPrecedence.slice();k=G();var w=u(b).height+10,m=u(b).width+20,h=u(a),l="floating";h.left+m>k.width||0>h.left+h.width/2-m?(s(g,"bottom"),s(g,"top")):(h.height+h.top+w>k.height&&s(g,"bottom"),0>h.top-w&&s(g,"top"));h.width+h.left+m>k.width&&s(g,"right");0>h.left-m&&s(g,"left");0<g.length&&(l=g[0]);
f&&"auto"!=f&&-1<g.indexOf(f)&&(l=f);k=l}f=u(a);a=u(b);g=G();switch(k){case "top":c.className="introjs-arrow bottom";H(f,e?0:15,a,g,b);b.style.bottom=f.height+20+"px";break;case "right":b.style.left=f.width+20+"px";f.top+a.height>g.height?(c.className="introjs-arrow left-bottom",b.style.top="-"+(a.height-f.height-20)+"px"):c.className="introjs-arrow left";break;case "left":e||!0!=this._options.showStepNumbers||(b.style.top="15px");f.top+a.height>g.height?(b.style.top="-"+(a.height-f.height-20)+"px",
c.className="introjs-arrow right-bottom"):c.className="introjs-arrow right";b.style.right=f.width+20+"px";break;case "floating":c.style.display="none";b.style.left="50%";b.style.top="50%";b.style.marginLeft="-"+a.width/2+"px";b.style.marginTop="-"+a.height/2+"px";"undefined"!=typeof d&&null!=d&&(d.style.left="-"+(a.width/2+18)+"px",d.style.top="-"+(a.height/2+18)+"px");break;case "bottom-right-aligned":c.className="introjs-arrow top-right";P(f,0,a,b);b.style.top=f.height+20+"px";break;case "bottom-middle-aligned":c.className=
"introjs-arrow top-middle";c=f.width/2-a.width/2;e&&(c+=5);P(f,c,a,b)&&(b.style.right=null,H(f,c,a,g,b));b.style.top=f.height+20+"px";break;default:c.className="introjs-arrow top",H(f,0,a,g,b),b.style.top=f.height+20+"px"}}}function H(a,b,c,d,e){if(a.left+b+c.width>d.width)return e.style.left=d.width-c.width-a.left+"px",!1;e.style.left=b+"px";return!0}function P(a,b,c,d){if(0>a.left+a.width-b-c.width)return d.style.left=-a.left+"px",!1;d.style.right=b+"px";return!0}function s(a,b){-1<a.indexOf(b)&&
a.splice(a.indexOf(b),1)}function t(a){if(a&&this._introItems[this._currentStep]){var b=this._introItems[this._currentStep],c=u(b.element),d=10;I(b.element)?a.className+=" introjs-fixedTooltip":a.className=a.className.replace(" introjs-fixedTooltip","");"floating"==b.position&&(d=0);a.setAttribute("style","width: "+(c.width+d)+"px; height:"+(c.height+d)+"px; top:"+(c.top-5)+"px;left: "+(c.left-5)+"px;")}}function X(){var a=document.querySelector(".introjs-disableInteraction");null===a&&(a=document.createElement("div"),
a.className="introjs-disableInteraction",this._targetElement.appendChild(a));t.call(this,a)}function D(a){a.setAttribute("role","button");a.tabIndex=0}function N(a){"undefined"!==typeof this._introChangeCallback&&this._introChangeCallback.call(this,a.element);var b=this,c=document.querySelector(".introjs-helperLayer"),d=document.querySelector(".introjs-tooltipReferenceLayer"),e="introjs-helperLayer";u(a.element);"string"===typeof a.highlightClass&&(e+=" "+a.highlightClass);"string"===typeof this._options.highlightClass&&
(e+=" "+this._options.highlightClass);if(null!=c){var f=d.querySelector(".introjs-helperNumberLayer"),g=d.querySelector(".introjs-tooltiptext"),k=d.querySelector(".introjs-arrow"),w=d.querySelector(".introjs-tooltip"),m=d.querySelector(".introjs-skipbutton"),h=d.querySelector(".introjs-prevbutton"),l=d.querySelector(".introjs-nextbutton");c.className=e;w.style.opacity=0;w.style.display="none";if(null!=f){var p=this._introItems[0<=a.step-2?a.step-2:0];if(null!=p&&"forward"==this._direction&&"floating"==
p.position||"backward"==this._direction&&"floating"==a.position)f.style.opacity=0}t.call(b,c);t.call(b,d);if((p=document.querySelectorAll(".introjs-fixParent"))&&0<p.length)for(e=p.length-1;0<=e;e--)p[e].className=p[e].className.replace(/introjs-fixParent/g,"").replace(/^\s+|\s+$/g,"");O();b._lastShowElementTimer&&clearTimeout(b._lastShowElementTimer);b._lastShowElementTimer=setTimeout(function(){null!=f&&(f.innerHTML=a.step);g.innerHTML=a.intro;w.style.display="block";F.call(b,a.element,w,k,f);b._options.showBullets&&
(d.querySelector(".introjs-bullets li > a.active").className="",d.querySelector('.introjs-bullets li > a[data-stepnumber="'+a.step+'"]').className="active");d.querySelector(".introjs-progress .introjs-progressbar").setAttribute("style","width:"+Q.call(b)+"%;");w.style.opacity=1;f&&(f.style.opacity=1);-1===l.tabIndex?m.focus():l.focus()},350)}else{var n=document.createElement("div"),h=document.createElement("div"),c=document.createElement("div"),q=document.createElement("div"),r=document.createElement("div"),
s=document.createElement("div"),v=document.createElement("div"),A=document.createElement("div");n.className=e;h.className="introjs-tooltipReferenceLayer";t.call(b,n);t.call(b,h);this._targetElement.appendChild(n);this._targetElement.appendChild(h);c.className="introjs-arrow";r.className="introjs-tooltiptext";r.innerHTML=a.intro;s.className="introjs-bullets";!1===this._options.showBullets&&(s.style.display="none");for(var n=document.createElement("ul"),e=0,C=this._introItems.length;e<C;e++){var y=
document.createElement("li"),B=document.createElement("a");B.onclick=function(){b.goToStep(this.getAttribute("data-stepnumber"))};e===a.step-1&&(B.className="active");D(B);B.innerHTML="&nbsp;";B.setAttribute("data-stepnumber",this._introItems[e].step);y.appendChild(B);n.appendChild(y)}s.appendChild(n);v.className="introjs-progress";!1===this._options.showProgress&&(v.style.display="none");e=document.createElement("div");e.className="introjs-progressbar";e.setAttribute("style","width:"+Q.call(this)+
"%;");v.appendChild(e);A.className="introjs-tooltipbuttons";!1===this._options.showButtons&&(A.style.display="none");q.className="introjs-tooltip";q.appendChild(r);q.appendChild(s);q.appendChild(v);!0==this._options.showStepNumbers&&(p=document.createElement("span"),p.className="introjs-helperNumberLayer",p.innerHTML=a.step,h.appendChild(p));q.appendChild(c);h.appendChild(q);l=document.createElement("a");l.onclick=function(){b._introItems.length-1!=b._currentStep&&x.call(b)};D(l);l.innerHTML=this._options.nextLabel;
h=document.createElement("a");h.onclick=function(){0!=b._currentStep&&E.call(b)};D(h);h.innerHTML=this._options.prevLabel;m=document.createElement("a");m.className="introjs-button introjs-skipbutton";D(m);m.innerHTML=this._options.skipLabel;m.onclick=function(){b._introItems.length-1==b._currentStep&&"function"===typeof b._introCompleteCallback&&b._introCompleteCallback.call(b);z.call(b,b._targetElement)};A.appendChild(m);1<this._introItems.length&&(A.appendChild(h),A.appendChild(l));q.appendChild(A);
F.call(b,a.element,q,c,p)}!0===this._options.disableInteraction&&X.call(b);h.removeAttribute("tabIndex");l.removeAttribute("tabIndex");0==this._currentStep&&1<this._introItems.length?(m.className="introjs-button introjs-skipbutton",l.className="introjs-button introjs-nextbutton",!0==this._options.hidePrev?(h.className="introjs-button introjs-prevbutton introjs-hidden",l.className+=" introjs-fullbutton"):h.className="introjs-button introjs-prevbutton introjs-disabled",h.tabIndex="-1",m.innerHTML=this._options.skipLabel):
this._introItems.length-1==this._currentStep||1==this._introItems.length?(m.innerHTML=this._options.doneLabel,m.className+=" introjs-donebutton",h.className="introjs-button introjs-prevbutton",!0==this._options.hideNext?(l.className="introjs-button introjs-nextbutton introjs-hidden",h.className+=" introjs-fullbutton"):l.className="introjs-button introjs-nextbutton introjs-disabled",l.tabIndex="-1"):(m.className="introjs-button introjs-skipbutton",h.className="introjs-button introjs-prevbutton",l.className=
"introjs-button introjs-nextbutton",m.innerHTML=this._options.skipLabel);l.focus();Y(a);Z(a.element)||!0!==this._options.scrollToElement||(q=a.element.getBoundingClientRect(),p=G().height,c=q.bottom-(q.bottom-q.top),q=q.bottom-p,0>c||a.element.clientHeight>p?window.scrollBy(0,c-this._options.scrollPadding):window.scrollBy(0,q+70+this._options.scrollPadding));"undefined"!==typeof this._introAfterChangeCallback&&this._introAfterChangeCallback.call(this,a.element)}function O(){for(var a=document.querySelectorAll(".introjs-showElement"),
b=0,c=a.length;b<c;b++){var d=a[b],e=/introjs-[a-zA-Z]+/g;if(d instanceof SVGElement){var f=d.getAttribute("class")||"";d.setAttribute("class",f.replace(e,"").replace(/^\s+|\s+$/g,""))}else d.className=d.className.replace(e,"").replace(/^\s+|\s+$/g,"")}}function Y(a){if(a.element instanceof SVGElement)for(var b=a.element.parentNode;null!=a.element.parentNode&&b.tagName&&"body"!==b.tagName.toLowerCase();)"svg"===b.tagName.toLowerCase()&&J(b,"introjs-showElement introjs-relativePosition"),b=b.parentNode;
J(a.element,"introjs-showElement");b=r(a.element,"position");"absolute"!==b&&("relative"!==b&&"fixed"!==b)&&J(a.element,"introjs-relativePosition");for(b=a.element.parentNode;null!=b&&b.tagName&&"body"!==b.tagName.toLowerCase();){a=r(b,"z-index");var c=parseFloat(r(b,"opacity")),d=r(b,"transform")||r(b,"-webkit-transform")||r(b,"-moz-transform")||r(b,"-ms-transform")||r(b,"-o-transform");if(/[0-9]+/.test(a)||1>c||"none"!==d&&void 0!==d)b.className+=" introjs-fixParent";b=b.parentNode}}function J(a,
b){if(a instanceof SVGElement){var c=a.getAttribute("class")||"";a.setAttribute("class",c+" "+b)}else a.className+=" "+b}function r(a,b){var c="";a.currentStyle?c=a.currentStyle[b]:document.defaultView&&document.defaultView.getComputedStyle&&(c=document.defaultView.getComputedStyle(a,null).getPropertyValue(b));return c&&c.toLowerCase?c.toLowerCase():c}function I(a){var b=a.parentNode;return b&&"HTML"!==b.nodeName?"fixed"==r(a,"position")?!0:I(b):!1}function G(){if(void 0!=window.innerWidth)return{width:window.innerWidth,
height:window.innerHeight};var a=document.documentElement;return{width:a.clientWidth,height:a.clientHeight}}function Z(a){a=a.getBoundingClientRect();return 0<=a.top&&0<=a.left&&a.bottom+80<=window.innerHeight&&a.right<=window.innerWidth}function W(a){var b=document.createElement("div"),c="",d=this;b.className="introjs-overlay";if(a.tagName&&"body"!==a.tagName.toLowerCase()){var e=u(a);e&&(c+="width: "+e.width+"px; height:"+e.height+"px; top:"+e.top+"px;left: "+e.left+"px;",b.setAttribute("style",
c))}else c+="top: 0;bottom: 0; left: 0;right: 0;position: fixed;",b.setAttribute("style",c);a.appendChild(b);b.onclick=function(){!0==d._options.exitOnOverlayClick&&z.call(d,a)};setTimeout(function(){c+="opacity: "+d._options.overlayOpacity.toString()+";";b.setAttribute("style",c)},10);return!0}function v(){var a=this._targetElement.querySelector(".introjs-hintReference");if(a){var b=a.getAttribute("data-step");a.parentNode.removeChild(a);return b}}function R(a){this._introItems=[];if(this._options.hints){a=
0;for(var b=this._options.hints.length;a<b;a++){var c=y(this._options.hints[a]);"string"===typeof c.element&&(c.element=document.querySelector(c.element));c.hintPosition=c.hintPosition||this._options.hintPosition;c.hintAnimation=c.hintAnimation||this._options.hintAnimation;null!=c.element&&this._introItems.push(c)}}else{c=a.querySelectorAll("*[data-hint]");if(1>c.length)return!1;a=0;for(b=c.length;a<b;a++){var d=c[a],e=d.getAttribute("data-hintAnimation"),e=e?"true"==e:this._options.hintAnimation;
this._introItems.push({element:d,hint:d.getAttribute("data-hint"),hintPosition:d.getAttribute("data-hintPosition")||this._options.hintPosition,hintAnimation:e,tooltipClass:d.getAttribute("data-tooltipClass"),position:d.getAttribute("data-position")||this._options.tooltipPosition})}}$.call(this);document.addEventListener?(document.addEventListener("click",v.bind(this),!1),window.addEventListener("resize",K.bind(this),!0)):document.attachEvent&&(document.attachEvent("onclick",v.bind(this)),document.attachEvent("onresize",
K.bind(this)))}function K(){for(var a=0,b=this._introItems.length;a<b;a++){var c=this._introItems[a];"undefined"!=typeof c.targetElement&&S.call(this,c.hintPosition,c.element,c.targetElement)}}function L(a){v.call(this);var b=this._targetElement.querySelector('.introjs-hint[data-step="'+a+'"]');b&&(b.className+=" introjs-hidehint");"undefined"!==typeof this._hintCloseCallback&&this._hintCloseCallback.call(this,a)}function T(a){if(a=this._targetElement.querySelector('.introjs-hint[data-step="'+a+'"]'))a.className=
a.className.replace(/introjs\-hidehint/g,"")}function U(a){(a=this._targetElement.querySelector('.introjs-hint[data-step="'+a+'"]'))&&a.parentNode.removeChild(a)}function $(){var a=this,b=document.querySelector(".introjs-hints");null==b&&(b=document.createElement("div"),b.className="introjs-hints");for(var c=0,d=this._introItems.length;c<d;c++){var e=this._introItems[c];if(!document.querySelector('.introjs-hint[data-step="'+c+'"]')){var f=document.createElement("a");D(f);(function(b,c,d){b.onclick=
function(e){e=e?e:window.event;e.stopPropagation&&e.stopPropagation();null!=e.cancelBubble&&(e.cancelBubble=!0);aa.call(a,b,c,d)}})(f,e,c);f.className="introjs-hint";e.hintAnimation||(f.className+=" introjs-hint-no-anim");I(e.element)&&(f.className+=" introjs-fixedhint");var g=document.createElement("div");g.className="introjs-hint-dot";var k=document.createElement("div");k.className="introjs-hint-pulse";f.appendChild(g);f.appendChild(k);f.setAttribute("data-step",c);e.targetElement=e.element;e.element=
f;S.call(this,e.hintPosition,f,e.targetElement);b.appendChild(f)}}document.body.appendChild(b);"undefined"!==typeof this._hintsAddedCallback&&this._hintsAddedCallback.call(this)}function S(a,b,c){c=u.call(this,c);switch(a){default:case "top-left":b.style.left=c.left+"px";b.style.top=c.top+"px";break;case "top-right":b.style.left=c.left+c.width-20+"px";b.style.top=c.top+"px";break;case "bottom-left":b.style.left=c.left+"px";b.style.top=c.top+c.height-20+"px";break;case "bottom-right":b.style.left=
c.left+c.width-20+"px";b.style.top=c.top+c.height-20+"px";break;case "middle-left":b.style.left=c.left+"px";b.style.top=c.top+(c.height-20)/2+"px";break;case "middle-right":b.style.left=c.left+c.width-20+"px";b.style.top=c.top+(c.height-20)/2+"px";break;case "middle-middle":b.style.left=c.left+(c.width-20)/2+"px";b.style.top=c.top+(c.height-20)/2+"px";break;case "bottom-middle":b.style.left=c.left+(c.width-20)/2+"px";b.style.top=c.top+c.height-20+"px";break;case "top-middle":b.style.left=c.left+(c.width-
20)/2+"px",b.style.top=c.top+"px"}}function aa(a,b,c){"undefined"!==typeof this._hintClickCallback&&this._hintClickCallback.call(this,a,b,c);var d=v.call(this);if(parseInt(d,10)!=c){var d=document.createElement("div"),e=document.createElement("div"),f=document.createElement("div"),g=document.createElement("div");d.className="introjs-tooltip";d.onclick=function(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0};e.className="introjs-tooltiptext";var k=document.createElement("p");k.innerHTML=
b.hint;b=document.createElement("a");b.className="introjs-button";b.innerHTML=this._options.hintButtonLabel;b.onclick=L.bind(this,c);e.appendChild(k);e.appendChild(b);f.className="introjs-arrow";d.appendChild(f);d.appendChild(e);this._currentStep=a.getAttribute("data-step");g.className="introjs-tooltipReferenceLayer introjs-hintReference";g.setAttribute("data-step",a.getAttribute("data-step"));t.call(this,g);g.appendChild(d);document.body.appendChild(g);F.call(this,a,d,f,null,!0)}}function u(a){var b=
{},c=document.body,d=document.documentElement,e=window.pageYOffset||d.scrollTop||c.scrollTop,c=window.pageXOffset||d.scrollLeft||c.scrollLeft;if(a instanceof SVGElement)a=a.getBoundingClientRect(),b.top=a.top+e,b.width=a.width,b.height=a.height,b.left=a.left+c;else{b.width=a.offsetWidth;b.height=a.offsetHeight;for(c=e=0;a&&!isNaN(a.offsetLeft)&&!isNaN(a.offsetTop);)e+=a.offsetLeft,c+=a.offsetTop,a=a.offsetParent;b.top=c;b.left=e}return b}function Q(){return 100*(parseInt(this._currentStep+1,10)/this._introItems.length)}
var M=function(a){if("object"===typeof a)return new n(a);if("string"===typeof a){if(a=document.querySelector(a))return new n(a);throw Error("There is no element with given selector.");}return new n(document.body)};M.version="2.5.0";M.fn=n.prototype={clone:function(){return new n(this)},setOption:function(a,b){this._options[a]=b;return this},setOptions:function(a){var b=this._options,c={},d;for(d in b)c[d]=b[d];for(d in a)c[d]=a[d];this._options=c;return this},start:function(){V.call(this,this._targetElement);
return this},goToStep:function(a){this._currentStep=a-2;"undefined"!==typeof this._introItems&&x.call(this);return this},addStep:function(a){this._options.steps||(this._options.steps=[]);this._options.steps.push(a);return this},addSteps:function(a){if(a.length){for(var b=0;b<a.length;b++)this.addStep(a[b]);return this}},goToStepNumber:function(a){this._currentStepNumber=a;"undefined"!==typeof this._introItems&&x.call(this);return this},nextStep:function(){x.call(this);return this},previousStep:function(){E.call(this);
return this},exit:function(){z.call(this,this._targetElement);return this},refresh:function(){t.call(this,document.querySelector(".introjs-helperLayer"));t.call(this,document.querySelector(".introjs-tooltipReferenceLayer"));K.call(this);return this},onbeforechange:function(a){if("function"===typeof a)this._introBeforeChangeCallback=a;else throw Error("Provided callback for onbeforechange was not a function");return this},onchange:function(a){if("function"===typeof a)this._introChangeCallback=a;else throw Error("Provided callback for onchange was not a function.");
return this},onafterchange:function(a){if("function"===typeof a)this._introAfterChangeCallback=a;else throw Error("Provided callback for onafterchange was not a function");return this},oncomplete:function(a){if("function"===typeof a)this._introCompleteCallback=a;else throw Error("Provided callback for oncomplete was not a function.");return this},onhintsadded:function(a){if("function"===typeof a)this._hintsAddedCallback=a;else throw Error("Provided callback for onhintsadded was not a function.");
return this},onhintclick:function(a){if("function"===typeof a)this._hintClickCallback=a;else throw Error("Provided callback for onhintclick was not a function.");return this},onhintclose:function(a){if("function"===typeof a)this._hintCloseCallback=a;else throw Error("Provided callback for onhintclose was not a function.");return this},onexit:function(a){if("function"===typeof a)this._introExitCallback=a;else throw Error("Provided callback for onexit was not a function.");return this},addHints:function(){R.call(this,
this._targetElement);return this},hideHint:function(a){L.call(this,a);return this},hideHints:function(){var a=this._targetElement.querySelectorAll(".introjs-hint");if(a&&0<a.length)for(var b=0;b<a.length;b++)L.call(this,a[b].getAttribute("data-step"));return this},showHint:function(a){T.call(this,a);return this},showHints:function(){var a=this._targetElement.querySelectorAll(".introjs-hint");if(a&&0<a.length)for(var b=0;b<a.length;b++)T.call(this,a[b].getAttribute("data-step"));else R.call(this,this._targetElement);
return this},removeHints:function(){var a=this._targetElement.querySelectorAll(".introjs-hint");if(a&&0<a.length)for(var b=0;b<a.length;b++)U.call(this,a[b].getAttribute("data-step"));return this},removeHint:function(a){U.call(this,a);return this}};return C.introJs=M});

1
public/lib/intro/introjs-rtl.min.css vendored Executable file
View File

@ -0,0 +1 @@
.introjs-tooltipbuttons{text-align:left}.introjs-skipbutton{margin-left:5px}.introjs-tooltip{direction:rtl}.introjs-prevbutton{border:1px solid #d4d4d4;border-left:none;-webkit-border-radius:0 .2em .2em 0;-moz-border-radius:0 .2em .2em 0;border-radius:0 .2em .2em 0}.introjs-nextbutton{border:1px solid #d4d4d4;-webkit-border-radius:.2em 0 0 .2em;-moz-border-radius:.2em 0 0 .2em;border-radius:.2em 0 0 .2em}

1
public/lib/intro/introjs.min.css vendored Executable file

File diff suppressed because one or more lines are too long

View File

@ -427,12 +427,6 @@ return [
'attachment_updated' => 'Updated attachment ":name"',
'upload_max_file_size' => 'Maximum file size: :size',
// tour:
'prev' => 'Prev',
'next' => 'Next',
'end-tour' => 'End tour',
'pause' => 'Pause',
// transaction index
'title_expenses' => 'Expenses',
'title_withdrawal' => 'Expenses',
@ -500,15 +494,6 @@ return [
'make_default_currency' => 'make default',
'default_currency' => 'default',
// new user:
'submit' => 'Submit',
'getting_started' => 'Getting started',
'to_get_started' => 'To get started with Firefly, please enter your current bank\'s name, and the balance of your checking account:',
'savings_balance_text' => 'If you have a savings account, please enter the current balance of your savings account:',
'cc_balance_text' => 'If you have a credit card, please enter your credit card\'s limit.',
'stored_new_account_new_user' => 'Yay! Your new account has been stored.',
'stored_new_accounts_new_user' => 'Yay! Your new accounts have been stored.',
// forms:
'mandatoryFields' => 'Mandatory fields',
'optionalFields' => 'Optional fields',
@ -644,6 +629,12 @@ return [
// new user:
'welcome' => 'Welcome to Firefly!',
'submit' => 'Submit',
'getting_started' => 'Getting started',
'to_get_started' => 'It is good to see you have successfully installed Firefly III. To get started with this tool please enter your bank\'s name and the balance of your main checking account. Do not worry yet if you have multiple accounts. You can add those later. It\'s just that Firefly III needs something to start with.',
'savings_balance_text' => 'Firefly III will automatically create a savings account for you. By default, there will be no money in your savings account, but if you tell Firefly III the balance it will be stored as such.',
'finish_up_new_user' => 'That\'s it! You can continue by pressing <strong>Submit</strong>. You will be taken to the index of Firefly III.',
'stored_new_accounts_new_user' => 'Yay! Your new accounts have been stored.',
// home page:
'yourAccounts' => 'Your accounts',

View File

@ -4,10 +4,6 @@
{{ Breadcrumbs.renderIfExists }}
{% endblock %}
{% block content %}
{% include 'partials.boxes' %}
<div class="row">
@ -31,7 +27,7 @@
<canvas id="budgets-chart" style="width:100%;height:400px;" height="400" width="100%"></canvas>
</div>
</div>
<!-- CATEGORIES -->
{# CATEGORIES #}
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ 'categories'|_ }}</h3>
@ -44,7 +40,7 @@
</div>
<div class="col-lg-4 col-md-6 col-sm-12">
{% if billCount > 0 %}
<!-- BILLS -->
{# BILLS #}
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ 'bills'|_ }}</h3>
@ -59,13 +55,12 @@
</div>
{% endif %}
<!-- TRANSACTIONS -->
{# TRANSACTIONS #}
{% for data in transactions %}
<div class="box">
<div class="box-header with-border">
<h3 class="box-title"><a href="{{ route('accounts.show', data[1].id) }}">{{ data[1].name }}</a></h3>
<!-- ACTIONS MENU -->
<div class="box-tools pull-right">
<div class="btn-group">
<button class="btn btn-box-tool dropdown-toggle" data-toggle="dropdown"><i class="fa fa-ellipsis-v"></i></button>
@ -107,7 +102,7 @@
</div>
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12">
<!-- EXPENSE ACCOUNTS -->
{# EXPENSE ACCOUNTS #}
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ 'expense_accounts'|_ }}</h3>
@ -117,7 +112,7 @@
<canvas id="expense-accounts-chart" style="width:100%;height:400px;" height="400" width="100%"></canvas>
</div>
</div>
<!-- OPTIONAL REVENUE ACCOUNTS -->
{# OPTIONAL REVENUE ACCOUNTS #}
{% if showDepositsFrontpage %}
<div class="box">
<div class="box-header with-border">
@ -134,14 +129,7 @@
{% endblock %}
{% block scripts %}
<!-- show tour? -->
<script type="text/javascript">
var showTour;
{% if showTour %}
showTour = true;
{% else %}
showTour = false;
{% endif %}
var billCount = {{ billCount }};
// uri's of charts:

View File

@ -1,15 +0,0 @@
<div class="popover" role="tooltip">
<div class="arrow"></div>
<h3 class="popover-title"></h3>
<div class="popover-content"></div>
<div class="popover-navigation">
<div class="btn-group">
<button class="btn btn-sm btn-default" data-role="prev">&laquo; {{ 'prev'|_ }}</button>
<button class="btn btn-sm btn-default" data-role="next">{{ 'next'|_ }} &raquo;</button>
<button class="btn btn-sm btn-default" data-role="pause-resume" data-pause-text="{{ 'pause'|_ }}"
data-resume-text="Resume"> {{ 'pause'|_ }}</button>
</div>
<button class="btn btn-sm btn-default" data-role="end">{{ 'end-tour'|_ }}</button>
</div>
</div>

View File

@ -24,7 +24,9 @@
<link href="lib/adminlte/css/skins/skin-blue-light.min.css" rel="stylesheet" type="text/css"/>
<link href="css/daterangepicker.css" rel="stylesheet" type="text/css"/>
<link href="css/firefly.css" rel="stylesheet" type="text/css"/>
<link href="css/bootstrap-tour.min.css" rel="stylesheet" type="text/css"/>
{% if not shownDemo %}
<link href="lib/intro/introjs.min.css" rel="stylesheet" type="text/css"/>
{% endif %}
{% block styles %}{% endblock %}
<!--[if lt IE 9]>
@ -60,8 +62,8 @@
<ul class="nav navbar-nav">
<li class="hidden-sm hidden-xs">
<a href="#" id="help" data-route="{{ Route.getCurrentRoute.getName }}">
<i class="fa fa-question-circle" data-route="{{ Route.getCurrentRoute.getName }}"></i>
<a href="#" id="help" data-route="{{ current_route_name }}">
<i class="fa fa-question-circle" data-route="{{ current_route_name }}"></i>
</a>
</li>
@ -176,10 +178,16 @@
<script src="js/lib/daterangepicker.js" type="text/javascript"></script>
<script src="lib/adminlte/js/app.min.js" type="text/javascript"></script>
<script type="text/javascript" src="js/lib/accounting.min.js"></script>
<script src="js/lib/bootstrap-tour.min.js" type="text/javascript"></script>
<script src="{{ route('javascript.variables') }}?ext=.js" type="text/javascript"></script>
<script type="text/javascript" src="js/ff/firefly.js"></script>
<script type="text/javascript" src="js/ff/help.js"></script>
{% if not shownDemo %}
<script type="text/javascript">
var route_for_tour = "{{ current_route_name }}";
</script>
<script type="text/javascript" src="lib/intro/intro.min.js"></script>
<script type="text/javascript" src="js/ff/intro/intro.js"></script>
{% endif %}
{% block scripts %}{% endblock %}
{% if env('ANALYTICS_ID','') != '' %}
@ -188,10 +196,10 @@
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)

View File

@ -10,13 +10,16 @@
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
<div class="row">
<div class="col-lg-6 col-sm-8 col-xs-12">
<div class="col-lg-6 col-lg-offset-3 col-md-12 col-xs-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'getting_started'|_ }}</h3>
</div>
<div class="box-body">
<p>
<strong>{{ 'welcome'|_ }}</strong>
</p>
<p>
{{ 'to_get_started'|_ }}
</p>
@ -28,15 +31,12 @@
{{ 'savings_balance_text'|_ }}
</p>
{{ ExpandedForm.balance('savings_balance') }}
{{ ExpandedForm.balance('savings_balance',0) }}
<p>
{{ 'cc_balance_text'|_ }}
{{ 'finish_up_new_user'|_ }}
</p>
{{ ExpandedForm.balance('credit_card_limit') }}
</div>
<div class="box-footer">
<input type="submit" name="submit" value="{{ 'submit'|_ }}" class="btn btn-success pull-right"/>

View File

@ -44,6 +44,7 @@ Route::group(
Route::get('error', ['uses' => 'HomeController@displayError', 'as' => 'error']);
Route::any('logout', ['uses' => 'Auth\LoginController@logout', 'as' => 'logout']);
Route::get('flush', ['uses' => 'HomeController@flush', 'as' => 'flush']);
Route::get('routes', ['uses' => 'HomeController@routes', 'as' => 'routes']);
}
);
@ -435,7 +436,6 @@ Route::group(
Route::get('categories', ['uses' => 'JsonController@categories', 'as' => 'categories']);
Route::get('budgets', ['uses' => 'JsonController@budgets', 'as' => 'budgets']);
Route::get('tags', ['uses' => 'JsonController@tags', 'as' => 'tags']);
Route::get('tour', ['uses' => 'JsonController@tour', 'as' => 'tour']);
Route::get('box/in', ['uses' => 'JsonController@boxIn', 'as' => 'box.in']);
Route::get('box/out', ['uses' => 'JsonController@boxOut', 'as' => 'box.out']);
Route::get('box/bills-unpaid', ['uses' => 'JsonController@boxBillsUnpaid', 'as' => 'box.unpaid']);
@ -446,8 +446,6 @@ Route::group(
Route::get('trigger', ['uses' => 'JsonController@trigger', 'as' => 'trigger']);
Route::get('action', ['uses' => 'JsonController@action', 'as' => 'action']);
Route::post('end-tour', ['uses' => 'JsonController@endTour', 'as' => 'end-tour']);
// currency conversion:
Route::get('rate/{fromCurrencyCode}/{toCurrencyCode}/{date}', ['uses' => 'Json\ExchangeController@getRate', 'as' => 'rate']);