From 5b78e4f86c50ceaabf55d23bbd2be248c0bf2ac2 Mon Sep 17 00:00:00 2001 From: NotII <46204250+NotII@users.noreply.github.com> Date: Wed, 30 Jul 2025 16:05:46 +0200 Subject: [PATCH] Improve broadcast dialog and product selector UI Enhanced the broadcast dialog with better product selection UX, including a 'Done' button and improved selected products display. Updated the product selector to show more concise product descriptions, adjusted scroll area height, and improved price styling for clarity. --- components/modals/broadcast-dialog.tsx | 61 ++++++++++++++++---------- components/modals/product-selector.tsx | 19 +++++--- public/git-info.json | 4 +- 3 files changed, 51 insertions(+), 33 deletions(-) diff --git a/components/modals/broadcast-dialog.tsx b/components/modals/broadcast-dialog.tsx index 13e9a0d..dec26b9 100644 --- a/components/modals/broadcast-dialog.tsx +++ b/components/modals/broadcast-dialog.tsx @@ -6,7 +6,6 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from " import { Send, Bold, Italic, Code, Link as LinkIcon, Image as ImageIcon, X, Eye, EyeOff, Package } from "lucide-react"; import { toast } from "sonner"; import { apiRequest } from "@/lib/api"; -import { cn } from "@/lib/utils/general"; import { Textarea } from "@/components/ui/textarea"; import ReactMarkdown from 'react-markdown'; import ProductSelector from "./product-selector"; @@ -30,7 +29,8 @@ export default function BroadcastDialog({ open, setOpen }: BroadcastDialogProps) const handleImageSelect = (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (file) { - if (file.size > 10 * 1024 * 1024) { // 10MB limit + // Magic 10 MB Limit + if (file.size > 10 * 1024 * 1024) { toast.error("Image size must be less than 10MB"); return; } @@ -59,7 +59,7 @@ export default function BroadcastDialog({ open, setOpen }: BroadcastDialogProps) const end = textarea.selectionEnd; const selectedText = textarea.value.substring(start, end); let insertText = ''; - + switch (type) { case 'bold': insertText = `**${selectedText || 'bold text'}**`; @@ -77,7 +77,7 @@ export default function BroadcastDialog({ open, setOpen }: BroadcastDialogProps) const newText = textarea.value.substring(0, start) + insertText + textarea.value.substring(end); setBroadcastMessage(newText); - + const newCursorPos = start + insertText.length; textarea.focus(); textarea.setSelectionRange(newCursorPos, newCursorPos); @@ -91,7 +91,7 @@ export default function BroadcastDialog({ open, setOpen }: BroadcastDialogProps) try { setIsSending(true); - + const API_URL = process.env.NEXT_PUBLIC_API_URL; if (!API_URL) throw new Error("API URL not configured"); @@ -107,7 +107,7 @@ export default function BroadcastDialog({ open, setOpen }: BroadcastDialogProps) } let response; - + if (selectedImage) { const formData = new FormData(); formData.append('file', selectedImage); @@ -117,7 +117,7 @@ export default function BroadcastDialog({ open, setOpen }: BroadcastDialogProps) if (selectedProducts.length > 0) { formData.append('productIds', JSON.stringify(selectedProducts)); } - + const res = await fetch(`/api/storefront/broadcast`, { method: 'POST', headers: { @@ -125,15 +125,15 @@ export default function BroadcastDialog({ open, setOpen }: BroadcastDialogProps) }, body: formData, }); - + if (!res.ok) { const errorData = await res.json().catch(() => ({})); throw new Error(errorData.error || 'Failed to send broadcast'); } - + response = await res.json(); } else { - response = await apiRequest("/storefront/broadcast", "POST", { + response = await apiRequest("/storefront/broadcast", "POST", { message: broadcastMessage, productIds: selectedProducts }); @@ -162,7 +162,7 @@ export default function BroadcastDialog({ open, setOpen }: BroadcastDialogProps) Global Broadcast Message - +
+
0 && !showProductSelector && ( -
+
- Selected Products ({selectedProducts.length}) +
+ + Selected Products ({selectedProducts.length}) +
-
+
Products will be added as interactive buttons in the broadcast message.
@@ -317,13 +330,13 @@ __italic text__ )}
- + -
- +
{filteredProducts.length === 0 ? (
@@ -88,23 +88,28 @@ export default function ProductSelector({ selectedProducts, onSelectionChange }: filteredProducts.map((product) => (
handleProductToggle(product._id)} + className="mt-0.5" />
-
+
-

{product.name}

+

+ {product.name} +

{product.description && ( -

- {product.description} +

+ {product.description.length > 80 + ? `${product.description.substring(0, 80)}...` + : product.description}

)}
-
+
£{getMinPrice(product).toFixed(2)}
diff --git a/public/git-info.json b/public/git-info.json index 0a44146..8da98fe 100644 --- a/public/git-info.json +++ b/public/git-info.json @@ -1,4 +1,4 @@ { - "commitHash": "2452a3c", - "buildTime": "2025-07-28T20:50:17.059Z" + "commitHash": "4d1c37d", + "buildTime": "2025-07-30T14:02:04.518Z" } \ No newline at end of file