mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2024-12-27 01:11:37 -06:00
Some general cleaning up in the menu's and the various controllers. Added a new class (yet to be tested) and removed most of the "piggy bank"-implementation in anticipation of the ideas from issue #6. Fixed a bug in the default user seeder.
This commit is contained in:
parent
dbcf6613c6
commit
e2940015ca
15
README.md
15
README.md
@ -41,15 +41,14 @@ Firefly III will feature:
|
||||
- Firefly will not encrypt the content of the (MySQL) tables. Old versions of Firefly had this capability but it sucks when searching, sorting and organizing entries.
|
||||
|
||||
## Current state
|
||||
I barely have the basics up and running and test coverage is doing very good. I have some good ideas about user configuration and preferences which was a huge pain in the butt with the previous Firefly.
|
||||
I have the basics up and running and test coverage is doing very well.
|
||||
|
||||
Current problems include proper time-based navigation (how and when to switch to the next month, previous week, etc) and the best
|
||||
way to display your current financial state, which is something that still needs thinking.
|
||||
Current issues are the consistent look-and-feel of forms and likewise, the consistent inner workings of most of Firefly.
|
||||
Example: every "create"-action tends to be slightly different from the rest. Also is the fact that not all lists
|
||||
and forms are equally well thought of; some are not looking very well or miss feedback.
|
||||
|
||||
Most forms will not allow you to enter invalid data because the database cracks, not because it's actually checked.
|
||||
|
||||
The problem is that most peoples finances are very flexible and Firefly can be pretty static. For example, did you spend all your money? Or
|
||||
do you have money left? Good question: when your rent is due at the 1st of the month Firefly might think you've spent way too much. But
|
||||
marking it as some kind of "bill" will make Firefly ignore it, but it might make Firefly forget that you've got bills coming! So there's
|
||||
a lot to do, and a lot to fix.
|
||||
A lot of views have CSRF vulnerabilities.
|
||||
|
||||
If you have an idea, [let me know](https://github.com/JC5/firefly-iii/issues/new)!
|
||||
Questions, ideas or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)!
|
||||
|
25
app/assets/javascripts/firefly/piggybanks-create.js
Normal file
25
app/assets/javascripts/firefly/piggybanks-create.js
Normal file
@ -0,0 +1,25 @@
|
||||
$(function () {
|
||||
|
||||
updatePiggyFields();
|
||||
$('input[name="repeats"]').on('change',updatePiggyFields);
|
||||
|
||||
});
|
||||
|
||||
function updatePiggyFields() {
|
||||
//var val = $('input[name="repeats"]').checked;
|
||||
|
||||
console.log('Repeating elements: ' + $('.repeat-piggy').length);
|
||||
console.log('Non-repeating elements: ' + $('.no-repeat-piggy').length);
|
||||
|
||||
if($('input[name="repeats"]').prop( "checked" )) {
|
||||
// checked, repeats!
|
||||
console.log('repeats!');
|
||||
$('.repeat-piggy').show();
|
||||
$('.no-repeat-piggy').hide();
|
||||
} else {
|
||||
console.log('no repeats!');
|
||||
// unchecked, does not repeat!
|
||||
$('.no-repeat-piggy').show();
|
||||
$('.repeat-piggy').hide();
|
||||
}
|
||||
}
|
@ -1,124 +1,4 @@
|
||||
$(function () {
|
||||
|
||||
$('input[type="range"]').on('input', inputRange);
|
||||
$('input[type="range"]').on('change', updateAmount);
|
||||
$('input[type="number"]').on('input',inputNumber);
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Update some fields to reflect drag changes.
|
||||
* @param e
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function inputRange(e) {
|
||||
var target = $(e.target);
|
||||
var piggyBankId = target.attr('name').substring(6);
|
||||
var accountId = target.data('account');
|
||||
var amount = parseFloat(target.val());
|
||||
|
||||
|
||||
|
||||
//
|
||||
// new percentage for amount in piggy bank, formatted.
|
||||
var pctId = 'piggy_' + piggyBankId + '_pct';
|
||||
percentage = Math.round((amount / parseFloat(target.attr('max'))) * 100) + '%'; //Math.round((value / parseFloat(target.attr('total'))) * 100) + '%';
|
||||
$('#' + pctId).text(percentage);
|
||||
|
||||
// new value for number input:
|
||||
var valueId = 'piggy_' + piggyBankId + '_amount';
|
||||
$('#' + valueId).val(amount.toFixed(2));
|
||||
|
||||
leftInAccounts(accountId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function inputNumber(e) {
|
||||
var target = $(e.target);
|
||||
var amount = parseFloat(target.val());
|
||||
var piggyBankId = target.data('piggy');
|
||||
var accountId = target.data('account');
|
||||
|
||||
|
||||
// update amount in range input:
|
||||
target.val(amount);
|
||||
$('input[name="piggy_'+piggyBankId+'"]').val(amount);
|
||||
console.log('SERVER: ' + amount);
|
||||
$.post('piggybanks/updateAmount/' + piggyBankId, {amount: amount});
|
||||
|
||||
leftInAccounts(accountId);
|
||||
}
|
||||
|
||||
|
||||
function updateAmount(e) {
|
||||
|
||||
// update amount on server:
|
||||
var target = $(e.target);
|
||||
var piggyBankId = target.attr('name').substring(6);
|
||||
var accountId = target.data('account');
|
||||
var amount = target.val();
|
||||
console.log('SERVER: ' + amount);
|
||||
$.post('piggybanks/updateAmount/' + piggyBankId, {amount: amount});
|
||||
|
||||
|
||||
}
|
||||
|
||||
function leftInAccounts(accountId) {
|
||||
// get the total:
|
||||
var total = parseFloat($('#account_'+accountId+'_total').data('raw'));
|
||||
|
||||
// sub all piggy banks:
|
||||
var inPiggies = 0;
|
||||
$('input[type="range"]').each(function(i,v) {
|
||||
var p = $(v);
|
||||
if(parseInt(p.data('account')) == accountId) {
|
||||
inPiggies += parseFloat(p.val());
|
||||
}
|
||||
});
|
||||
var left = total - inPiggies;
|
||||
|
||||
// set amount left:
|
||||
leftFormatted = '€ ' + left.toFixed(2);
|
||||
$('#account_'+accountId+'_left').text(leftFormatted);
|
||||
|
||||
// return amount left:
|
||||
return left;
|
||||
|
||||
|
||||
}
|
||||
|
||||
function updateAccounts(id) {
|
||||
//
|
||||
// var spent = 0;
|
||||
// $.each($('input[type="range"]'), function (i, v) {
|
||||
// var current = $(v);
|
||||
// var accountId = parseInt(current.data('account'));
|
||||
// if (accountId == id) {
|
||||
// spent += parseFloat(current.val());
|
||||
// }
|
||||
//// var value = parseFloat(current.val());
|
||||
//// var accountId = parseInt(current.data('account'));
|
||||
////
|
||||
//// // only when we're working on this account we update "spent"
|
||||
//// if(accountId == id) {
|
||||
//// spent = spent[accountId] == undefined ? value : spent[accountId] + value;
|
||||
//// //var leftNow = accountLeft[accountId] - value;
|
||||
//// }
|
||||
// });
|
||||
// console.log('Spent for account ' + id + ': ' + spent);
|
||||
// var left = accountLeft[id] - spent;
|
||||
// var leftFormatted = '€ ' + (Math.round((left) * 100) / 100).toFixed(2);
|
||||
// var entryId = 'account_' + id + '_left';
|
||||
// $('#' + entryId).text(leftFormatted);
|
||||
// if(left < 0) {
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
////
|
||||
//// // now we update the amount in the list of accounts:
|
||||
//// var left = accountLeft[id] - spent;
|
||||
//// var leftFormatted =
|
||||
|
||||
|
||||
}
|
||||
});
|
13
app/assets/javascripts/piggybanks-create.js
Normal file
13
app/assets/javascripts/piggybanks-create.js
Normal file
@ -0,0 +1,13 @@
|
||||
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||
// listed below.
|
||||
//
|
||||
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
||||
// can be referenced here using a relative path.
|
||||
//
|
||||
// It's not advisable to add code directly here, but if you do, it'll appear in whatever order it
|
||||
// gets included (e.g. say you have require_tree . then the code will appear after all the directories
|
||||
// but before any files alphabetically greater than 'application.js'
|
||||
//
|
||||
// The available directives right now are require, require_directory, and require_tree
|
||||
//
|
||||
//= require firefly/piggybanks-create
|
@ -20,7 +20,6 @@ class AccountController extends \BaseController
|
||||
{
|
||||
$this->_accounts = $accounts;
|
||||
$this->_repository = $repository;
|
||||
View::share('menu', 'accounts');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,7 +21,6 @@ class BudgetController extends BaseController
|
||||
{
|
||||
$this->_budgets = $budgets;
|
||||
$this->_repository = $repository;
|
||||
View::share('menu', 'budgets');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,7 +19,6 @@ class CategoryController extends BaseController
|
||||
{
|
||||
$this->_repository = $repository;
|
||||
$this->_category = $category;
|
||||
View::share('menu', 'categories');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -26,9 +26,6 @@ class HomeController extends BaseController
|
||||
$this->_preferences = $preferences;
|
||||
$this->_journal = $journal;
|
||||
$this->_budgets = $budgets;
|
||||
View::share('menu', 'home');
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,8 +20,6 @@ class LimitController extends BaseController
|
||||
{
|
||||
$this->_budgets = $budgets;
|
||||
$this->_limits = $limits;
|
||||
View::share('menu', 'budgets');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,8 +20,6 @@ class PiggybankController extends BaseController
|
||||
{
|
||||
$this->_repository = $repository;
|
||||
$this->_accounts = $accounts;
|
||||
View::share('menu', 'home');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -80,17 +78,7 @@ class PiggybankController extends BaseController
|
||||
// get accounts:
|
||||
foreach ($piggybanks as $piggyBank) {
|
||||
$account = $piggyBank->account;
|
||||
$piggyBank->pct = round(($piggyBank->amount / $piggyBank->target) * 100, 0) . '%';
|
||||
$id = $account->id;
|
||||
if (!isset($accounts[$id])) {
|
||||
$account->balance = $account->balance();
|
||||
$account->left = $account->balance - $piggyBank->amount;
|
||||
$account->total = $piggyBank->target;
|
||||
} else {
|
||||
$account->left -= $piggyBank->amount;
|
||||
$account->total += $piggyBank->target;
|
||||
|
||||
}
|
||||
$accounts[$id] = $account;
|
||||
}
|
||||
|
||||
@ -105,7 +93,7 @@ class PiggybankController extends BaseController
|
||||
*/
|
||||
public function show(Piggybank $piggyBank)
|
||||
{
|
||||
return View::make('piggybanks.show')->with('piggyBank',$piggyBank);
|
||||
return View::make('piggybanks.show')->with('piggyBank', $piggyBank);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,6 @@ class PreferencesController extends BaseController
|
||||
|
||||
$this->_accounts = $accounts;
|
||||
$this->_preferences = $preferences;
|
||||
View::share('menu', 'home');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,6 @@ class ProfileController extends BaseController
|
||||
public function __construct(URI $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
View::share('menu', 'home');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,6 @@ class RecurringController extends BaseController
|
||||
public function __construct(RTR $repository)
|
||||
{
|
||||
$this->_repository = $repository;
|
||||
View::share('menu', 'home');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,7 +17,6 @@ class TransactionController extends BaseController
|
||||
public function __construct(TJRI $repository)
|
||||
{
|
||||
$this->_repository = $repository;
|
||||
View::share('menu', 'home');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,13 +45,13 @@ class UserController extends BaseController
|
||||
'email' => Input::get('email'),
|
||||
'password' => Input::get('password')
|
||||
];
|
||||
if (Auth::attempt($data, $rememberMe)) {
|
||||
$result = Auth::attempt($data, $rememberMe);
|
||||
if ($result) {
|
||||
Session::flash('success', 'Logged in!');
|
||||
|
||||
return Redirect::route('index');
|
||||
}
|
||||
Session::flash('error', 'No good!');
|
||||
|
||||
Session::flash('error', 'No good!');
|
||||
return View::make('user.login');
|
||||
}
|
||||
|
||||
|
@ -23,10 +23,14 @@ class CreatePiggybanksTable extends Migration
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
$table->integer('account_id')->unsigned();
|
||||
$table->date('targetdate')->nullable();
|
||||
$table->string('name', 100);
|
||||
$table->decimal('amount', 10, 2);
|
||||
$table->decimal('target', 10, 2)->nullable();
|
||||
$table->decimal('targetamount', 10, 2);
|
||||
$table->date('targetdate')->nullable();
|
||||
$table->date('startdate')->nullable();
|
||||
$table->boolean('repeats');
|
||||
$table->enum('rep_length', ['day', 'week', 'month', 'year'])->nullable();
|
||||
$table->smallInteger('rep_times')->unsigned();
|
||||
$table->enum('reminder', ['day', 'week', 'month', 'year'])->nullable();
|
||||
$table->integer('order')->unsigned();
|
||||
|
||||
// connect account to piggybank.
|
||||
|
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreatePiggyInstance extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('piggybank_repetitions', function(Blueprint $table)
|
||||
{
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
$table->integer('piggybank_id')->unsigned();
|
||||
$table->date('targetdate')->nullable();
|
||||
$table->date('startdate')->nullable();
|
||||
$table->decimal('currentamount',10,2);
|
||||
|
||||
// connect instance to piggybank.
|
||||
$table->foreign('piggybank_id')
|
||||
->references('id')->on('piggybanks')
|
||||
->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('piggybank_repetitions');
|
||||
}
|
||||
|
||||
}
|
@ -12,7 +12,7 @@ class DefaultUserSeeder extends Seeder
|
||||
User::create(
|
||||
[
|
||||
'email' => 's@nder.be',
|
||||
'password' => Hash::make('sander'),
|
||||
'password' => 'sander',
|
||||
'reset' => null,
|
||||
'remember_token' => null,
|
||||
'migrated' => 0
|
||||
|
@ -9,6 +9,7 @@ namespace Firefly\Helper\Form;
|
||||
*/
|
||||
class FormHelper
|
||||
{
|
||||
|
||||
/**
|
||||
* @param null $value
|
||||
*
|
||||
|
@ -24,17 +24,33 @@ use LaravelBook\Ardent\Ardent as Ardent;
|
||||
* @method static \Illuminate\Database\Query\Builder|\Piggybank whereAmount($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Piggybank whereTarget($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Piggybank whereOrder($value)
|
||||
* @property float $targetamount
|
||||
* @property string $startdate
|
||||
* @property boolean $repeats
|
||||
* @property string $rep_length
|
||||
* @property integer $rep_times
|
||||
* @property string $reminder
|
||||
* @method static \Illuminate\Database\Query\Builder|\Piggybank whereTargetamount($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Piggybank whereStartdate($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepeats($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepLength($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepTimes($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Piggybank whereReminder($value)
|
||||
*/
|
||||
class Piggybank extends Ardent
|
||||
{
|
||||
public static $rules
|
||||
= [
|
||||
'name' => 'required|between:1,255',
|
||||
'account_id' => 'required|exists:accounts,id',
|
||||
'targetdate' => 'date',
|
||||
'amount' => 'required|min:0',
|
||||
'target' => 'required|min:1',
|
||||
'order' => 'required:min:1',
|
||||
'account_id' => 'required|exists:accounts,id',
|
||||
'name' => 'required|between:1,255',
|
||||
'targetamount' => 'required|min:0',
|
||||
'targetdate' => 'date',
|
||||
'startdate' => 'date',
|
||||
'repeats' => 'required|between:0,1',
|
||||
'rep_length' => 'in:day,week,month,year',
|
||||
'rep_times' => 'required|min:0|max:100',
|
||||
'reminder' => 'in:day,week,month,year',
|
||||
'order' => 'required:min:1',
|
||||
];
|
||||
|
||||
/**
|
||||
@ -44,14 +60,19 @@ class Piggybank extends Ardent
|
||||
{
|
||||
$start = new Carbon;
|
||||
$start->endOfMonth();
|
||||
$today = new Carbon;
|
||||
|
||||
return [
|
||||
'name' => 'string',
|
||||
'account_id' => 'factory|Account',
|
||||
'targetdate' => $start,
|
||||
'amount' => 0,
|
||||
'target' => 100,
|
||||
'order' => 1
|
||||
'name' => 'string',
|
||||
'targetamount' => 'required|min:0',
|
||||
'targetdate' => $start,
|
||||
'startdate' => $today,
|
||||
'repeats' => 0,
|
||||
'rep_length' => null,
|
||||
'rep_times' => 0,
|
||||
'reminder' => null,
|
||||
'order' => 1,
|
||||
];
|
||||
}
|
||||
|
||||
@ -63,6 +84,10 @@ class Piggybank extends Ardent
|
||||
return $this->belongsTo('Account');
|
||||
}
|
||||
|
||||
public function piggybankrepetitions() {
|
||||
return $this->hasMany('PiggybankRepetition');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
|
50
app/models/PiggybankRepetition.php
Normal file
50
app/models/PiggybankRepetition.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use LaravelBook\Ardent\Ardent as Ardent;
|
||||
|
||||
|
||||
/**
|
||||
* Class PiggybankRepetition
|
||||
*/
|
||||
class PiggybankRepetition extends Ardent
|
||||
{
|
||||
public static $rules
|
||||
= [
|
||||
'piggybank_id' => 'required|exists:piggybanks,id',
|
||||
'targetdate' => 'date',
|
||||
'startdate' => 'date',
|
||||
'currentamount' => 'required|numeric'
|
||||
];
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function factory()
|
||||
{
|
||||
$date = new Carbon;
|
||||
|
||||
return [
|
||||
'piggybank_id' => 'factory|Piggybank',
|
||||
'targetdate' => $date,
|
||||
'startdate' => $date,
|
||||
'currentamount' => 200
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDates()
|
||||
{
|
||||
return ['created_at', 'updated_at', 'targetdate', 'startdate'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function piggybank()
|
||||
{
|
||||
return $this->belongsTo('Piggybank');
|
||||
}
|
||||
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereCode($value)
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionjournals
|
||||
*/
|
||||
class TransactionCurrency extends Eloquent
|
||||
{
|
||||
|
@ -71,6 +71,10 @@ use LaravelBook\Ardent\Ardent;
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
*/
|
||||
class TransactionJournal extends Ardent
|
||||
{
|
||||
|
@ -13,6 +13,9 @@
|
||||
bank accounts are representated as accounts (naturally), but the stores you buy stuff at are also
|
||||
represented as accounts. Likewise, if you have a job, your salary is drawn from their account.
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{route('accounts.create')}}" class="btn btn-success">Create a new account</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
@ -22,6 +22,13 @@
|
||||
* <small>Every month, week, year, etc.</small>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<div class="btn-group">
|
||||
<a href="{{route('budgets.create')}}" class="btn btn-success"><span class="glyphicon glyphicon-plus"></span> Create a new budget</a>
|
||||
<a href="{{route('budgets.limits.create')}}" class="btn btn-success"><span class="glyphicon glyphicon-plus"></span> Create a new envelope</a>
|
||||
</div>
|
||||
</p>
|
||||
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default" href ="{{route('budgets.index')}}"><span class="glyphicon glyphicon-indent-left"></span> Group by date</a>
|
||||
<a class="btn btn-default" href ="{{route('budgets.create')}}?from=budget"><span class="glyphicon glyphicon-plus-sign"></span> Create a new budget</a>
|
||||
|
@ -10,6 +10,9 @@
|
||||
Use categories to group expenses by hobby, for certain types of groceries or what bills are for.
|
||||
Expenses grouped in categories do not have to reoccur every month or every week, like budgets.
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{route('categories.create')}}" class="btn btn-success"><span class="glyphicon glyphicon-plus"></span> Create a new category</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
@include('partials.menu.'.$menu)
|
||||
@include('partials.menu')
|
||||
@include('partials.flashes')
|
||||
@yield('content')
|
||||
</div>
|
||||
|
@ -21,11 +21,5 @@
|
||||
@include('partials.flashes')
|
||||
@yield('content')
|
||||
</div>
|
||||
<!-- {{App::environment()}} -->
|
||||
|
||||
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
|
||||
<!-- Include all compiled plugins (below), or include individual files as needed -->
|
||||
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
74
app/views/partials/menu.blade.php
Normal file
74
app/views/partials/menu.blade.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
$r = Route::current()->getName();
|
||||
?>
|
||||
<nav class="navbar navbar-default" role="navigation">
|
||||
<div class="container-fluid">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="{{route('index')}}">Firefly III</a>
|
||||
</div>
|
||||
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav">
|
||||
<li @if($r=='index')class="active"@endif><a href="{{route('index')}}">Home</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Go to...<span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="{{route('accounts.index')}}"><span class="glyphicon glyphicon-inbox"></span> Accounts</a></li>
|
||||
<li><a href="{{route('budgets.index')}}"><span class="glyphicon glyphicon-euro"></span> Budgets</a></li>
|
||||
<li><a href="{{route('categories.index')}}"><span class="glyphicon glyphicon-tags"></span> Categories</a></li>
|
||||
|
||||
<li class="divider"></li>
|
||||
<li><a href="{{route('transactions.index')}}"><span class="glyphicon glyphicon-list-alt"></span> Transactions</a></li>
|
||||
<li><a href="{{route('recurring.index')}}"><span class="glyphicon glyphicon-refresh"></span> Recurring transactions</a></li>
|
||||
|
||||
<li class="divider"></li>
|
||||
<li><a href="{{route('piggybanks.index')}}"><span class="glyphicon glyphicon-save"></span> Piggy banks</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- the rest -->
|
||||
<ul class="nav navbar-nav">
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Add ... <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
|
||||
<li><a href="{{route('transactions.create','withdrawal')}}" title="For when you spend money"><span class="glyphicon glyphicon-arrow-left"></span> Withdrawal</a></li>
|
||||
<li><a href="{{route('transactions.create','deposit')}}" title="For when you earn money"><span class="glyphicon glyphicon-arrow-right"></span> Deposit</a></li>
|
||||
<li><a href="{{route('transactions.create','transfer')}}" title="For when you move money around"><span class="glyphicon glyphicon-resize-full"></span> Transfer</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Create ... <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="{{route('transactions.create','withdrawal')}}" title="For when you spend money"><span class="glyphicon glyphicon-arrow-left"></span> Withdrawal</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
@if(\Auth::user() && \Auth::check())
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li @if($r=='preferences')class="active"@endif><a href="{{route('preferences')}}"><span class="glyphicon glyphicon-cog"></span> Preferences</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{{{Auth::user()->email}}} <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="{{route('profile')}}"><span class="glyphicon glyphicon-user"></span> Profile</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="{{route('logout')}}"><span class="glyphicon glyphicon-arrow-right"></span> Logout</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@endif
|
||||
</div><!-- /.navbar-collapse -->
|
||||
</div><!-- /.container-fluid -->
|
||||
</nav>
|
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
$r = Route::current()->getName();
|
||||
?>
|
||||
<nav class="navbar navbar-default" role="navigation">
|
||||
<div class="container-fluid">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="{{route('index')}}">Firefly III</a>
|
||||
</div>
|
||||
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav">
|
||||
<li @if($r=='index')class="active"@endif><a href="{{route('index')}}">Home</a></li>
|
||||
<li @if($r=='accounts.index')class="active"@endif><a href="{{route('accounts.index')}}">Accounts</a></li>
|
||||
<li @if($r=='accounts.create')class="active"@endif><a href="{{route('accounts.create')}}"><span class="glyphicon glyphicon-plus"></span> Create account</a></li>
|
||||
</ul>
|
||||
@include('partials.menu.shared')
|
||||
</div><!-- /.navbar-collapse -->
|
||||
</div><!-- /.container-fluid -->
|
||||
</nav>
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
$r = Route::current()->getName();
|
||||
?>
|
||||
<nav class="navbar navbar-default" role="navigation">
|
||||
<div class="container-fluid">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="{{route('index')}}">Firefly III</a>
|
||||
</div>
|
||||
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav">
|
||||
<li @if($r=='index')class="active"@endif><a href="{{route('index')}}">Home</a></li>
|
||||
<li @if($r=='budgets.index')class="active"@endif><a href="{{route('budgets.index')}}">Budgets</a></li>
|
||||
<li @if($r=='budgets.create')class="active"@endif><a href="{{route('budgets.create')}}"><span class="glyphicon glyphicon-plus"></span> Create budget</a></li>
|
||||
<li @if($r=='budgets.limits.create')class="active"@endif><a href="{{route('budgets.limits.create')}}"><span class="glyphicon glyphicon-plus"></span> Create envelope</a></li>
|
||||
</ul>
|
||||
@include('partials.menu.shared')
|
||||
</div><!-- /.navbar-collapse -->
|
||||
</div><!-- /.container-fluid -->
|
||||
</nav>
|
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
$r = Route::current()->getName();
|
||||
?>
|
||||
<nav class="navbar navbar-default" role="navigation">
|
||||
<div class="container-fluid">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="{{route('index')}}">Firefly III</a>
|
||||
</div>
|
||||
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav">
|
||||
<li @if($r=='index')class="active"@endif><a href="{{route('index')}}">Home</a></li>
|
||||
<li @if($r=='categories.index')class="active"@endif><a href="{{route('categories.index')}}">Categories</a></li>
|
||||
<li @if($r=='categories.create')class="active"@endif><a href="{{route('categories.create')}}"><span class="glyphicon glyphicon-plus"></span> Create category</a></li>
|
||||
</ul>
|
||||
@include('partials.menu.shared')
|
||||
</div><!-- /.navbar-collapse -->
|
||||
</div><!-- /.container-fluid -->
|
||||
</nav>
|
@ -1,40 +0,0 @@
|
||||
<?php
|
||||
$r = Route::current()->getName();
|
||||
?>
|
||||
<nav class="navbar navbar-default" role="navigation">
|
||||
<div class="container-fluid">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="{{route('index')}}">Firefly III</a>
|
||||
</div>
|
||||
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav">
|
||||
<li @if($r=='index')class="active"@endif><a href="{{route('index')}}">Home</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Go to...<span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="{{route('accounts.index')}}"><span class="glyphicon glyphicon-inbox"></span> Accounts</a></li>
|
||||
<li><a href="{{route('budgets.index')}}"><span class="glyphicon glyphicon-euro"></span> Budgets</a></li>
|
||||
<li><a href="{{route('categories.index')}}"><span class="glyphicon glyphicon-tags"></span> Categories</a></li>
|
||||
|
||||
<li class="divider"></li>
|
||||
<li><a href="{{route('transactions.index')}}"><span class="glyphicon glyphicon-list-alt"></span> Transactions</a></li>
|
||||
<li><a href="{{route('recurring.index')}}"><span class="glyphicon glyphicon-refresh"></span> Recurring transactions</a></li>
|
||||
|
||||
<li class="divider"></li>
|
||||
<li><a href="{{route('piggybanks.index')}}"><span class="glyphicon glyphicon-save"></span> Piggy banks</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@include('partials.menu.shared')
|
||||
</div><!-- /.navbar-collapse -->
|
||||
</div><!-- /.container-fluid -->
|
||||
</nav>
|
@ -1,26 +0,0 @@
|
||||
<ul class="nav navbar-nav">
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Add... <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
|
||||
<li><a href="{{route('transactions.create','withdrawal')}}" title="For when you spend money"><span class="glyphicon glyphicon-arrow-left"></span> Withdrawal</a></li>
|
||||
<li><a href="{{route('transactions.create','deposit')}}" title="For when you earn money"><span class="glyphicon glyphicon-arrow-right"></span> Deposit</a></li>
|
||||
<li><a href="{{route('transactions.create','transfer')}}" title="For when you move money around"><span class="glyphicon glyphicon-resize-full"></span> Transfer</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@if(\Auth::user() && \Auth::check())
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li @if($r=='preferences')class="active"@endif><a href="{{route('preferences')}}"><span class="glyphicon glyphicon-cog"></span> Preferences</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{{{Auth::user()->email}}} <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="{{route('profile')}}"><span class="glyphicon glyphicon-user"></span> Profile</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="{{route('logout')}}"><span class="glyphicon glyphicon-arrow-right"></span> Logout</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@endif
|
@ -32,6 +32,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="account_id" class="col-sm-4 control-label">
|
||||
Saving account
|
||||
</label>
|
||||
<div class="col-sm-8">
|
||||
{{Form::select('account_id',$accounts,Input::old('account_id') ?: Input::get('account'),['class' => 'form-control'])}}
|
||||
@if($errors->has('account_id'))
|
||||
<p class="text-danger">{{$errors->first('account_id')}}</p>
|
||||
@else
|
||||
<span class="help-block">Indicate on which account you've got your savings.</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ Form::label('target', 'Target amount', ['class' => 'col-sm-4 control-label'])}}
|
||||
<div class="col-sm-8">
|
||||
@ -49,23 +63,39 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="account_id" class="col-sm-4 control-label">
|
||||
Saving account
|
||||
</label>
|
||||
<label for="create" class="col-sm-4 control-label">Repeat this piggy bank.</label>
|
||||
<div class="col-sm-8">
|
||||
{{Form::select('account_id',$accounts,Input::old('account_id') ?: Input::get('account'),['class' => 'form-control'])}}
|
||||
@if($errors->has('account_id'))
|
||||
<p class="text-danger">{{$errors->first('account_id')}}</p>
|
||||
@else
|
||||
<span class="help-block">Indicate on which account you've got your savings.</span>
|
||||
@endif
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
{{Form::checkbox('repeats',1,Input::old('repeats') == '1')}}
|
||||
Repeat this piggy bank
|
||||
</label>
|
||||
</div>
|
||||
<span class="help-block">If you need to save money annually (to save for taxes) use this form and fill
|
||||
in the fields that will appear.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="repeat-piggy">
|
||||
<h4>Mandatory fields for repeating piggy banks</h4>
|
||||
Fields be here.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="col-lg-6 col-md-12 col-sm-6">
|
||||
<h4>Optional fields</h4>
|
||||
|
||||
<div class="no-repeat-piggy">
|
||||
<h4>Optional fields for non-repeating piggy banks</h4>
|
||||
Fields be here
|
||||
</div>
|
||||
<div class="repeat-piggy">
|
||||
<h4>Optional fields for repeating piggy banks</h4>
|
||||
Fields be here.
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="form-group">
|
||||
{{ Form::label('targetdate', 'Target date', ['class' => 'col-sm-4 control-label'])}}
|
||||
<div class="col-sm-8">
|
||||
@ -81,6 +111,7 @@
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
|
||||
</div>
|
||||
@ -89,19 +120,6 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-12 col-sm-6">
|
||||
|
||||
<!-- add another after this one? -->
|
||||
<div class="form-group">
|
||||
<label for="create" class="col-sm-4 control-label"> </label>
|
||||
<div class="col-sm-8">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
{{Form::checkbox('create',1,Input::old('create') == '1')}}
|
||||
Create another (return to this form)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-4 col-sm-8">
|
||||
<button type="submit" class="btn btn-default btn-success">Create the piggy bank</button>
|
||||
@ -111,6 +129,7 @@
|
||||
</div>
|
||||
|
||||
{{Form::close()}}
|
||||
|
||||
|
||||
@stop
|
||||
@section('scripts')
|
||||
<?php echo javascript_include_tag('piggybanks-create'); ?>
|
||||
@stop
|
||||
|
@ -3,14 +3,44 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<h1>Firefly
|
||||
<small>Piggy banks</small>
|
||||
<small>Piggy banks, large expenses and repeated expenses</small>
|
||||
</h1>
|
||||
<p class="lead">Set targets and save money</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<p class="lead">Save money for large expenses</p>
|
||||
<p class="text-info">
|
||||
Saving money is <em>hard</em>. Piggy banks allow you to group money
|
||||
from an account together. If you also set a target (and a target date) you
|
||||
can save towards your goals.
|
||||
Saving money is <em>hard</em>. Firefly's piggy banks can help you to save money. Simply set the amount
|
||||
of money you want to save, set an optional target and whether or not Firefly should remind you to add money
|
||||
to the piggy bank.
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{route('piggybanks.create')}}" class="btn btn-success">Create new piggy bank</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<p class="lead">Repeated expenses</p>
|
||||
<p class="text-info">
|
||||
Taxes are due every year. Or maybe you want to save up for your yearly fireworks-binge. Buy a new smart
|
||||
phone every three years. Firefly can help you organize these repeated expenses.
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{route('piggybanks.create')}}" class="btn btn-success">Create new repeated expense</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{--
|
||||
|
||||
<p class="text-info">
|
||||
Saving money is <em>hard</em>. Firefly's piggy banks can help you to save money. You can do two things using
|
||||
these piggy banks:
|
||||
</p>
|
||||
<ol class="text-info">
|
||||
<li>Save money towards a singular goal such as a new bike or a new car.</li>
|
||||
<li>Save money repeatedly, for yearly expenses or long-term recurring investments. One example may be buying
|
||||
a new phone every three year.</li>
|
||||
</ol>
|
||||
@if($count == 0)
|
||||
<p>
|
||||
<a href="{{route('piggybanks.create')}}" class="btn btn-success">Create new piggy bank</a>
|
||||
@ -19,10 +49,44 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@if($count > 0)
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<h4>Accounts used for piggy banks</h4>
|
||||
<p class="text-info">
|
||||
@if(count($accounts) != 1)
|
||||
These (savings) accounts have
|
||||
@else
|
||||
This (savings) account has
|
||||
@endif
|
||||
@if(count($piggybanks) == 1)
|
||||
a piggy bank
|
||||
@else
|
||||
piggy banks
|
||||
@endif
|
||||
associated to
|
||||
@if(count($piggybanks) != 1)
|
||||
them.
|
||||
@else
|
||||
it.
|
||||
@endif
|
||||
If you transfer money to or from
|
||||
@if(count($accounts) != 1)
|
||||
these accounts,
|
||||
@else
|
||||
this account,
|
||||
@endif
|
||||
you may associate it with your @if(count($piggybanks) != 1)
|
||||
piggy banks.
|
||||
@else
|
||||
piggy bank.
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>Account</th>
|
||||
@ -47,7 +111,14 @@
|
||||
<h3>Piggy banks</h3>
|
||||
|
||||
@foreach($piggybanks as $piggybank)
|
||||
<h4><a href="{{route('piggybanks.show',$piggybank->id)}}">{{{$piggybank->name}}}</a> <small>{{mf($piggybank->target)}}</small></h4>
|
||||
<h4>
|
||||
<a href="{{route('piggybanks.show',$piggybank->id)}}">{{{$piggybank->name}}}</a>
|
||||
</h4>
|
||||
@endforeach
|
||||
|
||||
|
||||
@foreach($piggybanks as $piggybank)
|
||||
|
||||
@if(!is_null($piggybank->targetdate))
|
||||
<p>
|
||||
Target date: {{$piggybank->targetdate->format('jS F Y')}}
|
||||
@ -72,16 +143,15 @@
|
||||
</tr>
|
||||
</table>
|
||||
@endforeach
|
||||
|
||||
|
||||
<p>
|
||||
<a href="{{route('piggybanks.create')}}" class="btn btn-success">Create new piggy bank</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endif
|
||||
--}}
|
||||
|
||||
@stop
|
||||
@section('scripts')
|
||||
<script type="text/javascript">
|
||||
|
@ -5,4 +5,4 @@ php artisan clear-compiled --env=local
|
||||
php artisan ide-helper:generate --env=local
|
||||
php artisan ide-helper:models --env=local --write
|
||||
php artisan optimize --env=local
|
||||
php artisan dump-autoload --env=m n
|
||||
php artisan dump-autoload --env=local
|
Loading…
Reference in New Issue
Block a user