Add toggleable DO's and DON'Ts guidelines component for icon submission

Co-authored-by: ajnart <49837342+ajnart@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-11-23 16:44:14 +00:00
parent da34ab7a43
commit cb13f92456
2 changed files with 168 additions and 19 deletions

View File

@@ -1,12 +1,13 @@
"use client";
import { useForm } from "@tanstack/react-form";
import { Check, FileImage, FileType, Link, Plus, X } from "lucide-react";
import { Check, FileImage, FileType, Plus, X } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import { revalidateAllSubmissions } from "@/app/actions/submissions";
import { ExperimentalWarning } from "@/components/experimental-warning";
import { IconNameCombobox } from "@/components/icon-name-combobox";
import { IconSubmissionGuidelines } from "@/components/icon-submission-guidelines";
import {
AlertDialog,
AlertDialogAction,
@@ -489,24 +490,7 @@ export function AdvancedIconSubmissionFormTanStack() {
</p>
</div>
<div className="rounded-lg border border-amber-500/50 bg-amber-500/10 p-4 space-y-2">
<p className="text-sm font-semibold text-amber-700 dark:text-amber-400">
File Format Requirements
</p>
<ul className="text-sm text-amber-700/90 dark:text-amber-400/90 space-y-1 list-disc list-inside">
<li>
<strong>SVG format is strongly preferred</strong> over PNG
or WebP for better scalability and quality
</li>
<li>
<strong>
All icons must have a transparent background
</strong>{" "}
- submissions with opaque or colored backgrounds will be
rejected
</li>
</ul>
</div>
<IconSubmissionGuidelines />
<form.Field name="selectedVariants">
{(field) => (

View File

@@ -0,0 +1,165 @@
"use client";
import { Check, ChevronDown, X } from "lucide-react";
import { useState } from "react";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
import { Button } from "@/components/ui/button";
interface GuidelineItem {
type: "do" | "dont";
title: string;
description: string;
}
const GUIDELINES: GuidelineItem[] = [
{
type: "do",
title: "Submit SVG files",
description:
"We strongly prefer SVG format for all icons. We'll automatically transform them into PNG and WebP formats as well.",
},
{
type: "do",
title: "Provide color variants when available",
description:
"Submit normal (colored), dark, and light variants when possible. The 'normal' variant is the colored version and is usually the 'light' one.",
},
{
type: "do",
title: "Ensure transparent backgrounds",
description:
"All icons must have transparent backgrounds. Icons with opaque or colored backgrounds will be rejected.",
},
{
type: "dont",
title: "Don't submit non-transparent backgrounds",
description:
"Submissions with solid color or non-transparent backgrounds will be rejected. Always use transparent backgrounds.",
},
{
type: "dont",
title: "Don't make multiple submissions for the same icon",
description:
"If you have both SVG and PNG versions, only submit the SVG. Do not create separate submissions like 'something.svg' and 'something.png'.",
},
{
type: "dont",
title: "Don't use PNG-to-SVG converter tools",
description:
"If an SVG version exists, use that instead. PNG-to-SVG converters produce poor quality results and should be avoided.",
},
];
export function IconSubmissionGuidelines() {
const [isOpen, setIsOpen] = useState(false);
const doItems = GUIDELINES.filter((item) => item.type === "do");
const dontItems = GUIDELINES.filter((item) => item.type === "dont");
return (
<div className="rounded-lg border border-blue-500/50 bg-blue-500/10">
<Collapsible open={isOpen} onOpenChange={setIsOpen}>
<div className="p-4">
<div className="flex items-center justify-between">
<div className="flex-1">
<p className="text-sm font-semibold text-blue-700 dark:text-blue-400">
Icon Submission Guidelines
</p>
<p className="text-sm text-blue-700/90 dark:text-blue-400/90 mt-1">
Review these important guidelines before submitting
</p>
</div>
<CollapsibleTrigger asChild>
<Button
variant="ghost"
size="sm"
className="ml-2 text-blue-700 dark:text-blue-400 hover:bg-blue-500/20"
>
{isOpen ? "Hide" : "Show"} Details
<ChevronDown
className={`ml-2 h-4 w-4 transition-transform duration-200 ${
isOpen ? "rotate-180" : ""
}`}
/>
</Button>
</CollapsibleTrigger>
</div>
</div>
<CollapsibleContent>
<div className="px-4 pb-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{/* DO's Section */}
<div className="space-y-2">
<div className="flex items-center gap-2 mb-3">
<div className="p-1.5 rounded-full bg-green-500/20">
<Check className="h-4 w-4 text-green-600 dark:text-green-400" />
</div>
<h4 className="text-sm font-semibold text-green-700 dark:text-green-400">
DO
</h4>
</div>
<div className="space-y-3">
{doItems.map((item, index) => (
<div
key={index}
className="rounded-lg border border-green-500/30 bg-green-500/5 p-3"
>
<div className="flex gap-2">
<Check className="h-4 w-4 text-green-600 dark:text-green-400 mt-0.5 flex-shrink-0" />
<div>
<p className="text-sm font-medium text-foreground">
{item.title}
</p>
<p className="text-xs text-muted-foreground mt-1">
{item.description}
</p>
</div>
</div>
</div>
))}
</div>
</div>
{/* DON'Ts Section */}
<div className="space-y-2">
<div className="flex items-center gap-2 mb-3">
<div className="p-1.5 rounded-full bg-red-500/20">
<X className="h-4 w-4 text-red-600 dark:text-red-400" />
</div>
<h4 className="text-sm font-semibold text-red-700 dark:text-red-400">
DON'T
</h4>
</div>
<div className="space-y-3">
{dontItems.map((item, index) => (
<div
key={index}
className="rounded-lg border border-red-500/30 bg-red-500/5 p-3"
>
<div className="flex gap-2">
<X className="h-4 w-4 text-red-600 dark:text-red-400 mt-0.5 flex-shrink-0" />
<div>
<p className="text-sm font-medium text-foreground">
{item.title}
</p>
<p className="text-xs text-muted-foreground mt-1">
{item.description}
</p>
</div>
</div>
</div>
))}
</div>
</div>
</div>
</div>
</CollapsibleContent>
</Collapsible>
</div>
);
}