feat: Add notification services for Email, Telegram, and WhatsApp

- Implement EmailNotifier for sending batch and test notifications via email.
- Implement TelegramNotifier for sending batch and test notifications via Telegram.
- Implement WahaNotifier for sending batch and test notifications via WhatsApp using WAHA API.
- Create migration for client_categories table and update clients table to include category_id.
- Create migration for notification_settings table to manage notification configurations.
- Add ClientCategorySeeder to populate default client categories.
- Create manifest.json for PWA support.
- Implement service worker (sw.js) for caching static assets and offline support.
- Add edit event view for modifying scheduled events.
- Create search results view for displaying search queries.
- Develop notification settings view for configuring notification channels and triggers.
This commit is contained in:
I-Fun
2026-04-01 12:46:58 +07:00
parent 1126877ef5
commit d3c35ad730
29 changed files with 1849 additions and 96 deletions

View File

@@ -0,0 +1,71 @@
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Models\ClientCategory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class ClientCategoryController extends Controller
{
public function index()
{
// Managed inline from the clients page; redirect there
return redirect()->route('clients.index');
}
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'name' => 'required|string|max:100',
'parent_id' => 'nullable|exists:client_categories,id',
'icon' => 'nullable|string|max:10',
'color' => 'nullable|string|max:20',
]);
// Auto slug
$validated['slug'] = \Illuminate\Support\Str::slug($validated['name']);
// If slug conflicts, suffix with random
if (ClientCategory::where('slug', $validated['slug'])->exists()) {
$validated['slug'] .= '-' . substr(uniqid(), -4);
}
ClientCategory::create($validated);
return back()->with('success', '🏷️ Category added!');
}
public function update(Request $request, ClientCategory $category): RedirectResponse
{
$validated = $request->validate([
'name' => 'required|string|max:100',
'parent_id' => 'nullable|exists:client_categories,id',
'icon' => 'nullable|string|max:10',
'color' => 'nullable|string|max:20',
]);
// Prevent a category from being its own parent
if (isset($validated['parent_id']) && $validated['parent_id'] == $category->id) {
$validated['parent_id'] = null;
}
$category->update($validated);
return back()->with('success', '🏷️ Category updated!');
}
public function destroy(ClientCategory $category): RedirectResponse
{
// Reassign children to the parent
$category->children()->update(['parent_id' => $category->parent_id]);
// Detach clients
$category->clients()->update(['category_id' => null]);
$category->delete();
return back()->with('success', '🏷️ Category removed.');
}
}