From 5829873f8c8c4d08e9f094848fd3b6af17a92322 Mon Sep 17 00:00:00 2001 From: michaelschal <35957947-michaelschal@users.noreply.replit.com> Date: Wed, 1 Oct 2025 13:36:26 +0000 Subject: [PATCH] Add all application pages and their functionalities Add new routes and components for AI, Calendar, Media, Pages Management, Analytics, History, and Settings. Replit-Commit-Author: Agent Replit-Commit-Session-Id: ae4037a0-2a6f-4530-9bac-79b543286bda Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/397bca8c-984f-43ff-841a-10897aeb8140/ae4037a0-2a6f-4530-9bac-79b543286bda/vhNnBGJ --- .replit | 4 + client/src/App.tsx | 16 ++ client/src/pages/ai.tsx | 43 +++++ client/src/pages/analytics.tsx | 110 ++++++++++++ client/src/pages/calendar.tsx | 41 +++++ client/src/pages/history.tsx | 114 +++++++++++++ client/src/pages/media.tsx | 41 +++++ client/src/pages/new-post.tsx | 288 ++++++++++++++++++++++++++++++++ client/src/pages/pages.tsx | 295 +++++++++++++++++++++++++++++++++ client/src/pages/settings.tsx | 139 ++++++++++++++++ 10 files changed, 1091 insertions(+) create mode 100644 client/src/pages/ai.tsx create mode 100644 client/src/pages/analytics.tsx create mode 100644 client/src/pages/calendar.tsx create mode 100644 client/src/pages/history.tsx create mode 100644 client/src/pages/media.tsx create mode 100644 client/src/pages/new-post.tsx create mode 100644 client/src/pages/pages.tsx create mode 100644 client/src/pages/settings.tsx diff --git a/.replit b/.replit index 3238a51..330c857 100644 --- a/.replit +++ b/.replit @@ -14,6 +14,10 @@ run = ["npm", "run", "start"] localPort = 5000 externalPort = 80 +[[ports]] +localPort = 39259 +externalPort = 3000 + [env] PORT = "5000" diff --git a/client/src/App.tsx b/client/src/App.tsx index 40f7f31..5ea27ba 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -5,11 +5,27 @@ import { Toaster } from "@/components/ui/toaster"; import { TooltipProvider } from "@/components/ui/tooltip"; import NotFound from "@/pages/not-found"; import Dashboard from "@/pages/dashboard"; +import NewPost from "@/pages/new-post"; +import Calendar from "@/pages/calendar"; +import Media from "@/pages/media"; +import PagesManagement from "@/pages/pages"; +import AI from "@/pages/ai"; +import Analytics from "@/pages/analytics"; +import History from "@/pages/history"; +import Settings from "@/pages/settings"; function Router() { return ( + + + + + + + + ); diff --git a/client/src/pages/ai.tsx b/client/src/pages/ai.tsx new file mode 100644 index 0000000..d8cce5c --- /dev/null +++ b/client/src/pages/ai.tsx @@ -0,0 +1,43 @@ +import { useState } from "react"; +import Sidebar from "@/components/sidebar"; +import TopBar from "@/components/topbar"; +import AiChat from "@/components/ai-chat"; + +export default function AI() { + const [sidebarOpen, setSidebarOpen] = useState(false); + + return ( +
+ {sidebarOpen && ( +
setSidebarOpen(false)} + /> + )} + +
+ +
+ +
+ setSidebarOpen(!sidebarOpen)} /> + +
+
+

Assistant IA

+

+ Générez du contenu personnalisé avec l'intelligence artificielle +

+
+ +
+ +
+
+
+
+ ); +} diff --git a/client/src/pages/analytics.tsx b/client/src/pages/analytics.tsx new file mode 100644 index 0000000..69b4c18 --- /dev/null +++ b/client/src/pages/analytics.tsx @@ -0,0 +1,110 @@ +import { useState } from "react"; +import { useQuery } from "@tanstack/react-query"; +import { TrendingUp, Users, Eye, Heart } from "lucide-react"; +import Sidebar from "@/components/sidebar"; +import TopBar from "@/components/topbar"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; + +export default function Analytics() { + const [sidebarOpen, setSidebarOpen] = useState(false); + + const { data: stats } = useQuery({ + queryKey: ['/api/stats'], + }); + + return ( +
+ {sidebarOpen && ( +
setSidebarOpen(false)} + /> + )} + +
+ +
+ +
+ setSidebarOpen(!sidebarOpen)} /> + +
+
+

Analyses

+

+ Statistiques et performances de vos publications +

+
+ +
+ + + + Publications totales + + + + +
0
+

Toutes plateformes

+
+
+ + + + + Portée totale + + + + +
0
+

Personnes atteintes

+
+
+ + + + + Impressions + + + + +
0
+

Vues totales

+
+
+ + + + + Engagement + + + + +
0
+

Interactions totales

+
+
+
+ + + + Fonctionnalité à venir + + +

+ Les analyses détaillées et les graphiques de performance seront disponibles prochainement. +

+
+
+
+
+
+ ); +} diff --git a/client/src/pages/calendar.tsx b/client/src/pages/calendar.tsx new file mode 100644 index 0000000..be2a7a5 --- /dev/null +++ b/client/src/pages/calendar.tsx @@ -0,0 +1,41 @@ +import { useState } from "react"; +import Sidebar from "@/components/sidebar"; +import TopBar from "@/components/topbar"; +import CalendarView from "@/components/calendar-view"; + +export default function Calendar() { + const [sidebarOpen, setSidebarOpen] = useState(false); + + return ( +
+ {sidebarOpen && ( +
setSidebarOpen(false)} + /> + )} + +
+ +
+ +
+ setSidebarOpen(!sidebarOpen)} /> + +
+
+

Calendrier

+

+ Visualisez et gérez vos publications planifiées +

+
+ + +
+
+
+ ); +} diff --git a/client/src/pages/history.tsx b/client/src/pages/history.tsx new file mode 100644 index 0000000..4b098e2 --- /dev/null +++ b/client/src/pages/history.tsx @@ -0,0 +1,114 @@ +import { useState } from "react"; +import { useQuery } from "@tanstack/react-query"; +import { Clock, CheckCircle, XCircle, Calendar } from "lucide-react"; +import Sidebar from "@/components/sidebar"; +import TopBar from "@/components/topbar"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import type { Post } from "@shared/schema"; +import { format } from "date-fns"; +import { fr } from "date-fns/locale"; + +export default function History() { + const [sidebarOpen, setSidebarOpen] = useState(false); + + const { data: posts = [], isLoading } = useQuery({ + queryKey: ['/api/posts'], + }); + + const publishedPosts = posts.filter(p => p.status === 'published'); + + return ( +
+ {sidebarOpen && ( +
setSidebarOpen(false)} + /> + )} + +
+ +
+ +
+ setSidebarOpen(!sidebarOpen)} /> + +
+
+

Historique

+

+ Consultez l'historique de vos publications +

+
+ + {isLoading ? ( +
+ {[1, 2, 3].map((i) => ( + + + + ))} +
+ ) : publishedPosts.length === 0 ? ( + + + +

Aucune publication

+

+ Vos publications apparaîtront ici une fois publiées +

+
+
+ ) : ( +
+ {publishedPosts.map((post) => ( + + +
+
+ + Publication #{post.id} + +

+ {post.content} +

+
+ + {post.status === 'published' && } + {post.status === 'failed' && } + {post.status === 'published' ? 'Publié' : 'Échoué'} + +
+
+ +
+
+ + {post.updatedAt + ? format(new Date(post.updatedAt), "d MMM yyyy 'à' HH:mm", { locale: fr }) + : 'Date inconnue' + } +
+ {post.aiGenerated && ( + + Généré par IA + + )} +
+
+
+ ))} +
+ )} +
+
+
+ ); +} diff --git a/client/src/pages/media.tsx b/client/src/pages/media.tsx new file mode 100644 index 0000000..ccc61a1 --- /dev/null +++ b/client/src/pages/media.tsx @@ -0,0 +1,41 @@ +import { useState } from "react"; +import Sidebar from "@/components/sidebar"; +import TopBar from "@/components/topbar"; +import MediaUpload from "@/components/media-upload"; + +export default function Media() { + const [sidebarOpen, setSidebarOpen] = useState(false); + + return ( +
+ {sidebarOpen && ( +
setSidebarOpen(false)} + /> + )} + +
+ +
+ +
+ setSidebarOpen(!sidebarOpen)} /> + +
+
+

Médiathèque

+

+ Gérez vos images et vidéos pour vos publications +

+
+ + +
+
+
+ ); +} diff --git a/client/src/pages/new-post.tsx b/client/src/pages/new-post.tsx new file mode 100644 index 0000000..a124fbd --- /dev/null +++ b/client/src/pages/new-post.tsx @@ -0,0 +1,288 @@ +import { useState } from "react"; +import { useQuery, useMutation } from "@tanstack/react-query"; +import { useLocation } from "wouter"; +import { Send, Sparkles, Image as ImageIcon, Calendar } from "lucide-react"; +import Sidebar from "@/components/sidebar"; +import TopBar from "@/components/topbar"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { Textarea } from "@/components/ui/textarea"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Checkbox } from "@/components/ui/checkbox"; +import { useToast } from "@/hooks/use-toast"; +import { apiRequest, queryClient } from "@/lib/queryClient"; +import type { SocialPage, Media } from "@shared/schema"; + +export default function NewPost() { + const [sidebarOpen, setSidebarOpen] = useState(false); + const [, navigate] = useLocation(); + const { toast } = useToast(); + + const [productInfo, setProductInfo] = useState(''); + const [selectedMedia, setSelectedMedia] = useState(null); + const [selectedPages, setSelectedPages] = useState([]); + const [scheduledDate, setScheduledDate] = useState(''); + + const { data: pages = [] } = useQuery({ + queryKey: ['/api/pages'], + }); + + const { data: mediaList = [] } = useQuery({ + queryKey: ['/api/media'], + }); + + const generateTextMutation = useMutation({ + mutationFn: (productInfo: string) => + apiRequest('POST', '/api/ai/generate', { productInfo }), + onSuccess: (data: any) => { + toast({ + title: "Texte généré", + description: `${data.variations?.length || 0} variations créées`, + }); + queryClient.invalidateQueries({ queryKey: ['/api/ai/generations'] }); + }, + onError: () => { + toast({ + title: "Erreur", + description: "Impossible de générer le texte", + variant: "destructive", + }); + }, + }); + + const createPostMutation = useMutation({ + mutationFn: (data: any) => + apiRequest('POST', '/api/posts', data), + onSuccess: () => { + toast({ + title: "Publication créée", + description: "La publication a été créée avec succès", + }); + navigate('/'); + }, + onError: () => { + toast({ + title: "Erreur", + description: "Impossible de créer la publication", + variant: "destructive", + }); + }, + }); + + const handleGenerateText = () => { + if (!productInfo.trim()) { + toast({ + title: "Information manquante", + description: "Veuillez saisir les informations du produit", + variant: "destructive", + }); + return; + } + generateTextMutation.mutate(productInfo); + }; + + const handleCreatePost = () => { + if (!productInfo.trim()) { + toast({ + title: "Contenu requis", + description: "Veuillez saisir le contenu de la publication", + variant: "destructive", + }); + return; + } + + createPostMutation.mutate({ + content: productInfo, + scheduledFor: scheduledDate || undefined, + }); + }; + + return ( +
+ {sidebarOpen && ( +
setSidebarOpen(false)} + /> + )} + +
+ +
+ +
+ setSidebarOpen(!sidebarOpen)} /> + +
+
+

Nouvelle publication

+

+ Créez et planifiez une nouvelle publication +

+
+ +
+
+ + + Contenu + Informations du produit ou message + + +
+ +