Feat: Ajout de la version mobile complète avec navigation sidebar

- Création de 3 composants UI mobile réutilisables (MobileHeader, MobileFAB, MobileCard)
- Création du layout MobileDashboard avec sidebar navigation
- Implémentation de 6 pages mobiles :
  * CalendarPage : gestion des événements avec pagination
  * NotesPage : liste des notes avec recherche et filtres
  * NoteDetailPage : édition complète de notes en fullscreen
  * TodosPage : gestion des tâches actives/complétées
  * RssPage : affichage des flux RSS avec actualisation
  * SettingsPage : paramètres de l'application
- Configuration du routing automatique mobile/desktop dans App.tsx
- Détection automatique du device avec redirection intelligente
- Tous les services backend réutilisés sans modification
- Build testé et fonctionnel
This commit is contained in:
Claude committed 2025-11-17 12:20:32 +00:00
1 parent 7d16876cd3
commit 3e6440bd90
11 files changed
+1664

No files matched your search

+42
View File
@@ -0,0 +1,42 @@
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { LucideIcon } from "lucide-react";
interface MobileCardProps {
title?: string;
icon?: LucideIcon;
children: React.ReactNode;
className?: string;
headerAction?: React.ReactNode;
onClick?: () => void;
}
export const MobileCard = ({
title,
icon: Icon,
children,
className = "",
headerAction,
onClick
}: MobileCardProps) => {
return (
<Card
className={`shadow-sm ${onClick ? 'cursor-pointer active:scale-[0.98] transition-transform' : ''} ${className}`}
onClick={onClick}
>
{(title || Icon) && (
<CardHeader className="pb-3 px-4 py-3">
<div className="flex items-center justify-between">
<CardTitle className="text-base flex items-center gap-2">
{Icon && <Icon className="h-5 w-5" />}
{title}
</CardTitle>
{headerAction}
</div>
</CardHeader>
)}
<CardContent className={`px-4 ${title ? 'py-3' : 'py-4'}`}>
{children}
</CardContent>
</Card>
);
};
+21
View File
@@ -0,0 +1,21 @@
import { Button } from "@/components/ui/button";
import { LucideIcon } from "lucide-react";
interface MobileFABProps {
icon: LucideIcon;
onClick: () => void;
label?: string;
}
export const MobileFAB = ({ icon: Icon, onClick, label }: MobileFABProps) => {
return (
<Button
onClick={onClick}
size="lg"
className="fixed bottom-6 right-6 h-14 w-14 rounded-full shadow-lg z-40"
aria-label={label}
>
<Icon className="h-6 w-6" />
</Button>
);
};
+54
View File
@@ -0,0 +1,54 @@
import { Menu, ArrowLeft } from "lucide-react";
import { Button } from "@/components/ui/button";
interface MobileHeaderProps {
title: string;
onMenuClick?: () => void;
onBackClick?: () => void;
showBack?: boolean;
rightAction?: React.ReactNode;
}
export const MobileHeader = ({
title,
onMenuClick,
onBackClick,
showBack = false,
rightAction
}: MobileHeaderProps) => {
return (
<header className="sticky top-0 z-30 bg-white dark:bg-gray-800 border-b">
<div className="flex items-center justify-between h-14 px-4">
<div className="flex items-center gap-2">
{showBack ? (
<Button
variant="ghost"
size="icon"
onClick={onBackClick}
className="h-9 w-9"
>
<ArrowLeft className="h-5 w-5" />
</Button>
) : (
<Button
variant="ghost"
size="icon"
onClick={onMenuClick}
className="h-9 w-9"
>
<Menu className="h-5 w-5" />
</Button>
)}
</div>
<h1 className="text-lg font-semibold truncate flex-1 text-center">
{title}
</h1>
<div className="flex items-center gap-2">
{rightAction || <div className="w-9" />}
</div>
</div>
</header>
);
};