feat: implement skill management form and dynamic icon rendering component
This commit is contained in:
@@ -104,7 +104,7 @@ export function SkillForm({ initialData, skillId }: { initialData?: any; skillId
|
||||
|
||||
<div className="space-y-3">
|
||||
<label className="text-sm font-semibold">
|
||||
Devicon Slug <span className="text-muted-foreground font-normal">(opsional — untuk ikon di Hero)</span>
|
||||
Devicon Slug / Custom URL <span className="text-muted-foreground font-normal">(contoh: spring, atau /icons/logo.svg)</span>
|
||||
</label>
|
||||
<input
|
||||
name="iconName"
|
||||
@@ -117,7 +117,9 @@ export function SkillForm({ initialData, skillId }: { initialData?: any; skillId
|
||||
{iconPreview && (
|
||||
<div className="flex items-center gap-3 p-3 rounded-xl border border-border bg-muted/20">
|
||||
<img
|
||||
src={`https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/${iconPreview}/${iconPreview}-original.svg`}
|
||||
src={iconPreview.startsWith("http") || iconPreview.startsWith("/")
|
||||
? iconPreview
|
||||
: `https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/${iconPreview}/${iconPreview}-original.svg`}
|
||||
alt={iconPreview}
|
||||
className="w-10 h-10 object-contain"
|
||||
onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}
|
||||
|
||||
@@ -14,9 +14,13 @@ export function SkillIcon({ iconName, name }: { iconName: string | null; name: s
|
||||
);
|
||||
}
|
||||
|
||||
const iconSrc = iconName.startsWith("http") || iconName.startsWith("/")
|
||||
? iconName
|
||||
: `https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/${iconName}/${iconName}-original.svg`;
|
||||
|
||||
return (
|
||||
<img
|
||||
src={`https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/${iconName}/${iconName}-original.svg`}
|
||||
src={iconSrc}
|
||||
alt={name}
|
||||
className="w-9 h-9 object-contain"
|
||||
onError={() => setErrored(true)}
|
||||
|
||||
Reference in New Issue
Block a user