This commit is contained in:
elnuage 2026-07-18 11:40:40 +01:00 committed by GitHub
commit 7a100554a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 127 additions and 0 deletions

View File

@ -0,0 +1,44 @@
<?php
namespace App\Http\Controllers;
use App\Models\PersonalSubscription;
use Illuminate\Http\Request;
use Inertia\Inertia;
class PersonalSubscriptionController extends Controller
{
public function index(Request $request)
{
return Inertia::render('PersonalSubscriptions/index', [
'subscriptions' => $request->user()
->personalSubscriptions()
->orderBy('next_billing_date')
->get(),
]);
}
public function store(Request $request)
{
$validated = $request->validate([
'name' => ['required', 'string', 'max:255'],
'amount' => ['required', 'numeric', 'min:0'],
'currency' => ['required', 'string', 'size:3'],
'billing_cycle' => ['required', 'in:weekly,monthly,biweekly,yearly'],
'next_billing_date' => ['required', 'date'],
'color' => ['nullable', 'string', 'max:20'],
]);
$request->user()->personalSubscriptions()->create($validated);
return back();
}
public function destroy(Request $request, PersonalSubscription $personalSubscription)
{
abort_unless($personalSubscription->user_id === $request->user()->id, 403);
$personalSubscription->delete();
return back();
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class PersonalSubscription extends Model
{
protected $fillable = [
'name', 'amount', 'currency', 'billing_cycle', 'next_billing_date', 'color',
];
protected $casts = [
'next_billing_date' => 'date',
'amount' => 'decimal:2',
];
public function user()
{
return $this->belongsTo(User::class);
}
}

View File

@ -521,4 +521,9 @@ class User extends Authenticatable implements HasLocalePreference, MustVerifyEma
return "{$timestamp}_{$this->getKey()}_{$originalEmail}";
}
public function personalSubscriptions()
{
return $this->hasMany(PersonalSubscription::class);
}
}

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('personal_subscriptions', function (Blueprint $table) {
$table->id();
$table->foreignUuid('user_id')->constrained()->cascadeOnDelete();
$table->string('name');
$table->decimal('amount', 8, 2);
$table->string('currency', 3)->default('EUR');
$table->enum('billing_cycle', ['weekly', 'monthly', 'biweekly', 'yearly'])->default('monthly');
$table->date('next_billing_date');
$table->string('color')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('personal_subscriptions');
}
};

View File

@ -1,9 +1,11 @@
import { index as accountsIndex } from '@/actions/App/Http/Controllers/AccountController';
import { index as budgetsIndex } from '@/actions/App/Http/Controllers/BudgetController';
import { index as transactionsIndex } from '@/actions/App/Http/Controllers/TransactionController';
import { index as PersonalSubscriptionIndex } from '@/actions/App/Http/Controllers/PersonalSubscriptionController';
import { cashflow, dashboard } from '@/routes';
import { Features, NavItem } from '@/types';
import {
CalendarSync,
CreditCard,
LayoutGrid,
PiggyBank,
@ -26,6 +28,13 @@ const mobileLabels: Record<string, Record<string, string>> = {
transactions: 'Movim.',
budgets: 'Presup.',
},
fr: {
dashboard: 'Accueil',
cashflow: 'Trésorerie',
accounts: 'Comptes',
transactions: 'Mouvements',
budgets: 'Budget',
},
};
function getMobileLabel(key: string, locale: string): string {
@ -75,6 +84,13 @@ export function getMainNavItems(features: Features, locale: string): NavItem[] {
href: budgetsIndex(),
icon: PiggyBank,
},
{
type: 'nav-item',
title: 'Subscriptions',
mobileTitle: getMobileLabel('budgets', locale),
href: PersonalSubscriptionIndex(),
icon: CalendarSync,
},
);
return items;

View File

@ -28,6 +28,7 @@ use App\Http\Controllers\SitemapController;
use App\Http\Controllers\SubscriptionController;
use App\Http\Controllers\TransactionController;
use App\Http\Controllers\UserLeadController;
use App\Http\Controllers\PersonalSubscriptionController;
use App\Models\Bank;
use App\Services\LandingAuthOverrideService;
use Illuminate\Http\Request;
@ -194,4 +195,9 @@ Route::middleware(['auth', 'verified', 'onboarded', 'subscribed'])->group(functi
Route::delete('budgets/{budget}', [BudgetController::class, 'destroy'])->name('budgets.destroy');
});
Route::middleware(['auth'])->group(function () {
Route::resource('personal-subscriptions', PersonalSubscriptionController::class)
->only(['index', 'store', 'destroy']);
});
require __DIR__.'/settings.php';