feat: add companies as top-level container for projects with departments
- Company → Project → (Locations + Departments) hierarchy - Company CRUD (add, edit, delete) with AJAX - Projects are created under a company via inline strip - Two-column project body: Locations | Departments - Stats show companies, projects, locations, departments, active projects - Dynamic stat counters update on add/delete without page reload Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
1 parent
60d57af630
commit
a425e12349
6 files changed
+518
-264
No files matched your search
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Settings;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Settings\Company;
|
||||
use App\Models\Settings\Department;
|
||||
use App\Models\Settings\Location;
|
||||
use App\Models\Settings\ProjectSetting;
|
||||
@@ -12,33 +13,60 @@ class ProjectSettingController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$projects = ProjectSetting::with([
|
||||
'locations' => fn ($q) => $q->orderBy('name'),
|
||||
'departments' => fn ($q) => $q->orderBy('name'),
|
||||
$companies = Company::with([
|
||||
'projects.locations' => fn ($q) => $q->orderBy('name'),
|
||||
'projects.departments' => fn ($q) => $q->orderBy('name'),
|
||||
])->orderBy('name')->get();
|
||||
|
||||
$allProjects = $companies->flatMap(fn ($c) => $c->projects);
|
||||
|
||||
$stats = [
|
||||
'total_projects' => $projects->count(),
|
||||
'active_projects' => $projects->where('is_active', true)->count(),
|
||||
'total_locations' => $projects->sum(fn ($p) => $p->locations->count()),
|
||||
'active_locations' => $projects->sum(fn ($p) => $p->locations->where('is_active', true)->count()),
|
||||
'total_departments' => $projects->sum(fn ($p) => $p->departments->count()),
|
||||
'total_companies' => $companies->count(),
|
||||
'total_projects' => $allProjects->count(),
|
||||
'active_projects' => $allProjects->where('is_active', true)->count(),
|
||||
'total_locations' => $allProjects->sum(fn ($p) => $p->locations->count()),
|
||||
'total_departments' => $allProjects->sum(fn ($p) => $p->departments->count()),
|
||||
];
|
||||
|
||||
return view('settings.projects.index', compact('projects', 'stats'));
|
||||
return view('settings.projects.index', compact('companies', 'stats'));
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validated = $request->validate(['name' => 'required|string|max:255|unique:settings_projects,name']);
|
||||
$project = ProjectSetting::create(['name' => $validated['name'], 'is_active' => true]);
|
||||
$validated = $request->validate([
|
||||
'name' => 'required|string|max:255|unique:settings_projects,name',
|
||||
'company_id' => 'required|exists:settings_companies,id',
|
||||
]);
|
||||
$project = ProjectSetting::create(['name' => $validated['name'], 'company_id' => $validated['company_id'], 'is_active' => true]);
|
||||
return response()->json(['project' => [
|
||||
'id' => $project->id,
|
||||
'name' => $project->name,
|
||||
'is_active' => $project->is_active,
|
||||
'id' => $project->id,
|
||||
'name' => $project->name,
|
||||
'is_active' => $project->is_active,
|
||||
'company_id' => $project->company_id,
|
||||
]]);
|
||||
}
|
||||
|
||||
// ── Company CRUD ──────────────────────────────────────────────────────────
|
||||
public function storeCompany(Request $request)
|
||||
{
|
||||
$validated = $request->validate(['name' => 'required|string|max:255|unique:settings_companies,name']);
|
||||
$company = Company::create(['name' => $validated['name'], 'is_active' => true]);
|
||||
return response()->json(['company' => ['id' => $company->id, 'name' => $company->name, 'is_active' => $company->is_active]]);
|
||||
}
|
||||
|
||||
public function updateCompany(Request $request, Company $company)
|
||||
{
|
||||
$validated = $request->validate(['name' => 'required|string|max:255|unique:settings_companies,name,' . $company->id]);
|
||||
$company->update(['name' => $validated['name'], 'is_active' => $request->boolean('is_active', true)]);
|
||||
return response()->json(['company' => ['id' => $company->id, 'name' => $company->name, 'is_active' => $company->is_active]]);
|
||||
}
|
||||
|
||||
public function destroyCompany(Company $company)
|
||||
{
|
||||
$company->delete();
|
||||
return response()->json(['ok' => true]);
|
||||
}
|
||||
|
||||
public function update(Request $request, ProjectSetting $project)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
|
||||
Reference in new issue
Block a user