mirror of
https://github.com/walkxcode/dashboard-icons.git
synced 2025-11-26 22:58:41 +01:00
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:
@@ -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) => (
|
||||
|
||||
165
web/src/components/icon-submission-guidelines.tsx
Normal file
165
web/src/components/icon-submission-guidelines.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user