mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-11 17:27:31 +02:00
Remove phone icon and improve horizontal overflow on mobile devices
Refactors Layout and Tasks components, removing the smartphone icon, disabling phone mode logic, and applying global CSS to prevent horizontal overflow across the application, particularly on mobile viewports. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 95e8aab4-f39f-4b48-aa57-a759ec15ba3d Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/95e8aab4-f39f-4b48-aa57-a759ec15ba3d/GEw2Z4s
This commit is contained in:
1 parent
d7de31ac2a
commit
c0a7b06c34
3 files changed
+39
-166
No files matched your search
@@ -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
@@ -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
@@ -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>
|
||||
|
||||
Reference in new issue
Block a user