built user profile added the logo created the family view etc

This commit is contained in:
ghassan committed 2026-01-20 16:19:00 +03:00
1 parent 4a7353e3fc
commit 43c2676d6f
33 files changed
+3783 -257

No files matched your search

@@ -0,0 +1,61 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AuthenticatedSessionController extends Controller
{
/**
* Display the login view.
*
* @return \Illuminate\View\View
*/
public function create()
{
return view('auth.login');
}
/**
* Handle an incoming authentication request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function store(Request $request)
{
$credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return redirect()->route('family.dashboard');
}
return back()->withErrors([
'email' => 'The provided credentials do not match our records.',
])->onlyInput('email');
}
/**
* Destroy an authenticated session.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(Request $request)
{
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}
@@ -0,0 +1,64 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
class NewPasswordController extends Controller
{
/**
* Display the password reset view.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\View\View
*/
public function create(Request $request)
{
return view('auth.reset-password', ['request' => $request]);
}
/**
* Handle an incoming new password request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request)
{
$request->validate([
'token' => ['required'],
'email' => ['required', 'email'],
'password' => ['required', 'confirmed', 'min:8'],
]);
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$status = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function ($user) use ($request) {
$user->forceFill([
'password' => Hash::make($request->password),
'remember_token' => Str::random(60),
])->save();
event(new PasswordReset($user));
}
);
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $status == Password::PASSWORD_RESET
? redirect()->route('login')->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
}
@@ -0,0 +1,47 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
class PasswordResetLinkController extends Controller
{
/**
* Display the password reset link request view.
*
* @return \Illuminate\View\View
*/
public function create()
{
return view('auth.forgot-password');
}
/**
* 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([
'email' => ['required', 'email'],
]);
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$status = Password::sendResetLink(
$request->only('email')
);
return $status == Password::RESET_LINK_SENT
? back()->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
}
@@ -0,0 +1,68 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Mail\WelcomeEmail;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Validation\Rules;
class RegisteredUserController extends Controller
{
/**
* Display the registration view.
*
* @return \Illuminate\View\View
*/
public function create()
{
return view('auth.register');
}
/**
* Handle an incoming registration request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request)
{
$request->validate([
'full_name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users,email'],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
'mobile_number' => ['required', 'string', 'max:20'],
'gender' => ['required', 'in:m,f'],
'birthdate' => ['required', 'date', 'before:today'],
'country_code' => ['required', 'string', 'max:10'],
'nationality' => ['required', 'string', 'max:255'],
]);
$user = User::create([
'name' => $request->full_name,
'full_name' => $request->full_name,
'email' => $request->email,
'password' => Hash::make($request->password),
'mobile' => $request->country_code . $request->mobile_number,
'gender' => $request->gender,
'birthdate' => $request->birthdate,
'nationality' => $request->nationality,
]);
event(new Registered($user));
// Send welcome email
Mail::to($user->email)->send(new WelcomeEmail($user, $user, null));
Auth::login($user);
return redirect()->route('login')->with('success', 'Registration successful! Please login with your credentials.');
}
}
+26 -3
View File
@@ -27,12 +27,35 @@ class FamilyController extends Controller
$user = Auth::user();
$dependents = UserRelationship::where('guardian_user_id', $user->id)
->with('dependent')
->get();
->get()
->sortBy(function($relationship) {
return $relationship->dependent->full_name;
});
$familyInvoices = $this->familyService->getFamilyInvoices($user->id);
return view('family.dashboard', compact('user', 'dependents', 'familyInvoices'));
}
/**
* Display the current user's profile.
*
* @return \Illuminate\View\View
*/
public function profile()
{
$user = Auth::user();
// Pass user directly and a flag to indicate it's the current user's profile
return view('family.show', [
'relationship' => (object)[
'dependent' => $user,
'relationship_type' => 'self',
'guardian_user_id' => $user->id,
'dependent_user_id' => $user->id,
]
]);
}
/**
* Show the form for creating a new family member.
*
@@ -54,7 +77,7 @@ class FamilyController extends Controller
$validated = $request->validate([
'full_name' => 'required|string|max:255',
'email' => 'nullable|email|max:255',
'gender' => 'required|in:male,female',
'gender' => 'required|in:m,f',
'birthdate' => 'required|date',
'blood_type' => 'nullable|string|max:10',
'nationality' => 'required|string|max:100',
@@ -115,7 +138,7 @@ class FamilyController extends Controller
$validated = $request->validate([
'full_name' => 'required|string|max:255',
'email' => 'nullable|email|max:255',
'gender' => 'required|in:male,female',
'gender' => 'required|in:m,f',
'birthdate' => 'required|date',
'blood_type' => 'nullable|string|max:10',
'nationality' => 'required|string|max:100',
+83
View File
@@ -0,0 +1,83 @@
<?php
namespace App\Mail;
use App\Models\User;
use App\Models\UserRelationship;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
class WelcomeEmail extends Mailable
{
/**
* The user instance.
*
* @var \App\Models\User
*/
public $user;
/**
* The guardian user instance.
*
* @var \App\Models\User|null
*/
public $guardian;
/**
* The relationship instance.
*
* @var \App\Models\UserRelationship|null
*/
public $relationship;
/**
* Create a new message instance.
*
* @param \App\Models\User $user
* @param \App\Models\User|null $guardian
* @param \App\Models\UserRelationship|null $relationship
* @return void
*/
public function __construct(User $user, ?User $guardian = null, ?UserRelationship $relationship = null)
{
$this->user = $user;
$this->guardian = $guardian;
$this->relationship = $relationship;
}
/**
* Get the message envelope.
*
* @return \Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
{
return new Envelope(
subject: 'Welcome to ' . config('app.name', 'Club SaaS') . ' - ' . $this->user->full_name,
);
}
/**
* Get the message content definition.
*
* @return \Illuminate\Mail\Mailables\Content
*/
public function content()
{
return new Content(
view: 'emails.welcome',
);
}
/**
* Get the attachments for the message.
*
* @return array
*/
public function attachments()
{
return [];
}
}
+1
View File
@@ -22,6 +22,7 @@ class User extends Authenticatable
* @var list<string>
*/
protected $fillable = [
'name',
'full_name',
'email',
'mobile',
+19 -3
View File
@@ -5,6 +5,8 @@ namespace App\Services;
use App\Models\User;
use App\Models\UserRelationship;
use App\Models\Invoice;
use App\Mail\WelcomeEmail;
use Illuminate\Support\Facades\Mail;
class FamilyService
{
@@ -17,15 +19,24 @@ class FamilyService
*/
public function createDependent(User $guardian, array $data): User
{
// Normalize gender value to match database enum (m/f)
$gender = $data['gender'];
if ($gender === 'male') {
$gender = 'm';
} elseif ($gender === 'female') {
$gender = 'f';
}
// Create the dependent user
$dependent = User::create([
'name' => $data['full_name'], // Required by database
'full_name' => $data['full_name'],
'email' => $data['email'] ?? null,
'password' => $data['password'] ?? null,
'mobile' => $data['mobile'] ?? null,
'gender' => $data['gender'],
'gender' => $gender,
'birthdate' => $data['birthdate'],
'blood_type' => $data['blood_type'] ?? null,
'blood_type' => $data['blood_type'] ?? 'Unknown',
'nationality' => $data['nationality'],
'addresses' => $data['addresses'] ?? [],
'social_links' => $data['social_links'] ?? [],
@@ -33,13 +44,18 @@ class FamilyService
]);
// Create the relationship between guardian and dependent
UserRelationship::create([
$relationship = UserRelationship::create([
'guardian_user_id' => $guardian->id,
'dependent_user_id' => $dependent->id,
'relationship_type' => $data['relationship_type'],
'is_billing_contact' => $data['is_billing_contact'] ?? false,
]);
// Send welcome email if dependent has an email address
if (!empty($dependent->email)) {
Mail::to($dependent->email)->send(new WelcomeEmail($dependent, $guardian, $relationship));
}
return $dependent;
}