6) Creator upload page (so designers can sell)

client/src/pages/Creator/UploadCoverTemplate.tsx

import { useState } from "react";
import { DashboardTemplatePage } from "@/components/DashboardTemplatePage";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { toast } from "sonner";

export default function UploadCoverTemplate() {
  const [title, setTitle] = useState("");
  const [category, setCategory] = useState("business");
  const [price, setPrice] = useState("12");
  const [preview, setPreview] = useState("");
  const [pptx, setPptx] = useState("");
  const [keynote, setKeynote] = useState("");
  const [gslides, setGslides] = useState("");
  const [bundle, setBundle] = useState("");

  async function submit() {
    const res = await fetch("/api/creator/cover-templates", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      credentials: "include",
      body: JSON.stringify({
        title, category, price_cents: Math.max(0, parseInt(price) * 100),
        preview_image_url: preview,
        pptx_url: pptx || null,
        keynote_url: keynote || null,
        gslides_url: gslides || null,
        download_bundle_url: bundle || null
      })
    });
    if (!res.ok) return toast.error("Upload failed");
    toast.success("Submitted for review. We’ll activate it soon.");
    setTitle(""); setPreview(""); setPptx(""); setKeynote(""); setGslides(""); setBundle("");
  }

  return (
    <DashboardTemplatePage title="Upload Cover Template">
      <div className="grid md:grid-cols-2 gap-4">
        <div className="space-y-3">
          <Input placeholder="Title" value={title} onChange={e=>setTitle(e.target.value)} />
          <Input placeholder="Category (business/minimal/creative/…)" value={category} onChange={e=>setCategory(e.target.value)} />
          <Input placeholder="Price (USD)" value={price} onChange={e=>setPrice(e.target.value)} />
          <Input placeholder="Preview Image URL" value={preview} onChange={e=>setPreview(e.target.value)} />
          <Input placeholder="PPTX URL (optional)" value={pptx} onChange={e=>setPptx(e.target.value)} />
          <Input placeholder="Keynote URL (optional)" value={keynote} onChange={e=>setKeynote(e.target.value)} />
          <Input placeholder="Google Slides link (optional)" value={gslides} onChange={e=>setGslides(e.target.value)} />
          <Input placeholder="Bundle ZIP (optional)" value={bundle} onChange={e=>setBundle(e.target.value)} />
        </div>
        <div className="rounded border p-3">
          <div className="font-medium mb-2">Preview</div>
          <div className="relative aspect-[4/3] bg-muted overflow-hidden">
            {preview && <img src={preview} className="w-full h-full object-cover" />}
            <div className="absolute inset-0 grid place-items-center pointer-events-none opacity-60 mix-blend-multiply">
              <div className="wm-bg text-sm">IBrandBiz • Preview</div>
            </div>
          </div>
          <Button className="mt-4 w-full" onClick={submit}>Submit for Review</Button>
        </div>
      </div>
    </DashboardTemplatePage>
  );
}


Routes (App.tsx):

import UploadCoverTemplate from "@/pages/Creator/UploadCoverTemplate";
<Route path="/creator/upload-cover-template">
  <ProtectedRoute><DashboardTemplatePage title="Upload Cover Template"><UploadCoverTemplate /></DashboardTemplatePage></ProtectedRoute>
</Route>


Link this from My Marketplace → Upload as an option (“Upload Cover Template”).