# ๐ CARDS - Documentazione Completa NetGescon
> **Sistema Cards dell'interfaccia universale**
> **๐
Creato:** 21/07/2025
> **๐ Ultimo aggiornamento:** 21/07/2025
> **๐ฏ Prioritร :** โก ALTO
---
## ๐ **OVERVIEW CARDS SYSTEM**
Il Sistema Cards NetGescon fornisce **COMPONENTI MODULARI** per:
- ๐ **Dashboard Stats Cards**
- ๐ **Info Cards**
- ๐ฏ **Action Cards**
- ๐ **Chart Cards**
- ๐ **Content Cards**
- โ ๏ธ **Alert Cards**
### ๐จ **Design Philosophy**
- **Consistenza Visiva** - Stile uniforme in tutta l'app
- **Interattivitร ** - Hover effects e animazioni smooth
- **Responsiveness** - Adattamento perfetto a ogni device
- **Accessibilitร ** - WCAG 2.1 AA compliant
---
## ๐จ **DESIGN SPECIFICATIONS**
### ๐ **Color Palette**
```css
/* Base Card Styles */
.netgescon-card {
background: white;
border: 1px solid var(--netgescon-gray-200);
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
.netgescon-card:hover {
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
transform: translateY(-2px);
}
/* Gradient Cards */
.card-gradient-blue {
background: linear-gradient(135deg, #ebf4ff 0%, #dbeafe 100%);
border-color: var(--netgescon-primary-light);
}
.card-gradient-green {
background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);
border-color: var(--netgescon-success);
}
.card-gradient-yellow {
background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);
border-color: var(--netgescon-warning);
}
.card-gradient-red {
background: linear-gradient(135deg, #fef2f2 0%, #fecaca 100%);
border-color: var(--netgescon-danger);
}
```
### ๐ **Base Dimensions**
```css
/* Standard Card */
.netgescon-card {
padding: 24px;
min-height: 120px;
}
/* Compact Card */
.netgescon-card-compact {
padding: 16px;
min-height: 80px;
}
/* Large Card */
.netgescon-card-large {
padding: 32px;
min-height: 200px;
}
```
---
## ๐ **DASHBOARD STATS CARDS**
### ๐ข **Stats Card Template**
```blade
@props([
'title' => '',
'value' => '',
'icon' => 'fas fa-chart-line',
'color' => 'blue',
'trend' => null,
'trendDirection' => 'up',
'subtitle' => '',
'url' => null
])
@php
$cardClass = "card-gradient-{$color}";
$iconColorClass = match($color) {
'blue' => 'text-blue-600',
'green' => 'text-green-600',
'yellow' => 'text-yellow-600',
'red' => 'text-red-600',
'purple' => 'text-purple-600',
default => 'text-gray-600'
};
$bgIconClass = match($color) {
'blue' => 'bg-blue-500',
'green' => 'bg-green-500',
'yellow' => 'bg-yellow-500',
'red' => 'bg-red-500',
'purple' => 'bg-purple-500',
default => 'bg-gray-500'
};
@endphp
{{ $title }}
{{ $value }}
@if($trend)
{{ $trend }}
@endif
@if($subtitle)
{{ $subtitle }}
@endif
```
### ๐ป **Usage Examples**
```blade
```
---
## ๐ **INFO CARDS**
### โน๏ธ **Info Card Template**
```blade
@props([
'title' => '',
'content' => '',
'icon' => 'fas fa-info-circle',
'type' => 'info', // info, success, warning, danger
'dismissible' => false
])
@php
$typeClasses = [
'info' => 'bg-blue-50 border-blue-200 text-blue-800',
'success' => 'bg-green-50 border-green-200 text-green-800',
'warning' => 'bg-yellow-50 border-yellow-200 text-yellow-800',
'danger' => 'bg-red-50 border-red-200 text-red-800'
];
$iconClasses = [
'info' => 'text-blue-600',
'success' => 'text-green-600',
'warning' => 'text-yellow-600',
'danger' => 'text-red-600'
];
@endphp
@if($title)
{{ $title }}
@endif
{!! $content !!}
@if($dismissible)
@endif
```
---
## ๐ฏ **ACTION CARDS**
### โก **Action Card Template**
```blade
@props([
'title' => '',
'description' => '',
'icon' => 'fas fa-plus',
'buttonText' => 'Azione',
'buttonUrl' => '#',
'buttonColor' => 'primary',
'image' => null
])
@if($image)

@else
@endif
{{ $title }}
@if($description)
{{ $description }}
@endif
{{ $buttonText }}
```
---
## ๐ **CHART CARDS**
### ๐ **Chart Card Template**
```blade
@props([
'title' => '',
'chartId' => '',
'chartType' => 'line',
'height' => '300px',
'data' => [],
'options' => []
])
{{ $title }}
@push('scripts')
@endpush
```
---
## ๐ **CONTENT CARDS**
### ๐ฐ **Content Card Template**
```blade
@props([
'title' => '',
'content' => '',
'image' => null,
'footer' => null,
'tags' => [],
'url' => null
])
@if($image)
@endif
@if($title)
{{ $title }}
@endif
{!! $content !!}
@if(count($tags) > 0)
@foreach($tags as $tag)
{{ $tag }}
@endforeach
@endif
@if($footer)
@endif
```
---
## โ ๏ธ **ALERT CARDS**
### ๐จ **Alert Card Template**
```blade
@props([
'type' => 'info', // info, success, warning, danger
'title' => '',
'message' => '',
'actions' => [],
'dismissible' => true
])
@php
$alertClasses = [
'info' => 'border-l-blue-500 bg-blue-50',
'success' => 'border-l-green-500 bg-green-50',
'warning' => 'border-l-yellow-500 bg-yellow-50',
'danger' => 'border-l-red-500 bg-red-50'
];
$iconClasses = [
'info' => 'fas fa-info-circle text-blue-500',
'success' => 'fas fa-check-circle text-green-500',
'warning' => 'fas fa-exclamation-triangle text-yellow-500',
'danger' => 'fas fa-exclamation-circle text-red-500'
];
@endphp
@if($title)
{{ $title }}
@endif
{!! $message !!}
@if(count($actions) > 0)
@endif
@if($dismissible)
@endif
```
---
## โก **JAVASCRIPT ENHANCEMENTS**
### ๐ **File:** `/public/js/components/cards.js`
```javascript
/**
* Cards NetGescon - JavaScript Enhancements
*/
// Initialize cards functionality
function initializeCards() {
initializeStatsCards();
initializeChartCards();
initializeContentCards();
initializeAnimations();
}
// Stats cards animations
function initializeStatsCards() {
const statsCards = document.querySelectorAll('.stats-grid .netgescon-card');
// Animate numbers on load
statsCards.forEach((card, index) => {
const valueElement = card.querySelector('.text-3xl');
if (valueElement) {
const targetValue = valueElement.textContent;
const numericValue = parseInt(targetValue.replace(/[^\d]/g, ''));
if (!isNaN(numericValue)) {
animateNumber(valueElement, 0, numericValue, 1000, index * 100);
}
}
});
// Add click analytics
statsCards.forEach(card => {
card.addEventListener('click', function() {
const title = this.querySelector('.text-sm').textContent;
trackCardClick('stats', title);
});
});
}
// Animate number counting
function animateNumber(element, start, end, duration, delay = 0) {
setTimeout(() => {
const range = end - start;
const startTime = performance.now();
const originalText = element.textContent;
const prefix = originalText.replace(/[\d,]/g, '');
function updateNumber(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
const current = Math.floor(start + (range * easeOutQuart(progress)));
element.textContent = prefix + current.toLocaleString();
if (progress < 1) {
requestAnimationFrame(updateNumber);
}
}
requestAnimationFrame(updateNumber);
}, delay);
}
// Easing function
function easeOutQuart(t) {
return 1 - (--t) * t * t * t;
}
// Chart cards functionality
function initializeChartCards() {
// Auto-refresh charts
setInterval(() => {
const autoRefreshCharts = document.querySelectorAll('[data-auto-refresh="true"]');
autoRefreshCharts.forEach(chart => {
const chartId = chart.querySelector('canvas').id;
refreshChart(chartId);
});
}, 300000); // 5 minutes
}
// Refresh chart data
async function refreshChart(chartId) {
try {
const response = await fetch(`/api/charts/${chartId}/data`);
const data = await response.json();
if (window.charts && window.charts[chartId]) {
window.charts[chartId].data = data;
window.charts[chartId].update();
}
} catch (error) {
console.warn('Failed to refresh chart:', chartId, error);
}
}
// Update chart period
async function updateChart(chartId, period) {
try {
const response = await fetch(`/api/charts/${chartId}/data?period=${period}`);
const data = await response.json();
if (window.charts && window.charts[chartId]) {
window.charts[chartId].data = data;
window.charts[chartId].update();
}
} catch (error) {
console.warn('Failed to update chart:', chartId, error);
}
}
// Content cards enhancements
function initializeContentCards() {
const contentCards = document.querySelectorAll('.netgescon-card[data-url]');
contentCards.forEach(card => {
card.addEventListener('click', function() {
const url = this.dataset.url;
const title = this.querySelector('h3')?.textContent || 'Unknown';
trackCardClick('content', title);
window.location.href = url;
});
});
}
// Animation enhancements
function initializeAnimations() {
// Intersection Observer for scroll animations
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-in');
}
});
}, { threshold: 0.1 });
// Observe all cards
document.querySelectorAll('.netgescon-card').forEach(card => {
observer.observe(card);
});
}
// Analytics tracking
function trackCardClick(type, title) {
// Send analytics data
if (window.gtag) {
gtag('event', 'card_click', {
card_type: type,
card_title: title,
page_location: window.location.href
});
}
// Send to internal analytics
fetch('/api/analytics/card-click', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
},
body: JSON.stringify({
type: type,
title: title,
url: window.location.href,
timestamp: new Date().toISOString()
})
}).catch(() => {}); // Silent fail
}
// Initialize on DOM ready
document.addEventListener('DOMContentLoaded', initializeCards);
```
---
## ๐ฑ **RESPONSIVE GRID SYSTEM**
### ๐ **Grid Layouts**
```css
/* Stats Cards Grid */
.stats-grid {
display: grid;
gap: 1.5rem;
grid-template-columns: 1fr;
}
@media (min-width: 640px) {
.stats-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.stats-grid {
grid-template-columns: repeat(4, 1fr);
}
}
/* Content Cards Grid */
.content-grid {
display: grid;
gap: 2rem;
grid-template-columns: 1fr;
}
@media (min-width: 768px) {
.content-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.content-grid {
grid-template-columns: repeat(3, 1fr);
}
}
/* Mixed Layout */
.cards-mixed {
display: grid;
gap: 1.5rem;
grid-template-columns: 1fr;
}
@media (min-width: 768px) {
.cards-mixed {
grid-template-columns: 2fr 1fr;
}
}
```
---
## ๐งช **TESTING CHECKLIST**
### โ
**Visual Tests**
- [ ] Cards consistent spacing
- [ ] Hover effects smooth
- [ ] Icons properly aligned
- [ ] Colors match brand palette
- [ ] Responsive grid working
### โ
**Functional Tests**
- [ ] Click handlers working
- [ ] Chart updates functional
- [ ] Animations performant
- [ ] Dismiss buttons working
- [ ] Analytics tracking
### โ
**Accessibility Tests**
- [ ] Keyboard navigation
- [ ] Screen reader compatibility
- [ ] Color contrast sufficient
- [ ] Focus indicators visible
- [ ] Alternative text present
---
## ๐ **PERFORMANCE OPTIMIZATION**
### โก **Best Practices**
```css
/* CSS Optimizations */
.netgescon-card {
/* Use transform instead of changing box-shadow directly */
will-change: transform, box-shadow;
}
.netgescon-card:hover {
/* Hardware acceleration */
transform: translateY(-2px) translateZ(0);
}
/* Reduce repaints */
.card-animation {
backface-visibility: hidden;
perspective: 1000px;
}
```
```javascript
// JavaScript Optimizations
function throttle(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// Throttled scroll handler
window.addEventListener('scroll', throttle(handleScroll, 16));
```
---
## ๐ **FILES CORRELATI**
### ๐งฉ **Components**
- `/resources/views/components/cards/` (directory)
- `/resources/views/components/cards/stats-card.blade.php`
- `/resources/views/components/cards/info-card.blade.php`
- `/resources/views/components/cards/action-card.blade.php`
- `/resources/views/components/cards/chart-card.blade.php`
- `/resources/views/components/cards/content-card.blade.php`
- `/resources/views/components/cards/alert-card.blade.php`
### ๐จ **Styles**
- `/public/css/components/cards.css`
- `/public/css/netgescon-admin.css`
### โก **JavaScript**
- `/public/js/components/cards.js`
- `/public/js/charts/chart-manager.js`
---
## ๐ฏ **NEXT STEPS**
### ๐ฎ **Planned Improvements**
- [ ] **Advanced Charts** - More chart types and interactions
- [ ] **Card Templates** - Pre-built card collections
- [ ] **Drag & Drop** - Rearrangeable dashboard cards
- [ ] **Real-time Data** - WebSocket live updates
- [ ] **Custom Themes** - User-customizable card appearances
---
*๐ Documento mantenuto da: GitHub Copilot AI Assistant*
*๐ Componente: Cards System NetGescon Interface v2.1.0*