Skip to content

Commit

Permalink
Rework blade component to replace it with VueJs in Inertia (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
RocketC31 authored Mar 25, 2022
1 parent 402d3a9 commit e9bb8fb
Show file tree
Hide file tree
Showing 243 changed files with 7,354 additions and 3,443 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ jobs:
run: composer install --no-interaction
- name: Generate key
run: php artisan key:generate
- name: npm install
run: npm install
- name: Run build js (for mix)
run: npm run production
- name: Prepare database
run: php artisan migrate --database=testing
- name: Run PHPUnit
Expand Down
26 changes: 20 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Budget

![GitHub latest release](https://img.shields.io/github/v/release/range-of-motion/budget?include_prereleases)
![GitHub downloads](https://img.shields.io/github/downloads/range-of-motion/budget/total)
[![Build status](https://travis-ci.com/range-of-motion/budget.svg?branch=master)](https://travis-ci.com/range-of-motion/budget)
[![codecov](https://codecov.io/gh/range-of-motion/budget/branch/master/graph/badge.svg)](https://codecov.io/gh/range-of-motion/budget)
[![GitHub license](https://img.shields.io/github/license/range-of-motion/budget.svg)](https://github.com/range-of-motion/budget/blob/master/LICENSE)
![GitHub latest release](https://img.shields.io/github/v/release/RocketC31/budget?include_prereleases)
![GitHub downloads](https://img.shields.io/github/downloads/RocketC31/budget/total)
[![Build status](https://travis-ci.com/RocketC31/budget.svg?branch=master)](https://travis-ci.com/RocketC31/budget)
[![codecov](https://codecov.io/gh/RocketC31/budget/branch/master/graph/badge.svg)](https://codecov.io/gh/RocketC31/budget)
[![GitHub license](https://img.shields.io/github/license/RocketC31/budget.svg)](https://github.com/RocketC31/budget/blob/master/LICENSE)

Budget is an open-source web application that helps you keep track of your finances.

Expand Down Expand Up @@ -33,7 +33,7 @@ You can use Budget by hosting it yourself, or using [the instance hosted by us](

## Installation

* Clone the repository (`git clone https://github.com/range-of-motion/budget.git`)
* Clone the repository (`git clone https://github.com/RocketC31/budget.git`)
* You should always check out a tag, since the `master` branch might not always be stable (`git checkout TAG`)
* Install dependencies (`composer install --no-dev -o`)
* Run installation command (`php artisan budget:install`)
Expand All @@ -51,6 +51,20 @@ Use the command below to update to the latest version.
php artisan budget:update
```

## Lang on front
Translations in VueJs is working with [matice librarie](https://github.com/GENL/matice)

If you want to use default lang path of laravel, do that :
```
php artisan vendor:publish --provider="Genl\Matice\MaticeServiceProvider"
```

And edit on `config/matice.php`

```PHP
'lang_directory' => lang_path(),
```

## Docker

You can get set-up with Budget using Docker.
Expand Down
2 changes: 2 additions & 0 deletions app/Actions/CreateUserAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Actions;

use App\Models\User;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

Expand All @@ -14,6 +15,7 @@ public function execute(string $name, string $email, string $password): User
'name' => $name,
'email' => $email,
'password' => Hash::make($password),
'language' => App::getLocale(),
'verification_token' => Str::random(100)
]);

Expand Down
5 changes: 4 additions & 1 deletion app/Actions/SendVerificationMailAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ public function execute(int $userId): void
throw new VerificationMailRateLimitException();
}

Mail::to($user->email)->queue(new VerifyRegistration($user));
try {
Mail::to($user->email)->queue(new VerifyRegistration($user));
} catch (\Exception $e) {
}

$user->fill([
'last_verification_mail_sent_at' => date('Y-m-d H:i:s')
Expand Down
3 changes: 2 additions & 1 deletion app/Http/Controllers/ActivityController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
namespace App\Http\Controllers;

use App\Models\Activity;
use Inertia\Inertia;

class ActivityController extends Controller
{
public function index()
{
$activities = Activity::ofSpace(session('space_id'))->get();

return view('activities.index', ['activities' => $activities]);
return Inertia::Render('Activities/Index', ['activities' => $activities]);
}
}
10 changes: 6 additions & 4 deletions app/Http/Controllers/AttachmentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,22 @@

use App\Models\Attachment;
use App\Repositories\AttachmentRepository;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class AttachmentController extends Controller
{
private $attachmentRepository;
private AttachmentRepository $attachmentRepository;

public function __construct(AttachmentRepository $attachmentRepository)
{
$this->attachmentRepository = $attachmentRepository;
}

public function store(Request $request)
public function store(Request $request): RedirectResponse
{
$request->validate([
'transaction_type' => 'required|in:earning,spending',
Expand All @@ -33,10 +35,10 @@ public function store(Request $request)

$this->attachmentRepository->create($transactionType, $transactionId, $filePath);

return redirect('/' . $transactionType . 's/' . $transactionId);
return redirect()->intended('/' . $transactionType . 's/' . $transactionId);
}

public function download(Request $request, Attachment $attachment)
public function download(Request $request, Attachment $attachment): ?BinaryFileResponse
{
$user = Auth::user();

Expand Down
87 changes: 87 additions & 0 deletions app/Http/Controllers/Auth/AuthenticatedSessionController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

namespace App\Http\Controllers\Auth;

use App\Actions\StoreSpaceInSessionAction;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Models\User;
use App\Providers\RouteServiceProvider;
use App\Repositories\LoginAttemptRepository;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;
use Inertia\Response;
use Nette\Schema\ValidationException;

class AuthenticatedSessionController extends Controller
{
private LoginAttemptRepository $loginAttemptRepository;

public function __construct(LoginAttemptRepository $loginAttemptRepository)
{
$this->loginAttemptRepository = $loginAttemptRepository;
}

/**
* Display the login view.
*
* @return Response
*/
public function create(): Response
{
return Inertia::render('Auth/Login', [
'canResetPassword' => Route::has('password.request'),
'status' => session('status'),
]);
}

/**
* Handle an incoming authentication request.
*
* @param LoginRequest $request
* @return RedirectResponse
* @throws \Illuminate\Validation\ValidationException
*/
public function store(LoginRequest $request): RedirectResponse
{
try {
$request->authenticate();

$user = Auth::user();
$request->session()->regenerate();
$this->loginAttemptRepository->create($user->id, $request->ip(), false);
if (count($user->spaces) > 0) {
(new StoreSpaceInSessionAction())->execute($user->spaces[0]->id);
}

return redirect()->intended(RouteServiceProvider::HOME);
} catch (ValidationException $validationException) {
if ($request->input('email')) {
$user = User::where('email', $request->input('email'))->first();

$this->loginAttemptRepository->create($user?->id, $request->ip(), true);
}
throw $validationException;
}
}

/**
* Destroy an authenticated session.
*
* @param Request $request
* @return RedirectResponse
*/
public function destroy(Request $request): RedirectResponse
{
Auth::guard('web')->logout();

$request->session()->invalidate();

$request->session()->regenerateToken();

return redirect('/');
}
}
93 changes: 93 additions & 0 deletions app/Http/Controllers/Auth/PasswordResetLinkController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Mail\ResetPassword;
use App\Models\User;
use App\Repositories\PasswordResetRepository;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
use Inertia\Inertia;

class PasswordResetLinkController extends Controller
{
private PasswordResetRepository $passwordResetRepository;

public function __construct(PasswordResetRepository $passwordResetRepository)
{
$this->passwordResetRepository = $passwordResetRepository;
}

/**
* Display the password reset link request view.
*
* @return \Inertia\Response
*/
public function create(Request $request)
{
return Inertia::render('Auth/ForgotPassword', [
'status' => session('status'),
'token' => $request->get('token'),
]);
}

/**
* Handle an incoming password reset link request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request)
{
$request->validate(User::getValidationRulesForPasswordReset());

if ($request->input('email') && !$request->has('token')) {
$email = $request->input('email');

$existingUser = User::where('email', $email)->first();

if ($existingUser) {
$existingRecord = $this->passwordResetRepository->getByEmail($email);

if (!$existingRecord) {
$shippingToken = Str::random(100);

$this->passwordResetRepository->create($email, $shippingToken);
} else {
$shippingToken = $existingRecord->token;
}

try {
Mail::to($email)->queue(new ResetPassword($shippingToken));
} catch (\Exception $e) {
}
}

$request->session()->flash('message', 'success');
return back();
} elseif ($request->has('token') && $request->has('password') && !$request->has('email')) {
$token = $request->input('token');
$password = $request->input('password');

$record = $this->passwordResetRepository->getByToken($token);

if ($record) {
$user = User::where('email', $record->email)->first();

$user->update(['password' => Hash::make($password)]);
}

$this->passwordResetRepository->delete($token);
$request->session()->flash('message', 'success');
return redirect()
->route('login');
}

return back();
}
}
76 changes: 76 additions & 0 deletions app/Http/Controllers/Auth/RegisteredUserController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace App\Http\Controllers\Auth;

use App\Actions\CreateUserAction;
use App\Actions\SendVerificationMailAction;
use App\Actions\StoreSpaceInSessionAction;
use App\Http\Controllers\Controller;
use App\Models\Currency;
use App\Models\User;
use App\Providers\RouteServiceProvider;
use App\Repositories\LoginAttemptRepository;
use App\Repositories\SpaceRepository;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Inertia\Inertia;
use Inertia\Response;

class RegisteredUserController extends Controller
{
private SpaceRepository $spaceRepository;
private LoginAttemptRepository $loginAttemptRepository;

public function __construct(
SpaceRepository $spaceRepository,
LoginAttemptRepository $loginAttemptRepository
) {
$this->spaceRepository = $spaceRepository;
$this->loginAttemptRepository = $loginAttemptRepository;
}

/**
* Display the registration view.
*
* @return Response
*/
public function create(): Response
{
if (config('app.disable_registration')) {
abort(404);
}

return Inertia::render('Auth/Register', [
'currencies' => Currency::orderBy('name')->get()
]);
}

/**
* Handle an incoming registration request.
*
*/
public function store(Request $request)
{
if (config('app.disable_registration')) {
abort(404);
}

$request->validate(User::getValidationRulesForRegistration());
$user = (new CreateUserAction())->execute($request->name, $request->email, $request->password);
$space = $this->spaceRepository->create($request->currency, $user->name . '\'s Space');
$user->spaces()->attach($space->id, ['role' => 'admin']);

event(new Registered($user));

Auth::login($user);

$this->loginAttemptRepository->create($user->id, $request->ip(), false);

(new StoreSpaceInSessionAction())->execute($user->spaces[0]->id);

(new SendVerificationMailAction())->execute($user->id);

return redirect(RouteServiceProvider::HOME);
}
}
Loading

0 comments on commit e9bb8fb

Please sign in to comment.