id(); $table->string('first_name'); $table->string('last_name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->string('phone')->nullable(); $table->date('date_of_birth')->nullable(); $table->enum('gender', ['male', 'female', 'other', 'prefer_not_to_say'])->nullable(); $table->string('avatar')->nullable(); $table->text('bio')->nullable(); $table->string('website')->nullable(); $table->string('linkedin')->nullable(); $table->string('github')->nullable(); $table->string('twitter')->nullable(); $table->json('preferences')->nullable(); // User preferences as JSON $table->boolean('newsletter_subscribed')->default(false); $table->timestamp('last_login_at')->nullable(); $table->string('last_login_ip')->nullable(); $table->enum('status', ['active', 'inactive', 'suspended'])->default('active'); $table->timestamp('suspended_at')->nullable(); $table->string('suspension_reason')->nullable(); $table->integer('login_attempts')->default(0); $table->timestamp('locked_until')->nullable(); $table->string('locale', 10)->default('en'); $table->string('timezone', 50)->default('UTC'); $table->boolean('two_factor_enabled')->default(false); $table->string('two_factor_secret')->nullable(); $table->json('two_factor_recovery_codes')->nullable(); $table->timestamp('profile_completed_at')->nullable(); $table->rememberToken(); $table->timestamps(); // Indexes for performance $table->index(['email', 'status']); $table->index(['last_login_at']); $table->index(['created_at']); $table->index(['status']); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('users'); } };