Merge pull request #438 from R0m1k3/1.1

Remove phone icon and improve horizontal overflow on mobile devices
This commit is contained in:
LogiFlow authored and GitHub committed 2025-09-11 12:24:48 +02:00
commit 4132ecf26c
3 files changed
+39 -166

No files matched your search

+11 -56
View File
@@ -3,14 +3,12 @@ import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useLocation } from "wouter";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Button } from "@/components/ui/button";
import { LogOut, Store, Menu, AlertTriangle, Smartphone, Monitor } from "lucide-react";
import { LogOut, Store, Menu, AlertTriangle } from "lucide-react";
import { useAuthUnified } from "@/hooks/useAuthUnified";
import { useIsMobile } from "@/hooks/use-mobile";
import { useScreenSize } from "@/hooks/use-screen-size";
import { usePhoneMode } from "@/hooks/use-phone-mode";
import { StoreProvider } from "@/contexts/StoreContext";
import Sidebar from "./Sidebar";
import PhoneBottomNav from "./PhoneBottomNav";
import WeatherWidget from "./WeatherWidget";
import DateWidget from "./DateWidget";
import type { Group } from "@shared/schema";
@@ -26,7 +24,6 @@ export default function Layout({ children }: LayoutProps) {
const queryClient = useQueryClient();
const isMobile = useIsMobile();
const { screenSize, isMobileOrTablet, isTablet } = useScreenSize();
const { isPhoneMode, setPhoneMode, canUsePhoneMode } = usePhoneMode();
const [selectedStoreId, setSelectedStoreId] = useState<number | null>(() => {
// Restaurer le selectedStoreId depuis localStorage si disponible
@@ -125,9 +122,9 @@ export default function Layout({ children }: LayoutProps) {
return (
<StoreProvider value={{ selectedStoreId, setSelectedStoreId, stores, sidebarCollapsed, setSidebarCollapsed, mobileMenuOpen, setMobileMenuOpen, storeInitialized }}>
<div className={`layout-container flex bg-gray-50 ${isPhoneMode ? 'phone-mode' : ''}`}>
<div className="layout-container flex bg-gray-50">
{/* Mobile overlay for normal mode */}
{!isPhoneMode && isMobile && mobileMenuOpen && (
{isMobile && mobileMenuOpen && (
<div
className="fixed inset-0 bg-black bg-opacity-50 z-40"
onClick={() => setMobileMenuOpen(false)}
@@ -135,25 +132,21 @@ export default function Layout({ children }: LayoutProps) {
)}
{/* Sidebar for normal mode */}
{!isPhoneMode && <Sidebar />}
<Sidebar />
<main className={`flex-1 flex flex-col h-full ${
// Ajustement des marges selon le mode
isPhoneMode
? 'ml-0 mb-20' // Mode téléphone : pas de marge gauche, marge bas pour bottom nav
: isMobile
isMobile
? 'ml-0'
: (isTablet && !sidebarCollapsed) ? 'ml-48' : 'ml-0'
}`}>
{/* Header with mobile menu and store selector */}
<header className={`${
isPhoneMode ? 'h-12' : 'h-16'
} bg-white border-b border-gray-200 flex items-center justify-between ${
<header className={`h-16 bg-white border-b border-gray-200 flex items-center justify-between ${
isMobileOrTablet ? 'px-3' : 'px-6'
}`}>
<div className="flex items-center gap-2 sm:gap-4 min-w-0 flex-1">
{/* Mobile menu button (only in normal mode) */}
{!isPhoneMode && isMobile && (
{isMobile && (
<Button
variant="ghost"
size="sm"
@@ -169,47 +162,13 @@ export default function Layout({ children }: LayoutProps) {
<div className={`flex items-center ${
isMobile ? 'gap-1' : 'gap-3'
} min-w-0`}>
{/* En mode téléphone, affichage simplifié */}
{isPhoneMode ? (
<div className="flex items-center gap-2">
<WeatherWidget />
{/* Phone mode toggle button */}
<Button
variant="ghost"
size="sm"
onClick={() => setPhoneMode(!isPhoneMode)}
className="min-h-[44px] min-w-[44px] p-2 flex-shrink-0"
data-testid="button-phone-mode-toggle"
title="Basculer vers le mode normal"
>
<Monitor className="h-4 w-4 text-blue-600" />
</Button>
</div>
) : (
<>
<WeatherWidget />
{!isMobile && <DateWidget />}
{/* Phone mode toggle button */}
{canUsePhoneMode && (
<Button
variant="ghost"
size="sm"
onClick={() => setPhoneMode(!isPhoneMode)}
className="min-h-[44px] min-w-[44px] p-2 flex-shrink-0"
data-testid="button-phone-mode-toggle"
title="Basculer vers le mode téléphone"
>
<Smartphone className="h-4 w-4 text-gray-600" />
</Button>
)}
</>
)}
<WeatherWidget />
{!isMobile && <DateWidget />}
</div>
</div>
{/* Store selector for admin, directeur, and manager - responsive */}
{!isPhoneMode && user && (user.role === 'admin' || user.role === 'directeur' || user.role === 'manager') && stores.length > 0 && (
{user && (user.role === 'admin' || user.role === 'directeur' || user.role === 'manager') && stores.length > 0 && (
<div className="flex items-center gap-1 sm:gap-2 flex-shrink-0">
<Store className="h-4 w-4 text-gray-500 hidden sm:block" />
<Select
@@ -299,16 +258,12 @@ export default function Layout({ children }: LayoutProps) {
)}
<div className={`flex-1 bg-gray-50 h-full overflow-y-auto ${
isPhoneMode
? 'p-2' // Mode téléphone : padding réduit
: isMobileOrTablet ? 'p-3' : 'p-6'
isMobileOrTablet ? 'p-3' : 'p-6'
}`}>
{children}
</div>
</main>
{/* Bottom navigation for phone mode (only when authenticated) */}
{isPhoneMode && user && <PhoneBottomNav user={user} location={location} />}
</div>
</StoreProvider>
);
+14 -1
View File
@@ -64,11 +64,24 @@
@apply font-sans antialiased bg-surface text-foreground;
max-width: 100vw;
height: 100%;
overflow-x: hidden;
}
#root {
max-width: 100vw;
height: 100%;
min-height: 100%;
overflow-x: hidden;
}
/* Éviter le débordement horizontal sur mobile */
* {
box-sizing: border-box;
}
/* Forcer les conteneurs à ne pas déborder */
.container, .main-content, [data-testid*="task"] {
max-width: 100vw;
overflow-x: hidden;
}
/* Forcer la cohérence des largeurs de sidebar */
+14 -109
View File
@@ -1565,37 +1565,10 @@ export default function Tasks() {
{/* Modal d'édition */}
{showEditModal && selectedTask && (
<div style={{
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
zIndex: 1000,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}>
<div style={{
backgroundColor: 'white',
borderRadius: '0px',
maxWidth: '600px',
width: '90%',
maxHeight: '90vh',
overflow: 'auto',
boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25)'
}}>
<div style={{
padding: '24px 24px 16px',
borderBottom: '1px solid #e5e7eb',
position: 'relative'
}}>
<h2 style={{
fontSize: '18px',
fontWeight: '600',
margin: '0'
}}>
<div className="fixed inset-0 bg-black bg-opacity-50 z-[1000] flex items-start sm:items-center justify-center p-4">
<div className="bg-white dark:bg-gray-800 rounded-lg max-w-full sm:max-w-2xl w-full max-h-[calc(100vh-2rem)] overflow-y-auto shadow-2xl">
<div className="p-6 pb-4 border-b border-gray-200 dark:border-gray-700 sticky top-0 bg-white dark:bg-gray-800">
<h2 className="text-lg font-semibold m-0 pr-10 dark:text-white">
Modifier la tâche
</h2>
<button
@@ -1603,21 +1576,7 @@ export default function Tasks() {
setShowEditModal(false);
setSelectedTask(null);
}}
style={{
position: 'absolute',
top: '16px',
right: '16px',
background: 'none',
border: 'none',
fontSize: '20px',
cursor: 'pointer',
padding: '4px',
borderRadius: '0px',
color: '#6b7280',
transition: 'color 0.2s'
}}
onMouseEnter={(e) => (e.target as HTMLButtonElement).style.color = '#374151'}
onMouseLeave={(e) => (e.target as HTMLButtonElement).style.color = '#6b7280'}
className="absolute top-4 right-4 bg-transparent border-none text-xl cursor-pointer p-2 rounded text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 transition-colors"
>
✕
</button>
@@ -1637,86 +1596,32 @@ export default function Tasks() {
{/* Modal de confirmation de suppression */}
{showDeleteModal && taskToDelete && (
<div style={{
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
zIndex: 1000,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}>
<div style={{
backgroundColor: 'white',
borderRadius: '0px',
maxWidth: '400px',
width: '90%',
padding: '24px',
boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25)'
}}>
<h2 style={{
fontSize: '18px',
fontWeight: '600',
margin: '0 0 16px 0',
color: '#dc2626',
display: 'flex',
alignItems: 'center',
gap: '8px'
}}>
<div className="fixed inset-0 bg-black bg-opacity-50 z-[1000] flex items-center justify-center p-4">
<div className="bg-white dark:bg-gray-800 rounded-lg max-w-sm w-full p-6 shadow-2xl mx-4">
<h2 className="text-lg font-semibold mb-4 text-red-600 dark:text-red-400 flex items-center gap-2">
⚠️ Confirmer la suppression
</h2>
<div style={{ marginBottom: '24px' }}>
<p style={{
color: '#374151',
lineHeight: '1.5',
margin: '0 0 8px 0'
}}>
<div className="mb-6">
<p className="text-gray-700 dark:text-gray-300 leading-relaxed mb-2">
Êtes-vous sûr de vouloir supprimer la tâche "{taskToDelete.title}" ?
</p>
<p style={{
fontSize: '14px',
color: '#6b7280',
margin: '0'
}}>
<p className="text-sm text-gray-500 dark:text-gray-400">
Cette action est irréversible.
</p>
</div>
<div style={{
display: 'flex',
gap: '12px',
justifyContent: 'flex-end'
}}>
<div className="flex gap-3 flex-col sm:flex-row">
<button
onClick={() => {
setShowDeleteModal(false);
setTaskToDelete(null);
}}
style={{
padding: '8px 16px',
border: '1px solid #d1d5db',
borderRadius: '0px',
backgroundColor: 'white',
cursor: 'pointer'
}}
className="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-700 dark:text-gray-300 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-600 order-2 sm:order-1"
>
Annuler
</button>
<button
onClick={handleConfirmDelete}
style={{
padding: '8px 16px',
border: 'none',
borderRadius: '0px',
backgroundColor: '#dc2626',
color: 'white',
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
gap: '8px'
}}
className="px-4 py-2 border-none rounded-md bg-red-600 text-white cursor-pointer hover:bg-red-700 flex items-center justify-center gap-2 order-1 sm:order-2"
>
🗑️ Supprimer
</button>