Skip to content

Commit 35aed90

Browse files
author
mcarbonell
committed
feat: Páginas de categorías por perfil de usuario (developers, designers, writers, etc)
1 parent 5970463 commit 35aed90

18 files changed

+801
-1
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
"main": "generate-site.js",
66
"scripts": {
77
"prebuild": "node scripts/bump-version.js",
8-
"build": "node generate-site.js",
8+
"build": "node generate-site.js && node scripts/generate-category-pages.js",
99
"build:old": "node generate-tools.js",
1010
"build:tools": "node scripts/generate-tools-json.js",
11+
"build:categories": "node scripts/generate-category-pages.js",
1112
"test": "node tests/automated-qa.js",
1213
"test:old": "node tests/run-all-tests.js",
1314
"serve": "npx http-server web -p 8000",

scripts/generate-category-pages.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
const fs = require('fs').promises;
2+
const path = require('path');
3+
4+
const siteConfig = require('../site-config.json');
5+
const projectRoot = path.join(__dirname, '..', 'web');
6+
const templatePath = path.join(projectRoot, 'templates', 'category-base.html');
7+
const audienceMappingPath = path.join(projectRoot, 'data', 'audience-mapping.json');
8+
const toolsIndexPath = path.join(projectRoot, 'data', 'tools-index-unified.json');
9+
10+
const categories = [
11+
{ id: 'developers', slug: { es: 'desarrolladores', en: 'developers' }, icon: '💻' },
12+
{ id: 'designers', slug: { es: 'disenadores', en: 'designers' }, icon: '🎨' },
13+
{ id: 'writers', slug: { es: 'escritores', en: 'writers' }, icon: '✍️' },
14+
{ id: 'data-analysts', slug: { es: 'analistas-datos', en: 'data-analysts' }, icon: '📊' },
15+
{ id: 'marketers', slug: { es: 'marketing', en: 'marketers' }, icon: '📱' },
16+
{ id: 'productivity', slug: { es: 'productividad', en: 'productivity' }, icon: '⚡' },
17+
{ id: 'ai-tools', slug: { es: 'ia', en: 'ai' }, icon: '🤖' }
18+
];
19+
20+
const categoryNames = {
21+
developers: { es: 'Desarrolladores', en: 'Developers' },
22+
designers: { es: 'Diseñadores', en: 'Designers' },
23+
writers: { es: 'Escritores', en: 'Writers' },
24+
'data-analysts': { es: 'Analistas de Datos', en: 'Data Analysts' },
25+
marketers: { es: 'Marketing', en: 'Marketers' },
26+
productivity: { es: 'Productividad', en: 'Productivity' },
27+
'ai-tools': { es: 'IA', en: 'AI' }
28+
};
29+
30+
const categoryDescriptions = {
31+
developers: {
32+
es: 'Herramientas esenciales para programadores y desarrolladores web',
33+
en: 'Essential tools for programmers and web developers'
34+
},
35+
designers: {
36+
es: 'Herramientas para diseñadores gráficos y creativos',
37+
en: 'Tools for graphic designers and creatives'
38+
},
39+
writers: {
40+
es: 'Herramientas para escritores, editores y creadores de contenido',
41+
en: 'Tools for writers, editors and content creators'
42+
},
43+
'data-analysts': {
44+
es: 'Herramientas para análisis y conversión de datos',
45+
en: 'Tools for data analysis and conversion'
46+
},
47+
marketers: {
48+
es: 'Herramientas para profesionales del marketing digital',
49+
en: 'Tools for digital marketing professionals'
50+
},
51+
productivity: {
52+
es: 'Herramientas para mejorar tu productividad diaria',
53+
en: 'Tools to improve your daily productivity'
54+
},
55+
'ai-tools': {
56+
es: 'Herramientas potenciadas con inteligencia artificial',
57+
en: 'AI-powered tools'
58+
}
59+
};
60+
61+
async function generateCategoryPages() {
62+
console.log('🎯 Generando páginas de categorías...\n');
63+
64+
const template = await fs.readFile(templatePath, 'utf8');
65+
const audienceMapping = JSON.parse(await fs.readFile(audienceMappingPath, 'utf8'));
66+
const toolsData = JSON.parse(await fs.readFile(toolsIndexPath, 'utf8'));
67+
68+
for (const category of categories) {
69+
const toolIds = audienceMapping[category.id] || [];
70+
71+
for (const lang of siteConfig.languages) {
72+
const toolsIndexLangPath = path.join(projectRoot, 'data', `tools-index-${lang}.json`);
73+
const toolsIndex = JSON.parse(await fs.readFile(toolsIndexLangPath, 'utf8'));
74+
75+
const categoryTools = toolsIndex.filter(tool => toolIds.includes(tool.id));
76+
77+
let toolsGrid = '';
78+
categoryTools.forEach(tool => {
79+
const toolUrl = lang === siteConfig.defaultLanguage ? tool.slug : tool.slug;
80+
toolsGrid += `
81+
<div class="col-md-6 col-lg-4">
82+
<div class="card h-100">
83+
<div class="card-body">
84+
<h5 class="card-title">${tool.icon} ${tool.title}</h5>
85+
<p class="card-text">${tool.description}</p>
86+
<a href="${lang === siteConfig.defaultLanguage ? '/' : '/' + lang + '/'}${toolUrl}" class="btn btn-primary">${lang === 'es' ? 'Abrir' : 'Open'}</a>
87+
</div>
88+
</div>
89+
</div>`;
90+
});
91+
92+
let html = template;
93+
html = html.replace(/{{lang}}/g, lang);
94+
html = html.replace(/{{category_name}}/g, categoryNames[category.id][lang]);
95+
html = html.replace(/{{category_description}}/g, categoryDescriptions[category.id][lang]);
96+
html = html.replace(/{{category_icon}}/g, category.icon);
97+
html = html.replace(/{{tools_grid}}/g, toolsGrid);
98+
html = html.replace(/{{view_all_tools}}/g, lang === 'es' ? 'Ver todas las herramientas' : 'View all tools');
99+
html = html.replace(/{{css_path}}/g, lang === siteConfig.defaultLanguage ? '' : '../');
100+
html = html.replace(/{{home_path}}/g, lang === siteConfig.defaultLanguage ? '/' : '/' + lang + '/');
101+
html = html.replace(/{{hreflang_tags}}/g, '');
102+
103+
const outputDir = lang === siteConfig.defaultLanguage ? projectRoot : path.join(projectRoot, lang);
104+
const fileName = `${category.slug[lang]}.html`;
105+
const outputPath = path.join(outputDir, fileName);
106+
107+
await fs.writeFile(outputPath, html, 'utf8');
108+
console.log(`✅ ${lang}/${fileName}`);
109+
}
110+
}
111+
112+
console.log('\n✨ Páginas de categorías generadas!');
113+
}
114+
115+
generateCategoryPages().catch(console.error);

web/ai.html

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>AI - FastTools</title>
7+
<meta name="description" content="AI-powered tools">
8+
9+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
10+
<link rel="stylesheet" href="css/style-v2.css">
11+
<link rel="icon" href="favicon.svg" type="image/svg+xml">
12+
</head>
13+
<body>
14+
<nav class="navbar navbar-expand-lg navbar-light bg-white border-bottom sticky-top">
15+
<div class="container">
16+
<a class="navbar-brand fw-bold" href="/">
17+
<span class="text-primary">Fast</span>Tools
18+
</a>
19+
</div>
20+
</nav>
21+
22+
<div class="container my-5">
23+
<div class="text-center mb-5">
24+
<h1 class="display-5 fw-bold mb-3">🤖 AI</h1>
25+
<p class="lead text-muted">AI-powered tools</p>
26+
</div>
27+
28+
<div class="row g-4">
29+
30+
</div>
31+
32+
<div class="text-center mt-5">
33+
<a href="/" class="btn btn-outline-primary">View all tools</a>
34+
</div>
35+
</div>
36+
37+
<footer class="bg-light py-4 mt-5">
38+
<div class="container text-center text-muted">
39+
<p class="mb-0">© 2024 FastTools</p>
40+
</div>
41+
</footer>
42+
43+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
44+
</body>
45+
</html>

web/data-analysts.html

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Data Analysts - FastTools</title>
7+
<meta name="description" content="Tools for data analysis and conversion">
8+
9+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
10+
<link rel="stylesheet" href="css/style-v2.css">
11+
<link rel="icon" href="favicon.svg" type="image/svg+xml">
12+
</head>
13+
<body>
14+
<nav class="navbar navbar-expand-lg navbar-light bg-white border-bottom sticky-top">
15+
<div class="container">
16+
<a class="navbar-brand fw-bold" href="/">
17+
<span class="text-primary">Fast</span>Tools
18+
</a>
19+
</div>
20+
</nav>
21+
22+
<div class="container my-5">
23+
<div class="text-center mb-5">
24+
<h1 class="display-5 fw-bold mb-3">📊 Data Analysts</h1>
25+
<p class="lead text-muted">Tools for data analysis and conversion</p>
26+
</div>
27+
28+
<div class="row g-4">
29+
30+
</div>
31+
32+
<div class="text-center mt-5">
33+
<a href="/" class="btn btn-outline-primary">View all tools</a>
34+
</div>
35+
</div>
36+
37+
<footer class="bg-light py-4 mt-5">
38+
<div class="container text-center text-muted">
39+
<p class="mb-0">© 2024 FastTools</p>
40+
</div>
41+
</footer>
42+
43+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
44+
</body>
45+
</html>

web/data/audience-mapping.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"developers": ["json-formatter", "csv-json", "yaml-json", "xml-json", "toml-json", "base64", "url-encoder", "html-encoder", "hash-calculator", "diff"],
3+
"designers": ["image-resizer", "convert-image", "image-cropper", "image-compressor", "color-palette-generator", "color-picker-converter", "exif-viewer-cleaner", "edit-image-ai"],
4+
"writers": ["text-cleaner", "lorem-ipsum-generator", "diff", "summarize-text-ai", "improve-text-ai", "chat-ai"],
5+
"data-analysts": ["json-formatter", "csv-json", "yaml-json", "xml-json", "toml-json", "pdf-to-text"],
6+
"marketers": ["qr-generator", "image-resizer", "convert-image", "image-compressor", "color-palette-generator", "chat-ai"],
7+
"productivity": ["stopwatch-timer", "password-generator", "qr-generator", "text-cleaner", "pdf-to-text", "merge-pdfs", "split-pdf", "compress-pdf"],
8+
"ai-tools": ["chat-ai", "summarize-text-ai", "improve-text-ai", "chat-pdf", "edit-image-ai"]
9+
}

web/designers.html

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Designers - FastTools</title>
7+
<meta name="description" content="Tools for graphic designers and creatives">
8+
9+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
10+
<link rel="stylesheet" href="css/style-v2.css">
11+
<link rel="icon" href="favicon.svg" type="image/svg+xml">
12+
</head>
13+
<body>
14+
<nav class="navbar navbar-expand-lg navbar-light bg-white border-bottom sticky-top">
15+
<div class="container">
16+
<a class="navbar-brand fw-bold" href="/">
17+
<span class="text-primary">Fast</span>Tools
18+
</a>
19+
</div>
20+
</nav>
21+
22+
<div class="container my-5">
23+
<div class="text-center mb-5">
24+
<h1 class="display-5 fw-bold mb-3">🎨 Designers</h1>
25+
<p class="lead text-muted">Tools for graphic designers and creatives</p>
26+
</div>
27+
28+
<div class="row g-4">
29+
30+
</div>
31+
32+
<div class="text-center mt-5">
33+
<a href="/" class="btn btn-outline-primary">View all tools</a>
34+
</div>
35+
</div>
36+
37+
<footer class="bg-light py-4 mt-5">
38+
<div class="container text-center text-muted">
39+
<p class="mb-0">© 2024 FastTools</p>
40+
</div>
41+
</footer>
42+
43+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
44+
</body>
45+
</html>

web/developers.html

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Developers - FastTools</title>
7+
<meta name="description" content="Essential tools for programmers and web developers">
8+
9+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
10+
<link rel="stylesheet" href="css/style-v2.css">
11+
<link rel="icon" href="favicon.svg" type="image/svg+xml">
12+
</head>
13+
<body>
14+
<nav class="navbar navbar-expand-lg navbar-light bg-white border-bottom sticky-top">
15+
<div class="container">
16+
<a class="navbar-brand fw-bold" href="/">
17+
<span class="text-primary">Fast</span>Tools
18+
</a>
19+
</div>
20+
</nav>
21+
22+
<div class="container my-5">
23+
<div class="text-center mb-5">
24+
<h1 class="display-5 fw-bold mb-3">💻 Developers</h1>
25+
<p class="lead text-muted">Essential tools for programmers and web developers</p>
26+
</div>
27+
28+
<div class="row g-4">
29+
30+
</div>
31+
32+
<div class="text-center mt-5">
33+
<a href="/" class="btn btn-outline-primary">View all tools</a>
34+
</div>
35+
</div>
36+
37+
<footer class="bg-light py-4 mt-5">
38+
<div class="container text-center text-muted">
39+
<p class="mb-0">© 2024 FastTools</p>
40+
</div>
41+
</footer>
42+
43+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
44+
</body>
45+
</html>

web/es/analistas-datos.html

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!DOCTYPE html>
2+
<html lang="es">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Analistas de Datos - FastTools</title>
7+
<meta name="description" content="Herramientas para análisis y conversión de datos">
8+
9+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
10+
<link rel="stylesheet" href="../css/style-v2.css">
11+
<link rel="icon" href="../favicon.svg" type="image/svg+xml">
12+
</head>
13+
<body>
14+
<nav class="navbar navbar-expand-lg navbar-light bg-white border-bottom sticky-top">
15+
<div class="container">
16+
<a class="navbar-brand fw-bold" href="/es/">
17+
<span class="text-primary">Fast</span>Tools
18+
</a>
19+
</div>
20+
</nav>
21+
22+
<div class="container my-5">
23+
<div class="text-center mb-5">
24+
<h1 class="display-5 fw-bold mb-3">📊 Analistas de Datos</h1>
25+
<p class="lead text-muted">Herramientas para análisis y conversión de datos</p>
26+
</div>
27+
28+
<div class="row g-4">
29+
30+
</div>
31+
32+
<div class="text-center mt-5">
33+
<a href="/es/" class="btn btn-outline-primary">Ver todas las herramientas</a>
34+
</div>
35+
</div>
36+
37+
<footer class="bg-light py-4 mt-5">
38+
<div class="container text-center text-muted">
39+
<p class="mb-0">© 2024 FastTools</p>
40+
</div>
41+
</footer>
42+
43+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
44+
</body>
45+
</html>

0 commit comments

Comments
 (0)