mirror of
https://github.com/Dvorinka/PPve.git
synced 2026-06-04 04:22:58 +00:00
463 lines
21 KiB
HTML
463 lines
21 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="cs">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Aplikační Rozcestník</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
|
|
<style>
|
|
.card {
|
|
transition: transform 0.2s, box-shadow 0.2s;
|
|
}
|
|
.card:hover {
|
|
transform: translateY(-5px);
|
|
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
|
}
|
|
.auth-container {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
z-index: 1000;
|
|
}
|
|
.auth-modal {
|
|
background: white;
|
|
padding: 2rem;
|
|
border-radius: 10px;
|
|
width: 90%;
|
|
max-width: 400px;
|
|
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
|
|
}
|
|
.admin-panel {
|
|
display: none;
|
|
}
|
|
</style>
|
|
<script>
|
|
tailwind.config = {
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
'brand-blue': '#004990',
|
|
'brand-light-blue': '#0072b0',
|
|
'brand-gray': '#f0f2f5'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
</head>
|
|
<body class="bg-gray-100 min-h-screen">
|
|
<nav class="bg-brand-blue text-white shadow-lg">
|
|
<div class="max-w-6xl mx-auto px-4 py-3 flex justify-between items-center">
|
|
<div class="flex items-center space-x-2">
|
|
<a href="http://webportal/index.html"><img src="http://pp-kunovice.cz/wp-content/uploads/2022/04/logo-retina-white.png" alt="Poppe Potthoff Logo" class="h-10"></a>
|
|
<div class="hidden md:block text-xl font-semibold">Poppe + Potthoff</div>
|
|
</div>
|
|
|
|
<!-- Mobile menu button -->
|
|
<div class="md:hidden">
|
|
<button id="mobile-menu-button" class="text-white focus:outline-none">
|
|
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Desktop menu -->
|
|
<div class="hidden md:flex space-x-6">
|
|
<a href="http://webportal/index.html" class="hover:text-brand-light-blue">Rozcestník</a>
|
|
<a href="http://webportal/evidence-aut" class="hover:text-brand-light-blue">Evidence aut</a>
|
|
<a href="http://ppc-app/pwkweb2/" class="hover:text-brand-light-blue">Obědy</a>
|
|
<a href="http://osticket/" class="hover:text-brand-light-blue">OSticket</a>
|
|
<a href="http://kanboard/" class="hover:text-brand-light-blue">Kanboard</a>
|
|
<a href="http://webportal/kontakt" class="hover:text-brand-light-blue">Kontakt</a>
|
|
<div id="admin-link" class="hidden">
|
|
<a href="/admin" class="hover:text-brand-light-blue">Administrace</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex items-center space-x-2">
|
|
<div id="user-info" class="hidden">
|
|
<span id="username" class="text-sm"></span>
|
|
<button id="logout-btn" class="text-sm hover:text-brand-light-blue">Odhlásit</button>
|
|
</div>
|
|
<div id="login-btn" class="text-sm hover:text-brand-light-blue">
|
|
<button onclick="showLoginModal()">Přihlásit</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Mobile menu -->
|
|
<div id="mobile-menu" class="hidden md:hidden px-2 pt-2 pb-3 space-y-1">
|
|
<a href="webportal/index.html" class="block px-3 py-2 rounded-md text-base font-medium hover:text-brand-light-blue">Rozcestník</a>
|
|
<a href="webportal/evidence-aut" class="block px-3 py-2 rounded-md text-base font-medium hover:text-brand-light-blue">Evidence aut</a>
|
|
<a href="http://ppc-app/pwkweb2/" class="block px-3 py-2 rounded-md text-base font-medium hover:text-brand-light-blue">Obědy</a>
|
|
<a href="http://osticket/" class="block px-3 py-2 rounded-md text-base font-medium hover:text-brand-light-blue">OSticket</a>
|
|
<a href="http://kanboard/" class="block px-3 py-2 rounded-md text-base font-medium hover:text-brand-light-blue">Kanboard</a>
|
|
<a href="webportal/kontakt" class="block px-3 py-2 rounded-md text-base font-medium hover:text-brand-light-blue">Kontakt</a>
|
|
<div id="mobile-admin-link" class="hidden">
|
|
<a href="/admin" class="block px-3 py-2 rounded-md text-base font-medium hover:text-brand-light-blue">Administrace</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<script>
|
|
// Mobile menu toggle
|
|
const mobileMenuButton = document.getElementById('mobile-menu-button');
|
|
const mobileMenu = document.getElementById('mobile-menu');
|
|
|
|
mobileMenuButton.addEventListener('click', () => {
|
|
mobileMenu.classList.toggle('hidden');
|
|
});
|
|
</script>
|
|
|
|
<!-- Page Header -->
|
|
<div class="bg-gradient-to-r from-brand-blue to-brand-light-blue text-white py-6 mb-8">
|
|
<div class="max-w-6xl mx-auto px-4">
|
|
<h1 class="text-3xl font-bold">Poppe + Potthoff - Firemní Aplikace</h1>
|
|
<p class="text-gray-100 mt-2">Rychlý přístup ke všem důležitým systémům</p>
|
|
</div>
|
|
</div>
|
|
|
|
<main class="container mx-auto px-4 py-8">
|
|
<!-- Login Modal -->
|
|
<div id="login-modal" class="auth-container">
|
|
<div class="auth-modal">
|
|
<h2 class="text-2xl font-bold mb-4 text-center">Přihlášení</h2>
|
|
<form id="login-form" class="space-y-4">
|
|
<div>
|
|
<label for="username" class="block text-sm font-medium text-gray-700 mb-1">Uživatelské jméno</label>
|
|
<input type="text" id="username" name="username" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-blue">
|
|
</div>
|
|
<div>
|
|
<label for="password" class="block text-sm font-medium text-gray-700 mb-1">Heslo</label>
|
|
<input type="password" id="password" name="password" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-blue">
|
|
</div>
|
|
<button type="submit" class="w-full bg-brand-blue text-white py-2 px-4 rounded-md hover:bg-brand-light-blue transition-colors">Přihlásit</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Search -->
|
|
<div class="mb-8 max-w-xl mx-auto">
|
|
<div class="relative">
|
|
<input type="text" id="search" placeholder="Hledat aplikaci..." style="margin-bottom: 20px;"
|
|
class="w-full px-4 py-3 rounded-lg shadow-sm border-gray-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none">
|
|
<div class="absolute right-3 top-3 text-gray-400">
|
|
<i class="fas fa-search"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Apps Grid -->
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6" id="apps-grid">
|
|
<!-- 1. Car trips app -->
|
|
<div class="card bg-white rounded-xl shadow p-6 border-t-4 border-blue-600" data-name="zápis cest aut project">
|
|
<div class="rounded-full w-14 h-14 flex items-center justify-center bg-blue-100 text-blue-600 mb-4">
|
|
<i class="fas fa-car-side text-2xl"></i>
|
|
</div>
|
|
<h2 class="text-xl font-bold text-gray-800 mb-2">Záznam služebních jízd</h2>
|
|
<p class="text-gray-600 mb-4">Jednoduchý systém pro evidenci a správu jízd služebními vozidly.</p>
|
|
<a href="/evidence-aut" class="block text-center bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
|
Otevřít aplikaci
|
|
</a>
|
|
</div>
|
|
|
|
<!-- 2. Lunches -->
|
|
<div class="card bg-white rounded-xl shadow p-6 border-t-4 border-green-600" data-name="obědy obedy jídlo lunch">
|
|
<div class="rounded-full w-14 h-14 flex items-center justify-center bg-green-100 text-green-600 mb-4">
|
|
<i class="fas fa-utensils text-2xl"></i>
|
|
</div>
|
|
<h2 class="text-xl font-bold text-gray-800 mb-2">Objednávka obědů</h2>
|
|
<p class="text-gray-600 mb-4">Portál pro objednávku a přehled firemních obědů</p>
|
|
<a href="http://ppc-app/pwkweb2/" class="block text-center bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
|
Otevřít aplikaci
|
|
</a>
|
|
</div>
|
|
|
|
<!-- 3. OSTicket -->
|
|
<div class="card bg-white rounded-xl shadow p-6 border-t-4 border-orange-600" data-name="osticket pomoc podpora support ticket">
|
|
<div class="rounded-full w-14 h-14 flex items-center justify-center bg-orange-100 text-orange-600 mb-4">
|
|
<i class="fas fa-headset text-2xl"></i>
|
|
</div>
|
|
<h2 class="text-xl font-bold text-gray-800 mb-2">OSTicket</h2>
|
|
<p class="text-gray-600 mb-4">Systém technické podpory a hlášení problémů</p>
|
|
<a href="http://osticket/" class="block text-center bg-orange-600 hover:bg-orange-700 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
|
Otevřít aplikaci
|
|
</a>
|
|
</div>
|
|
|
|
<!-- 4. Canboard tasks -->
|
|
<div class="card bg-white rounded-xl shadow p-6 border-t-4 border-purple-600" data-name="canboard úkoly úkolníček tasks">
|
|
<div class="rounded-full w-14 h-14 flex items-center justify-center bg-purple-100 text-purple-600 mb-4">
|
|
<i class="fas fa-tasks text-2xl"></i>
|
|
</div>
|
|
<h2 class="text-xl font-bold text-gray-800 mb-2">Kanboard</h2>
|
|
<p class="text-gray-600 mb-4">Správa úkolů a projektů v přehledném kanban stylu</p>
|
|
<a href="http://kanboard/" class="block text-center bg-purple-600 hover:bg-purple-700 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
|
Otevřít aplikaci
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
<style>
|
|
/* Rounded border */
|
|
hr.rounded {
|
|
border-top: 2px solid #bbb;
|
|
border-radius: 5px;
|
|
margin-top: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
</style>
|
|
|
|
<hr class="rounded">
|
|
|
|
<!-- Contact card - Subtle and full width -->
|
|
<div>
|
|
<div class="bg-gray-50 rounded-lg p-4 border border-gray-200">
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center">
|
|
<div class="rounded-full w-10 h-10 flex items-center justify-center bg-gray-100 text-gray-500 mr-3">
|
|
<i class="fas fa-phone-alt"></i>
|
|
</div>
|
|
<div>
|
|
<h3 class="text-sm font-medium text-gray-700">Telefonní seznam</h3>
|
|
<p class="text-xs text-gray-500">Firemní kontakty a důležitá čísla</p>
|
|
</div>
|
|
</div>
|
|
<a href="http://webportal/kontakt" class="text-sm text-blue-600 hover:text-blue-800 hover:underline">
|
|
Otevřít
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<!-- Admin Panel -->
|
|
<div id="admin-panel" class="admin-panel">
|
|
<div class="p-6 bg-white rounded-lg shadow">
|
|
<h2 class="text-2xl font-bold mb-4">Správa aplikací</h2>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<!-- Admin cards will be dynamically inserted here -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Authentication state
|
|
let authToken = localStorage.getItem('authToken');
|
|
let currentUser = null;
|
|
|
|
// Show/hide login modal
|
|
function showLoginModal() {
|
|
document.getElementById('login-modal').style.display = 'flex';
|
|
}
|
|
|
|
function hideLoginModal() {
|
|
document.getElementById('login-modal').style.display = 'none';
|
|
}
|
|
|
|
// Handle login form submission
|
|
document.getElementById('login-form').addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
const formData = new FormData(e.target);
|
|
const response = await fetch('/login', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
username: formData.get('username'),
|
|
password: formData.get('password'),
|
|
}),
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.success) {
|
|
authToken = data.token;
|
|
currentUser = { username: formData.get('username'), role: data.role };
|
|
localStorage.setItem('authToken', authToken);
|
|
updateAuthUI();
|
|
hideLoginModal();
|
|
} else {
|
|
alert(data.message);
|
|
}
|
|
});
|
|
|
|
// Update UI based on auth state
|
|
function updateAuthUI() {
|
|
const userDiv = document.getElementById('user-info');
|
|
const loginBtn = document.getElementById('login-btn');
|
|
const adminLink = document.getElementById('admin-link');
|
|
const mobileAdminLink = document.getElementById('mobile-admin-link');
|
|
|
|
if (currentUser) {
|
|
userDiv.classList.remove('hidden');
|
|
loginBtn.classList.add('hidden');
|
|
document.getElementById('username').textContent = currentUser.username;
|
|
|
|
if (currentUser.role === 'admin') {
|
|
adminLink.classList.remove('hidden');
|
|
mobileAdminLink.classList.remove('hidden');
|
|
}
|
|
} else {
|
|
userDiv.classList.add('hidden');
|
|
loginBtn.classList.remove('hidden');
|
|
adminLink.classList.add('hidden');
|
|
mobileAdminLink.classList.add('hidden');
|
|
}
|
|
}
|
|
|
|
// Handle logout
|
|
document.getElementById('logout-btn').addEventListener('click', async () => {
|
|
const response = await fetch('/logout', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': `Bearer ${authToken}`,
|
|
},
|
|
});
|
|
|
|
if (response.ok) {
|
|
authToken = null;
|
|
currentUser = null;
|
|
localStorage.removeItem('authToken');
|
|
updateAuthUI();
|
|
}
|
|
});
|
|
|
|
// Load cards on page load
|
|
async function loadCards() {
|
|
try {
|
|
const response = await fetch('/api/cards');
|
|
const cards = await response.json();
|
|
|
|
const grid = document.getElementById('apps-grid');
|
|
grid.innerHTML = '';
|
|
|
|
cards.forEach(card => {
|
|
if (card.enabled) {
|
|
const cardElement = document.createElement('div');
|
|
cardElement.className = 'card bg-white rounded-xl shadow p-6 border-t-4';
|
|
cardElement.style.borderColor = card.color;
|
|
cardElement.innerHTML = `
|
|
<div class="rounded-full w-14 h-14 flex items-center justify-center bg-${card.color}-100 text-${card.color}-600 mb-4">
|
|
<i class="fas ${card.icon} text-2xl"></i>
|
|
</div>
|
|
<h2 class="text-xl font-bold text-gray-800 mb-2">${card.title}</h2>
|
|
<p class="text-gray-600 mb-4">${card.description}</p>
|
|
<a href="${card.link}" class="block text-center bg-${card.color}-600 hover:bg-${card.color}-700 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
|
Otevřít aplikaci
|
|
</a>
|
|
`;
|
|
grid.appendChild(cardElement);
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error('Error loading cards:', error);
|
|
}
|
|
}
|
|
|
|
// Initialize
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
if (authToken) {
|
|
// Verify token
|
|
fetch('/api/verify', {
|
|
headers: {
|
|
'Authorization': `Bearer ${authToken}`,
|
|
},
|
|
})
|
|
.then(response => {
|
|
if (response.ok) {
|
|
updateAuthUI();
|
|
} else {
|
|
authToken = null;
|
|
localStorage.removeItem('authToken');
|
|
updateAuthUI();
|
|
}
|
|
});
|
|
}
|
|
loadCards();
|
|
});
|
|
|
|
// Search functionality
|
|
document.getElementById('search').addEventListener('input', (e) => {
|
|
const searchTerm = e.target.value.toLowerCase();
|
|
const cards = document.querySelectorAll('#apps-grid .card');
|
|
|
|
cards.forEach(card => {
|
|
const title = card.querySelector('h2').textContent.toLowerCase();
|
|
const description = card.querySelector('p').textContent.toLowerCase();
|
|
const isVisible = title.includes(searchTerm) || description.includes(searchTerm);
|
|
card.style.display = isVisible ? 'block' : 'none';
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<footer class="bg-gray-800 text-gray-400 py-8 mt-12">
|
|
<div class="max-w-6xl mx-auto px-4">
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
|
<!-- Company Info -->
|
|
<div>
|
|
<h3 class="text-white text-lg font-semibold mb-4">Poppe + Potthoff CZ</h3>
|
|
<p class="mb-2">IČO: 26902214</p>
|
|
<p class="mb-2">DIČ: CZ26902214</p>
|
|
<p class="mb-2">Schránka: gfrk5qy</p>
|
|
<p>Na Záhonech 1086, 686 04 Kunovice</p>
|
|
</div>
|
|
|
|
<!-- Quick Links -->
|
|
<div>
|
|
<h3 class="text-white text-lg font-semibold mb-4">Rychlé odkazy</h3>
|
|
<ul class="space-y-2">
|
|
<li><a href="http://webportal/" class="hover:text-white">Rozcestník</a></li>
|
|
<li><a href="http://webportal/evidence-aut" class="hover:text-white">Evidence aut</a></li>
|
|
<li><a href="http://ppc-app/pwkweb2/" class="hover:text-white">Objednávka obědů</a></li>
|
|
<li><a href="http://osticket/" class="hover:text-white">Technická podpora</a></li>
|
|
<li><a href="http://webportal/kontakt" class="hover:text-white">Kontakty</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- Copyright -->
|
|
<div class="md:text-right">
|
|
<img src="http://pp-kunovice.cz/wp-content/uploads/2022/04/logo-retina-white.png" alt="Poppe Potthoff Logo" class="h-10 mb-4 inline-block">
|
|
<p class="text-sm"> 2025 Poppe + Potthoff CZ</p>
|
|
<p class="text-xs mt-2">Všechna práva vyhrazena</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="border-t border-gray-700 mt-8 pt-6 text-center text-sm">
|
|
<p>Created by <a href="https://tdvorak.dev" class="text-blue-400 hover:text-blue-300">TDvorak</a></p>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
<script>
|
|
// Search functionality
|
|
const searchInput = document.getElementById('search');
|
|
const appCards = document.querySelectorAll('.card');
|
|
|
|
searchInput.addEventListener('input', function() {
|
|
const searchTerm = this.value.toLowerCase();
|
|
|
|
appCards.forEach(card => {
|
|
const cardName = card.getAttribute('data-name').toLowerCase();
|
|
const cardTitle = card.querySelector('h2').textContent.toLowerCase();
|
|
const cardDesc = card.querySelector('p').textContent.toLowerCase();
|
|
|
|
if (cardName.includes(searchTerm) || cardTitle.includes(searchTerm) || cardDesc.includes(searchTerm)) {
|
|
card.style.display = 'block';
|
|
} else {
|
|
card.style.display = 'none';
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |