@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\ContactSettingsRequest;
|
||||
use App\Models\SiteSetting;
|
||||
use App\Support\SiteInfo;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
/**
|
||||
* Company contact details and office locations shown across the site.
|
||||
*/
|
||||
class CompanyController extends Controller
|
||||
{
|
||||
public function edit(): Response
|
||||
{
|
||||
return Inertia::render('admin/company/edit', SiteInfo::get());
|
||||
}
|
||||
|
||||
public function updateContact(ContactSettingsRequest $request): RedirectResponse
|
||||
{
|
||||
SiteSetting::put(SiteInfo::CONTACT_KEY, $request->validated());
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Kontak perusahaan diperbarui.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Enums\ConsultationStatus;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\UpdateConsultationRequest;
|
||||
use App\Models\Consultation;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class ConsultationController extends Controller
|
||||
{
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$status = ConsultationStatus::tryFrom((string) $request->query('status'));
|
||||
|
||||
return Inertia::render('admin/consultations/index', [
|
||||
'consultations' => Consultation::query()
|
||||
->when($status, fn ($query) => $query->where('status', $status))
|
||||
->latest()
|
||||
->paginate(20)
|
||||
->withQueryString(),
|
||||
'status' => $status?->value,
|
||||
'counts' => Consultation::query()
|
||||
->selectRaw('status, count(*) as total')
|
||||
->groupBy('status')
|
||||
->pluck('total', 'status'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(UpdateConsultationRequest $request, Consultation $consultation): RedirectResponse
|
||||
{
|
||||
$consultation->update($request->validated());
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Permintaan konsultasi diperbarui.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function destroy(Consultation $consultation): RedirectResponse
|
||||
{
|
||||
$consultation->delete();
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Permintaan konsultasi dihapus.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Enums\ConsultationStatus;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Consultation;
|
||||
use App\Models\Project;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function __invoke(): Response
|
||||
{
|
||||
return Inertia::render('dashboard', [
|
||||
'projects' => Project::query()
|
||||
->latestFirst()
|
||||
->get(['id', 'title', 'client', 'year', 'sector', 'program', 'scope']),
|
||||
'newConsultations' => Consultation::query()
|
||||
->where('status', ConsultationStatus::New)
|
||||
->count(),
|
||||
'latestConsultations' => Consultation::query()
|
||||
->latest()
|
||||
->limit(5)
|
||||
->get(['id', 'name', 'company', 'service', 'status', 'created_at']),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\OfficeRequest;
|
||||
use App\Models\Office;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class OfficeController extends Controller
|
||||
{
|
||||
public function store(OfficeRequest $request): RedirectResponse
|
||||
{
|
||||
Office::query()->create($request->validated());
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Kantor ditambahkan.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function update(OfficeRequest $request, Office $office): RedirectResponse
|
||||
{
|
||||
$office->update($request->validated());
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Kantor diperbarui.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function destroy(Office $office): RedirectResponse
|
||||
{
|
||||
$office->delete();
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Kantor dihapus.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\ProjectRequest;
|
||||
use App\Models\Project;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class ProjectController extends Controller
|
||||
{
|
||||
public function index(): Response
|
||||
{
|
||||
return Inertia::render('admin/projects/index', [
|
||||
'projects' => Project::query()->latestFirst()->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(ProjectRequest $request): RedirectResponse
|
||||
{
|
||||
Project::query()->create($request->validated());
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Proyek ditambahkan.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function update(ProjectRequest $request, Project $project): RedirectResponse
|
||||
{
|
||||
$project->update($request->validated());
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Proyek diperbarui.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function destroy(Project $project): RedirectResponse
|
||||
{
|
||||
$project->delete();
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Proyek dihapus.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\TestimonialRequest;
|
||||
use App\Models\Testimonial;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class TestimonialController extends Controller
|
||||
{
|
||||
public function index(): Response
|
||||
{
|
||||
return Inertia::render('admin/testimonials/index', [
|
||||
'testimonials' => Testimonial::query()->orderBy('sort_order')->orderBy('id')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(TestimonialRequest $request): RedirectResponse
|
||||
{
|
||||
Testimonial::query()->create($request->validated());
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Testimoni ditambahkan.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function update(TestimonialRequest $request, Testimonial $testimonial): RedirectResponse
|
||||
{
|
||||
$testimonial->update($request->validated());
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Testimoni diperbarui.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function destroy(Testimonial $testimonial): RedirectResponse
|
||||
{
|
||||
$testimonial->delete();
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Testimoni dihapus.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\UserRequest;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
/**
|
||||
* Admin-only management of panel accounts (registration is disabled).
|
||||
*/
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function index(): Response
|
||||
{
|
||||
return Inertia::render('admin/users/index', [
|
||||
'users' => User::query()->orderBy('name')->get(['id', 'name', 'email', 'role', 'created_at']),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(UserRequest $request): RedirectResponse
|
||||
{
|
||||
$user = User::query()->create($request->safe()->only(['name', 'email', 'role', 'password']));
|
||||
// Accounts are created by an admin, so there is nothing left to verify.
|
||||
$user->forceFill(['email_verified_at' => now()])->save();
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Pengguna ditambahkan.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function update(UserRequest $request, User $user): RedirectResponse
|
||||
{
|
||||
$data = $request->safe()->only(['name', 'email', 'role']);
|
||||
|
||||
if ($request->filled('password')) {
|
||||
$data['password'] = $request->validated('password');
|
||||
}
|
||||
|
||||
// Keep at least one admin: nobody may demote themselves.
|
||||
if ($user->is($request->user())) {
|
||||
unset($data['role']);
|
||||
}
|
||||
|
||||
$user->update($data);
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Pengguna diperbarui.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function destroy(Request $request, User $user): RedirectResponse
|
||||
{
|
||||
abort_if($user->is($request->user()), 403, 'Anda tidak dapat menghapus akun sendiri.');
|
||||
|
||||
$user->delete();
|
||||
|
||||
Inertia::flash('toast', ['type' => 'success', 'message' => 'Pengguna dihapus.']);
|
||||
|
||||
return back();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\StoreConsultationRequest;
|
||||
use App\Models\Consultation;
|
||||
use App\Notifications\NewConsultationRequest;
|
||||
use App\Support\SiteInfo;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
|
||||
class ConsultationController extends Controller
|
||||
{
|
||||
/**
|
||||
* Save a consultation request from the public site and notify the team.
|
||||
*/
|
||||
public function store(StoreConsultationRequest $request): RedirectResponse
|
||||
{
|
||||
$consultation = Consultation::query()->create([
|
||||
...$request->safe()->except(['website', 'nda_agreed']),
|
||||
'nda_agreed' => $request->boolean('nda_agreed'),
|
||||
'locale' => app()->getLocale(),
|
||||
]);
|
||||
|
||||
Notification::route('mail', SiteInfo::get()['contact']['email_busdev'])
|
||||
->notify(new NewConsultationRequest($consultation));
|
||||
|
||||
return back();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Project;
|
||||
use App\Models\Testimonial;
|
||||
use Illuminate\Support\Collection;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
/**
|
||||
* Public company-profile pages. Page copy lives in the frontend content
|
||||
* files; editable data (portfolio, testimonials) comes from the database.
|
||||
*/
|
||||
class SitePageController extends Controller
|
||||
{
|
||||
public function home(): Response
|
||||
{
|
||||
return Inertia::render('site/home', ['projects' => $this->projects()]);
|
||||
}
|
||||
|
||||
public function about(): Response
|
||||
{
|
||||
return Inertia::render('site/about', ['projects' => $this->projects()]);
|
||||
}
|
||||
|
||||
public function services(): Response
|
||||
{
|
||||
return Inertia::render('site/services');
|
||||
}
|
||||
|
||||
public function clients(): Response
|
||||
{
|
||||
$locale = app()->getLocale();
|
||||
|
||||
return Inertia::render('site/clients', [
|
||||
'projects' => $this->projects(),
|
||||
'testimonials' => Testimonial::query()
|
||||
->published()
|
||||
->get()
|
||||
->map(fn (Testimonial $testimonial) => $testimonial->localized($locale)),
|
||||
]);
|
||||
}
|
||||
|
||||
public function contact(): Response
|
||||
{
|
||||
return Inertia::render('site/contact');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, Project>
|
||||
*/
|
||||
private function projects(): Collection
|
||||
{
|
||||
return Project::query()
|
||||
->latestFirst()
|
||||
->get(['id', 'title', 'client', 'year', 'sector', 'program', 'scope']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user