Merge pull request 'bump to 1.3.0 + teams filter client-side sin recarga' (#27) from feat/android-app-redesign into master
Reviewed-on: #27
This commit was merged in pull request #27.
This commit is contained in:
@@ -12,8 +12,8 @@ android {
|
||||
applicationId = "com.devlab.app"
|
||||
minSdk = 26
|
||||
targetSdk = 37
|
||||
versionCode = 3
|
||||
versionName = "1.2.0"
|
||||
versionCode = 4
|
||||
versionName = "1.3.0"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
||||
Binary file not shown.
@@ -17,73 +17,114 @@
|
||||
<i class="fas fa-search teams-search-icon"></i>
|
||||
<input type="text" id="teamSearch" class="form-input teams-search-input"
|
||||
placeholder="Search teams..." value="<?= htmlspecialchars($search) ?>">
|
||||
<?php if ($search !== ''): ?>
|
||||
<button class="teams-search-clear" onclick="clearSearch()">×</button>
|
||||
<?php endif; ?>
|
||||
<button class="teams-search-clear" id="searchClear" onclick="filterTeams('')" style="display:none">×</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (empty($teams)): ?>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-users-cog"></i>
|
||||
<p><?= $search !== '' ? 'No teams match your search.' : 'No teams created yet.' ?></p>
|
||||
<?php if ($search !== ''): ?>
|
||||
<a href="/teams" class="btn btn-secondary">Clear Search</a>
|
||||
<?php else: ?>
|
||||
<div id="teamsContainer">
|
||||
<?php if (empty($teams)): ?>
|
||||
<div class="empty-state" id="emptyState">
|
||||
<i class="fas fa-users-cog"></i>
|
||||
<p id="emptyText">No teams created yet.</p>
|
||||
<a href="/teams/create" class="btn btn-primary">Create Your First Team</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="teams-grid" id="teamsGrid">
|
||||
<?php foreach ($teams as $team): ?>
|
||||
<div class="team-card">
|
||||
<div class="team-card-header">
|
||||
<div class="team-card-icon">
|
||||
<i class="fas fa-users"></i>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="teams-grid" id="teamsGrid">
|
||||
<?php foreach ($teams as $team): ?>
|
||||
<div class="team-card" data-name="<?= htmlspecialchars(mb_strtolower($team['name'] ?? '')) ?>"
|
||||
data-desc="<?= htmlspecialchars(mb_strtolower($team['description'] ?? '')) ?>">
|
||||
<div class="team-card-header">
|
||||
<div class="team-card-icon">
|
||||
<i class="fas fa-users"></i>
|
||||
</div>
|
||||
<h3 class="team-card-title">
|
||||
<a href="/teams/<?= $team['id'] ?>"><?= htmlspecialchars($team['name']) ?></a>
|
||||
</h3>
|
||||
</div>
|
||||
<p class="team-card-desc">
|
||||
<?= htmlspecialchars(mb_substr($team['description'] ?? 'No description', 0, 100)) ?>
|
||||
</p>
|
||||
<div class="team-card-stats">
|
||||
<span class="team-stat">
|
||||
<i class="fas fa-user"></i> <?= (int) ($team['member_count'] ?? 0) ?> members
|
||||
</span>
|
||||
<span class="team-stat">
|
||||
<i class="fas fa-server"></i> <?= (int) ($team['server_count'] ?? 0) ?> servers
|
||||
</span>
|
||||
</div>
|
||||
<div class="team-card-actions">
|
||||
<a href="/teams/<?= $team['id'] ?>" class="btn btn-sm btn-primary">
|
||||
<i class="fas fa-cog"></i> Manage
|
||||
</a>
|
||||
<button class="btn btn-sm btn-danger" title="Delete"
|
||||
onclick="deleteTeam(<?= $team['id'] ?>, '<?= htmlspecialchars(addslashes($team['name'])) ?>')">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
<h3 class="team-card-title">
|
||||
<a href="/teams/<?= $team['id'] ?>"><?= htmlspecialchars($team['name']) ?></a>
|
||||
</h3>
|
||||
</div>
|
||||
<p class="team-card-desc">
|
||||
<?= htmlspecialchars(mb_substr($team['description'] ?? 'No description', 0, 100)) ?>
|
||||
</p>
|
||||
<div class="team-card-stats">
|
||||
<span class="team-stat">
|
||||
<i class="fas fa-user"></i> <?= (int) ($team['member_count'] ?? 0) ?> members
|
||||
</span>
|
||||
<span class="team-stat">
|
||||
<i class="fas fa-server"></i> <?= (int) ($team['server_count'] ?? 0) ?> servers
|
||||
</span>
|
||||
</div>
|
||||
<div class="team-card-actions">
|
||||
<a href="/teams/<?= $team['id'] ?>" class="btn btn-sm btn-primary">
|
||||
<i class="fas fa-cog"></i> Manage
|
||||
</a>
|
||||
<button class="btn btn-sm btn-danger" title="Delete"
|
||||
onclick="deleteTeam(<?= $team['id'] ?>, '<?= htmlspecialchars(addslashes($team['name'])) ?>')">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<form id="deleteForm" method="POST" style="display:none">
|
||||
<input type="hidden" name="_csrf_token" value="<?= $this->csrfToken() ?>">
|
||||
</form>
|
||||
|
||||
<script>
|
||||
const allCards = document.querySelectorAll('.team-card');
|
||||
|
||||
function filterTeams(query) {
|
||||
const q = query.toLowerCase().trim();
|
||||
const grid = document.getElementById('teamsGrid');
|
||||
const empty = document.getElementById('emptyState');
|
||||
const clearBtn = document.getElementById('searchClear');
|
||||
let visible = 0;
|
||||
|
||||
clearBtn.style.display = q ? 'block' : 'none';
|
||||
|
||||
if (grid) {
|
||||
allCards.forEach(function(card) {
|
||||
const name = card.dataset.name || '';
|
||||
const desc = card.dataset.desc || '';
|
||||
const match = !q || name.includes(q) || desc.includes(q);
|
||||
card.style.display = match ? '' : 'none';
|
||||
if (match) visible++;
|
||||
});
|
||||
|
||||
if (visible === 0) {
|
||||
if (!empty) {
|
||||
const container = document.getElementById('teamsContainer');
|
||||
const div = document.createElement('div');
|
||||
div.className = 'empty-state';
|
||||
div.id = 'emptyState';
|
||||
div.innerHTML = '<i class="fas fa-users-cog"></i><p>No teams match your search.</p>';
|
||||
container.appendChild(div);
|
||||
} else {
|
||||
empty.querySelector('p').textContent = 'No teams match your search.';
|
||||
empty.style.display = '';
|
||||
}
|
||||
} else {
|
||||
if (empty) empty.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// Update URL without reload
|
||||
const url = q ? '?search=' + encodeURIComponent(query) : window.location.pathname;
|
||||
window.history.replaceState({}, '', url);
|
||||
}
|
||||
|
||||
document.getElementById('teamSearch')?.addEventListener('input', function() {
|
||||
const val = this.value.trim();
|
||||
const url = val ? '/teams?search=' + encodeURIComponent(val) : '/teams';
|
||||
window.location.href = url;
|
||||
filterTeams(this.value);
|
||||
});
|
||||
|
||||
function clearSearch() {
|
||||
window.location.href = '/teams';
|
||||
}
|
||||
// Restore search on page load
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const searchInput = document.getElementById('teamSearch');
|
||||
if (searchInput && searchInput.value) {
|
||||
filterTeams(searchInput.value);
|
||||
}
|
||||
});
|
||||
|
||||
function deleteTeam(id, name) {
|
||||
if (confirm('Delete team "' + name + '"?\nThis will remove access for all members.')) {
|
||||
|
||||
Reference in New Issue
Block a user