Browse Source

Add new views.

pull/581/head
James Cole 1 year ago
parent
commit
5008c4a020
No known key found for this signature in database GPG Key ID: B49A324B7EAD6D80
  1. 1
      app/Http/Controllers/IndexController.php
  2. 7
      app/Http/Controllers/TokenController.php
  3. 19
      resources/js/v2/src/pages/index/index.js
  4. 14
      resources/js/v2/vite.config.js
  5. 78
      resources/views/v2/debug-table.blade.php
  6. 45
      resources/views/v2/debug.blade.php
  7. 52
      resources/views/v2/emails/import/report.blade.php
  8. 86
      resources/views/v2/errors/503.blade.php
  9. 110
      resources/views/v2/errors/exception.blade.php
  10. 118
      resources/views/v2/import/002-authenticate/index.blade.php
  11. 152
      resources/views/v2/import/005-roles/index-camt.blade.php
  12. 91
      resources/views/v2/token/client_id.blade.php

1
app/Http/Controllers/IndexController.php

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace App\Http\Controllers;
use App\Exceptions\ImporterErrorException;
use App\Services\Session\Constants;
use App\Services\Shared\Authentication\SecretManager;
use Illuminate\Http\Request;

7
app/Http/Controllers/TokenController.php

@ -225,7 +225,12 @@ class TokenController extends Controller
// Option 3: either is empty, ask for client ID and/or base URL:
$clientId = 0 === $clientId ? '' : $clientId;
return view('token.client_id', compact('baseUrl', 'clientId', 'pageTitle'));
// if the vanity url is the same as the base url, just give this view an empty string
if($vanityUrl === $baseUrl) {
$vanityUrl = '';
}
return view('token.client_id', compact('baseUrl','vanityUrl', 'clientId', 'pageTitle'));
}
/**

19
resources/js/v2/src/pages/index/index.js

@ -53,6 +53,8 @@ let index = function () {
let tokenPageUrl = './token';
window.axios.get(validateUrl).then((response) => {
let message = response.data.result;
console.log('message is ', message)
if ('OK' === message) {
this.loadingFunctions.file = false;
this.importFunctions.file = true;
@ -68,7 +70,7 @@ let index = function () {
this.importFunctions.spectre = false;
this.pageProperties.connectionError = true;
this.pageProperties.connectionErrorMessage = data.message;
this.pageProperties.connectionErrorMessage = response.data.message;
}).catch((error) => {
this.loadingFunctions.file = false;
this.loadingFunctions.gocardless = false;
@ -80,9 +82,12 @@ let index = function () {
this.pageProperties.connectionError = true;
this.pageProperties.connectionErrorMessage = error;
}).finally(() => {
this.checkSpectreConnection();
this.checkGoCardlessConnection();
if(false === this.pageProperties.connectionError) {
this.checkSpectreConnection();
this.checkGoCardlessConnection();
}
});
},
checkSpectreConnection() {
let validateUrl = './validate/spectre';
@ -97,7 +102,9 @@ let index = function () {
this.importFunctions.spectre = false;
this.errors.spectre = 'The Spectre / Salt Edge API is configured incorrectly and cannot be used to import data.';
}).catch((error) => {
this.loadingFunctions.spectre = false;
this.importFunctions.spectre = false;
this.errors.spectre = 'The Spectre / Salt Edge API is configured incorrectly and cannot be used to import data.';
});
},
checkGoCardlessConnection() {
@ -113,7 +120,9 @@ let index = function () {
this.importFunctions.gocardless = false;
this.errors.gocardless = 'The GoCardless API is configured incorrectly and cannot be used to import data.';
}).catch((error) => {
this.loadingFunctions.gocardless = false;
this.importFunctions.gocardless = false;
this.errors.gocardless = 'The GoCardless API is configured incorrectly and cannot be used to import data.';
});
}
}

14
resources/js/v2/vite.config.js

@ -48,19 +48,11 @@ export default defineConfig({
'src/sass/app.scss',
// index
'src/pages/index/index.js',
// configuration
'src/pages/configuration/index.js',
// selection
'src/pages/selection/gocardless.js',
// conversion
'src/pages/conversion/index.js',
// submission
'src/pages/submission/index.js',
'src/pages/index/index.js',
'src/pages/selection/gocardless.js',
'src/pages/submit/index.js',
],
publicDirectory: '../../../public',
refresh: true

78
resources/views/v2/debug-table.blade.php

@ -0,0 +1,78 @@
<table>
<tr>
<th colspan="2">System information</th>
</tr>
<tr>
<th>Item</th>
<th>Value</th>
</tr>
<tr>
<td>Version</td>
<td>{{ config('importer.version') }}</td>
</tr>
@if($system['is_docker'])
<tr>
<td>Build</td>
<td><span>#</span>{{ $system['build'] }}, base <span>#</span>{{ $system['base_build'] }}</td>
</tr>
@endif
<tr>
<td>System</td>
<td>PHP {{ $system['php_version'] }}, {{ $system['php_os'] }}, {{ $system['interface'] }}</td>
</tr>
</table>
<table>
<tr>
<th colspan="2">App information</th>
</tr>
<tr>
<th>Item</th>
<th>Value</th>
</tr>
<tr>
<td>Timezone</td>
<td>{{ config('app.timezone') }}, [BrowserTZ]</td>
</tr>
<tr>
<td>Environment</td>
<td>{{ config('app.env') }}</td>
</tr>
<tr>
<td>Debug mode</td>
<td>{{ $app['debug'] }}, cache '{{ config('cache.default') }}'</td>
</tr>
<tr>
<td>Log level</td>
<td>{{ config('logging.level') }}, {{ config('logging.default') }}</td>
</tr>
<tr>
<td>Display errors</td>
<td>{{ $app['display_errors'] }}, {{ $app['reporting'] }}</td>
</tr>
<tr>
<td>BCscale</td>
<td>{{ $app['bcscale'] }}</td>
</tr>
<tr>
<td>Trusted proxies</td>
<td>{{ config('importer.trusted_proxies') }}</td>
</tr>
</table>
<table>
<tr>
<th colspan="2">User information</th>
</tr>
<tr>
<th>Item</th>
<th>Value</th>
</tr>
<tr>
<td>
User agent
</td>
<td>
{{ $user['user_agent'] }}
</td>
</tr>
</table>

45
resources/views/v2/debug.blade.php

@ -0,0 +1,45 @@
<html>
<head>
<title>Firefly III Data Importer Debug</title>
</head>
<body>
<p style="font-family:Arial, Arial, Helvetica, sans-serif;font-size:12pt;width:600px;">
Firefly III data importer debug page
</p>
<p style="font-family:Arial, Arial, Helvetica, sans-serif;font-size:12pt;width:800px;">
Copy and paste the content of this textarea in your issue. <strong>Please do not add quotes or backticks, it breaks the table.</strong>
</p>
<textarea rows="30" cols="100" name="debug_info" id="debug_info" style="font-family:Menlo, Monaco, Consolas, monospace;font-size:8pt;">
Debug information generated at {{ $now }} for Firefly III Data Importer version **{{ config('importer.version') }}**.
{{ $table }}
</textarea>
<script type="text/javascript">
var textArea = document.getElementById('debug_info');
var text = textArea.value;
var timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
text = text.replace('[BrowserTZ]', timeZone);
textArea.value = text;
</script>
<p style="font-family:Arial, Arial, Helvetica, sans-serif;font-size:12pt;width:600px;color:#a00;">
<a href="{{ route('index') }}">Back to index</a>
</p>
<p style="font-family:Arial, Arial, Helvetica, sans-serif;font-size:12pt;width:600px;color:#a00;">
Extra info. Do not share this lightly!
</p>
<textarea rows="30" cols="100" name="log_info" style="font-family:Menlo, Monaco, Consolas, monospace;font-size:7pt;">
```
{{ $logContent }}
```
</textarea>
<p style="font-family:Arial, Arial, Helvetica, sans-serif;font-size:12pt;width:600px;color:#a00;">
<a href="{{ route('index') }}">Back to index</a>
</p>
</body>
</html>

52
resources/views/v2/emails/import/report.blade.php

@ -0,0 +1,52 @@
@component('mail::message')
# Result of your import on {{ $time }}
<hr>
@if(count($errors) > 0)
## Errors
@endif
@foreach($errors as $index => $objList)
@foreach($objList as $message)
- Line #{{ $index + 1 }}: {!! $message !!}
@endforeach
@endforeach
@if(count($warnings) > 0)
## Warnings
@endif
@foreach($warnings as $index => $objList)
@foreach($objList as $message)
- Line #{{ $index + 1 }}: {!! $message !!}
@endforeach
@endforeach
@if(count($messages) > 0)
## Messages
@endif
@foreach($messages as $index => $objList)
@foreach($objList as $message)
- Line #{{ $index + 1 }}: {!! $message !!}
@endforeach
@endforeach
<hr>
@if(0 === count($errors) and 0 === count($messages) and 0 === count($warnings))
*No messages, warnings or errors: nothing to report*
@endif
@if('' !== $url)
@component('mail::button', ['url' => $url])
Go to Firefly III
@endcomponent
@endif
Enjoy!<br>
Firefly III Data Importer, v{{ config('importer.version') }}
@endcomponent

86
resources/views/v2/errors/503.blade.php

@ -0,0 +1,86 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex, nofollow, noarchive, noodp, NoImageIndex, noydir">
<title>Firefly III Data Importer Maintenance Mode</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<base href="{{ route('index') }}/">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="color-scheme" content="light dark">
<script type="text/javascript">
/*!
* Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
* Copyright 2011-2023 The Bootstrap Authors
* Licensed under the Creative Commons Attribution 3.0 Unported License.
*/
(() => {
'use strict'
// todo store just happens to store in localStorage but if not, this would break.
const getStoredTheme = () => JSON.parse(localStorage.getItem('darkMode'))
const getPreferredTheme = () => {
const storedTheme = getStoredTheme()
if (storedTheme) {
return storedTheme
}
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
}
const setTheme = theme => {
if (theme === 'browser' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.setAttribute('data-bs-theme', 'dark')
window.theme = 'dark';
return;
}
if (theme === 'browser' && window.matchMedia('(prefers-color-scheme: light)').matches) {
window.theme = 'light';
document.documentElement.setAttribute('data-bs-theme', 'light')
return;
}
document.documentElement.setAttribute('data-bs-theme', theme)
window.theme = theme;
}
setTheme(getPreferredTheme())
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
const storedTheme = getStoredTheme()
if (storedTheme !== 'light' && storedTheme !== 'dark') {
setTheme(getPreferredTheme())
}
})
})()
</script>
@yield('styles')
@vite(['src/sass/app.scss'])
</head>
<body class="container">
<div class="row mt-3">
<div class="col-lg-10 col-lg-offset-1 col-md-12 col-sm-12 col-xs-12">
<h1><strong>Firefly III</strong> Data Importer</h1>
</div>
</div>
<div class="row">
<div class="col-lg-10 col-lg-offset-1 col-md-12 col-sm-12 col-xs-12">
<h3 class="text-info">The Firefly III Data Importer is in maintenance mode.</h3>
</div>
</div>
<div class="row">
<div class="col-lg-10 col-lg-offset-1 col-md-12 col-sm-12 col-xs-12">
<p>
This should only take a few moments. If you had an import running, you may have to start over. My apologies.
</p>
<p>
Please check back in a second!
</p>
</div>
</div>
</body>
</html>

110
resources/views/v2/errors/exception.blade.php

@ -0,0 +1,110 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="color-scheme" content="light dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<base href="{{ route('index') }}/">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="color-scheme" content="light dark">
<script type="text/javascript">
/*!
* Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
* Copyright 2011-2023 The Bootstrap Authors
* Licensed under the Creative Commons Attribution 3.0 Unported License.
*/
(() => {
'use strict'
// todo store just happens to store in localStorage but if not, this would break.
const getStoredTheme = () => JSON.parse(localStorage.getItem('darkMode'))
const getPreferredTheme = () => {
const storedTheme = getStoredTheme()
if (storedTheme) {
return storedTheme
}
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
}
const setTheme = theme => {
if (theme === 'browser' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.setAttribute('data-bs-theme', 'dark')
window.theme = 'dark';
return;
}
if (theme === 'browser' && window.matchMedia('(prefers-color-scheme: light)').matches) {
window.theme = 'light';
document.documentElement.setAttribute('data-bs-theme', 'light')
return;
}
document.documentElement.setAttribute('data-bs-theme', theme)
window.theme = theme;
}
setTheme(getPreferredTheme())
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
const storedTheme = getStoredTheme()
if (storedTheme !== 'light' && storedTheme !== 'dark') {
setTheme(getPreferredTheme())
}
})
})()
</script>
@yield('styles')
@vite(['src/sass/app.scss'])
<title>500 error :(</title>
</head>
<body>
@if(config('importer.is_external'))
<div class="alert alert-warning" role="alert">
This Firefly III Data Importer installation is <strong>publicly accessible</strong>. Please read <a
href="https://docs.firefly-iii.org/references/data-importer/public/" class="alert-link" target="_blank">the
considerations</a> (link opens in a new window or tab).
</div>
@endif
<div class="container">
<div class="row mt-3">
<div class="col-lg-10 offset-lg-1">
<h1>Whoops! 500 :(</h1>
<p>
Sorry, the Firefly III Data Importer broke down.
</p>
<h2>Error message</h2>
<p class="text-danger">
{{ $exception->getMessage() }}
</p>
<h2>More information</h2>
<p>
The error occurred in <code>{{ $exception->getFile() }}:{{ $exception->getLine() }}</code>.
</p>
<p>
Please collect more information in the <code>storage/logs</code> directory, where you will find log files.
If you're running Docker, use <code>docker logs -f [container]</code>.
You can read more about collecting error information <a href="https://docs.firefly-iii.org/how-to/general/debug/"
target="_blank">in the FAQ</a>.
</p>
<h2>Get help on GitHub</h2>
<p>
You're more than welcome to open a new issue <strong><a href="https://github.com/firefly-iii/firefly-iii/issues">on GitHub</a></strong>.
</p>
<ol>
<li>Use the search!</li>
<li>Include the information <a href="{{ route('debug') }}">from this debug page</a>.</li>
<li>Tell us more than &quot;it says Whoops!&quot;</li>
<li>Include error logs (see above).</li>
<li>Tell us what you were doing.</li>
</ol>
</div>
</div>
</body>
</html>

118
resources/views/v2/import/002-authenticate/index.blade.php

@ -0,0 +1,118 @@
@extends('layout.v2')
@section('content')
<div class="container">
<div class="row mt-3">
<div class="col-lg-10 offset-lg-1">
<h1>{{ $mainTitle }}</h1>
</div>
</div>
<div class="row mt-3">
<div class="col-lg-10 offset-lg-1">
<div class="card">
<div class="card-header">
{{ $subTitle }}
</div>
<div class="card-body">
<p>In order to import using
@if('nordigen' === $flow)
GoCardless,
@endif
@if('spectre' === $flow)
Spectre,
@endif
you must enter the authentication data you
received from this provider.
You can read how to get the necessary codes in the
<a target="_blank" href="https://docs.firefly-iii.org/explanation/data-importer/about/gocardless-salt-edge/">documentation</a>
</p>
</div>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-lg-10 offset-lg-1">
<div class="card">
<div class="card-header">
Form
</div>
<div class="card-body">
@if('' !== ($error ?? ''))
<p class="text-danger">{{ $error }}</p>
@endif
<form method="post" action="{{ route('002-authenticate.post') }}" accept-charset="UTF-8">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
@if('nordigen' === $flow)
<!-- nordigen ID -->
<div class="form-group row">
<label for="date" class="col-sm-3 col-form-label">GoCardless ID</label>
<div class="col-sm-9">
<input type="text" name="nordigen_id" class="form-control" id="nordigen_id"
placeholder="GoCardless ID" value="" aria-describedby="nordigenIdHelp">
<small id="nordigenIdHelp" class="form-text text-muted">
Your GoCardless ID
</small>
</div>
</div>
<!-- nordigen key -->
<div class="form-group row">
<label for="date" class="col-sm-3 col-form-label">GoCardless key</label>
<div class="col-sm-9">
<input type="text" name="nordigen_key" class="form-control" id="nordigen_key"
placeholder="GoCardless key" value="" aria-describedby="nordigenKeyHelp">
<small id="nordigenKeyHelp" class="form-text text-muted">
Your GoCardless secret key
</small>
</div>
</div>
@endif
@if('spectre' === $flow)
<!-- spectre app id -->
<div class="form-group row">
<label for="date" class="col-sm-3 col-form-label">Spectre App ID</label>
<div class="col-sm-9">
<input type="text" name="spectre_app_id" class="form-control"
id="spectre_app_id" placeholder="Spectre App ID" value=""
aria-describedby="spectreAppIdHelp">
<small id="spectreAppIdHelp" class="form-text text-muted">
The app ID
</small>
</div>
</div>
<!-- spectre secret -->
<div class="form-group row">
<label for="date" class="col-sm-3 col-form-label">Spectre secret</label>
<div class="col-sm-9">
<input type="text" name="spectre_secret" class="form-control"
id="spectre_secret" placeholder="Spectre Secret" value=""
aria-describedby="spectreSecret">
<small id="spectreSecret" class="form-text text-muted">
The secret
</small>
</div>
</div>
@endif
<button type="submit" class="float-end btn btn-primary">Authenticate &rarr;</button>
</form>
</div>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-lg-10 offset-lg-1">
<div class="card">
<div class="card-body">
<div class="btn-group btn-group-sm">
<a href="{{ route('back.start') }}" class="btn btn-secondary"><span
class="fas fa-arrow-left"></span> Go back to index</a>
<a href="{{ route('flush') }}" class="btn btn-danger text-white btn-sm"><span
class="fas fa-redo-alt"></span> Start over</a>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection

152
resources/views/v2/import/005-roles/index-camt.blade.php

@ -0,0 +1,152 @@
@extends('layout.v2')
@section('content')
<div class="container">
<div class="row mt-3">
<div class="col-lg-10 offset-lg-1">
<h1>{{ $mainTitle }}</h1>
</div>
</div>
<div class="row">
<div class="col-lg-10 offset-lg-1">
<div class="card">
<div class="card-header">
{{ $subTitle }}
</div>
<div class="card-body">
<p>
CAMT files feature "layers", where each layer has its own content.
Your options per field may be limited. Firefly III will not be able to
store <em>all</em> content of a CAMT file. If you feel your choices are too limited, please
open <a href="https://github.com/firefly-iii/firefly-iii/issues">an issue on GitHub</a>.
</p>
</div>
</div>
</div>
</div>
@if(!$errors->isEmpty())
<div class="row mt-3">
<div class="col-lg-10 offset-lg-1">
<div class="card">
<div class="card-header">
Errors :(
</div>
<div class="card-body">
<p class="text-danger">Some error(s) occurred:</p>
<ul>
@foreach($errors->all() as $error)
<li class="text-danger">{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
</div>
</div>
@endif
<div class="row mt-3">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
Role configuration
</div>
<div class="card-body">
<form method="post" action="{{ route('005-roles.post') }}" accept-charset="UTF-8">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
@foreach($levels as $key => $level)
<h4>Level {{ $key }}: {{ $level['title'] }}</h4>
<p>
{{ $level['title'] }}: {{ $level['explanation'] }}
</p>
@if(count($level['fields']) > 0)
<table class="table">
<thead>
<tr>
<th style="width:30%;">Field</th>
<th style="width:30%;">Example data</th>
<th>Firefly III role</th>
<th style="width:10%">Map data?</th>
</tr>
</thead>
<tbody>
@foreach($level['fields'] as $field)
@if(true === ($field['section'] ?? false))
<tr>
<th colspan="4">{{ __('camt.section_'. $field['title']) }}</th>
</tr>
@endif
@if(false === ($field['section'] ?? false))
<tr>
<td>
{{ __('camt.field_'.$field['title']) }}
@if(__('camt.field_' . $field['title'] . '_description') !== 'camt.field_' . $field['title'] . '_description')
<br><span class="text-muted small">{{ __('camt.field_' . $field['title'] . '_description') }}</span>
@endif
</td>
<td>
@if(0 == count($examples[$field['title']]))
<small class="text-muted"><em>(no example data)</em></small>
@endif
@if(count($examples[$field['title']]) > 0)
@foreach($examples[$field['title']] as $example)
<code>{{ $example }}</code><br>
@endforeach
@endif
</td>
<td>
@if(0 === count(config('camt.roles.' . $field['roles'])))
<small class="text-muted"><em>(no roles available)</em></small>
@endif
@if(count(config('camt.roles.' . $field['roles'])) > 0)
<select name="roles[{{ $field['title'] }}]" id="roles_{{ $field['title'] }}" class="form-control">
@foreach(config('camt.roles.' . $field['roles']) as $roleKey => $role)
<option value="{{ $roleKey }}" label="{{ __('import.column_' . $roleKey) }}"
@if($field['default_role'] === $roleKey) selected @endif
@if($field['default_role'] !== $roleKey && array_key_exists($field['title'], $roles) && $roles[$field['title']] == $roleKey) selected @endif
>
{{ trans('import.column_' . $roleKey) }}
</option>
@endforeach
</select>
@endif
</td>
<td>
@if(true === $field['mappable'])
<label for="do_mapping_{{ $field['title'] }}">
<input type="checkbox" name="do_mapping[{{ $field['title'] }}]" id="do_mapping_{{ $field['title'] }}"
@if($doMapping[$field['title']]) checked="checked" @endif
value="1"/>
</label>
@endif
</td>
</tr>
@endif
@endforeach
</tbody>
</table>
@endif
@endforeach
<button type="submit" class="float-end btn btn-primary">Submit &rarr;</button>
</form>
</div>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-lg-10 offset-lg-1">
<div class="card">
<div class="card-body">
<div class="btn-group btn-group-sm">
<a href="{{ route('back.config') }}" class="btn btn-secondary"><span
class="fas fa-arrow-left"></span> Go back to configuration</a>
<a href="{{ route('flush') }}" class="btn btn-danger btn-sm"><span
class="fas fa-redo-alt"></span> Start over</a>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection

91
resources/views/v2/token/client_id.blade.php

@ -0,0 +1,91 @@
@extends('layout.v2')
@section('content')
<div class="container">
<div class="row mt-4">
<div class="col-lg-10 offset-lg-1">
<h1>Firefly III Data Import Tool, v{{ $version }}</h1>
</div>
</div>
<div class="row mt-3">
<div class="col-lg-10 offset-lg-1">
<div class="card">
<div class="card-header">
Authenticate with Firefly III
</div>
<div class="card-body">
<p class="card-text">
Welcome! This tool will help you import data into Firefly III.
</p>
<p>
This tool is sparsely documented, you can find all the details you need
in the <a href="https://docs.firefly-iii.org/" target="_blank">
documentation</a>. Any links you see to the docs will open in a new window or tab.
</p>
<p class="card-text">
@if('' !== (string)$baseUrl)
In order to get access to your Firefly III installation at <a
href="{{ $baseUrl }}">{{ $baseUrl }}</a>
@if('' !== (string)$vanityUrl)
(<a href="{{ $vanityUrl }}">{{ $vanityUrl }}</a>)
@endif
, you will need to submit a valid Client ID. This is a number.
@else
In order to get access to your Firefly III installation, you will need to submit a valid Client ID. This is a number.
@endif
</p>
<p>
@if('' !== (string)$baseUrl)
If you don't have one, you must create <a href="{{ $baseUrl }}/profile">in your
profile</a> under "OAuth". Make sure you
<em>remove</em> the checkbox under "Confidential".
@else
If you don't have one, you must create in your profile under "OAuth". Make sure you
<em>remove</em> the checkbox under "Confidential".
@endif
</p>
<p>
The callback URL for this installation is<br> <code>{{ route('token.callback') }}</code>
</p>
@foreach($errors->all() as $error)
<p class="text-danger">{{ $error }}</p>
@endforeach
<form action="{{ route('token.submitClientId') }}" method="POST">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
@if('' === (string)$baseUrl)
<div class="form-group mb-3">
<label for="input_base_url">Firefly III URL</label>
<input type="url" placeholder="https://" value="{{ $baseUrl }}" class="form-control" id="input_base_url" autocomplete="off" name="base_url">
@if($errors->has('base_url'))
<span class="text-danger">{{ $errors->first('base_url') }}</span>
@endif
@if(session()->has('secure_url'))
<span class="text-danger">{{ session()->get('secure_url') }}</span>
@endif
</div>
@endif
<div class="form-group mb-3">
<label for="input_client_id">Client ID</label>
<input type="number" step="1" min="1" class="form-control" id="input_client_id" autocomplete="off" name="client_id" value="{{ $clientId }}">
@if($errors->has('client_id'))
<span class="text-danger">{{ $errors->first('client_id') }}</span>
@endif
</div>
<input type="submit" name="submit" value="Submit" class="float-end text-white btn btn-success"/>
</form>
</div>
</div>
<div class="card mt-3">
<div class="card-body">
<p>
<a class="btn btn-danger text-white btn-sm" href="{{ route('flush') }}" data-bs-toggle="tooltip"
data-bs-placement="top" title="This button resets your progress">Start over</a>
</p>
</div>
</div>
</div>
</div>
</div>
@endsection
Loading…
Cancel
Save