created admin panel with some of its content
This commit is contained in:
1 parent
2ee4b76599
commit
b16351c416
52 files changed
+5690
-203
No files matched your search
@@ -0,0 +1,64 @@
|
||||
<?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
|
||||
{
|
||||
// Roles table
|
||||
Schema::create('roles', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('slug')->unique();
|
||||
$table->text('description')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
// Permissions table
|
||||
Schema::create('permissions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('slug')->unique();
|
||||
$table->text('description')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
// Role-Permission pivot table
|
||||
Schema::create('role_permission', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('role_id')->constrained('roles')->cascadeOnDelete();
|
||||
$table->foreignId('permission_id')->constrained('permissions')->cascadeOnDelete();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['role_id', 'permission_id']);
|
||||
});
|
||||
|
||||
// User-Role pivot table (with tenant_id for club-specific roles)
|
||||
Schema::create('user_roles', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->foreignId('role_id')->constrained('roles')->cascadeOnDelete();
|
||||
$table->foreignId('tenant_id')->nullable()->constrained('tenants')->cascadeOnDelete();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['user_id', 'role_id', 'tenant_id']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('user_roles');
|
||||
Schema::dropIfExists('role_permission');
|
||||
Schema::dropIfExists('permissions');
|
||||
Schema::dropIfExists('roles');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,84 @@
|
||||
<?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::table('tenants', function (Blueprint $table) {
|
||||
// Basic Information
|
||||
$table->string('slogan')->nullable()->after('club_name');
|
||||
$table->text('description')->nullable()->after('slogan');
|
||||
$table->decimal('enrollment_fee', 10, 2)->default(0)->after('description');
|
||||
$table->string('commercial_reg_number')->nullable()->after('enrollment_fee');
|
||||
$table->string('vat_reg_number')->nullable()->after('commercial_reg_number');
|
||||
$table->decimal('vat_percentage', 5, 2)->default(0)->after('vat_reg_number');
|
||||
|
||||
// Contact Information
|
||||
$table->string('email')->nullable()->after('vat_percentage');
|
||||
$table->json('phone')->nullable()->after('email'); // {code: '+973', number: '12345678'}
|
||||
$table->string('currency', 3)->default('BHD')->after('phone'); // ISO 4217 currency code
|
||||
$table->string('timezone')->default('Asia/Bahrain')->after('currency');
|
||||
$table->string('country')->default('Bahrain')->after('timezone');
|
||||
$table->text('address')->nullable()->after('country');
|
||||
|
||||
// Branding Assets
|
||||
$table->string('favicon')->nullable()->after('logo');
|
||||
$table->string('cover_image')->nullable()->after('favicon');
|
||||
|
||||
// Owner Information (denormalized for quick access)
|
||||
$table->string('owner_name')->nullable()->after('owner_user_id');
|
||||
$table->string('owner_email')->nullable()->after('owner_name');
|
||||
|
||||
// Settings (JSON for code prefixes and other configurations)
|
||||
$table->json('settings')->nullable()->after('gps_long');
|
||||
// Example settings structure:
|
||||
// {
|
||||
// "member_code_prefix": "MEM",
|
||||
// "child_code_prefix": "CHILD",
|
||||
// "invoice_code_prefix": "INV",
|
||||
// "receipt_code_prefix": "REC",
|
||||
// "expense_code_prefix": "EXP",
|
||||
// "specialist_code_prefix": "SPEC"
|
||||
// }
|
||||
|
||||
// Soft Deletes
|
||||
$table->softDeletes()->after('updated_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('tenants', function (Blueprint $table) {
|
||||
$table->dropSoftDeletes();
|
||||
$table->dropColumn([
|
||||
'slogan',
|
||||
'description',
|
||||
'enrollment_fee',
|
||||
'commercial_reg_number',
|
||||
'vat_reg_number',
|
||||
'vat_percentage',
|
||||
'email',
|
||||
'phone',
|
||||
'currency',
|
||||
'timezone',
|
||||
'country',
|
||||
'address',
|
||||
'favicon',
|
||||
'cover_image',
|
||||
'owner_name',
|
||||
'owner_email',
|
||||
'settings',
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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('club_facilities', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete();
|
||||
$table->string('name');
|
||||
$table->string('photo')->nullable();
|
||||
$table->text('address')->nullable();
|
||||
$table->decimal('gps_lat', 10, 7)->nullable();
|
||||
$table->decimal('gps_long', 10, 7)->nullable();
|
||||
$table->boolean('is_available')->default(true);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('tenant_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('club_facilities');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
<?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('club_instructors', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->string('role')->default('Instructor'); // e.g., "TaeKwonDo Instructor", "Fitness Coach"
|
||||
$table->integer('experience_years')->default(0);
|
||||
$table->decimal('rating', 3, 2)->default(0.00); // 0.00 to 5.00
|
||||
$table->json('skills')->nullable(); // ["taekwondo", "fitness", "self-defense"]
|
||||
$table->text('bio')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('tenant_id');
|
||||
$table->index('user_id');
|
||||
$table->unique(['tenant_id', 'user_id']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('club_instructors');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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('club_activities', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete();
|
||||
$table->string('name'); // e.g., "TAEKWONDO (S.M.W) CLASS A"
|
||||
$table->integer('duration_minutes')->default(60);
|
||||
$table->integer('frequency_per_week')->default(3); // How many times per week
|
||||
$table->foreignId('facility_id')->nullable()->constrained('club_facilities')->nullOnDelete();
|
||||
$table->json('schedule')->nullable();
|
||||
// Example schedule structure:
|
||||
// [
|
||||
// {"day": "Saturday", "time": "16:00"},
|
||||
// {"day": "Monday", "time": "16:00"},
|
||||
// {"day": "Wednesday", "time": "16:00"}
|
||||
// ]
|
||||
$table->text('description')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('tenant_id');
|
||||
$table->index('facility_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('club_activities');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
<?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('club_packages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete();
|
||||
$table->string('name'); // e.g., "Juniors & Fighters (S.M.W) Group A"
|
||||
$table->string('cover_image')->nullable();
|
||||
$table->enum('type', ['single', 'multi'])->default('single'); // Single Activity or Multi Activity
|
||||
$table->integer('age_min')->nullable(); // Minimum age
|
||||
$table->integer('age_max')->nullable(); // Maximum age
|
||||
$table->enum('gender', ['mixed', 'male', 'female'])->default('mixed');
|
||||
$table->decimal('price', 10, 2); // Price in club's currency
|
||||
$table->integer('duration_months')->default(1); // Package duration in months
|
||||
$table->integer('session_count')->default(0); // Total sessions included (0 = unlimited)
|
||||
$table->text('description')->nullable();
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('tenant_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('club_packages');
|
||||
}
|
||||
};
|
||||
@@ -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('club_package_activities', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('package_id')->constrained('club_packages')->cascadeOnDelete();
|
||||
$table->foreignId('activity_id')->constrained('club_activities')->cascadeOnDelete();
|
||||
$table->foreignId('instructor_id')->nullable()->constrained('club_instructors')->nullOnDelete();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['package_id', 'activity_id']);
|
||||
$table->index('package_id');
|
||||
$table->index('activity_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('club_package_activities');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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('club_member_subscriptions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->foreignId('package_id')->constrained('club_packages')->cascadeOnDelete();
|
||||
$table->date('start_date');
|
||||
$table->date('end_date');
|
||||
$table->enum('status', ['active', 'expired', 'cancelled', 'pending'])->default('pending');
|
||||
$table->enum('payment_status', ['paid', 'unpaid', 'partial', 'refunded'])->default('unpaid');
|
||||
$table->decimal('amount_paid', 10, 2)->default(0);
|
||||
$table->decimal('amount_due', 10, 2)->default(0);
|
||||
$table->text('notes')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('tenant_id');
|
||||
$table->index('user_id');
|
||||
$table->index('package_id');
|
||||
$table->index('status');
|
||||
$table->index('end_date'); // For expiring subscriptions queries
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('club_member_subscriptions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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('club_transactions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->nullable()->constrained('users')->nullOnDelete(); // Member associated with transaction
|
||||
$table->enum('type', ['income', 'expense', 'refund'])->default('income');
|
||||
$table->string('category')->nullable(); // e.g., "Membership Fee", "Equipment", "Utilities"
|
||||
$table->decimal('amount', 10, 2);
|
||||
$table->enum('payment_method', ['cash', 'card', 'bank_transfer', 'online', 'other'])->default('cash');
|
||||
$table->text('description')->nullable();
|
||||
$table->date('transaction_date');
|
||||
$table->string('reference_number')->nullable(); // Invoice/Receipt number
|
||||
$table->foreignId('subscription_id')->nullable()->constrained('club_member_subscriptions')->nullOnDelete();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('tenant_id');
|
||||
$table->index('user_id');
|
||||
$table->index('type');
|
||||
$table->index('transaction_date');
|
||||
$table->index('reference_number');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('club_transactions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
<?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('club_gallery_images', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete();
|
||||
$table->string('image_path');
|
||||
$table->string('caption')->nullable();
|
||||
$table->foreignId('uploaded_by')->constrained('users')->cascadeOnDelete();
|
||||
$table->integer('display_order')->default(0);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('tenant_id');
|
||||
$table->index('uploaded_by');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('club_gallery_images');
|
||||
}
|
||||
};
|
||||
@@ -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('club_social_links', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete();
|
||||
$table->string('platform'); // e.g., "Instagram", "TikTok", "Snapchat", "WhatsApp", "Phone", "Email"
|
||||
$table->string('url'); // Full URL or contact info
|
||||
$table->string('icon')->nullable(); // Icon class or path
|
||||
$table->integer('display_order')->default(0);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('tenant_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('club_social_links');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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('club_bank_accounts', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete();
|
||||
$table->string('bank_name');
|
||||
$table->string('account_name');
|
||||
$table->text('account_number'); // Encrypted
|
||||
$table->text('iban')->nullable(); // Encrypted
|
||||
$table->text('swift_code')->nullable(); // Encrypted
|
||||
$table->boolean('is_primary')->default(false);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('tenant_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('club_bank_accounts');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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('club_messages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete();
|
||||
$table->foreignId('sender_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->foreignId('recipient_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->string('subject')->nullable();
|
||||
$table->text('message');
|
||||
$table->boolean('is_read')->default(false);
|
||||
$table->timestamp('read_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('tenant_id');
|
||||
$table->index('sender_id');
|
||||
$table->index('recipient_id');
|
||||
$table->index('is_read');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('club_messages');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
<?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('club_reviews', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained('tenants')->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->integer('rating'); // 1-5 stars
|
||||
$table->text('comment')->nullable();
|
||||
$table->boolean('is_approved')->default(false);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('tenant_id');
|
||||
$table->index('user_id');
|
||||
$table->index('rating');
|
||||
$table->unique(['tenant_id', 'user_id']); // One review per user per club
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('club_reviews');
|
||||
}
|
||||
};
|
||||
Reference in new issue
Block a user