initial: project state before operator dashboard card redesign
This commit is contained in:
commit
e0aed8eed7
113 files changed
+20074
No files matched your search
@@ -0,0 +1 @@
|
||||
*.sqlite*
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @extends Factory<User>
|
||||
*/
|
||||
class UserFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The current password being used by the factory.
|
||||
*/
|
||||
protected static ?string $password;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => fake()->name(),
|
||||
'email' => fake()->unique()->safeEmail(),
|
||||
'email_verified_at' => now(),
|
||||
'password' => static::$password ??= Hash::make('password'),
|
||||
'remember_token' => Str::random(10),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that the model's email address should be unverified.
|
||||
*/
|
||||
public function unverified(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'email_verified_at' => null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?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('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('password_reset_tokens', function (Blueprint $table) {
|
||||
$table->string('email')->primary();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
|
||||
Schema::create('sessions', function (Blueprint $table) {
|
||||
$table->string('id')->primary();
|
||||
$table->foreignId('user_id')->nullable()->index();
|
||||
$table->string('ip_address', 45)->nullable();
|
||||
$table->text('user_agent')->nullable();
|
||||
$table->longText('payload');
|
||||
$table->integer('last_activity')->index();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('users');
|
||||
Schema::dropIfExists('password_reset_tokens');
|
||||
Schema::dropIfExists('sessions');
|
||||
}
|
||||
};
|
||||
@@ -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('cache', function (Blueprint $table) {
|
||||
$table->string('key')->primary();
|
||||
$table->mediumText('value');
|
||||
$table->integer('expiration')->index();
|
||||
});
|
||||
|
||||
Schema::create('cache_locks', function (Blueprint $table) {
|
||||
$table->string('key')->primary();
|
||||
$table->string('owner');
|
||||
$table->integer('expiration')->index();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('cache');
|
||||
Schema::dropIfExists('cache_locks');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
<?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('jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('queue')->index();
|
||||
$table->longText('payload');
|
||||
$table->unsignedTinyInteger('attempts');
|
||||
$table->unsignedInteger('reserved_at')->nullable();
|
||||
$table->unsignedInteger('available_at');
|
||||
$table->unsignedInteger('created_at');
|
||||
});
|
||||
|
||||
Schema::create('job_batches', function (Blueprint $table) {
|
||||
$table->string('id')->primary();
|
||||
$table->string('name');
|
||||
$table->integer('total_jobs');
|
||||
$table->integer('pending_jobs');
|
||||
$table->integer('failed_jobs');
|
||||
$table->longText('failed_job_ids');
|
||||
$table->mediumText('options')->nullable();
|
||||
$table->integer('cancelled_at')->nullable();
|
||||
$table->integer('created_at');
|
||||
$table->integer('finished_at')->nullable();
|
||||
});
|
||||
|
||||
Schema::create('failed_jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uuid')->unique();
|
||||
$table->text('connection');
|
||||
$table->text('queue');
|
||||
$table->longText('payload');
|
||||
$table->longText('exception');
|
||||
$table->timestamp('failed_at')->useCurrent();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('jobs');
|
||||
Schema::dropIfExists('job_batches');
|
||||
Schema::dropIfExists('failed_jobs');
|
||||
}
|
||||
};
|
||||
@@ -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('parking_lots', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->text('address');
|
||||
$table->integer('total_capacity');
|
||||
$table->decimal('price_per_hour', 8, 0);
|
||||
$table->decimal('latitude', 10, 8);
|
||||
$table->decimal('longitude', 11, 8);
|
||||
$table->string('working_hours')->default('24/7');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('parking_lots');
|
||||
}
|
||||
};
|
||||
?>
|
||||
|
||||
@@ -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('bookings', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('parking_lot_id')->constrained()->onDelete('cascade');
|
||||
$table->string('customer_name');
|
||||
$table->string('phone');
|
||||
$table->dateTime('start_time');
|
||||
$table->dateTime('end_time');
|
||||
$table->enum('status', ['active', 'completed', 'cancelled'])->default('active');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('bookings');
|
||||
}
|
||||
};
|
||||
?>
|
||||
|
||||
@@ -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('car_registries', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('parking_lot_id')->constrained()->onDelete('cascade');
|
||||
$table->string('plate_number');
|
||||
$table->dateTime('entry_time');
|
||||
$table->dateTime('exit_time')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['parking_lot_id', 'exit_time']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('car_registries');
|
||||
}
|
||||
};
|
||||
?>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?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_access_tokens', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->morphs('tokenable');
|
||||
$table->text('name');
|
||||
$table->string('token', 64)->unique();
|
||||
$table->text('abilities')->nullable();
|
||||
$table->timestamp('last_used_at')->nullable();
|
||||
$table->timestamp('expires_at')->nullable()->index();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('personal_access_tokens');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?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('parking_lots', function (Blueprint $table) {
|
||||
$table->boolean('is_active')->default(true)->after('working_hours');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('parking_lots', function (Blueprint $table) {
|
||||
$table->dropColumn('is_active');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->enum('role', ['user', 'admin', 'operator'])->default('user')->after('email');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('role');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?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('bookings', function (Blueprint $table) {
|
||||
$table->foreignId('user_id')->nullable()->after('id')->constrained('users')->nullOnDelete();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('bookings', function (Blueprint $table) {
|
||||
$table->dropForeignIdFor(\App\Models\User::class);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?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('bookings', function (Blueprint $table) {
|
||||
$table->string('vehicle_plate')->nullable()->after('phone');
|
||||
$table->enum('source', ['walk_in', 'reservation'])->default('reservation')->after('vehicle_plate');
|
||||
$table->decimal('total_fee', 10, 2)->nullable()->after('status');
|
||||
$table->enum('payment_method', ['cash', 'upload'])->nullable()->after('total_fee');
|
||||
$table->string('payment_proof')->nullable()->after('payment_method');
|
||||
$table->timestamp('paid_at')->nullable()->after('payment_proof');
|
||||
$table->string('customer_name')->nullable()->change();
|
||||
$table->string('phone')->nullable()->change();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('bookings', function (Blueprint $table) {
|
||||
$table->dropColumn(['vehicle_plate', 'source', 'total_fee', 'payment_method', 'payment_proof', 'paid_at']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
<?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('parking_lots', function (Blueprint $table) {
|
||||
// JSON: {"1":100,"2":100,...,"7":150} keys = ISO weekday (1=Mon,7=Sun), values = price/hour
|
||||
$table->json('pricing_rules')->nullable()->after('price_per_hour');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('parking_lots', function (Blueprint $table) {
|
||||
$table->dropColumn('pricing_rules');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class AdminUserSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
// Super Admin
|
||||
User::updateOrCreate(
|
||||
['email' => '[email protected]'],
|
||||
[
|
||||
'name' => 'مدير النظام',
|
||||
'role' => 'admin',
|
||||
'password' => Hash::make('admin123'),
|
||||
]
|
||||
);
|
||||
|
||||
// Operator
|
||||
User::updateOrCreate(
|
||||
['email' => '[email protected]'],
|
||||
[
|
||||
'name' => 'مشغل الموقف',
|
||||
'role' => 'operator',
|
||||
'password' => Hash::make('operator123'),
|
||||
]
|
||||
);
|
||||
|
||||
echo "✅ Super Admin: [email protected] / admin123\n";
|
||||
echo "✅ Operator: [email protected] / operator123\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Booking;
|
||||
use App\Models\ParkingLot;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class BookingSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$lots = ParkingLot::all();
|
||||
|
||||
if ($lots->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$names = ['أحمد الخطيب', 'سامر العلي', 'رنا موسى', 'خالد إبراهيم', 'منى حسن',
|
||||
'عمر الزعبي', 'لينا صالح', 'فراس نعمة', 'هبة الدار', 'باسل قاسم',
|
||||
'نور السيد', 'وسيم طه', 'ديانا فارس', 'زياد جبر', 'ريم عبدالله'];
|
||||
|
||||
$phones = ['0912345678', '0923456789', '0934567890', '0945678901', '0956789012',
|
||||
'0967890123', '0978901234', '0989012345', '0990123456', '0901234567'];
|
||||
|
||||
$now = Carbon::now();
|
||||
|
||||
// Seed bookings spread across the last 7 days
|
||||
foreach ($lots as $lot) {
|
||||
// 2–5 active bookings per lot
|
||||
$activeCount = rand(2, 5);
|
||||
for ($i = 0; $i < $activeCount; $i++) {
|
||||
$start = $now->clone()->subHours(rand(1, 5));
|
||||
$end = $start->clone()->addHours(rand(1, 4));
|
||||
Booking::create([
|
||||
'parking_lot_id' => $lot->id,
|
||||
'customer_name' => $names[array_rand($names)],
|
||||
'phone' => $phones[array_rand($phones)],
|
||||
'start_time' => $start,
|
||||
'end_time' => $end,
|
||||
'status' => 'active',
|
||||
'created_at' => $start,
|
||||
'updated_at' => $start,
|
||||
]);
|
||||
}
|
||||
|
||||
// 3–8 completed bookings spread over the past 7 days
|
||||
$completedCount = rand(3, 8);
|
||||
for ($i = 0; $i < $completedCount; $i++) {
|
||||
$daysAgo = rand(0, 6);
|
||||
$start = $now->clone()->subDays($daysAgo)->subHours(rand(2, 10));
|
||||
$end = $start->clone()->addHours(rand(1, 3));
|
||||
Booking::create([
|
||||
'parking_lot_id' => $lot->id,
|
||||
'customer_name' => $names[array_rand($names)],
|
||||
'phone' => $phones[array_rand($phones)],
|
||||
'start_time' => $start,
|
||||
'end_time' => $end,
|
||||
'status' => 'completed',
|
||||
'created_at' => $start,
|
||||
'updated_at' => $end,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
{
|
||||
use WithoutModelEvents;
|
||||
|
||||
/**
|
||||
* Seed the application's database.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// User::factory(10)->create();
|
||||
|
||||
$this->call(ParkingLotSeeder::class);
|
||||
$this->call(BookingSeeder::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\Models\ParkingLot;
|
||||
use App\Models\CarRegistry;
|
||||
|
||||
class ParkingLotSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$lots = [
|
||||
[
|
||||
'name' => 'موقف البرامكة',
|
||||
'address' => 'شارع البرامكة، دمشق',
|
||||
'total_capacity' => 120,
|
||||
'price_per_hour' => 1500,
|
||||
'latitude' => 33.5138,
|
||||
'longitude' => 36.2765,
|
||||
'working_hours' => '06:00 - 22:00',
|
||||
],
|
||||
[
|
||||
'name' => 'موقف المرجة',
|
||||
'address' => 'ساحة المرجة، دمشق القديمة',
|
||||
'total_capacity' => 80,
|
||||
'price_per_hour' => 2000,
|
||||
'working_hours' => '24/7',
|
||||
'latitude' => 33.5105,
|
||||
'longitude' => 36.3118,
|
||||
],
|
||||
[
|
||||
'name' => 'موقف المالكي',
|
||||
'address' => 'شارع المالكي، دمشق',
|
||||
'total_capacity' => 60,
|
||||
'price_per_hour' => 1200,
|
||||
'working_hours' => '24/7',
|
||||
'latitude' => 33.5230,
|
||||
'longitude' => 36.3050,
|
||||
],
|
||||
[
|
||||
'name' => 'موقف المزة',
|
||||
'address' => 'شارع المزة الأوتوستراد',
|
||||
'total_capacity' => 100,
|
||||
'price_per_hour' => 1800,
|
||||
'working_hours' => '05:00 - 23:00',
|
||||
'latitude' => 33.5080,
|
||||
'longitude' => 36.2650,
|
||||
],
|
||||
[
|
||||
'name' => 'موقف كفرسوسة',
|
||||
'address' => 'طريق المزة، كفرسوسة',
|
||||
'total_capacity' => 75,
|
||||
'price_per_hour' => 1000,
|
||||
'working_hours' => '24/7',
|
||||
'latitude' => 33.4980,
|
||||
'longitude' => 36.2450,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($lots as $lotData) {
|
||||
$lot = ParkingLot::create($lotData);
|
||||
|
||||
// Seed some active car registries (walk-ins + bookings) for realistic availability
|
||||
$occupied = rand(10, (int)($lotData['total_capacity'] * 0.4)); // 10-40% occupied
|
||||
for ($i = 0; $i < $occupied; $i++) {
|
||||
CarRegistry::create([
|
||||
'parking_lot_id' => $lot->id,
|
||||
'plate_number' => sprintf('%d س دم %s', rand(100, 999), substr(md5(rand()), 0, 3)),
|
||||
'entry_time' => now()->subHours(rand(1, 12)),
|
||||
'exit_time' => rand(0, 4) > 3 ? null : now()->addHours(rand(1, 6)), // Most still active
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
Reference in new issue
Block a user