Skip to content

Commit 105f393

Browse files
add yaml as storage for tools (#19)
* add yaml as storage for tools * fix next build errors * fix yaml lint * fix yaml * fix failed builds * add yaml json validation * fix failed lint * fix validate tools jobs * fix retriving tools wihout selecting categories
1 parent d52f726 commit 105f393

33 files changed

+1790
-484
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Validate tools
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
validate:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v3
16+
- uses: actions/setup-node@v3
17+
with:
18+
node-version: "18"
19+
- run: npm install --legacy-peer-deps
20+
- run: npm run validate-tools

app/components/Home.tsx

Lines changed: 74 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use client"
2-
import React, { useState, useMemo } from "react"
2+
import React, { useState, useMemo, useEffect } from "react"
3+
import yaml from "js-yaml"
34
import { Input, Card, Typography, Menu, Collapse, Empty, Button } from "antd"
45
import ToolMapButton from "./Button"
56

@@ -35,75 +36,67 @@ const categories = {
3536
"End Of Life": ["Repossession & Reverse logistics", "E-Waste Management"],
3637
}
3738

38-
const tools = [
39-
{
40-
name: "PayGee",
41-
summary: "A payment processing tool.",
42-
logo: "/path/to/paygee-logo.png",
43-
link: "https://paygee.com",
44-
categories: ["Bookkeeping & Accounting"],
45-
},
46-
{
47-
name: "Odoo",
48-
summary: "An all-in-one management software.",
49-
logo: "/path/to/odoo-logo.png",
50-
link: "https://odoo.com",
51-
categories: ["Bookkeeping & Accounting"],
52-
},
53-
{
54-
name: "Quickbooks",
55-
summary: "Accounting software for small businesses.",
56-
logo: "/path/to/quickbooks-logo.png",
57-
link: "https://quickbooks.intuit.com",
58-
categories: ["Bookkeeping & Accounting"],
59-
},
60-
{
61-
name: "Upya",
62-
summary: "A financial management tool.",
63-
logo: "/path/to/upya-logo.png",
64-
link: "https://upya.com",
65-
categories: [
66-
"Bookkeeping & Accounting",
67-
"Impact Measurements & Performance",
68-
],
69-
},
70-
{
71-
name: "Xero",
72-
summary: "Online accounting software.",
73-
logo: "/path/to/xero-logo.png",
74-
link: "https://xero.com",
75-
categories: ["Bookkeeping & Accounting"],
76-
},
77-
{
78-
name: "Odyssey",
79-
summary: "A project management tool.",
80-
logo: "/path/to/odyssey-logo.png",
81-
link: "https://odyssey.com",
82-
categories: ["Product Procurement", "Impact Measurements & Performance"],
83-
},
84-
{
85-
name: "Unleashed",
86-
summary: "Inventory management software.",
87-
logo: "/path/to/unleashed-logo.png",
88-
link: "https://unleashedsoftware.com",
89-
categories: ["Product Procurement", "Impact Measurements & Performance"],
90-
},
91-
]
92-
9339
interface EnAccessToolMapProps {
9440
setIsModalOpen: (value: boolean) => void
9541
}
9642

43+
interface Tool {
44+
name: string
45+
summary: string
46+
logo: string
47+
link: string
48+
categories?: string[] // Make categories optional
49+
}
50+
9751
const EnAccessToolMap = ({ setIsModalOpen }: EnAccessToolMapProps) => {
9852
const [activeTool, setActiveTool] = useState<string | null>(null)
9953
const [searchTerm, setSearchTerm] = useState<string>("")
10054
const [selectedCategories, setSelectedCategories] = useState<string[]>([])
55+
const [tools, setTools] = useState<Tool[]>([])
56+
57+
useEffect(() => {
58+
// Load all YAML files
59+
const loadTools = async () => {
60+
try {
61+
const toolFiles = [
62+
"/tools/paygee.yaml",
63+
"/tools/odoo.yaml",
64+
"/tools/quickbooks.yaml",
65+
"/tools/upya.yaml",
66+
"/tools/xero.yaml",
67+
"/tools/odyssey.yaml",
68+
"/tools/unleashed.yaml",
69+
"/tools/3cx.yaml",
70+
"/tools/d-rec.yaml",
71+
"/tools/ixo.yaml",
72+
"/tools/p-rec.yaml",
73+
"/tools/sendy.yaml",
74+
"/tools/challenges.yaml",
75+
"/tools/carbon-clear.yaml",
76+
"/tools/cavex.yaml",
77+
]
78+
79+
const loadedTools = await Promise.all(
80+
toolFiles.map(async (file) => {
81+
const response = await fetch(file)
82+
const text = await response.text()
83+
return yaml.load(text) as Tool
84+
})
85+
)
86+
87+
setTools(loadedTools)
88+
} catch (error) {
89+
console.error("Error loading YAML files:", error)
90+
}
91+
}
92+
93+
loadTools()
94+
}, [])
10195

10296
const handleToolClick = (toolName: string) => {
10397
setActiveTool(activeTool === toolName ? null : toolName)
10498
}
10599

106-
// Handle menu item selection
107100
const handleMenuClick = ({ key }: { key: string }) => {
108101
// Check if the category is already selected
109102
if (selectedCategories.includes(key)) {
@@ -113,26 +106,26 @@ const EnAccessToolMap = ({ setIsModalOpen }: EnAccessToolMapProps) => {
113106
}
114107
}
115108

116-
// Filter tools based on search term and selected categories
117109
const filteredTools = useMemo(() => {
118-
// Only show tools when categories are selected
119-
if (selectedCategories.length === 0) {
110+
if (selectedCategories.length === 0 && !searchTerm) {
120111
return []
121112
}
122113

123114
return tools.filter((tool) => {
124115
const matchesSearch = tool.name
125116
.toLowerCase()
126117
.includes(searchTerm.toLowerCase())
118+
127119
const matchesCategories =
128120
selectedCategories.length === 0 ||
129-
selectedCategories.some((category) =>
130-
tool.categories.includes(category)
131-
)
121+
(tool.categories &&
122+
selectedCategories.some((category) =>
123+
tool.categories!.includes(category)
124+
))
132125

133126
return matchesSearch && matchesCategories
134127
})
135-
}, [searchTerm, selectedCategories])
128+
}, [searchTerm, selectedCategories, tools])
136129

137130
return (
138131
<div className="bg-white text-gray-800">
@@ -234,19 +227,21 @@ const EnAccessToolMap = ({ setIsModalOpen }: EnAccessToolMapProps) => {
234227
</a>
235228
</Paragraph>
236229
<Paragraph>{tool.summary}</Paragraph>
237-
<div className="mt-2">
238-
<strong>Categories:</strong>
239-
<div className="flex flex-wrap gap-2 mt-1">
240-
{tool.categories.map((category) => (
241-
<span
242-
key={category}
243-
className="bg-[#95D5B2] text-black px-2 py-1 rounded-full text-sm"
244-
>
245-
{category}
246-
</span>
247-
))}
230+
{tool.categories && (
231+
<div className="mt-2">
232+
<strong>Categories:</strong>
233+
<div className="flex flex-wrap gap-2 mt-1">
234+
{tool.categories.map((category) => (
235+
<span
236+
key={category}
237+
className="bg-[#95D5B2] text-black px-2 py-1 rounded-full text-sm"
238+
>
239+
{category}
240+
</span>
241+
))}
242+
</div>
248243
</div>
249-
</div>
244+
)}
250245
</Panel>
251246
</Collapse>
252247
</Card>
@@ -256,9 +251,9 @@ const EnAccessToolMap = ({ setIsModalOpen }: EnAccessToolMapProps) => {
256251
<Empty
257252
description={
258253
<span className="text-gray-600">
259-
{selectedCategories.length === 0
260-
? "Select a category to view tools"
261-
: "No tools found for the selected categories"}
254+
{selectedCategories.length === 0 && !searchTerm
255+
? "Select a category or search to view tools"
256+
: "No tools found for the selected filters"}
262257
</span>
263258
}
264259
/>

0 commit comments

Comments
 (0)