Nowa aplikacja: Company - widok informacji o firmie

This commit is contained in:
2026-03-07 18:03:23 +01:00
parent c63e7e6c9c
commit eed545736d
7 changed files with 972 additions and 8 deletions

View File

@@ -0,0 +1,291 @@
<?php
$enablePrototypeComments = true;
include '../../header-invoice.php';
?>
<!-- Vendor CSS -->
<link rel="stylesheet" href="../../assets/vendor/libs/select2/select2.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.css" />
<style>
/* Obłe krawędzie dla kółka wykadrowania w Cropper JS */
.cropper-view-box,
.cropper-face {
border-radius: 50%;
}
</style>
<div class="container-xxl flex-grow-1 container-p-y">
<h4 class="fw-bold py-3 mb-4">
<span class="text-muted fw-light">Zarządzanie firmą /</span> Informacje o firmie
</h4>
<div class="row">
<div class="col-md-12">
<div class="card mb-4">
<h5 class="card-header border-bottom">Profil firmy</h5>
<div class="card-body mt-3">
<div class="d-flex align-items-start align-items-sm-center gap-4">
<img src="https://ui-avatars.com/api/?name=Firma&background=e7e7ff&color=696cff&size=150"
alt="Logo firmy" class="d-block rounded-circle" height="100" width="100" id="uploadedLogo"
style="object-fit: cover;">
<div class="button-wrapper">
<label for="upload" class="btn btn-primary me-2 mb-3" tabindex="0">
<span class="d-none d-sm-block">Wgraj nowe logo</span>
<i class="bx bx-upload d-block d-sm-none"></i>
<input type="file" id="upload" class="account-file-input" hidden
accept="image/png, image/jpeg, image/jpg">
</label>
<button type="button" class="btn btn-label-secondary account-image-reset mb-3">
<i class="bx bx-reset d-block d-sm-none"></i>
<span class="d-none d-sm-block">Usuń</span>
</button>
<p class="text-muted mb-0">Dozwolone formaty: JPG, GIF lub PNG. Max rozmiar 800K</p>
</div>
</div>
</div>
<hr class="my-0">
<div class="card-body">
<form id="formCompanyProfile" onsubmit="return false">
<div class="row">
<div class="mb-3 col-md-6">
<label for="companyShortName" class="form-label">
Krótka nazwa firmy
<i class="bx bx-info-circle text-muted ms-1 cursor-pointer" data-bs-toggle="tooltip"
data-bs-placement="top"
title="Nazwa będzie widoczna tylko dla Ciebie i współpracowników. Wykorzystywana w aplikacjach magico."></i>
</label>
<input class="form-control" type="text" id="companyShortName" name="companyShortName"
placeholder="Wpisz krótką nazwę..." value="" autofocus>
</div>
</div>
</form>
</div>
</div>
<div class="card mb-4">
<h5 class="card-header border-bottom">Dane rozliczeniowe</h5>
<div class="card-body mt-3">
<form id="formBillingSettings" onsubmit="return false">
<div class="row g-4">
<div class="col-md-6">
<label for="locationLabel" class="form-label">Kraj</label>
<select id="locationLabel" class="form-select select2-country">
<option value="pl" selected>Polska</option>
<option value="us">Stany Zjednoczone</option>
<option value="gb">Wielka Brytania</option>
<option value="de">Niemcy</option>
<option value="fr">Francja</option>
<option value="it">Włochy</option>
<option value="es">Hiszpania</option>
<option value="ua">Ukraina</option>
</select>
</div>
<div class="col-md-6">
<label for="nipNumber" class="form-label">Numer NIP</label>
<input type="text" name="nipNumber" id="nipNumber" placeholder="___-___-__-__"
class="form-control">
</div>
<div class="col-md-12">
<label for="companyFullName" class="form-label">Pełna nazwa firmy</label>
<input type="text" name="companyFullName" id="companyFullName"
placeholder="Wpisz pełną nazwę podmiotu..." class="form-control">
<div class="form-text">Do użytku w rozliczeniach i fakturach</div>
</div>
<div class="col-md-4">
<label for="zipCode" class="form-label">Kod pocztowy</label>
<input type="text" name="zipCode" id="zipCode" placeholder="__-___"
class="form-control">
</div>
<div class="col-md-8">
<label for="cityName" class="form-label">Miasto</label>
<input type="text" name="cityName" id="cityName" placeholder="Wpisz miasto..."
class="form-control">
</div>
<div class="col-md-12">
<label for="addressDetails" class="form-label">Adres</label>
<input type="text" name="addressDetails" id="addressDetails"
placeholder="Ulica i numer budynku/lokalu" class="form-control">
</div>
<div class="col-md-12 mt-4">
<div class="border-top pt-4">
<label for="billingEmail" class="form-label">Dodatkowy adres e-mail do
rozliczeń</label>
<input type="email" name="billingEmail" id="billingEmail"
placeholder="np. ksiegowosc@twojafirma.pl" class="form-control mb-2">
<div class="alert alert-primary d-flex align-items-baseline mb-0" role="alert">
<span class="alert-icon align-middle me-2">
<i class="bx bx-info-circle"></i>
</span>
<div>
Dokumenty rozliczeniowe będą automatycznie wysyłane na powyższy adres
(opcjonalnie) oraz do wszystkich użytkowników posiadających rolę
<strong>"Właściciel"</strong> ustawioną w sekcji Zespół.
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- Modal dla Cropper.js -->
<div class="modal fade" id="cropModal" tabindex="-1" aria-hidden="true" data-bs-backdrop="static">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="cropModalLabel">Wykadruj logo (koło)</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Zamknij"></button>
</div>
<div class="modal-body">
<div class="img-container"
style="max-height: 400px; display: flex; justify-content: center; background-color: #f5f5f9;">
<img id="imageToCrop" src="" alt="Obraz do wykadrowania" style="max-width: 100%; display: block;">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-label-secondary" data-bs-dismiss="modal">Anuluj</button>
<button type="button" class="btn btn-primary" id="cropButton">Zatwierdź logo</button>
</div>
</div>
</div>
</div>
<div id="footer" class="footer" style="background: #e7e7ff; position: sticky; bottom: 0px; right: 0px;">
<footer class="content-footer footer">
<div class="container-xxl d-flex py-3 justify-content-center">
<button class="btn btn-primary btn-lg">Zapisz</button>
</div>
</footer>
</div>
<div class="content-backdrop fade"></div>
<?php include '../../footer.php'; ?>
<!-- Scripts -->
<script src="../../assets/vendor/libs/select2/select2.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
// --- Inicjalizacja Tooltipów ---
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl);
});
// --- Inicjalizacja Select2 ---
function renderIcons(option) {
if (!option.id) { return option.text; }
var $icon = $(
"<span class='d-flex align-items-center'><img src='https://flagcdn.com/w20/" + option.id.toLowerCase() + ".png' class='me-2' style='width: 20px; border-radius: 2px;' alt='flag' />" + option.text + "</span>"
);
return $icon;
}
if ($('.select2-country').length) {
$('.select2-country').select2({
templateResult: renderIcons,
templateSelection: renderIcons,
escapeMarkup: function (es) { return es; }
});
}
// --- Inicjalizacja Cropper JS ---
let cropper;
const image = document.getElementById('imageToCrop');
const input = document.getElementById('upload');
const cropModalEl = document.getElementById('cropModal');
const uploadedLogo = document.getElementById('uploadedLogo');
let cropModal;
if (cropModalEl) {
cropModal = new bootstrap.Modal(cropModalEl);
}
if (input) {
input.addEventListener('change', function (e) {
const files = e.target.files;
if (files && files.length > 0) {
const file = files[0];
const reader = new FileReader();
reader.onload = function (e) {
image.src = e.target.result;
cropModal.show();
};
reader.readAsDataURL(file);
}
input.value = ''; // reset value to allow choosing the same file again
});
}
if (cropModalEl) {
cropModalEl.addEventListener('shown.bs.modal', function () {
cropper = new Cropper(image, {
aspectRatio: 1, // kwadrat = koło po zaokrągleniu
viewMode: 1,
dragMode: 'move',
autoCropArea: 0.8,
restore: false,
guides: false,
center: false,
highlight: false,
cropBoxMovable: true,
cropBoxResizable: true,
toggleDragModeOnDblclick: false,
});
});
cropModalEl.addEventListener('hidden.bs.modal', function () {
if (cropper) {
cropper.destroy();
cropper = null;
}
});
}
const cropBtn = document.getElementById('cropButton');
if (cropBtn) {
cropBtn.addEventListener('click', function () {
if (!cropper) return;
const canvas = cropper.getCroppedCanvas({
width: 300,
height: 300
});
uploadedLogo.src = canvas.toDataURL(); // aktualizacja logo
cropModal.hide();
});
}
// Reset obrazka
const resetBtn = document.querySelector('.account-image-reset');
if (resetBtn) {
resetBtn.addEventListener('click', () => {
uploadedLogo.src = 'https://ui-avatars.com/api/?name=Firma&background=e7e7ff&color=696cff&size=150';
});
}
});
</script>
</body>
</html>

131
prototype/company/index.php Normal file
View File

@@ -0,0 +1,131 @@
<?php
$enablePrototypeComments = true;
include '../../header-invoice.php';
?>
<div class="container-fluid flex-grow-1 container-p-y">
<div
class="d-flex flex-column flex-md-row justify-content-between align-items-start align-items-md-center mb-4 gap-3">
<div class="d-flex flex-column justify-content-center">
<h4 class="mb-1 text-body">Witaj w panelu firmy! 👋</h4>
<p class="text-muted mb-0">Oto finansowe podsumowanie Twojego biznesu.</p>
</div>
<div class="d-flex align-content-center flex-wrap gap-2">
<a href="app-invoice-add.php" class="btn btn-primary">
<i class="bx bx-plus me-1"></i> Utwórz nową firmę
</a>
</div>
</div>
</div>
<div class="content-backdrop fade"></div>
<?php include '../../footer.php'; ?>
<script src="../../assets/vendor/libs/apex-charts/apexcharts.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
// Konfiguracja i kolory ze stylu szablonu
let cardColor = '#fff',
headingColor = '#566a7f',
axisColor = '#a1acb8',
borderColor = '#eceef1',
primaryColor = '#696cff',
infoColor = '#03c3ec';
// 1. Wykres Słupkowy - 12 Miesięcy (Przychody)
const sales12MonthsEl = document.querySelector('#sales12MonthsChart');
if (sales12MonthsEl) {
const sales12MonthsOptions = {
chart: {
height: 300,
type: 'bar',
toolbar: { show: false }
},
plotOptions: {
bar: {
borderRadius: 4,
columnWidth: '40%',
startingShape: 'rounded',
endingShape: 'rounded'
}
},
colors: [primaryColor],
dataLabels: { enabled: false },
series: [{
name: 'Sprzedaż Netto (zł)',
data: [12000, 15000, 14000, 18000, 22000, 19000, 25000, 21000, 17000, 23000, 21800, 24500]
}],
xaxis: {
categories: ['Kwi', 'Maj', 'Cze', 'Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru', 'Sty', 'Lut', 'Mar'],
axisBorder: { show: false },
axisTicks: { show: false },
labels: { style: { colors: axisColor } }
},
yaxis: {
labels: { style: { colors: axisColor }, formatter: function (val) { return val / 1000 + "k"; } }
},
grid: {
borderColor: borderColor,
strokeDashArray: 4,
padding: { top: -20, bottom: -10, left: 10, right: 10 }
}
};
const sales12MonthsChart = new ApexCharts(sales12MonthsEl, sales12MonthsOptions);
sales12MonthsChart.render();
}
// 2. Wykres Liniowy - Porównanie Rok do Roku (YoY)
const salesYoYEl = document.querySelector('#salesYoYChart');
if (salesYoYEl) {
const salesYoYOptions = {
chart: {
height: 300,
type: 'line',
toolbar: { show: false }
},
stroke: {
width: [2, 2, 2],
curve: 'smooth'
},
colors: [primaryColor, infoColor, '#ffab00'], // Lata 2026, 2025, 2024
series: [
{ name: '2026', data: [15, 21.8, 24.5, null, null, null, null, null, null, null, null, null] },
{ name: '2025', data: [12, 14, 18, 20, 25, 22, 28, 29, 31, 26, 33, 35] },
{ name: '2024', data: [10, 11, 13, 14, 17, 16, 20, 21, 23, 22, 25, 28] }
],
legend: {
show: true,
position: 'top',
horizontalAlign: 'start',
labels: { colors: headingColor }
},
xaxis: {
categories: ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII'],
axisBorder: { show: false },
axisTicks: { show: false },
labels: { style: { colors: axisColor } }
},
yaxis: {
show: false // Ukrywamy oś Y by wykres był czystszy (trend jest widoczny z tooltipów)
},
grid: {
borderColor: borderColor,
strokeDashArray: 4,
padding: { top: 0, bottom: -10, left: 10, right: 10 }
}
};
const salesYoYChart = new ApexCharts(salesYoYEl, salesYoYOptions);
salesYoYChart.render();
}
});
</script>
</body>
</html>

View File

@@ -0,0 +1,73 @@
<?php
$currentPage = basename($_SERVER['PHP_SELF']);
?>
<aside id="layout-menu" class="layout-menu menu-vertical menu bg-menu-theme">
<div class="app-brand demo">
<a href="index.php" class="app-brand-link">
<span class="app-brand-text demo menu-text fw-bold ms-2">company.magico</span>
</a>
<a href="javascript:void(0);" class="layout-menu-toggle menu-link text-large ms-auto">
<i class="bx bx-chevron-left bx-sm align-middle"></i>
</a>
</div>
<div class="menu-inner-shadow"></div>
<ul class="menu-inner py-1">
<!-- Zarządzanie firmą -->
<li class="menu-header small text-uppercase">
<span class="menu-header-text" data-i18n="Zarządzanie firmą">Zarządzanie firmą</span>
</li>
<li class="menu-item <?php echo ($currentPage == 'index.php') ? 'active' : ''; ?>">
<a href="index.php" class="menu-link">
<i class="menu-icon tf-icons bx bx-home-circle"></i>
<div class="text-truncate" data-i18n="Kokpit">Kokpit</div>
</a>
</li>
<li class="menu-item <?php echo ($currentPage == 'app-services.php') ? 'active' : ''; ?>">
<a href="app-services.php" class="menu-link">
<i class="menu-icon tf-icons bx bx-grid-alt"></i>
<div class="text-truncate" data-i18n="Usługi i aplikacje">Usługi i aplikacje</div>
</a>
</li>
<li class="menu-item <?php echo ($currentPage == 'app-billing.php') ? 'active' : ''; ?>">
<a href="app-billing.php" class="menu-link">
<i class="menu-icon tf-icons bx bx-receipt"></i>
<div class="text-truncate" data-i18n="Rozliczenia">Rozliczenia</div>
</a>
</li>
<li class="menu-item <?php echo ($currentPage == 'app-company-info.php') ? 'active' : ''; ?>">
<a href="app-company-info.php" class="menu-link">
<i class="menu-icon tf-icons bx bx-buildings"></i>
<div class="text-truncate" data-i18n="Informacje o firmie">Informacje o firmie</div>
</a>
</li>
<!-- Zarządzanie zespołem -->
<li class="menu-header small text-uppercase">
<span class="menu-header-text" data-i18n="Zarządzanie zespołem">Zarządzanie zespołem</span>
</li>
<li class="menu-item <?php echo ($currentPage == 'app-team.php') ? 'active' : ''; ?>">
<a href="app-team.php" class="menu-link">
<i class="menu-icon tf-icons bx bx-group"></i>
<div class="text-truncate" data-i18n="Zespół">Zespół</div>
</a>
</li>
<li class="menu-item <?php echo ($currentPage == 'app-groups.php') ? 'active' : ''; ?>">
<a href="app-groups.php" class="menu-link">
<i class="menu-icon tf-icons bx bx-sitemap"></i>
<div class="text-truncate" data-i18n="Grupy">Grupy</div>
</a>
</li>
<li class="menu-item <?php echo ($currentPage == 'app-permissions.php') ? 'active' : ''; ?>">
<a href="app-permissions.php" class="menu-link">
<i class="menu-icon tf-icons bx bx-shield-quarter"></i>
<div class="text-truncate" data-i18n="Uprawnienia">Uprawnienia</div>
</a>
</li>
</ul>
</aside>