# ๐ CONTENT AREA - Documentazione Completa NetGescon
> **Componente Content Area dell'interfaccia universale**
> **๐
Creato:** 21/07/2025
> **๐ Ultimo aggiornamento:** 21/07/2025
> **๐ฏ Prioritร :** ๐ฅ CRITICA
---
## ๐ **OVERVIEW CONTENT AREA**
Il Content Area NetGescon รจ la **ZONA PRINCIPALE** dove vengono visualizzati:
- ๐บ๏ธ **Breadcrumb Navigation**
- ๐ **Page Headers con Actions**
- ๐ **Dashboard Cards**
- ๐ **Forms & Tables**
- ๐ **Alert Messages**
- ๐ **Main Page Content**
### ๐ **Specifiche Layout**
- **Posizione:** `margin-left: 280px` desktop, `margin-left: 0` mobile
- **Altezza:** `calc(100vh - 140px)` (header + footer esclusi)
- **Padding:** `24px` standard, `16px` mobile
- **Overflow:** `scroll` quando contenuto > viewport
---
## ๐จ **DESIGN SPECIFICATIONS**
### ๐ **Color Palette**
```css
/* Content Background */
.content-area {
background: var(--netgescon-gray-50);
min-height: calc(100vh - 140px);
}
/* Page Headers */
.page-header {
background: white;
border-bottom: 1px solid var(--netgescon-gray-200);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
/* Content Containers */
.content-container {
background: white;
border: 1px solid var(--netgescon-gray-200);
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
```
### ๐ **Dimensions**
```css
.content-area {
margin-left: 280px; /* Desktop con sidebar */
margin-top: 70px; /* Header height */
margin-bottom: 70px; /* Footer height */
padding: 24px;
min-height: calc(100vh - 140px);
}
/* Mobile */
@media (max-width: 767px) {
.content-area {
margin-left: 0;
padding: 16px;
}
}
```
---
## ๐งฉ **STRUTTURA CONTENT AREA**
### ๐ **Layout Template**
```blade
@if(isset($breadcrumbs) && count($breadcrumbs) > 0)
@include('components.layout.breadcrumb', ['breadcrumbs' => $breadcrumbs])
@endif
@if(isset($pageTitle) || isset($pageActions))
@include('components.layout.page-header', [
'title' => $pageTitle ?? '',
'subtitle' => $pageSubtitle ?? '',
'actions' => $pageActions ?? []
])
@endif
@include('components.layout.alerts')
@yield('content')
```
---
## ๐บ๏ธ **BREADCRUMB COMPONENT**
### ๐ **File:** `components/layout/breadcrumb.blade.php`
```blade
```
### ๐ป **Usage Examples**
```php
// In Controller
$breadcrumbs = [
['title' => 'Gestione Stabili', 'url' => route('admin.stabili.index'), 'icon' => 'fas fa-building'],
['title' => 'Nuovo Stabile', 'icon' => 'fas fa-plus']
];
return view('admin.stabili.create', compact('breadcrumbs'));
```
---
## ๐ **PAGE HEADER COMPONENT**
### ๐ **File:** `components/layout/page-header.blade.php`
```blade
@if(isset($title))
{{ $title }}
@endif
@if(isset($subtitle))
{{ $subtitle }}
@endif
@if(isset($stats))
@foreach($stats as $stat)
@if(isset($stat['icon']))
@endif
{{ $stat['label'] }}:
{{ $stat['value'] }}
@endforeach
@endif
@if(isset($actions) && count($actions) > 0)
@endif
```
### ๐ป **Usage Examples**
```php
// In Controller
$pageTitle = 'Gestione Stabili';
$pageSubtitle = 'Visualizza e gestisci tutti gli stabili del sistema';
$pageActions = [
[
'type' => 'primary',
'label' => 'Nuovo Stabile',
'url' => route('admin.stabili.create'),
'icon' => 'fas fa-plus'
],
[
'type' => 'secondary',
'label' => 'Esporta Excel',
'url' => route('admin.stabili.export'),
'icon' => 'fas fa-download'
]
];
$stats = [
['label' => 'Totale Stabili', 'value' => '45', 'icon' => 'fas fa-building'],
['label' => 'Condomini', 'value' => '128', 'icon' => 'fas fa-home'],
['label' => 'Unitร ', 'value' => '1,247', 'icon' => 'fas fa-door-open']
];
return view('admin.stabili.index', compact('pageTitle', 'pageSubtitle', 'pageActions', 'stats'));
```
---
## ๐ **ALERT MESSAGES COMPONENT**
### ๐ **File:** `components/layout/alerts.blade.php`
```blade
@if(session('success'))
Operazione completata!
{{ session('success') }}
@endif
@if(session('error'))
Errore!
{{ session('error') }}
@endif
@if(session('warning'))
Attenzione!
{{ session('warning') }}
@endif
@if(session('info'))
Informazione
{{ session('info') }}
@endif
@if($errors->any())
Errori di validazione
@foreach($errors->all() as $error)
- โข {{ $error }}
@endforeach
@endif
```
---
## ๐ **DASHBOARD CARDS PATTERN**
### ๐ **Stats Cards**
```blade
Stabili
{{ $stats['stabili'] ?? 0 }}
+3 questo mese
Condomini
{{ $stats['condomini'] ?? 0 }}
+8 questo mese
Unitร
{{ $stats['unita'] ?? 0 }}
Nessuna variazione
Fatturato
โฌ{{ number_format($stats['fatturato'] ?? 0, 0, ',', '.') }}
+12% vs mese scorso
```
---
## ๐ **FORMS PATTERN**
### ๐ **Standard Form Container**
```blade
```
---
## ๐ **TABLES PATTERN**
### ๐ **Data Table Container**
```blade
@if(isset($pagination))
@endif
```
---
## โก **JAVASCRIPT FUNCTIONALITY**
### ๐ **File:** `/public/js/components/content.js`
```javascript
/**
* Content Area - JavaScript Functions
*/
// Inizializza content area
function initializeContentArea() {
initializeAlerts();
initializeScrollToTop();
initializeStickyHeaders();
initializeInfiniteScroll();
}
// Alert management
function initializeAlerts() {
// Auto-hide alerts
const alerts = document.querySelectorAll('.alert');
alerts.forEach(alert => {
const closeBtn = alert.querySelector('.alert-close');
// Close button
if (closeBtn) {
closeBtn.addEventListener('click', () => {
hideAlert(alert);
});
}
// Auto-hide after 5 seconds
setTimeout(() => {
hideAlert(alert);
}, 5000);
});
}
function hideAlert(alert) {
alert.style.opacity = '0';
alert.style.transform = 'translateY(-10px)';
setTimeout(() => {
if (alert.parentNode) {
alert.parentNode.removeChild(alert);
}
}, 300);
}
// Scroll to top functionality
function initializeScrollToTop() {
const scrollBtn = document.createElement('button');
scrollBtn.className = 'scroll-to-top fixed bottom-20 right-6 bg-blue-600 text-white p-3 rounded-full shadow-lg opacity-0 transition-opacity duration-300 z-50';
scrollBtn.innerHTML = '';
scrollBtn.onclick = () => window.scrollTo({ top: 0, behavior: 'smooth' });
document.body.appendChild(scrollBtn);
window.addEventListener('scroll', () => {
if (window.scrollY > 300) {
scrollBtn.style.opacity = '1';
} else {
scrollBtn.style.opacity = '0';
}
});
}
// Sticky headers for long content
function initializeStickyHeaders() {
const headers = document.querySelectorAll('.page-header');
headers.forEach(header => {
const observer = new IntersectionObserver(
([entry]) => {
if (!entry.isIntersecting) {
header.classList.add('sticky-header');
} else {
header.classList.remove('sticky-header');
}
},
{ threshold: 0.1 }
);
observer.observe(header);
});
}
// Infinite scroll for tables/lists
function initializeInfiniteScroll() {
const container = document.querySelector('[data-infinite-scroll]');
if (!container) return;
let loading = false;
let page = 2;
window.addEventListener('scroll', () => {
if (loading) return;
const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 5) {
loading = true;
loadMoreContent(page++).then(() => {
loading = false;
});
}
});
}
// Load more content via AJAX
async function loadMoreContent(page) {
try {
const response = await fetch(`${window.location.pathname}?page=${page}`, {
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
});
const html = await response.text();
const container = document.querySelector('[data-infinite-scroll]');
container.insertAdjacentHTML('beforeend', html);
} catch (error) {
console.error('Error loading more content:', error);
}
}
// Initialize on DOM ready
document.addEventListener('DOMContentLoaded', initializeContentArea);
```
---
## ๐ฑ **RESPONSIVE BEHAVIOR**
### ๐ฅ๏ธ **Desktop (โฅ1024px)**
```css
.content-area {
margin-left: 280px;
padding: 24px;
}
.page-header {
flex-direction: row;
align-items: center;
}
.stats-grid {
grid-template-columns: repeat(4, 1fr);
}
```
### ๐ฑ **Tablet (768px - 1023px)**
```css
.content-area {
margin-left: 0;
padding: 20px;
}
.stats-grid {
grid-template-columns: repeat(2, 1fr);
}
.page-header .flex {
flex-direction: column;
align-items: stretch;
}
```
### ๐ฑ **Mobile (โค767px)**
```css
.content-area {
padding: 16px;
}
.stats-grid {
grid-template-columns: 1fr;
}
.table-container {
overflow-x: scroll;
}
.form-actions {
flex-direction: column;
align-items: stretch;
}
```
---
## ๐งช **TESTING CHECKLIST**
### โ
**Layout Tests**
- [ ] Content area positioning correct
- [ ] Responsive margins working
- [ ] Scroll behavior smooth
- [ ] Cards grid responsive
- [ ] Forms layout consistent
### โ
**Component Tests**
- [ ] Breadcrumb navigation functional
- [ ] Page header actions working
- [ ] Alerts display/hide correctly
- [ ] Tables search/filter working
- [ ] Forms validation display
### โ
**Interaction Tests**
- [ ] Scroll to top button
- [ ] Infinite scroll loading
- [ ] Alert auto-hide
- [ ] Mobile form usability
---
## ๐ **COMMON ISSUES & FIXES**
### ๐จ **Content nascosto sotto header/footer**
**Causa:** Margin/padding calculations incorrect
**Fix:** Verifica calcoli height e margins CSS
### ๐จ **Cards non responsive**
**Causa:** Grid breakpoints non configurati
**Fix:** Aggiorna grid-template-columns per ogni breakpoint
### ๐จ **Alerts non si chiudono**
**Causa:** JavaScript event listeners non agganciati
**Fix:** Verifica inizializzazione initializeAlerts()
### ๐จ **Forms troppo larghi su mobile**
**Causa:** Responsive form layout non implementato
**Fix:** Aggiorna CSS per form mobile-first
---
## ๐ **FILES CORRELATI**
### ๐งฉ **Templates**
- `/resources/views/layouts/content.blade.php`
- `/resources/views/components/layout/` (directory)
### ๐จ **Styles**
- `/public/css/components/content.css`
- `/public/css/components/forms.css`
- `/public/css/components/tables.css`
### โก **JavaScript**
- `/public/js/components/content.js`
- `/public/js/components/forms.js`
- `/public/js/components/tables.js`
---
## ๐ฏ **NEXT STEPS**
### ๐ฎ **Planned Improvements**
- [ ] **Virtual Scrolling** - Performance per grandi dataset
- [ ] **Advanced Filters** - Multi-criteria filtering
- [ ] **Bulk Actions** - Multiple selections
- [ ] **Export Templates** - Custom export formats
- [ ] **Real-time Updates** - WebSocket integration
---
*๐ Documento mantenuto da: GitHub Copilot AI Assistant*
*๐ Componente: Content Area NetGescon Interface v2.1.0*