update UI
This commit is contained in:
parent
46f50e3054
commit
8228fe865f
@ -37,8 +37,8 @@ export function Header() {
|
|||||||
{ name: "Accueil", path: "/", icon: Home, public: true },
|
{ name: "Accueil", path: "/", icon: Home, public: true },
|
||||||
{ name: "Recettes", path: "/recipes", icon: BookOpen, public: true },
|
{ name: "Recettes", path: "/recipes", icon: BookOpen, public: true },
|
||||||
// { name: "Mes recettes", path: "/my-recipes", icon: BookOpen, public: false },
|
// { name: "Mes recettes", path: "/my-recipes", icon: BookOpen, public: false },
|
||||||
{ name: "Favoris", path: "/favorites", icon: Heart, public: false },
|
// { name: "Favoris", path: "/favorites", icon: Heart, public: false },
|
||||||
{ name: "Profil", path: "/profile", icon: User, public: false },
|
// { name: "Profil", path: "/profile", icon: User, public: false },
|
||||||
]
|
]
|
||||||
|
|
||||||
const filteredNavItems = navItems.filter((item) => item.public || isAuthenticated)
|
const filteredNavItems = navItems.filter((item) => item.public || isAuthenticated)
|
||||||
@ -54,7 +54,7 @@ export function Header() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Navigation desktop */}
|
{/* Navigation desktop */}
|
||||||
<nav className="hidden md:flex items-center gap-6">
|
<nav className="hidden md:flex items-center gap-10">
|
||||||
{filteredNavItems.map((item) => (
|
{filteredNavItems.map((item) => (
|
||||||
<Link
|
<Link
|
||||||
key={item.path}
|
key={item.path}
|
||||||
|
|||||||
@ -5,73 +5,78 @@ interface KitchenIllustrationProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function KitchenIllustration({ height = 200 }: KitchenIllustrationProps) {
|
export function KitchenIllustration({ height = 200 }: KitchenIllustrationProps) {
|
||||||
// Calculate width based on original ratio (280:200)
|
const ratio = 280 / 100;
|
||||||
const ratio = 280 / 200;
|
|
||||||
const width = height * ratio;
|
const width = height * ratio;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<svg
|
<div style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>
|
||||||
width={width}
|
<svg
|
||||||
height={height}
|
width={width}
|
||||||
viewBox="0 0 280 200"
|
height={height}
|
||||||
fill="none"
|
viewBox="0 100 280 100"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
fill="none"
|
||||||
style={{ maxWidth: '100%' }}
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
>
|
style={{
|
||||||
{/* Pot */}
|
maxWidth: '100%',
|
||||||
<rect x="100" y="120" width="80" height="60" rx="5" fill="#6B7280" />
|
height: 'auto',
|
||||||
<rect x="90" y="110" width="100" height="15" rx="5" fill="#9CA3AF" />
|
aspectRatio: `${ratio}`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Pot */}
|
||||||
|
<rect x="100" y="120" width="80" height="60" rx="5" fill="#6B7280" />
|
||||||
|
<rect x="90" y="110" width="100" height="15" rx="5" fill="#9CA3AF" />
|
||||||
|
|
||||||
{/* Pot handles */}
|
{/* Pot handles */}
|
||||||
<rect x="85" y="130" width="10" height="25" rx="5" fill="#9CA3AF" />
|
<rect x="85" y="130" width="10" height="25" rx="5" fill="#9CA3AF" />
|
||||||
<rect x="185" y="130" width="10" height="25" rx="5" fill="#9CA3AF" />
|
<rect x="185" y="130" width="10" height="25" rx="5" fill="#9CA3AF" />
|
||||||
|
|
||||||
{/* Steam animation */}
|
{/* Steam animation */}
|
||||||
<motion.path
|
<motion.path
|
||||||
d="M120 100C120 100 115 90 125 85C135 80 130 70 120 70"
|
d="M120 100C120 100 115 90 125 85C135 80 130 70 120 70"
|
||||||
stroke="#E5E7EB"
|
stroke="#E5E7EB"
|
||||||
strokeWidth="3"
|
strokeWidth="3"
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
initial={{ opacity: 0.3 }}
|
initial={{ opacity: 0.3 }}
|
||||||
animate={{ opacity: 1 }}
|
animate={{ opacity: 1 }}
|
||||||
transition={{ duration: 1.5, repeat: Infinity, repeatType: "reverse" }}
|
transition={{ duration: 1.5, repeat: Infinity, repeatType: "reverse" }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<motion.path
|
<motion.path
|
||||||
d="M140 100C140 100 135 85 145 80C155 75 150 65 140 60"
|
d="M140 100C140 100 135 85 145 80C155 75 150 65 140 60"
|
||||||
stroke="#E5E7EB"
|
stroke="#E5E7EB"
|
||||||
strokeWidth="3"
|
strokeWidth="3"
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
initial={{ opacity: 0.5 }}
|
initial={{ opacity: 0.5 }}
|
||||||
animate={{ opacity: 1 }}
|
animate={{ opacity: 1 }}
|
||||||
transition={{ duration: 2, repeat: Infinity, repeatType: "reverse", delay: 0.5 }}
|
transition={{ duration: 2, repeat: Infinity, repeatType: "reverse", delay: 0.5 }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<motion.path
|
<motion.path
|
||||||
d="M160 100C160 100 155 90 165 85C175 80 170 70 160 70"
|
d="M160 100C160 100 155 90 165 85C175 80 170 70 160 70"
|
||||||
stroke="#E5E7EB"
|
stroke="#E5E7EB"
|
||||||
strokeWidth="3"
|
strokeWidth="3"
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
initial={{ opacity: 0.3 }}
|
initial={{ opacity: 0.3 }}
|
||||||
animate={{ opacity: 1 }}
|
animate={{ opacity: 1 }}
|
||||||
transition={{ duration: 1.8, repeat: Infinity, repeatType: "reverse", delay: 0.3 }}
|
transition={{ duration: 1.8, repeat: Infinity, repeatType: "reverse", delay: 0.3 }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Stove */}
|
{/* Stove */}
|
||||||
<rect x="70" y="180" width="140" height="10" rx="2" fill="#4B5563" />
|
<rect x="70" y="180" width="140" height="10" rx="2" fill="#4B5563" />
|
||||||
<circle cx="140" cy="185" r="3" fill="#EF4444" />
|
<circle cx="140" cy="185" r="3" fill="#EF4444" />
|
||||||
<circle cx="120" cy="185" r="3" fill="#EF4444" />
|
<circle cx="120" cy="185" r="3" fill="#EF4444" />
|
||||||
<circle cx="160" cy="185" r="3" fill="#EF4444" />
|
<circle cx="160" cy="185" r="3" fill="#EF4444" />
|
||||||
|
|
||||||
{/* Spoon */}
|
{/* Spoon */}
|
||||||
<rect x="190" y="100" width="5" height="70" rx="2" fill="#D1D5DB" />
|
<rect x="190" y="100" width="5" height="70" rx="2" fill="#D1D5DB" />
|
||||||
<ellipse cx="192.5" cy="95" rx="10" ry="5" fill="#D1D5DB" />
|
<ellipse cx="192.5" cy="95" rx="10" ry="5" fill="#D1D5DB" />
|
||||||
|
|
||||||
{/* Vegetables */}
|
{/* Vegetables */}
|
||||||
<circle cx="60" cy="150" r="10" fill="#10B981" /> {/* Lettuce */}
|
<circle cx="60" cy="150" r="10" fill="#10B981" /> {/* Lettuce */}
|
||||||
<circle cx="40" cy="160" r="8" fill="#EF4444" /> {/* Tomato */}
|
<circle cx="40" cy="160" r="8" fill="#EF4444" /> {/* Tomato */}
|
||||||
<rect x="210" y="150" width="20" height="8" rx="2" fill="#F59E0B" /> {/* Carrot */}
|
<rect x="210" y="150" width="20" height="8" rx="2" fill="#F59E0B" /> {/* Carrot */}
|
||||||
<rect x="220" y="140" width="15" height="10" rx="2" fill="#F59E0B" transform="rotate(45 220 140)" /> {/* Carrot top */}
|
<rect x="220" y="140" width="15" height="10" rx="2" fill="#F59E0B" transform="rotate(45 220 140)" /> {/* Carrot top */}
|
||||||
</svg>
|
</svg>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,10 +8,10 @@ interface MainLayoutProps {
|
|||||||
|
|
||||||
export function MainLayout({ children }: MainLayoutProps) {
|
export function MainLayout({ children }: MainLayoutProps) {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
// Exclure le layout pour les pages d'authentification
|
// Exclure le layout pour les pages d'authentification
|
||||||
const authPages = ["/auth/login", "/auth/register"];
|
const authPages = ["/auth/login", "/auth/register"];
|
||||||
|
|
||||||
if (authPages.includes(location.pathname)) {
|
if (authPages.includes(location.pathname)) {
|
||||||
return <>{children}</>;
|
return <>{children}</>;
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ export function MainLayout({ children }: MainLayoutProps) {
|
|||||||
<p className="text-center text-sm text-muted-foreground md:text-left">
|
<p className="text-center text-sm text-muted-foreground md:text-left">
|
||||||
© {new Date().getFullYear()} Freedge. Tous droits réservés.
|
© {new Date().getFullYear()} Freedge. Tous droits réservés.
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center gap-4 text-sm text-muted-foreground">
|
<div className="flex items-center gap-4 text-sm text-muted-foreground pt-4">
|
||||||
<a href="#" className="hover:underline">Mentions légales</a>
|
<a href="#" className="hover:underline">Mentions légales</a>
|
||||||
<a href="#" className="hover:underline">Confidentialité</a>
|
<a href="#" className="hover:underline">Confidentialité</a>
|
||||||
<a href="#" className="hover:underline">Contact</a>
|
<a href="#" className="hover:underline">Contact</a>
|
||||||
|
|||||||
@ -2,11 +2,10 @@
|
|||||||
|
|
||||||
import type React from "react"
|
import type React from "react"
|
||||||
|
|
||||||
import { useState, useRef } from "react"
|
import { useState } from "react"
|
||||||
import { useNavigate } from "react-router-dom"
|
import { useNavigate } from "react-router-dom"
|
||||||
import { recipeService } from "@/api/recipe"
|
import { recipeService } from "@/api/recipe"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { Input } from "@/components/ui/input"
|
|
||||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
|
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
|
||||||
import { Mic, Upload, ArrowLeft, Loader2 } from "lucide-react"
|
import { Mic, Upload, ArrowLeft, Loader2 } from "lucide-react"
|
||||||
import { motion } from "framer-motion"
|
import { motion } from "framer-motion"
|
||||||
@ -15,7 +14,6 @@ import { CookingLoader } from "@/components/illustrations/CookingLoader"
|
|||||||
|
|
||||||
export default function RecipeForm() {
|
export default function RecipeForm() {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
|
||||||
|
|
||||||
const [audioFile, setAudioFile] = useState<File | null>(null)
|
const [audioFile, setAudioFile] = useState<File | null>(null)
|
||||||
const [isRecording, setIsRecording] = useState(false)
|
const [isRecording, setIsRecording] = useState(false)
|
||||||
@ -24,13 +22,6 @@ export default function RecipeForm() {
|
|||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [error, setError] = useState("")
|
const [error, setError] = useState("")
|
||||||
|
|
||||||
// Gérer l'upload de fichier audio
|
|
||||||
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
if (e.target.files && e.target.files.length > 0) {
|
|
||||||
setAudioFile(e.target.files[0])
|
|
||||||
setError("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Démarrer l'enregistrement audio
|
// Démarrer l'enregistrement audio
|
||||||
const startRecording = async () => {
|
const startRecording = async () => {
|
||||||
@ -123,7 +114,7 @@ export default function RecipeForm() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Card className="border-none shadow-lg">
|
<Card className="border-none shadow-lg">
|
||||||
<CardHeader className="p-4 sm:p-6">
|
<CardHeader className="p-2 sm:p-4">
|
||||||
<CardTitle className="text-xl sm:text-2xl">Créer une nouvelle recette</CardTitle>
|
<CardTitle className="text-xl sm:text-2xl">Créer une nouvelle recette</CardTitle>
|
||||||
<CardDescription className="text-sm">
|
<CardDescription className="text-sm">
|
||||||
Enregistrez ou téléchargez un fichier audio listant les ingrédients disponibles, et nous générerons une
|
Enregistrez ou téléchargez un fichier audio listant les ingrédients disponibles, et nous générerons une
|
||||||
@ -131,7 +122,7 @@ export default function RecipeForm() {
|
|||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|
||||||
<CardContent className="p-4 sm:p-6">
|
<CardContent className="p-2 sm:p-4">
|
||||||
{error && (
|
{error && (
|
||||||
<div className="rounded-md bg-red-50 p-4 text-sm text-red-700 dark:bg-red-900/50 dark:text-red-200 mb-4">
|
<div className="rounded-md bg-red-50 p-4 text-sm text-red-700 dark:bg-red-900/50 dark:text-red-200 mb-4">
|
||||||
{error}
|
{error}
|
||||||
@ -174,7 +165,7 @@ export default function RecipeForm() {
|
|||||||
)}
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|
||||||
<CardFooter className="p-4 sm:p-6 flex justify-between">
|
<CardFooter className="p-2 sm:p-4 flex justify-between">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
|
|||||||
@ -88,22 +88,24 @@ export default function RecipeList() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="flex flex-col mx-4 md:mx-4 sm:flex-row sm:items-center sm:justify-between mb-6 mt-6">
|
<div className="flex flex-col mx-4 md:mx-4 sm:flex-row sm:items-center sm:justify-between mb-6 mt-6">
|
||||||
<Tabs defaultValue="all" className="w-full sm:w-auto" onValueChange={setActiveFilter}>
|
{/* <Tabs defaultValue="all" className="w-full sm:w-auto" onValueChange={setActiveFilter}>
|
||||||
<TabsList className="grid grid-cols-4 w-full sm:w-auto">
|
<TabsList className="grid grid-cols-4 w-full sm:w-auto">
|
||||||
<TabsTrigger value="all">Toutes</TabsTrigger>
|
<TabsTrigger value="all">Toutes</TabsTrigger>
|
||||||
<TabsTrigger value="easy">Faciles</TabsTrigger>
|
<TabsTrigger value="easy">Faciles</TabsTrigger>
|
||||||
<TabsTrigger value="quick">Rapides</TabsTrigger>
|
<TabsTrigger value="quick">Rapides</TabsTrigger>
|
||||||
<TabsTrigger value="vegetarian">Végé</TabsTrigger>
|
<TabsTrigger value="vegetarian">Végé</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
</Tabs>
|
</Tabs> */}
|
||||||
|
{
|
||||||
<Button
|
filteredRecipes.length !== 0 &&
|
||||||
onClick={handleCreateRecipe}
|
<Button
|
||||||
className="mt-4 sm:mt-0 bg-gradient-to-r from-orange-500 to-amber-500 hover:from-orange-600 hover:to-amber-600 text-white cursor-pointer"
|
onClick={handleCreateRecipe}
|
||||||
>
|
className="mt-4 sm:mt-0 bg-gradient-to-r from-orange-500 to-amber-500 hover:from-orange-600 hover:to-amber-600 text-white cursor-pointer"
|
||||||
<Plus className="mr-2 h-4 w-4" />
|
>
|
||||||
Nouvelle recette
|
<Plus className="mr-2 h-4 w-4" />
|
||||||
</Button>
|
Nouvelle recette
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{loading ? (
|
{loading ? (
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user