Merge pull request #59 from R0m1k3/1.1

Improve layout and visual spacing across the application
This commit is contained in:
LogiFlow authored and GitHub committed 2025-08-12 21:53:57 +02:00
commit e84bbb9249
6 files changed
+83 -68

No files matched your search

+8 -6
View File
@@ -91,10 +91,10 @@ export default function Layout({ children }: LayoutProps) {
{!isMobile && <Sidebar />} {!isMobile && <Sidebar />}
<main className={`flex-1 flex flex-col overflow-hidden ${ <main className={`flex-1 flex flex-col overflow-hidden ${
isMobile ? 'ml-0' : sidebarCollapsed ? 'ml-16' : 'ml-64' isMobile ? 'ml-0' : sidebarCollapsed ? 'ml-16' : 'ml-72 xl:ml-80'
}`}> }`}>
{/* Header with store selector for admin */} {/* Header with store selector for admin */}
<header className="h-16 bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between px-4 sm:px-6"> <header className="h-20 xl:h-24 bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between px-6 sm:px-8 xl:px-12">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
{/* Mobile menu button */} {/* Mobile menu button */}
{isMobile && ( {isMobile && (
@@ -107,7 +107,7 @@ export default function Layout({ children }: LayoutProps) {
{mobileMenuOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />} {mobileMenuOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
</Button> </Button>
)} )}
<h1 className="text-lg font-medium text-gray-800 dark:text-gray-200">LogiFlow</h1> <h1 className="text-xl xl:text-2xl font-semibold text-gray-800 dark:text-gray-200">LogiFlow</h1>
</div> </div>
{/* Store selector for admin - moved to top right */} {/* Store selector for admin - moved to top right */}
@@ -155,7 +155,7 @@ export default function Layout({ children }: LayoutProps) {
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div <div
className="w-3 h-3" className="w-3 h-3"
style={{ backgroundColor: store.color }} style={{ backgroundColor: store.color || '#6B7280' }}
/> />
<span>{store.name}</span> <span>{store.name}</span>
</div> </div>
@@ -168,9 +168,11 @@ export default function Layout({ children }: LayoutProps) {
</header> </header>
{/* Main content area */} {/* Main content area */}
<div className="flex-1 overflow-auto bg-gray-50 dark:bg-gray-900 p-4 sm:p-6"> <div className="flex-1 bg-gray-50 dark:bg-gray-900 p-6 sm:p-8 xl:p-12 overflow-y-auto">
<div className="container-responsive"> <div className="container-responsive">
{children} <div className="desktop-spacing">
{children}
</div>
</div> </div>
</div> </div>
</main> </main>
+6 -6
View File
@@ -259,13 +259,13 @@ export default function Sidebar() {
} }
return ( return (
<aside className={`${isCollapsed ? 'w-16' : 'w-64'} bg-white dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 flex flex-col shadow-lg transition-all duration-300 ease-in-out`}> <aside className={`${isCollapsed ? 'w-16' : 'w-72 xl:w-80'} bg-white dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 flex flex-col shadow-xl transition-all duration-300 ease-in-out`}>
{/* Logo et bouton de collapse */} {/* Logo et bouton de collapse */}
<div className="h-16 flex items-center justify-between border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 px-3"> <div className="h-20 xl:h-24 flex items-center justify-between border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 px-4 xl:px-6">
{!isCollapsed && ( {!isCollapsed && (
<div className="flex items-center space-x-3"> <div className="flex items-center space-x-3">
<Store className="h-6 w-6 text-blue-600 dark:text-blue-400" /> <Store className="h-6 w-6 text-blue-600 dark:text-blue-400" />
<span className="text-lg font-semibold text-gray-900 dark:text-gray-100">LogiFlow</span> <span className="text-xl xl:text-2xl font-bold text-gray-900 dark:text-gray-100">LogiFlow</span>
</div> </div>
)} )}
{isCollapsed && ( {isCollapsed && (
@@ -290,8 +290,8 @@ export default function Sidebar() {
</div> </div>
{/* Navigation */} {/* Navigation */}
<nav className="flex-1 py-4 px-3"> <nav className="flex-1 py-6 xl:py-8 px-4 xl:px-6">
<div className="space-y-1"> <div className="space-y-2 xl:space-y-3">
{menuItems.map((item) => { {menuItems.map((item) => {
const hasRolePermission = hasPermission(item.roles); const hasRolePermission = hasPermission(item.roles);
// console.log(`🔍 Menu item ${item.path} (${item.label}):`, { // console.log(`🔍 Menu item ${item.path} (${item.label}):`, {
@@ -374,7 +374,7 @@ export default function Sidebar() {
</h3> </h3>
</div> </div>
)} )}
<div className="space-y-1"> <div className="space-y-2 xl:space-y-3">
{adminItems.map((item) => { {adminItems.map((item) => {
if (!hasPermission(item.roles)) return null; if (!hasPermission(item.roles)) return null;
+22 -9
View File
@@ -126,30 +126,30 @@
background-color: var(--accent); background-color: var(--accent);
} }
/* Responsive utilities */ /* Responsive utilities - Optimisé pour grand écran */
.container-responsive { .container-responsive {
@apply w-full mx-auto px-4 sm:px-6 lg:px-8; @apply w-full mx-auto px-4 sm:px-6 lg:px-8 xl:px-12;
max-width: 1400px; max-width: none; /* Utilise toute la largeur disponible */
} }
.grid-responsive { .grid-responsive {
@apply grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4; @apply grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5;
} }
.card-responsive { .card-responsive {
@apply bg-card border border-border rounded-lg shadow-sm hover:shadow-md transition-shadow p-4 sm:p-6; @apply bg-card border border-border rounded-xl shadow-sm hover:shadow-lg transition-all p-6 sm:p-8;
} }
.text-responsive-sm { .text-responsive-sm {
@apply text-sm sm:text-base; @apply text-base sm:text-lg lg:text-xl;
} }
.text-responsive-lg { .text-responsive-lg {
@apply text-lg sm:text-xl lg:text-2xl; @apply text-xl sm:text-2xl lg:text-3xl xl:text-4xl;
} }
.sidebar-width { .sidebar-width {
@apply w-16 lg:w-64; @apply w-16 lg:w-72 xl:w-80;
} }
.sidebar-collapsed { .sidebar-collapsed {
@@ -157,12 +157,25 @@
} }
.main-content { .main-content {
@apply flex-1 flex flex-col overflow-hidden ml-16 lg:ml-64; @apply flex-1 flex flex-col overflow-hidden ml-16 lg:ml-72 xl:ml-80;
} }
.main-content-expanded { .main-content-expanded {
@apply ml-16; @apply ml-16;
} }
/* Utilitaires pour grand écran */
.desktop-padding {
@apply p-8 xl:p-12;
}
.desktop-text {
@apply text-lg xl:text-xl;
}
.desktop-spacing {
@apply space-y-8 xl:space-y-12;
}
} }
/* Supprimer le contour orange de la date du jour dans le calendrier */ /* Supprimer le contour orange de la date du jour dans le calendrier */
+4 -4
View File
@@ -138,7 +138,7 @@ export default function Dashboard() {
const deliveredThisMonth = Array.isArray(allDeliveries) ? allDeliveries.filter((delivery: any) => { const deliveredThisMonth = Array.isArray(allDeliveries) ? allDeliveries.filter((delivery: any) => {
const deliveryDate = safeDate(delivery.deliveredDate || delivery.createdAt); const deliveryDate = safeDate(delivery.deliveredDate || delivery.createdAt);
const now = new Date(); const now = new Date();
return deliveryDate.getMonth() === now.getMonth() && return deliveryDate && deliveryDate.getMonth() === now.getMonth() &&
deliveryDate.getFullYear() === now.getFullYear() && deliveryDate.getFullYear() === now.getFullYear() &&
delivery.status === 'delivered'; delivery.status === 'delivered';
}).length : 0; }).length : 0;
@@ -148,7 +148,7 @@ export default function Dashboard() {
if (delivery.status === 'delivered' && delivery.unit === 'palettes') { if (delivery.status === 'delivered' && delivery.unit === 'palettes') {
const deliveryDate = safeDate(delivery.deliveredDate || delivery.createdAt); const deliveryDate = safeDate(delivery.deliveredDate || delivery.createdAt);
const now = new Date(); const now = new Date();
if (deliveryDate.getMonth() === now.getMonth() && deliveryDate.getFullYear() === now.getFullYear()) { if (deliveryDate && deliveryDate.getMonth() === now.getMonth() && deliveryDate.getFullYear() === now.getFullYear()) {
return total + (delivery.quantity || 0); return total + (delivery.quantity || 0);
} }
} }
@@ -403,7 +403,7 @@ export default function Dashboard() {
.slice(0, 3) .slice(0, 3)
.map((publicity: any) => { .map((publicity: any) => {
const participatingStores = publicity.participations || []; const participatingStores = publicity.participations || [];
const isCurrentStoreParticipating = selectedStoreId && participatingStores.some((p: any) => p.groupId === parseInt(selectedStoreId)); const isCurrentStoreParticipating = selectedStoreId && participatingStores.some((p: any) => p.groupId === parseInt(selectedStoreId.toString()));
return ( return (
<div key={publicity.id} className="p-4 bg-gray-50 hover:bg-gray-100 transition-colors border-l-3 border-purple-500 space-y-2"> <div key={publicity.id} className="p-4 bg-gray-50 hover:bg-gray-100 transition-colors border-l-3 border-purple-500 space-y-2">
@@ -436,7 +436,7 @@ export default function Dashboard() {
<Badge <Badge
key={participation.groupId} key={participation.groupId}
className={`text-xs ${ className={`text-xs ${
selectedStoreId && participation.groupId === parseInt(selectedStoreId) selectedStoreId && participation.groupId === parseInt(selectedStoreId.toString())
? 'bg-green-100 text-green-800 border border-green-300' ? 'bg-green-100 text-green-800 border border-green-300'
: 'bg-gray-100 text-gray-700' : 'bg-gray-100 text-gray-700'
}`} }`}
+21 -21
View File
@@ -29,6 +29,7 @@ import CreateDeliveryModal from "@/components/modals/CreateDeliveryModal";
import EditDeliveryModal from "@/components/modals/EditDeliveryModal"; import EditDeliveryModal from "@/components/modals/EditDeliveryModal";
import OrderDetailModal from "@/components/modals/OrderDetailModal"; import OrderDetailModal from "@/components/modals/OrderDetailModal";
import ConfirmDeleteModal from "@/components/modals/ConfirmDeleteModal"; import ConfirmDeleteModal from "@/components/modals/ConfirmDeleteModal";
import { usePermissions } from "@shared/permissions";
import type { DeliveryWithRelations } from "@shared/schema"; import type { DeliveryWithRelations } from "@shared/schema";
export default function Deliveries() { export default function Deliveries() {
@@ -36,6 +37,7 @@ export default function Deliveries() {
const { selectedStoreId } = useStore(); const { selectedStoreId } = useStore();
const { toast } = useToast(); const { toast } = useToast();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const permissions = usePermissions(user?.role);
// Redirection pour les employés // Redirection pour les employés
if (user?.role === 'employee') { if (user?.role === 'employee') {
@@ -336,11 +338,10 @@ export default function Deliveries() {
)} )}
</div> </div>
) : ( ) : (
<div className="flex-1 overflow-y-auto p-6"> <div className="bg-white border border-gray-200 shadow-lg overflow-hidden rounded-xl">
<div className="bg-white border border-gray-200 shadow-lg overflow-hidden"> <div className="overflow-x-auto">
<div className="overflow-x-auto"> <table className="w-full">
<table className="w-full"> <thead className="bg-gray-50 border-b border-gray-200">
<thead className="bg-gray-50 border-b border-gray-200">
<tr> <tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Fournisseur Fournisseur
@@ -367,8 +368,8 @@ export default function Deliveries() {
Actions Actions
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody className="bg-white divide-y divide-gray-200"> <tbody className="bg-white divide-y divide-gray-200">
{paginatedDeliveries.map((delivery) => ( {paginatedDeliveries.map((delivery) => (
<tr key={delivery.id} className="hover:bg-gray-50"> <tr key={delivery.id} className="hover:bg-gray-50">
<td className="px-6 py-4 whitespace-nowrap"> <td className="px-6 py-4 whitespace-nowrap">
@@ -466,21 +467,20 @@ export default function Deliveries() {
</td> </td>
</tr> </tr>
))} ))}
</tbody> </tbody>
</table> </table>
</div>
{/* Pagination */}
<Pagination
currentPage={currentPage}
totalPages={totalPages}
totalItems={totalItems}
itemsPerPage={itemsPerPage}
onPageChange={setCurrentPage}
onItemsPerPageChange={setItemsPerPage}
className="mt-4 p-4 border-t border-gray-200"
/>
</div> </div>
{/* Pagination */}
<Pagination
currentPage={currentPage}
totalPages={totalPages}
totalItems={totalItems}
itemsPerPage={itemsPerPage}
onPageChange={setCurrentPage}
onItemsPerPageChange={setItemsPerPage}
className="mt-4 p-4 border-t border-gray-200"
/>
</div> </div>
)} )}
</div> </div>
+22 -22
View File
@@ -27,6 +27,7 @@ import CreateOrderModal from "@/components/modals/CreateOrderModal";
import EditOrderModal from "@/components/modals/EditOrderModal"; import EditOrderModal from "@/components/modals/EditOrderModal";
import OrderDetailModal from "@/components/modals/OrderDetailModal"; import OrderDetailModal from "@/components/modals/OrderDetailModal";
import ConfirmDeleteModal from "@/components/modals/ConfirmDeleteModal"; import ConfirmDeleteModal from "@/components/modals/ConfirmDeleteModal";
import { usePermissions } from "@shared/permissions";
import type { OrderWithRelations } from "@shared/schema"; import type { OrderWithRelations } from "@shared/schema";
export default function Orders() { export default function Orders() {
@@ -34,6 +35,7 @@ export default function Orders() {
const { selectedStoreId } = useStore(); const { selectedStoreId } = useStore();
const { toast } = useToast(); const { toast } = useToast();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const permissions = usePermissions(user?.role);
// Redirection pour les employés // Redirection pour les employés
if (user?.role === 'employee') { if (user?.role === 'employee') {
@@ -285,7 +287,7 @@ export default function Orders() {
<div className="flex items-center justify-center h-64"> <div className="flex items-center justify-center h-64">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div> <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
</div> </div>
) : (console.log('📦 Filtered orders length:', filteredOrders.length) || filteredOrders.length === 0) ? ( ) : filteredOrders.length === 0 ? (
<div className="flex flex-col items-center justify-center h-64 text-gray-500"> <div className="flex flex-col items-center justify-center h-64 text-gray-500">
<Package className="w-16 h-16 mb-4 text-gray-300" /> <Package className="w-16 h-16 mb-4 text-gray-300" />
<h3 className="text-lg font-medium mb-2">Aucune commande trouvée</h3> <h3 className="text-lg font-medium mb-2">Aucune commande trouvée</h3>
@@ -305,11 +307,10 @@ export default function Orders() {
)} )}
</div> </div>
) : ( ) : (
<div className="flex-1 overflow-y-auto p-6"> <div className="bg-white border border-gray-200 shadow-lg overflow-hidden rounded-xl">
<div className="bg-white border border-gray-200 shadow-lg overflow-hidden"> <div className="overflow-x-auto">
<div className="overflow-x-auto"> <table className="w-full">
<table className="w-full"> <thead className="bg-gray-50 border-b border-gray-200">
<thead className="bg-gray-50 border-b border-gray-200">
<tr> <tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Fournisseur Fournisseur
@@ -330,8 +331,8 @@ export default function Orders() {
Actions Actions
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody className="bg-white divide-y divide-gray-200"> <tbody className="bg-white divide-y divide-gray-200">
{paginatedOrders.map((order) => ( {paginatedOrders.map((order) => (
<tr key={order.id} className="hover:bg-gray-50"> <tr key={order.id} className="hover:bg-gray-50">
<td className="px-6 py-4 whitespace-nowrap"> <td className="px-6 py-4 whitespace-nowrap">
@@ -404,21 +405,20 @@ export default function Orders() {
</td> </td>
</tr> </tr>
))} ))}
</tbody> </tbody>
</table> </table>
</div>
{/* Pagination */}
<Pagination
currentPage={currentPage}
totalPages={totalPages}
totalItems={totalItems}
itemsPerPage={itemsPerPage}
onPageChange={setCurrentPage}
onItemsPerPageChange={setItemsPerPage}
className="mt-4 p-4 border-t border-gray-200"
/>
</div> </div>
{/* Pagination */}
<Pagination
currentPage={currentPage}
totalPages={totalPages}
totalItems={totalItems}
itemsPerPage={itemsPerPage}
onPageChange={setCurrentPage}
onItemsPerPageChange={setItemsPerPage}
className="mt-4 p-4 border-t border-gray-200"
/>
</div> </div>
)} )}
</div> </div>