Initial Commit
This commit is contained in:
102
app/Views/groups/create.php
Normal file
102
app/Views/groups/create.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
$title = 'Create Notification Group';
|
||||
$pageTitle = 'Create Notification Group';
|
||||
$pageDescription = 'Set up a new notification group for your domains';
|
||||
$pageIcon = 'fas fa-plus-circle';
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<!-- Main Form -->
|
||||
<div class="max-w-3xl mx-auto">
|
||||
<div class="bg-white rounded-lg border border-gray-200 overflow-hidden">
|
||||
<div class="px-6 py-4 border-b border-gray-200">
|
||||
<h2 class="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<i class="fas fa-bell text-gray-400 mr-2 text-sm"></i>
|
||||
Group Information
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="p-6">
|
||||
<form method="POST" action="/groups/store" class="space-y-5">
|
||||
<!-- Group Name -->
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-medium text-gray-700 mb-1.5">
|
||||
Group Name *
|
||||
</label>
|
||||
<input type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
class="w-full px-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-colors text-sm"
|
||||
placeholder="e.g., Production Alerts, Team Notifications"
|
||||
required
|
||||
autofocus>
|
||||
<p class="mt-1.5 text-xs text-gray-500">
|
||||
Choose a descriptive name for this notification group
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<div>
|
||||
<label for="description" class="block text-sm font-medium text-gray-700 mb-1.5">
|
||||
Description (Optional)
|
||||
</label>
|
||||
<textarea id="description"
|
||||
name="description"
|
||||
class="w-full px-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-colors text-sm"
|
||||
rows="4"
|
||||
placeholder="Add details about this notification group, its purpose, or who should be notified..."></textarea>
|
||||
<p class="mt-1.5 text-xs text-gray-500">
|
||||
Optional: Add notes to help identify this group's purpose
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="flex flex-col sm:flex-row gap-3 pt-3">
|
||||
<button type="submit"
|
||||
class="inline-flex items-center justify-center px-5 py-2.5 bg-primary hover:bg-primary-dark text-white rounded-lg font-medium transition-colors text-sm">
|
||||
<i class="fas fa-plus-circle mr-2"></i>
|
||||
Create Group
|
||||
</button>
|
||||
<a href="/groups"
|
||||
class="inline-flex items-center justify-center px-5 py-2.5 border border-gray-300 text-gray-700 rounded-lg font-medium hover:bg-gray-50 transition-colors text-sm">
|
||||
<i class="fas fa-times mr-2"></i>
|
||||
Cancel
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Info Section -->
|
||||
<div class="mt-4 bg-blue-50 border border-blue-200 rounded-lg p-4">
|
||||
<div class="flex items-start">
|
||||
<div class="flex-shrink-0">
|
||||
<div class="w-10 h-10 bg-blue-500 rounded-lg flex items-center justify-center">
|
||||
<i class="fas fa-info-circle text-white"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<h3 class="text-sm font-semibold text-gray-900 mb-1">Next Steps</h3>
|
||||
<ul class="text-xs text-gray-600 space-y-1">
|
||||
<li class="flex items-center">
|
||||
<i class="fas fa-circle text-blue-500" style="font-size: 6px;"></i>
|
||||
<span class="ml-2">After creating the group, you'll be able to add notification channels (Email, Telegram, Discord, Slack)</span>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<i class="fas fa-circle text-blue-500" style="font-size: 6px;"></i>
|
||||
<span class="ml-2">Configure each channel with the necessary credentials and settings</span>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<i class="fas fa-circle text-blue-500" style="font-size: 6px;"></i>
|
||||
<span class="ml-2">Assign domains to this group to start receiving notifications</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$content = ob_get_clean();
|
||||
include __DIR__ . '/../layout/base.php';
|
||||
?>
|
||||
304
app/Views/groups/edit.php
Normal file
304
app/Views/groups/edit.php
Normal file
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
$title = 'Edit Notification Group';
|
||||
$pageTitle = 'Edit Notification Group';
|
||||
$pageDescription = htmlspecialchars($group['name']);
|
||||
$pageIcon = 'fas fa-edit';
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<div class="max-w-7xl mx-auto space-y-4">
|
||||
<!-- Group Details Form -->
|
||||
<div class="bg-white rounded-lg border border-gray-200 overflow-hidden">
|
||||
<div class="px-6 py-4 border-b border-gray-200">
|
||||
<h2 class="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<i class="fas fa-info-circle text-gray-400 mr-2 text-sm"></i>
|
||||
Group Details
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="p-6">
|
||||
<form method="POST" action="/groups/update" class="space-y-5">
|
||||
<input type="hidden" name="id" value="<?= $group['id'] ?>">
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
|
||||
<!-- Group Name -->
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-medium text-gray-700 mb-1.5">
|
||||
Group Name *
|
||||
</label>
|
||||
<input type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
class="w-full px-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-colors text-sm"
|
||||
value="<?= htmlspecialchars($group['name']) ?>"
|
||||
required>
|
||||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<div>
|
||||
<label for="description" class="block text-sm font-medium text-gray-700 mb-1.5">
|
||||
Description (Optional)
|
||||
</label>
|
||||
<textarea id="description"
|
||||
name="description"
|
||||
class="w-full px-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-colors text-sm"
|
||||
rows="3"><?= htmlspecialchars($group['description'] ?? '') ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-3">
|
||||
<button type="submit"
|
||||
class="inline-flex items-center px-5 py-2.5 bg-primary hover:bg-primary-dark text-white rounded-lg font-medium transition-colors text-sm">
|
||||
<i class="fas fa-save mr-2"></i>
|
||||
Update Group
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notification Channels -->
|
||||
<div class="bg-white rounded-lg border border-gray-200 overflow-hidden">
|
||||
<div class="px-6 py-4 border-b border-gray-200">
|
||||
<h2 class="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<i class="fas fa-plug text-gray-400 mr-2 text-sm"></i>
|
||||
Notification Channels
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="p-6">
|
||||
<?php if (empty($group['channels'])): ?>
|
||||
<div class="text-center py-10">
|
||||
<i class="fas fa-plug text-gray-300 text-5xl mb-3"></i>
|
||||
<p class="text-gray-500">No channels configured yet</p>
|
||||
<p class="text-sm text-gray-400 mt-1">Add your first channel below to start receiving notifications</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-6">
|
||||
<?php foreach ($group['channels'] as $channel):
|
||||
$config = json_decode($channel['channel_config'], true);
|
||||
$icons = ['email' => 'fa-envelope', 'telegram' => 'fa-telegram', 'discord' => 'fa-discord', 'slack' => 'fa-slack'];
|
||||
$colors = ['email' => 'blue', 'telegram' => 'blue', 'discord' => 'indigo', 'slack' => 'purple'];
|
||||
$icon = $icons[$channel['channel_type']] ?? 'fa-bell';
|
||||
$color = $colors[$channel['channel_type']] ?? 'gray';
|
||||
?>
|
||||
<div class="bg-gray-50 border border-gray-200 rounded-lg p-6 hover:shadow-md transition-shadow duration-200">
|
||||
<div class="flex items-start justify-between mb-4">
|
||||
<div class="w-12 h-12 bg-<?= $color ?>-100 rounded-lg flex items-center justify-center">
|
||||
<i class="fab <?= $icon ?> text-<?= $color ?>-600 text-xl"></i>
|
||||
</div>
|
||||
<span class="px-3 py-1 rounded-full text-xs font-semibold <?= $channel['is_active'] ? 'bg-green-100 text-green-800' : 'bg-gray-200 text-gray-600' ?>">
|
||||
<?= $channel['is_active'] ? 'Active' : 'Disabled' ?>
|
||||
</span>
|
||||
</div>
|
||||
<h3 class="font-semibold text-gray-800 mb-2"><?= ucfirst($channel['channel_type']) ?></h3>
|
||||
<p class="text-sm text-gray-600 mb-4 truncate">
|
||||
<?php
|
||||
if ($channel['channel_type'] === 'email') {
|
||||
echo htmlspecialchars($config['email'] ?? 'No email');
|
||||
} elseif ($channel['channel_type'] === 'telegram') {
|
||||
echo "Chat: " . htmlspecialchars($config['chat_id'] ?? 'N/A');
|
||||
} else {
|
||||
echo "Webhook configured";
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
<div class="flex gap-2">
|
||||
<a href="/channels/toggle?id=<?= $channel['id'] ?>&group_id=<?= $group['id'] ?>"
|
||||
class="flex-1 px-3 py-2 bg-yellow-50 text-yellow-700 rounded text-center text-sm hover:bg-yellow-100 transition-colors duration-150">
|
||||
<i class="fas fa-<?= $channel['is_active'] ? 'pause' : 'play' ?> mr-1"></i>
|
||||
<?= $channel['is_active'] ? 'Disable' : 'Enable' ?>
|
||||
</a>
|
||||
<a href="/channels/delete?id=<?= $channel['id'] ?>&group_id=<?= $group['id'] ?>"
|
||||
class="flex-1 px-3 py-2 bg-red-50 text-red-700 rounded text-center text-sm hover:bg-red-100 transition-colors duration-150"
|
||||
onclick="return confirm('Delete this channel?')">
|
||||
<i class="fas fa-trash mr-1"></i>
|
||||
Delete
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Add Channel Form -->
|
||||
<div class="bg-gray-50 rounded-lg p-5 border border-gray-200">
|
||||
<h3 class="text-sm font-semibold text-gray-900 mb-4 flex items-center">
|
||||
<i class="fas fa-plus-circle text-gray-400 mr-2 text-sm"></i>
|
||||
Add New Channel
|
||||
</h3>
|
||||
|
||||
<form method="POST" action="/channels/add" id="channelForm" class="space-y-5">
|
||||
<input type="hidden" name="group_id" value="<?= $group['id'] ?>">
|
||||
|
||||
<!-- Channel Type -->
|
||||
<div>
|
||||
<label for="channel_type" class="block text-sm font-medium text-gray-700 mb-1.5">Channel Type</label>
|
||||
<select id="channel_type"
|
||||
name="channel_type"
|
||||
class="w-full px-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-colors text-sm"
|
||||
onchange="toggleChannelFields()">
|
||||
<option value="">-- Select Channel Type --</option>
|
||||
<option value="email">Email</option>
|
||||
<option value="telegram">Telegram</option>
|
||||
<option value="discord">Discord</option>
|
||||
<option value="slack">Slack</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Email Fields -->
|
||||
<div id="email_fields" class="hidden space-y-4">
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-gray-700 mb-1.5">
|
||||
Email Address
|
||||
</label>
|
||||
<input type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
class="w-full px-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-colors text-sm"
|
||||
placeholder="user@example.com">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Telegram Fields -->
|
||||
<div id="telegram_fields" class="hidden space-y-4">
|
||||
<div>
|
||||
<label for="bot_token" class="block text-sm font-medium text-gray-700 mb-1.5">
|
||||
Bot Token
|
||||
</label>
|
||||
<input type="text"
|
||||
id="bot_token"
|
||||
name="bot_token"
|
||||
class="w-full px-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-colors text-sm"
|
||||
placeholder="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11">
|
||||
<p class="mt-1.5 text-xs text-gray-500">
|
||||
Get from @BotFather on Telegram
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label for="chat_id" class="block text-sm font-medium text-gray-700 mb-1.5">
|
||||
Chat ID
|
||||
</label>
|
||||
<input type="text"
|
||||
id="chat_id"
|
||||
name="chat_id"
|
||||
class="w-full px-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-colors text-sm"
|
||||
placeholder="123456789">
|
||||
<p class="mt-1.5 text-xs text-gray-500">
|
||||
Use @userinfobot to get your chat ID
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Discord Fields -->
|
||||
<div id="discord_fields" class="hidden space-y-4">
|
||||
<div>
|
||||
<label for="discord_webhook" class="block text-sm font-medium text-gray-700 mb-1.5">
|
||||
Webhook URL
|
||||
</label>
|
||||
<input type="url"
|
||||
id="discord_webhook"
|
||||
name="webhook_url"
|
||||
class="w-full px-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-colors text-sm"
|
||||
placeholder="https://discord.com/api/webhooks/...">
|
||||
<p class="mt-1.5 text-xs text-gray-500">
|
||||
Create in Discord Server Settings → Integrations → Webhooks
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Slack Fields -->
|
||||
<div id="slack_fields" class="hidden space-y-4">
|
||||
<div>
|
||||
<label for="slack_webhook" class="block text-sm font-medium text-gray-700 mb-1.5">
|
||||
Webhook URL
|
||||
</label>
|
||||
<input type="url"
|
||||
id="slack_webhook"
|
||||
name="webhook_url"
|
||||
class="w-full px-3 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-colors text-sm"
|
||||
placeholder="https://hooks.slack.com/services/...">
|
||||
<p class="mt-1.5 text-xs text-gray-500">
|
||||
Create in Slack App Settings → Incoming Webhooks
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit"
|
||||
class="inline-flex items-center px-5 py-2.5 bg-primary hover:bg-primary-dark text-white rounded-lg font-medium transition-colors text-sm">
|
||||
<i class="fas fa-plus mr-2"></i>
|
||||
Add Channel
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Assigned Domains -->
|
||||
<div class="bg-white rounded-lg border border-gray-200 overflow-hidden">
|
||||
<div class="px-6 py-4 border-b border-gray-200">
|
||||
<h2 class="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<i class="fas fa-globe text-gray-400 mr-2 text-sm"></i>
|
||||
Assigned Domains (<?= count($group['domains']) ?>)
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="p-6">
|
||||
<?php if (empty($group['domains'])): ?>
|
||||
<div class="text-center py-10">
|
||||
<i class="fas fa-globe text-gray-300 text-5xl mb-3"></i>
|
||||
<p class="text-gray-500">No domains assigned to this group yet</p>
|
||||
<a href="/domains/create" class="mt-3 inline-flex items-center px-5 py-2.5 bg-primary text-white text-sm rounded-lg hover:bg-primary-dark transition-colors font-medium">
|
||||
<i class="fas fa-plus mr-2"></i>
|
||||
Add a Domain
|
||||
</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<?php foreach ($group['domains'] as $domain): ?>
|
||||
<a href="/domains/<?= $domain['id'] ?>" class="block bg-gray-50 border border-gray-200 rounded-lg p-6 hover:shadow-md hover:border-primary transition-all duration-200">
|
||||
<div class="flex items-start justify-between mb-3">
|
||||
<div class="w-12 h-12 bg-primary bg-opacity-10 rounded-lg flex items-center justify-center">
|
||||
<i class="fas fa-globe text-primary text-xl"></i>
|
||||
</div>
|
||||
<?php
|
||||
$statusClass = $domain['status'] === 'active' ? 'bg-green-100 text-green-800' : 'bg-gray-200 text-gray-600';
|
||||
?>
|
||||
<span class="px-3 py-1 rounded-full text-xs font-semibold <?= $statusClass ?>">
|
||||
<?= ucfirst($domain['status']) ?>
|
||||
</span>
|
||||
</div>
|
||||
<h3 class="font-semibold text-gray-800 mb-2 truncate"><?= htmlspecialchars($domain['domain_name']) ?></h3>
|
||||
<p class="text-sm text-gray-600 flex items-center">
|
||||
<i class="far fa-calendar mr-2"></i>
|
||||
Expires: <?= date('M j, Y', strtotime($domain['expiration_date'])) ?>
|
||||
</p>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleChannelFields() {
|
||||
const channelType = document.getElementById('channel_type').value;
|
||||
|
||||
// Hide all fields
|
||||
document.getElementById('email_fields').classList.add('hidden');
|
||||
document.getElementById('telegram_fields').classList.add('hidden');
|
||||
document.getElementById('discord_fields').classList.add('hidden');
|
||||
document.getElementById('slack_fields').classList.add('hidden');
|
||||
|
||||
// Show selected field
|
||||
if (channelType) {
|
||||
document.getElementById(channelType + '_fields').classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php
|
||||
$content = ob_get_clean();
|
||||
include __DIR__ . '/../layout/base.php';
|
||||
?>
|
||||
156
app/Views/groups/index.php
Normal file
156
app/Views/groups/index.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
$title = 'Notification Groups';
|
||||
$pageTitle = 'Notification Groups';
|
||||
$pageDescription = 'Manage notification channels and assignments';
|
||||
$pageIcon = 'fas fa-bell';
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<!-- Quick Actions -->
|
||||
<div class="mb-4 flex justify-end">
|
||||
<a href="/groups/create" class="inline-flex items-center px-4 py-2.5 bg-primary text-white text-sm rounded-lg hover:bg-primary-dark transition-colors font-medium">
|
||||
<i class="fas fa-plus mr-2"></i>
|
||||
Create New Group
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Info Card -->
|
||||
<div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-4">
|
||||
<div class="flex items-start">
|
||||
<div class="flex-shrink-0">
|
||||
<i class="fas fa-info-circle text-blue-500 text-lg"></i>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<h3 class="text-sm font-semibold text-gray-900 mb-1">About Notification Groups</h3>
|
||||
<p class="text-xs text-gray-600 leading-relaxed">
|
||||
Notification groups allow you to organize your notification channels. You can create multiple channels
|
||||
(Email, Telegram, Discord, Slack) within each group, then assign domains to the group. When a domain
|
||||
is about to expire, all active channels in its group will receive notifications.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Groups List -->
|
||||
<div class="bg-white rounded-lg border border-gray-200 overflow-hidden">
|
||||
<?php if (!empty($groups)): ?>
|
||||
<!-- Table View (Desktop) -->
|
||||
<div class="hidden md:block overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Group Name</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Description</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Channels</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">Domains</th>
|
||||
<th class="px-6 py-4 text-right text-xs font-semibold text-gray-600 uppercase tracking-wider">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
<?php foreach ($groups as $group): ?>
|
||||
<tr class="hover:bg-gray-50 transition-colors duration-150">
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="flex items-center">
|
||||
<div class="flex-shrink-0 h-10 w-10 bg-primary bg-opacity-10 rounded-lg flex items-center justify-center">
|
||||
<i class="fas fa-bell text-primary"></i>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<div class="text-sm font-semibold text-gray-900"><?= htmlspecialchars($group['name']) ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="text-sm text-gray-700 max-w-xs truncate">
|
||||
<?= htmlspecialchars($group['description'] ?? 'No description') ?>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-blue-100 text-blue-800">
|
||||
<i class="fas fa-plug mr-1"></i>
|
||||
<?= $group['channel_count'] ?> channel<?= $group['channel_count'] != 1 ? 's' : '' ?>
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-green-100 text-green-800">
|
||||
<i class="fas fa-globe mr-1"></i>
|
||||
<?= $group['domain_count'] ?> domain<?= $group['domain_count'] != 1 ? 's' : '' ?>
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||
<div class="flex items-center justify-end space-x-2">
|
||||
<a href="/groups/edit?id=<?= $group['id'] ?>" class="text-blue-600 hover:text-blue-800" title="Manage">
|
||||
<i class="fas fa-cog"></i>
|
||||
</a>
|
||||
<a href="/groups/delete?id=<?= $group['id'] ?>"
|
||||
class="text-red-600 hover:text-red-800"
|
||||
title="Delete"
|
||||
onclick="return confirm('Are you sure? Domains will be unassigned from this group.')">
|
||||
<i class="fas fa-trash"></i>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Card View (Mobile) -->
|
||||
<div class="md:hidden divide-y divide-gray-200">
|
||||
<?php foreach ($groups as $group): ?>
|
||||
<div class="p-6 hover:bg-gray-50 transition-colors duration-150">
|
||||
<div class="flex items-start justify-between mb-3">
|
||||
<div class="flex items-center">
|
||||
<div class="flex-shrink-0 h-10 w-10 bg-primary bg-opacity-10 rounded-lg flex items-center justify-center">
|
||||
<i class="fas fa-bell text-primary"></i>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<h3 class="font-semibold text-gray-900"><?= htmlspecialchars($group['name']) ?></h3>
|
||||
<p class="text-sm text-gray-500"><?= htmlspecialchars($group['description'] ?? 'No description') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex space-x-3 mb-3">
|
||||
<span class="px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
|
||||
<i class="fas fa-plug mr-1"></i>
|
||||
<?= $group['channel_count'] ?> channels
|
||||
</span>
|
||||
<span class="px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800">
|
||||
<i class="fas fa-globe mr-1"></i>
|
||||
<?= $group['domain_count'] ?> domains
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex space-x-2">
|
||||
<a href="/groups/edit?id=<?= $group['id'] ?>" class="flex-1 px-3 py-1.5 bg-blue-50 text-blue-600 rounded text-center text-sm hover:bg-blue-100 transition-colors">
|
||||
<i class="fas fa-cog mr-1"></i> Manage
|
||||
</a>
|
||||
<a href="/groups/delete?id=<?= $group['id'] ?>"
|
||||
class="flex-1 px-3 py-1.5 bg-red-50 text-red-600 rounded text-center text-sm hover:bg-red-100 transition-colors"
|
||||
onclick="return confirm('Are you sure? Domains will be unassigned from this group.')">
|
||||
<i class="fas fa-trash mr-1"></i> Delete
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-12 px-6">
|
||||
<div class="mb-4">
|
||||
<i class="fas fa-bell-slash text-gray-300 text-6xl"></i>
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold text-gray-700 mb-1">No Notification Groups</h3>
|
||||
<p class="text-sm text-gray-500 mb-4">Create your first notification group to start receiving alerts</p>
|
||||
<a href="/groups/create" class="inline-flex items-center px-5 py-2.5 bg-primary text-white text-sm rounded-lg hover:bg-primary-dark transition-colors font-medium">
|
||||
<i class="fas fa-plus mr-2"></i>
|
||||
Create Your First Group
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$content = ob_get_clean();
|
||||
include __DIR__ . '/../layout/base.php';
|
||||
?>
|
||||
Reference in New Issue
Block a user