k beauty product manager

import { useState, useRef } from “react”;

const TAG_OPTIONS = [
{ label: “Serum”, className: “serum”, bg: “#ede8f5”, color: “#9b8bb4” },
{ label: “Moisturizer”, className: “moisturizer”, bg: “#e8f2f7”, color: “#4a7a8a” },
{ label: “Cleanser”, className: “cleanser”, bg: “#fef5e7”, color: “#8a6d3b” },
{ label: “Sunscreen”, className: “sunscreen”, bg: “#d0e4ed”, color: “#4a7a8a” },
{ label: “Toner”, className: “toner”, bg: “#f0f8f0”, color: “#4a7a4a” },
{ label: “Ampoule”, className: “ampoule”, bg: “#ede8f5”, color: “#9b8bb4” },
{ label: “Mask”, className: “mask”, bg: “#fef5e7”, color: “#8a6d3b” },
{ label: “Eye Cream”, className: “eye”, bg: “#e8f2f7”, color: “#4a7a8a” },
{ label: “Bunnyless ✓”, className: “bunnyless”, bg: “#fef0f5”, color: “#b05a7a” },
{ label: “Bestseller”, className: “bestseller”, bg: “#1e2a42”, color: “#ADDFAD” },
];

const emptyProduct = {
brand: “”,
name: “”,
price: “”,
score: 75,
imageUrl: “”,
affiliateLink: “”,
tags: [],
};

function getProofColor(score) {
if (score >= 75) return “#ADDFAD”;
if (score >= 50) return “#8BAFC0”;
return “#9b8bb4”;
}

function ProductCard({ product, small }) {
const proofColor = getProofColor(product.score);
return (


{!product.imageUrl && “Product Image”}
{product.tags.map((t, i) => {
const tagDef = TAG_OPTIONS.find(o => o.label === t);
return (
{t}
);
})}
{product.brand || “Brand”}
{product.name || “Product Name”}
Proof

{product.score}


{product.price ? `$${product.price}` : “$0.00”}
Buy →

);
}

function generateHTML(products) {
const cards = products.map((p) => {
const proofClass = p.score >= 75 ? “proof-high” : p.score >= 50 ? “proof-mid” : “proof-low”;
const tagHTML = p.tags.map((t) => {
const td = TAG_OPTIONS.find(o => o.label === t);
const cls = td ? `tag-${td.className}` : “tag-skincare”;
return ` ${t}`;
}).join(“\n”);

return `

${p.brand} ${p.name}

${tagHTML}
${p.brand}
${p.name}
Proof

${p.score}

`;
}).join(“\n\n”);

return `

${cards}

`;
}

export default function KBrandProductManager() {
const [products, setProducts] = useState([]);
const [current, setCurrent] = useState({ …emptyProduct });
const [editingIndex, setEditingIndex] = useState(null);
const [copied, setCopied] = useState(false);
const [view, setView] = useState(“form”); // form | preview | export

const addOrUpdate = () => {
if (!current.brand || !current.name) return;
if (editingIndex !== null) {
const updated = […products];
updated[editingIndex] = { …current };
setProducts(updated);
setEditingIndex(null);
} else {
setProducts([…products, { …current }]);
}
setCurrent({ …emptyProduct });
};

const edit = (i) => {
setCurrent({ …products[i] });
setEditingIndex(i);
setView(“form”);
};

const remove = (i) => {
setProducts(products.filter((_, idx) => idx !== i));
if (editingIndex === i) {
setEditingIndex(null);
setCurrent({ …emptyProduct });
}
};

const copyHTML = async () => {
const html = generateHTML(products);
await navigator.clipboard.writeText(html);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};

const toggleTag = (label) => {
setCurrent(prev => ({
…prev,
tags: prev.tags.includes(label)
? prev.tags.filter(t => t !== label)
: […prev.tags, label],
}));
};

const inputStyle = {
width: “100%”,
padding: “10px 14px”,
border: “1px solid rgba(30,42,66,0.12)”,
borderRadius: 8,
fontFamily: “‘DM Sans’, sans-serif”,
fontSize: 14,
color: “#1e2a42”,
outline: “none”,
background: “#fff”,
};

const labelStyle = {
fontFamily: “‘DM Sans’, sans-serif”,
fontSize: 11,
fontWeight: 700,
letterSpacing: “0.08em”,
textTransform: “uppercase”,
color: “#6b8577”,
marginBottom: 6,
display: “block”,
};

return (

{/* Header */}

K Brand Product Manager
Add products → Preview grid → Copy HTML → Paste in WordPress

{/* Nav tabs */}


{[
{ key: “form”, label: `Add Product${products.length ? ` (${products.length})` : “”}` },
{ key: “preview”, label: “Preview Grid” },
{ key: “export”, label: “Export HTML” },
].map(tab => (

))}

{/* FORM VIEW */}
{view === “form” && (


setCurrent({ …current, brand: e.target.value })} placeholder=”e.g. COSRX” />

setCurrent({ …current, name: e.target.value })} placeholder=”e.g. Snail 96 Mucin Essence” />


setCurrent({ …current, price: e.target.value })} placeholder=”e.g. 12.50″ />

setCurrent({ …current, score: parseInt(e.target.value) })} style={{ flex: 1 }} />
{current.score}


setCurrent({ …current, imageUrl: e.target.value })} placeholder=”https://… (paste product image URL)” />

setCurrent({ …current, affiliateLink: e.target.value })} placeholder=”https://… (Amazon, iHerb, etc.)” />

{TAG_OPTIONS.map(tag => (

))}

{/* Live preview */}
{(current.brand || current.name) && (

)}

{/* Product list */}
{products.length > 0 && (


{products.map((p, i) => (

{p.brand}

{p.name}

{p.score}

))}

)}

)}

{/* PREVIEW VIEW */}
{view === “preview” && (

{products.length === 0 ? (

No products yet
Add some products first, then come back here to preview the grid.

) : (


{products.map((p, i) => (

))}

)}

)}

{/* EXPORT VIEW */}
{view === “export” && (

{products.length === 0 ? (

Nothing to export
Add products first.

) : (
<>

Ready to export
{products.length} product{products.length !== 1 ? “s” : “”} — copy and paste into WordPress Custom HTML block

{generateHTML(products)}


)}

)}

);
}