diff --git a/artifacts/api-server/src/routes/tools.ts b/artifacts/api-server/src/routes/tools.ts index a75d7b1..1b881da 100644 --- a/artifacts/api-server/src/routes/tools.ts +++ b/artifacts/api-server/src/routes/tools.ts @@ -84,6 +84,7 @@ router.post("/tools", requireAuth, async (req, res): Promise => { description: parsed.data.description, category: parsed.data.category, websiteUrl: parsed.data.websiteUrl ?? null, + iconUrl: parsed.data.iconUrl ?? null, features: parsed.data.features ?? [], tags: parsed.data.tags ?? [], }).returning(); @@ -130,6 +131,7 @@ router.patch("/tools/:id", requireAuth, async (req, res): Promise => { if (parsed.data.description !== undefined) updateData.description = parsed.data.description; if (parsed.data.category !== undefined) updateData.category = parsed.data.category; if (parsed.data.websiteUrl !== undefined) updateData.websiteUrl = parsed.data.websiteUrl; + if (parsed.data.iconUrl !== undefined) updateData.iconUrl = parsed.data.iconUrl; if (parsed.data.features !== undefined) updateData.features = parsed.data.features; if (parsed.data.tags !== undefined) updateData.tags = parsed.data.tags; diff --git a/artifacts/toolrate/src/components/tool-card.tsx b/artifacts/toolrate/src/components/tool-card.tsx index 22253fd..65639dd 100644 --- a/artifacts/toolrate/src/components/tool-card.tsx +++ b/artifacts/toolrate/src/components/tool-card.tsx @@ -1,7 +1,7 @@ import { ToolWithStats } from "@workspace/api-client-react"; import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; -import { Star, MessageSquare } from "lucide-react"; +import { Star, MessageSquare, Wrench } from "lucide-react"; import { Link } from "wouter"; export function ToolCard({ tool }: { tool: ToolWithStats }) { @@ -9,9 +9,25 @@ export function ToolCard({ tool }: { tool: ToolWithStats }) { -
- {tool.name} - {tool.category} +
+
+ {tool.iconUrl ? ( + {tool.name} { (e.target as HTMLImageElement).style.display = "none"; }} + /> + ) : ( + + )} +
+
+
+ {tool.name} + {tool.category} +
+
{tool.description} diff --git a/artifacts/toolrate/src/pages/analytics.tsx b/artifacts/toolrate/src/pages/analytics.tsx index 6817d71..b732f97 100644 --- a/artifacts/toolrate/src/pages/analytics.tsx +++ b/artifacts/toolrate/src/pages/analytics.tsx @@ -164,30 +164,36 @@ export default function Analytics() { {loadingDistribution ? ( - + ) : ( -
-
+
+
Usefulness - - - - - - - - +
+ + + + + + + + + +
-
+
Usability - - - - - - - - +
+ + + + + + + + + +
)} diff --git a/artifacts/toolrate/src/pages/tool-detail.tsx b/artifacts/toolrate/src/pages/tool-detail.tsx index 6ae113d..6ce453d 100644 --- a/artifacts/toolrate/src/pages/tool-detail.tsx +++ b/artifacts/toolrate/src/pages/tool-detail.tsx @@ -142,9 +142,25 @@ export default function ToolDetail() {
-
-

{tool.name}

- {tool.category} +
+
+ {tool.iconUrl ? ( + {tool.name} { (e.target as HTMLImageElement).style.display = "none"; }} + /> + ) : ( + + {tool.name.charAt(0).toUpperCase()} + + )} +
+
+

{tool.name}

+ {tool.category} +

diff --git a/artifacts/toolrate/src/pages/tool-new.tsx b/artifacts/toolrate/src/pages/tool-new.tsx index 95ee38c..00f75e0 100644 --- a/artifacts/toolrate/src/pages/tool-new.tsx +++ b/artifacts/toolrate/src/pages/tool-new.tsx @@ -23,6 +23,7 @@ const toolSchema = z.object({ description: z.string().min(10, "Description must be at least 10 characters"), category: z.string().min(2, "Category is required"), websiteUrl: z.string().url("Must be a valid URL").optional().or(z.literal("")), + iconUrl: z.string().url("Must be a valid URL").optional().or(z.literal("")), features: z.array(z.object({ value: z.string() })).optional(), tags: z.array(z.object({ value: z.string() })).optional(), }); @@ -43,6 +44,7 @@ export default function ToolNew() { description: "", category: "", websiteUrl: "", + iconUrl: "", features: [{ value: "" }], tags: [{ value: "" }], }, @@ -62,6 +64,7 @@ export default function ToolNew() { const payload = { ...data, websiteUrl: data.websiteUrl || undefined, + iconUrl: data.iconUrl || undefined, features: data.features?.map((f) => f.value).filter((v) => v.trim() !== ""), tags: data.tags?.map((t) => t.value).filter((v) => v.trim() !== ""), }; @@ -166,6 +169,40 @@ export default function ToolNew() { )} /> + ( + + Icon / Logo URL (Optional) + +

+
+ {field.value ? ( + icon preview { (e.target as HTMLImageElement).style.display = "none"; }} + /> + ) : ( + img + )} +
+ +
+ + + + )} + /> +