first&last

This commit is contained in:
sbb45
2026-03-20 15:47:17 +05:00
commit d6441abdd2
230 changed files with 20367 additions and 0 deletions
+106
View File
@@ -0,0 +1,106 @@
<?php
namespace App\Livewire\Users;
use App\Models\Department;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rule;
use Livewire\Attributes\Layout;
use Livewire\Component;
#[Layout('layouts.app')]
class UserFormPage extends Component
{
public ?User $userModel = null;
public string $name = '';
public string $email = '';
public string $password = '';
public string $password_confirmation = '';
public string $role = 'client';
public string $departmentId = '';
public string $phone = '';
public bool $isActive = true;
public function mount(?User $user = null): void
{
abort_unless(auth()->user()->isAdmin(), 403);
if ($user && $user->exists) {
$this->userModel = $user;
$this->name = $user->name;
$this->email = $user->email;
$this->role = $user->role->value;
$this->departmentId = (string) $user->department_id;
$this->phone = (string) $user->phone;
$this->isActive = (bool) $user->is_active;
}
}
public function save()
{
$emailRule = Rule::unique('users', 'email');
if ($this->userModel) {
$emailRule = $emailRule->ignore($this->userModel->id);
}
$rules = [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'email', 'max:255', $emailRule],
'role' => ['required', Rule::in(['admin', 'manager', 'technician', 'client'])],
'departmentId' => ['nullable', 'exists:departments,id'],
'phone' => ['nullable', 'string', 'max:32'],
'isActive' => ['boolean'],
];
if ($this->userModel) {
$rules['password'] = ['nullable', 'string', 'min:8', 'same:password_confirmation'];
} else {
$rules['password'] = ['required', 'string', 'min:8', 'same:password_confirmation'];
}
$this->validate($rules);
$payload = [
'name' => $this->name,
'email' => $this->email,
'role' => $this->role,
'department_id' => $this->departmentId ?: null,
'phone' => $this->phone,
'is_active' => $this->isActive,
];
if ($this->password !== '') {
$payload['password'] = Hash::make($this->password);
}
if ($this->userModel) {
$this->userModel->update($payload);
session()->flash('success', 'Пользователь обновлен.');
return redirect()->route('users.show', $this->userModel);
}
$payload['password'] = Hash::make($this->password);
$user = User::query()->create($payload);
session()->flash('success', 'Пользователь создан.');
return redirect()->route('users.show', $user);
}
public function render()
{
return view('livewire.users.user-form-page', [
'departments' => Department::query()->orderBy('name')->get(),
])->title($this->userModel ? 'Редактирование пользователя' : 'Создание пользователя');
}
}
+39
View File
@@ -0,0 +1,39 @@
<?php
namespace App\Livewire\Users;
use App\Models\ActivityLog;
use App\Models\ServiceRequest;
use App\Models\User;
use Livewire\Attributes\Layout;
use Livewire\Component;
#[Layout('layouts.app')]
class UserShowPage extends Component
{
public User $user;
public function mount(User $user): void
{
abort_unless(auth()->user()->isAdmin() || auth()->user()->isManager(), 403);
$this->user = $user->load('department');
}
public function render()
{
$assigned = ServiceRequest::query()->where('assigned_to', $this->user->id)->count();
$resolved = ServiceRequest::query()
->where('assigned_to', $this->user->id)
->whereHas('status', fn ($q) => $q->whereIn('slug', ['resolved', 'closed']))
->count();
$avgRating = ServiceRequest::query()->where('assigned_to', $this->user->id)->whereNotNull('client_rating')->avg('client_rating');
return view('livewire.users.user-show-page', [
'assigned' => $assigned,
'resolved' => $resolved,
'avgRating' => $avgRating ? round((float) $avgRating, 2) : 0,
'activities' => ActivityLog::query()->where('user_id', $this->user->id)->latest('created_at')->limit(20)->get(),
'recentRequests' => ServiceRequest::query()->where('assigned_to', $this->user->id)->latest()->limit(10)->get(),
])->title("Профиль: {$this->user->name}");
}
}
+45
View File
@@ -0,0 +1,45 @@
<?php
namespace App\Livewire\Users;
use App\Models\User;
use Livewire\Attributes\Layout;
use Livewire\Component;
use Livewire\WithPagination;
#[Layout('layouts.app')]
class UsersIndexPage extends Component
{
use WithPagination;
public string $search = '';
public string $role = '';
public string $status = '';
public function mount(): void
{
abort_unless(auth()->user()->isAdmin() || auth()->user()->isManager(), 403);
}
public function render()
{
$users = User::query()
->with('department')
->when($this->search !== '', function ($query): void {
$query->where(function ($q): void {
$q->where('name', 'like', "%{$this->search}%")
->orWhere('email', 'like', "%{$this->search}%");
});
})
->when($this->role !== '', fn ($q) => $q->where('role', $this->role))
->when($this->status !== '', fn ($q) => $q->where('is_active', $this->status === 'active'))
->latest()
->paginate(15);
return view('livewire.users.users-index-page', [
'users' => $users,
])->title('Пользователи');
}
}