Company: Widok wyboru firmy
This commit is contained in:
427
prototype/company/app-select-company.php
Normal file
427
prototype/company/app-select-company.php
Normal file
@@ -0,0 +1,427 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Wybierz firmę - company.magico</title>
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Public+Sans:wght@400;500;600;700&display=swap"
|
||||
rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* === STYLE WZOROWANE NA SNEAT (Standalone) === */
|
||||
body {
|
||||
background-color: #f5f5f9;
|
||||
/* Charakterystyczne tło Sneat */
|
||||
font-family: 'Public Sans', sans-serif;
|
||||
color: #566a7f;
|
||||
}
|
||||
|
||||
/* Kontener ograniczający szerokość siatki */
|
||||
.tenant-container {
|
||||
max-width: 1000px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Logo tekstowe */
|
||||
.brand-logo {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
color: #696cff;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
/* Kafelki firm */
|
||||
.tenant-card {
|
||||
background-color: #fff;
|
||||
border-radius: 0.5rem;
|
||||
border: 1px solid transparent;
|
||||
box-shadow: 0 2px 6px 0 rgba(67, 89, 113, 0.12);
|
||||
transition: all 0.2s ease-in-out;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 1.25rem;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.tenant-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 4px 12px 0 rgba(67, 89, 113, 0.16);
|
||||
border-color: rgba(105, 108, 255, 0.2);
|
||||
}
|
||||
|
||||
/* Avatary firm */
|
||||
.tenant-avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
flex-shrink: 0;
|
||||
background-color: #e7e7ff;
|
||||
color: #696cff;
|
||||
}
|
||||
|
||||
/* Gwiazdka (Ulubione) */
|
||||
.star-btn {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 5px;
|
||||
font-size: 1.3rem;
|
||||
color: #d9dee3;
|
||||
/* Wygaszony szary */
|
||||
transition: 0.2s ease;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.star-btn:hover {
|
||||
color: #ffab00;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.star-btn.active {
|
||||
color: #ffab00;
|
||||
}
|
||||
|
||||
.tenant-card>div:last-child {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
/* === Alert: brak firm === */
|
||||
.no-company-alert {
|
||||
background: #fff;
|
||||
border-radius: 0.5rem;
|
||||
border: 1px solid #e7e7ff;
|
||||
box-shadow: 0 2px 6px 0 rgba(67, 89, 113, 0.08);
|
||||
padding: 1.5rem 1.75rem;
|
||||
}
|
||||
|
||||
.no-company-alert .alert-divider {
|
||||
width: 1px;
|
||||
background: #e4e6ea;
|
||||
align-self: stretch;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.no-company-alert .alert-section {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.no-company-alert .alert-icon {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.15rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.no-company-alert .create-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
color: #696cff;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
font-size: 0.875rem;
|
||||
transition: opacity 0.15s;
|
||||
}
|
||||
|
||||
.no-company-alert .create-link:hover {
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
@media (max-width: 575px) {
|
||||
.no-company-alert .alert-divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.no-company-alert .alert-section+.alert-section {
|
||||
border-top: 1px solid #e4e6ea;
|
||||
padding-top: 1rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="d-flex flex-column align-items-center justify-content-center min-vh-100 py-5 px-3">
|
||||
|
||||
<div class="tenant-container">
|
||||
|
||||
<div class="text-center mb-5">
|
||||
<div class="brand-logo mb-3">
|
||||
<img src="https://cdn.magico.pro/logo/company.svg" width="300" class="mb-3">
|
||||
</div>
|
||||
<h3 class="fw-bold mb-2" style="color: #435971;">Wybierz firmę</h3>
|
||||
<p class="text-muted">Wybierz kontekst roboczy, do którego chcesz się zalogować.</p>
|
||||
</div>
|
||||
|
||||
<!-- Soft alert: brak firm -->
|
||||
<div class="d-flex align-items-center gap-3 mt-4 px-4 py-3 rounded-2 mb-4"
|
||||
style="background:#fffbeb; border:1px solid #fde68a;">
|
||||
<i class='bx bx-info-circle fs-5' style="color:#d97706; flex-shrink:0;"></i>
|
||||
<p class="mb-0 small" style="color:#92400e; line-height:1.6;">
|
||||
<strong>Nie masz jeszcze przypisanej żadnej firmy.</strong>
|
||||
Twoje konto jest aktywne, ale nie należy jeszcze do żadnej organizacji w systemie.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
|
||||
|
||||
<div class="col">
|
||||
<div class="tenant-card" onclick="loginToTenant('1')">
|
||||
<button class="star-btn active" title="Usuń z ulubionych">
|
||||
<i class='bx bx-star'></i>
|
||||
</button>
|
||||
|
||||
<div class="tenant-avatar me-3 bg-label-primary">
|
||||
AM
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="mb-1 text-dark">Agencja Magico Software Sp. z o.o.</h6>
|
||||
<div class="d-flex align-items-center text-muted small">
|
||||
<i class='bx bx-group me-1'></i> 142 użytkowników
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="tenant-card" onclick="loginToTenant('2')">
|
||||
<button class="star-btn" title="Dodaj do ulubionych">
|
||||
<i class='bx bx-star'></i>
|
||||
</button>
|
||||
|
||||
<div class="tenant-avatar me-3" style="background-color: #e8fadf; color: #71dd37;">
|
||||
TR
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="mb-1 text-dark">Travel Pay</h6>
|
||||
<div class="d-flex align-items-center text-muted small">
|
||||
<i class='bx bx-group me-1'></i> 12 użytkowników
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="tenant-card" onclick="loginToTenant('3')">
|
||||
<button class="star-btn" title="Dodaj do ulubionych">
|
||||
<i class='bx bx-star'></i>
|
||||
</button>
|
||||
|
||||
<div class="tenant-avatar me-3 p-0 overflow-hidden">
|
||||
<img src="https://ui-avatars.com/api/?name=Artex&background=fff2d6&color=ffab00" alt="Logo"
|
||||
class="w-100 h-100 object-fit-cover">
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="mb-1 text-dark">Artex S.C.</h6>
|
||||
<div class="d-flex align-items-center text-muted small">
|
||||
<i class='bx bx-group me-1'></i> 5 użytkowników
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="tenant-card" onclick="loginToTenant('4')">
|
||||
<button class="star-btn" title="Dodaj do ulubionych">
|
||||
<i class='bx bx-star'></i>
|
||||
</button>
|
||||
|
||||
<div class="tenant-avatar me-3" style="background-color: #ffe1e1; color: #ff3e1d;">
|
||||
FL
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="mb-1 text-dark">Flixbus Polska</h6>
|
||||
<div class="d-flex align-items-center text-muted small">
|
||||
<i class='bx bx-group me-1'></i> 48 użytkowników
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="tenant-card" onclick="loginToTenant('5')">
|
||||
<button class="star-btn" title="Dodaj do ulubionych">
|
||||
<i class='bx bx-star'></i>
|
||||
</button>
|
||||
|
||||
<div class="tenant-avatar me-3" style="background-color: #e1f0ff; color: #03c3ec;">
|
||||
GW
|
||||
</div>
|
||||
<div>
|
||||
<h6 class="mb-1 text-dark">Global Wings Tour</h6>
|
||||
<div class="d-flex align-items-center text-muted small">
|
||||
<i class='bx bx-group me-1'></i> 2 użytkowników
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Alert: brak firm do wyboru (pokazywany gdy lista jest pusta) -->
|
||||
<div class="no-company-alert mt-4 d-flex flex-column flex-sm-row gap-3 align-items-sm-center">
|
||||
|
||||
<!-- Sekcja: pracownik -->
|
||||
<div class="alert-section d-flex align-items-start gap-3">
|
||||
<div class="alert-icon" style="background:#e1f0ff; color:#03c3ec;">
|
||||
<i class='bx bx-user'></i>
|
||||
</div>
|
||||
<div>
|
||||
<p class="mb-1 fw-semibold" style="color:#435971; font-size:.875rem;">Jestem pracownikiem</p>
|
||||
<p class="mb-0 text-muted" style="font-size:.8125rem; line-height:1.5;">
|
||||
Jeśli powinieneś mieć dostęp do firmy, skontaktuj się z administratorem
|
||||
systemu — to on nadaje uprawnienia i przypisuje konta do organizacji.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Sekcja: właściciel / manager -->
|
||||
<div class="alert-section d-flex align-items-start gap-3">
|
||||
<div class="alert-icon" style="background:#e7e7ff; color:#696cff;">
|
||||
<i class='bx bx-buildings'></i>
|
||||
</div>
|
||||
<div>
|
||||
<p class="mb-1 fw-semibold" style="color:#435971; font-size:.875rem;">Jestem właścicielem lub
|
||||
managerem</p>
|
||||
<p class="mb-0 text-muted" style="font-size:.8125rem; line-height:1.5;">
|
||||
Nie masz jeszcze żadnej firmy w systemie?
|
||||
</p>
|
||||
<a href="/create-company" class="create-link mt-2">
|
||||
<i class='bx bx-plus-circle'></i> Załóż nową firmę
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-5">
|
||||
<p class="text-muted small">
|
||||
Nie widzisz swojej firmy? <a href="#" class="text-primary text-decoration-none fw-semibold">Zaloguj
|
||||
się na inne konto</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Zapisz oryginalne indeksy kolumn przy starcie strony
|
||||
const grid = document.querySelector('.row');
|
||||
[...grid.children].forEach((col, i) => {
|
||||
col.dataset.originalIndex = i;
|
||||
});
|
||||
|
||||
// FLIP animation helper — przesuwa kolumnę do zadanego miejsca w DOM
|
||||
function flipMove(colToMove, insertFn) {
|
||||
const cols = [...grid.children];
|
||||
|
||||
// FIRST: zapisz pozycje wszystkich kolumn
|
||||
const firstRects = cols.map(col => col.getBoundingClientRect());
|
||||
|
||||
// Wykonaj przestawienie w DOM
|
||||
insertFn();
|
||||
|
||||
// LAST + INVERT + PLAY
|
||||
cols.forEach((col, i) => {
|
||||
const lastRect = col.getBoundingClientRect();
|
||||
const dx = firstRects[i].left - lastRect.left;
|
||||
const dy = firstRects[i].top - lastRect.top;
|
||||
|
||||
if (dx === 0 && dy === 0) return;
|
||||
|
||||
col.style.transition = 'none';
|
||||
col.style.transform = `translate(${dx}px, ${dy}px)`;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
col.style.transition = 'transform 0.45s cubic-bezier(0.25, 0.46, 0.45, 0.94)';
|
||||
col.style.transform = '';
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Przenieś na początek listy
|
||||
function moveToFront(col) {
|
||||
flipMove(col, () => grid.insertBefore(col, grid.firstChild));
|
||||
}
|
||||
|
||||
// Wróć na oryginalną pozycję
|
||||
function moveToOriginal(col) {
|
||||
const targetIndex = parseInt(col.dataset.originalIndex);
|
||||
flipMove(col, () => {
|
||||
const allCols = [...grid.children];
|
||||
// Znajdź element, przed którym należy wstawić (pierwszy z oryginalnym indeksem >= targetIndex, pomijając col)
|
||||
const ref = allCols.find(c => c !== col && parseInt(c.dataset.originalIndex) > targetIndex);
|
||||
if (ref) {
|
||||
grid.insertBefore(col, ref);
|
||||
} else {
|
||||
grid.appendChild(col);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Obsługa gwiazdek (Ulubione)
|
||||
document.querySelectorAll('.star-btn').forEach(btn => {
|
||||
// Ustaw poprawną ikonę przy starcie
|
||||
const icon = btn.querySelector('i');
|
||||
if (btn.classList.contains('active')) {
|
||||
icon.className = 'bx bxs-star';
|
||||
}
|
||||
|
||||
btn.addEventListener('click', function (e) {
|
||||
e.stopPropagation();
|
||||
|
||||
this.classList.toggle('active');
|
||||
|
||||
const icon = this.querySelector('i');
|
||||
const col = this.closest('.col');
|
||||
|
||||
if (this.classList.contains('active')) {
|
||||
icon.className = 'bx bxs-star';
|
||||
this.setAttribute('title', 'Usuń z ulubionych');
|
||||
moveToFront(col);
|
||||
// Tutaj wrzucisz request do API zapisujący ulubione
|
||||
} else {
|
||||
icon.className = 'bx bx-star';
|
||||
this.setAttribute('title', 'Dodaj do ulubionych');
|
||||
moveToOriginal(col);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Obsługa wyboru firmy
|
||||
function loginToTenant(tenantId) {
|
||||
console.log('Logowanie do firmy ID:', tenantId);
|
||||
// window.location.href = '/dashboard?tenant=' + tenantId;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user