mirror of
https://github.com/R0m1k3/Socialflow.git
synced 2026-10-23 06:58:12 +02:00
Update application UI with a modern and streamlined design
Revamp the entire UI with a new theme, enhancing readability and modern aesthetics across all components, including AI chat, calendar, media uploads, and user management sections. 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/nriKMjY
This commit is contained in:
1 parent
c208939745
commit
63ae963cd3
18 files changed
+566
-473
No files matched your search
@@ -4,7 +4,7 @@ import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import { apiRequest, queryClient } from "@/lib/queryClient";
|
||||
import { Bot, User, Lightbulb, History, Zap } from "lucide-react";
|
||||
import { Bot, User, Lightbulb, History, Zap, Sparkles } from "lucide-react";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
|
||||
interface Message {
|
||||
@@ -51,11 +51,9 @@ export default function AiChat() {
|
||||
const handleSubmit = () => {
|
||||
if (!input.trim()) return;
|
||||
|
||||
// Add user message
|
||||
const userMessage = input;
|
||||
setMessages((prev) => [...prev, { role: "user", content: userMessage }]);
|
||||
|
||||
// Parse product info from input (simple parsing)
|
||||
const productInfo = {
|
||||
name: userMessage.match(/Produit:\s*(.+?)(?:\n|$)/i)?.[1] || userMessage,
|
||||
price: userMessage.match(/Prix:\s*(.+?)(?:\n|$)/i)?.[1] || "",
|
||||
@@ -68,93 +66,97 @@ export default function AiChat() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-card rounded-lg border border-border overflow-hidden h-full">
|
||||
<div className="border-b border-border p-4 flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-lg bg-primary/10 flex items-center justify-center">
|
||||
<Bot className="text-primary w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-foreground">Assistant IA - Génération de contenu</h3>
|
||||
<p className="text-xs text-muted-foreground">Décrivez votre produit pour générer du texte</p>
|
||||
<div className="bg-card rounded-2xl border border-border/50 overflow-hidden shadow-lg h-full flex flex-col">
|
||||
<div className="border-b border-border/50 p-6 bg-gradient-to-r from-primary/5 to-secondary/5">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-primary to-secondary flex items-center justify-center shadow-lg">
|
||||
<Sparkles className="text-white w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-foreground">Assistant IA</h3>
|
||||
<p className="text-sm text-muted-foreground">Génération de contenu intelligent</p>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setMessages([messages[0]])}
|
||||
className="rounded-xl"
|
||||
data-testid="button-new-chat"
|
||||
>
|
||||
<Sparkles className="w-4 h-4 mr-2" />
|
||||
Nouveau chat
|
||||
</Button>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setMessages([messages[0]])}
|
||||
data-testid="button-new-chat"
|
||||
>
|
||||
<i className="fas fa-plus mr-2"></i>Nouveau chat
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="h-96 overflow-y-auto p-6 space-y-4 bg-muted/20">
|
||||
<div className="flex-1 overflow-y-auto p-6 space-y-6 bg-muted/20">
|
||||
{messages.map((message, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`flex gap-3 chat-message ${message.role === "user" ? "justify-end" : ""}`}
|
||||
className={`flex gap-4 chat-message ${message.role === "user" ? "justify-end" : ""}`}
|
||||
>
|
||||
{message.role === "assistant" && (
|
||||
<div className="w-8 h-8 rounded-full bg-primary flex-shrink-0 flex items-center justify-center">
|
||||
<Bot className="text-primary-foreground w-4 h-4" />
|
||||
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-primary to-secondary flex-shrink-0 flex items-center justify-center shadow-md">
|
||||
<Bot className="text-white w-5 h-5" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={`flex-1 ${message.role === "user" ? "max-w-md ml-auto" : ""}`}>
|
||||
<div className={`flex-1 ${message.role === "user" ? "max-w-md ml-auto" : "max-w-2xl"}`}>
|
||||
<div className={`
|
||||
rounded-lg p-4
|
||||
rounded-2xl p-6 shadow-md
|
||||
${message.role === "user"
|
||||
? "bg-primary text-primary-foreground ml-auto"
|
||||
: "bg-card border border-border"
|
||||
? "bg-gradient-to-br from-primary to-secondary text-white ml-auto"
|
||||
: "bg-card border border-border/50"
|
||||
}
|
||||
`}>
|
||||
<p className="text-sm whitespace-pre-wrap">{message.content}</p>
|
||||
<p className="text-sm leading-relaxed whitespace-pre-wrap">{message.content}</p>
|
||||
|
||||
{message.variants && (
|
||||
<div className="space-y-3 mt-3">
|
||||
<div className="space-y-4 mt-6">
|
||||
{message.variants.map((variant, vIndex) => (
|
||||
<div
|
||||
key={vIndex}
|
||||
className="p-3 rounded-lg bg-accent/50 border border-border cursor-pointer hover:bg-accent transition-all"
|
||||
className="p-5 rounded-xl bg-muted/50 border border-border/50 cursor-pointer hover:bg-muted hover:shadow-md transition-all"
|
||||
data-testid={`variant-${vIndex}`}
|
||||
>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<span className={`
|
||||
inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
|
||||
${vIndex === 0 ? "bg-primary text-primary-foreground" : "bg-secondary text-secondary-foreground"}
|
||||
inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold
|
||||
${vIndex === 0 ? "bg-gradient-to-r from-primary to-secondary text-white" : "bg-secondary/20 text-secondary"}
|
||||
`}>
|
||||
{variant.variant}
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground">{variant.characterCount} caractères</span>
|
||||
<span className="text-xs text-muted-foreground font-medium">{variant.characterCount} caractères</span>
|
||||
</div>
|
||||
<p className="text-sm text-foreground">{variant.text}</p>
|
||||
<p className="text-sm text-foreground leading-relaxed">{variant.text}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<span className="text-xs text-muted-foreground mt-1 inline-block">
|
||||
<span className="text-xs text-muted-foreground mt-2 inline-block">
|
||||
{message.role === "user" ? "Maintenant" : "Il y a quelques secondes"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{message.role === "user" && (
|
||||
<div className="w-8 h-8 rounded-full bg-secondary flex-shrink-0 flex items-center justify-center">
|
||||
<User className="text-secondary-foreground w-4 h-4" />
|
||||
<div className="w-10 h-10 rounded-xl bg-secondary/20 flex-shrink-0 flex items-center justify-center">
|
||||
<User className="text-secondary w-5 h-5" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="p-4 border-t border-border bg-card">
|
||||
<div className="flex gap-3">
|
||||
<div className="p-6 border-t border-border/50 bg-card space-y-4">
|
||||
<div className="flex gap-4">
|
||||
<Textarea
|
||||
placeholder="Décrivez votre produit (nom, prix, caractéristiques)..."
|
||||
value={input}
|
||||
onChange={(e) => setInput(e.target.value)}
|
||||
className="flex-1 min-h-[60px]"
|
||||
className="flex-1 min-h-[80px] rounded-xl bg-muted/30 border-border/50 focus:border-primary/50"
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter" && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
@@ -166,34 +168,37 @@ export default function AiChat() {
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
disabled={generateMutation.isPending || !input.trim()}
|
||||
className="bg-gradient-to-r from-primary to-secondary hover:opacity-90 rounded-xl px-6"
|
||||
data-testid="button-generate"
|
||||
>
|
||||
<i className="fas fa-paper-plane mr-2"></i>
|
||||
<Sparkles className="w-4 h-4 mr-2" />
|
||||
{generateMutation.isPending ? "Génération..." : "Générer"}
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mt-3 flex items-center gap-2">
|
||||
<div className="flex items-center gap-3 flex-wrap">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="rounded-xl"
|
||||
onClick={() => toast({ title: "Bientôt disponible", description: "Les suggestions de produits seront disponibles prochainement" })}
|
||||
data-testid="button-suggestions"
|
||||
>
|
||||
<Lightbulb className="w-4 h-4 mr-1" />
|
||||
<Lightbulb className="w-4 h-4 mr-2" />
|
||||
Suggestions
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="rounded-xl"
|
||||
onClick={() => toast({ title: "Bientôt disponible", description: "L'historique des générations sera disponible prochainement" })}
|
||||
data-testid="button-history"
|
||||
>
|
||||
<History className="w-4 h-4 mr-1" />
|
||||
<History className="w-4 h-4 mr-2" />
|
||||
Historique
|
||||
</Button>
|
||||
<div className="ml-auto text-xs text-muted-foreground flex items-center gap-1">
|
||||
<Zap className="w-3 h-3 text-chart-3" />
|
||||
Propulsé par OpenRouter
|
||||
<div className="ml-auto text-xs text-muted-foreground flex items-center gap-2">
|
||||
<Zap className="w-4 h-4 text-success" />
|
||||
<span>Propulsé par OpenRouter</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user