mirror of
https://github.com/R0m1k3/Socialflow.git
synced 2026-10-22 06:28:10 +02:00
Refonte UI : design system, logo, shell responsive et pages simples
- Nouveaux tokens (indigo/corail, statuts, plateformes) et mode sombre - Logo et favicon Social Flow redessinés - AppShell partagé : sidebar groupée (desktop) + barre de navigation basse (mobile) - Suppression des pages mobiles dupliquées et des composants morts - Tableau de bord, connexion, 404, calendrier, médiathèque, IA, statistiques Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ADkrVcVFTT14hbB148HYS
This commit is contained in:
55 files changed
+1591
-6331
No files matched your search
@@ -0,0 +1,36 @@
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import { useLocation } from "wouter";
|
||||
import { apiRequest, AUTH_MUTATION, queryClient } from "@/lib/queryClient";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
|
||||
export interface Session {
|
||||
id: string;
|
||||
username: string;
|
||||
role: string;
|
||||
}
|
||||
|
||||
/** Session courante (mise en cache par react-query, partagée par toute l'app). */
|
||||
export function useSession() {
|
||||
const query = useQuery<Session>({
|
||||
queryKey: ["/api/auth/session"],
|
||||
retry: false,
|
||||
});
|
||||
return { ...query, session: query.data, isAdmin: query.data?.role === "admin" };
|
||||
}
|
||||
|
||||
export function useLogout() {
|
||||
const [, setLocation] = useLocation();
|
||||
const { toast } = useToast();
|
||||
return useMutation({
|
||||
mutationKey: [AUTH_MUTATION, "logout"],
|
||||
mutationFn: async () => {
|
||||
const res = await apiRequest("POST", "/api/auth/logout", {});
|
||||
return await res.json();
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.clear();
|
||||
setLocation("/login");
|
||||
toast({ title: "Déconnecté", description: "À bientôt !" });
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
/**
|
||||
* Hook to detect if the user is on a mobile device
|
||||
* Uses both media query and user agent for robust detection
|
||||
*
|
||||
* @param breakpoint - The max-width breakpoint for mobile (default: 768px)
|
||||
* @returns boolean - true if mobile, false if desktop
|
||||
*/
|
||||
export function useIsMobile(breakpoint: number = 768): boolean {
|
||||
const [isMobile, setIsMobile] = useState<boolean>(() => {
|
||||
// Initial detection (SSR-safe)
|
||||
if (typeof window === 'undefined') return false;
|
||||
|
||||
// Check media query
|
||||
const mediaMatch = window.matchMedia(`(max-width: ${breakpoint}px)`).matches;
|
||||
|
||||
// Check user agent for mobile devices
|
||||
const userAgent = navigator.userAgent.toLowerCase();
|
||||
const mobileKeywords = ['android', 'webos', 'iphone', 'ipad', 'ipod', 'blackberry', 'windows phone'];
|
||||
const isUserAgentMobile = mobileKeywords.some(keyword => userAgent.includes(keyword));
|
||||
|
||||
// Return true if either media query or user agent indicates mobile
|
||||
return mediaMatch || isUserAgentMobile;
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
// Create media query list
|
||||
const mediaQueryList = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
||||
|
||||
// Handler for media query changes
|
||||
const handleChange = (e: MediaQueryListEvent) => {
|
||||
setIsMobile(e.matches);
|
||||
};
|
||||
|
||||
// Listen for changes (modern browsers)
|
||||
if (mediaQueryList.addEventListener) {
|
||||
mediaQueryList.addEventListener('change', handleChange);
|
||||
} else {
|
||||
// Fallback for older browsers
|
||||
mediaQueryList.addListener(handleChange);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
return () => {
|
||||
if (mediaQueryList.removeEventListener) {
|
||||
mediaQueryList.removeEventListener('change', handleChange);
|
||||
} else {
|
||||
mediaQueryList.removeListener(handleChange);
|
||||
}
|
||||
};
|
||||
}, [breakpoint]);
|
||||
|
||||
return isMobile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to detect device type with more granularity
|
||||
* @returns object with device type information
|
||||
*/
|
||||
export function useDeviceType() {
|
||||
const isMobile = useIsMobile(768);
|
||||
const isTablet = useIsMobile(1024) && !useIsMobile(768);
|
||||
const isDesktop = !useIsMobile(1024);
|
||||
|
||||
return {
|
||||
isMobile,
|
||||
isTablet,
|
||||
isDesktop,
|
||||
deviceType: isMobile ? 'mobile' : isTablet ? 'tablet' : 'desktop'
|
||||
} as const;
|
||||
}
|
||||
Reference in new issue
Block a user