consolidation
This commit is contained in:
parent
1e7c1a2468
commit
b7fea4f31f
@ -1,4 +1,6 @@
|
|||||||
---
|
---
|
||||||
|
import { createToolSlug } from '../utils/toolHelpers.js';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
toolName: string;
|
toolName: string;
|
||||||
context: 'card' | 'modal-primary' | 'modal-secondary';
|
context: 'card' | 'modal-primary' | 'modal-secondary';
|
||||||
@ -7,12 +9,8 @@ export interface Props {
|
|||||||
|
|
||||||
const { toolName, context, size = 'small' } = Astro.props;
|
const { toolName, context, size = 'small' } = Astro.props;
|
||||||
|
|
||||||
// Create URL-safe slug from tool name
|
// AFTER: Single line with centralized function
|
||||||
const toolSlug = toolName.toLowerCase()
|
const toolSlug = createToolSlug(toolName);
|
||||||
.replace(/[^a-z0-9\s-]/g, '') // Remove special characters
|
|
||||||
.replace(/\s+/g, '-') // Replace spaces with hyphens
|
|
||||||
.replace(/-+/g, '-') // Remove duplicate hyphens
|
|
||||||
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
|
|
||||||
|
|
||||||
const iconSize = size === 'small' ? '14' : '16';
|
const iconSize = size === 'small' ? '14' : '16';
|
||||||
---
|
---
|
||||||
|
@ -286,26 +286,12 @@ domains.forEach((domain: any) => {
|
|||||||
|
|
||||||
// ===== SHARING FUNCTIONALITY =====
|
// ===== SHARING FUNCTIONALITY =====
|
||||||
|
|
||||||
// Create tool slug from name (same logic as ShareButton.astro)
|
// REMOVED: createToolSlug function - now using window.createToolSlug
|
||||||
function createToolSlug(toolName) {
|
// REMOVED: findTool function - now using window.findToolByIdentifier
|
||||||
return toolName.toLowerCase()
|
|
||||||
.replace(/[^a-z0-9\s-]/g, '') // Remove special characters
|
|
||||||
.replace(/\s+/g, '-') // Replace spaces with hyphens
|
|
||||||
.replace(/-+/g, '-') // Remove duplicate hyphens
|
|
||||||
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find tool by name or slug
|
|
||||||
function findTool(identifier) {
|
|
||||||
return toolsData.find(tool =>
|
|
||||||
tool.name === identifier ||
|
|
||||||
createToolSlug(tool.name) === identifier.toLowerCase()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate share URLs
|
// Generate share URLs
|
||||||
function generateShareURL(toolName, view, modal = null) {
|
function generateShareURL(toolName, view, modal = null) {
|
||||||
const toolSlug = createToolSlug(toolName);
|
const toolSlug = window.createToolSlug(toolName);
|
||||||
const baseUrl = window.location.origin + window.location.pathname;
|
const baseUrl = window.location.origin + window.location.pathname;
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.set('tool', toolSlug);
|
params.set('tool', toolSlug);
|
||||||
@ -517,10 +503,7 @@ domains.forEach((domain: any) => {
|
|||||||
elements.description.textContent = tool.description;
|
elements.description.textContent = tool.description;
|
||||||
|
|
||||||
// Badges
|
// Badges
|
||||||
const hasValidProjectUrl = tool.projectUrl !== undefined &&
|
const hasValidProjectUrl = window.isToolHosted(tool);
|
||||||
tool.projectUrl !== null &&
|
|
||||||
tool.projectUrl !== "" &&
|
|
||||||
tool.projectUrl.trim() !== "";
|
|
||||||
|
|
||||||
elements.badges.innerHTML = '';
|
elements.badges.innerHTML = '';
|
||||||
if (isConcept) {
|
if (isConcept) {
|
||||||
@ -645,7 +628,7 @@ domains.forEach((domain: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tool.knowledgebase === true) {
|
if (tool.knowledgebase === true) {
|
||||||
const kbId = tool.name.toLowerCase().replace(/\s+/g, '-');
|
const kbId = window.createToolSlug(tool.name);
|
||||||
linksHTML += `
|
linksHTML += `
|
||||||
<a href="/knowledgebase#kb-${kbId}" class="btn btn-secondary" style="width: 100%; margin-top: 0.5rem;">
|
<a href="/knowledgebase#kb-${kbId}" class="btn btn-secondary" style="width: 100%; margin-top: 0.5rem;">
|
||||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
|
||||||
@ -665,7 +648,7 @@ domains.forEach((domain: any) => {
|
|||||||
// ===== POPULATE SHARE BUTTON =====
|
// ===== POPULATE SHARE BUTTON =====
|
||||||
const shareButtonContainer = document.getElementById(`share-button-${modalType}`);
|
const shareButtonContainer = document.getElementById(`share-button-${modalType}`);
|
||||||
if (shareButtonContainer) {
|
if (shareButtonContainer) {
|
||||||
const toolSlug = createToolSlug(tool.name);
|
const toolSlug = window.createToolSlug(tool.name);
|
||||||
shareButtonContainer.innerHTML = `
|
shareButtonContainer.innerHTML = `
|
||||||
<button class="share-btn share-btn--medium"
|
<button class="share-btn share-btn--medium"
|
||||||
data-tool-name="${tool.name}"
|
data-tool-name="${tool.name}"
|
||||||
@ -822,10 +805,7 @@ domains.forEach((domain: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const isMethod = tool.type === 'method';
|
const isMethod = tool.type === 'method';
|
||||||
const hasValidProjectUrl = tool.projectUrl !== undefined &&
|
const hasValidProjectUrl = window.isToolHosted(tool);
|
||||||
tool.projectUrl !== null &&
|
|
||||||
tool.projectUrl !== "" &&
|
|
||||||
tool.projectUrl.trim() !== "";
|
|
||||||
|
|
||||||
const domains = tool.domains || [];
|
const domains = tool.domains || [];
|
||||||
const phases = tool.phases || [];
|
const phases = tool.phases || [];
|
||||||
|
@ -23,6 +23,9 @@ const { title, description = 'CC24-Guide - A comprehensive directory of digital
|
|||||||
<!-- CONSOLIDATED: Load theme script -->
|
<!-- CONSOLIDATED: Load theme script -->
|
||||||
<script src="/src/scripts/theme.js"></script>
|
<script src="/src/scripts/theme.js"></script>
|
||||||
|
|
||||||
|
<!-- CONSOLIDATED: Load tool utilities -->
|
||||||
|
<script src="/src/scripts/tool-utils.js"></script>
|
||||||
|
|
||||||
<!-- CONSOLIDATED: Load client-side auth utilities -->
|
<!-- CONSOLIDATED: Load client-side auth utilities -->
|
||||||
<script src="/src/scripts/client-auth.js"></script>
|
<script src="/src/scripts/client-auth.js"></script>
|
||||||
|
|
||||||
|
@ -217,22 +217,8 @@ const tools = data.tools;
|
|||||||
checkboxWrappers.forEach(wrapper => wrapper.style.display = 'flex');
|
checkboxWrappers.forEach(wrapper => wrapper.style.display = 'flex');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create tool slug from name
|
// REMOVED: createToolSlug function - now using window.createToolSlug
|
||||||
function createToolSlug(toolName) {
|
// REMOVED: findTool function - now using window.findToolByIdentifier
|
||||||
return toolName.toLowerCase()
|
|
||||||
.replace(/[^a-z0-9\s-]/g, '')
|
|
||||||
.replace(/\s+/g, '-')
|
|
||||||
.replace(/-+/g, '-')
|
|
||||||
.replace(/^-|-$/g, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find tool by name or slug
|
|
||||||
function findTool(identifier) {
|
|
||||||
return window.toolsData.find(tool =>
|
|
||||||
tool.name === identifier ||
|
|
||||||
createToolSlug(tool.name) === identifier.toLowerCase()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Navigation functions for sharing
|
// Navigation functions for sharing
|
||||||
window.navigateToGrid = function(toolName) {
|
window.navigateToGrid = function(toolName) {
|
||||||
@ -337,8 +323,8 @@ const tools = data.tools;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the tool by name or slug
|
// Find the tool by name or slug using global function
|
||||||
const tool = findTool(toolParam);
|
const tool = window.findToolByIdentifier(window.toolsData, toolParam);
|
||||||
if (!tool) {
|
if (!tool) {
|
||||||
console.warn('Shared tool not found:', toolParam);
|
console.warn('Shared tool not found:', toolParam);
|
||||||
return;
|
return;
|
||||||
|
52
src/scripts/tool-utils.ts
Normal file
52
src/scripts/tool-utils.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Client-side tool utilities
|
||||||
|
// Mirrors server-side function logic for consistency
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a URL-safe slug from a tool name (client-side version)
|
||||||
|
*/
|
||||||
|
function createToolSlug(toolName) {
|
||||||
|
if (!toolName || typeof toolName !== 'string') {
|
||||||
|
console.warn('[toolUtils] Invalid toolName provided:', toolName);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return toolName.toLowerCase()
|
||||||
|
.replace(/[^a-z0-9\s-]/g, '') // Remove special characters
|
||||||
|
.replace(/\s+/g, '-') // Replace spaces with hyphens
|
||||||
|
.replace(/-+/g, '-') // Remove duplicate hyphens
|
||||||
|
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a tool by name or slug from tools array (client-side version)
|
||||||
|
*/
|
||||||
|
function findToolByIdentifier(tools, identifier) {
|
||||||
|
if (!identifier || !Array.isArray(tools)) return undefined;
|
||||||
|
|
||||||
|
return tools.find(tool =>
|
||||||
|
tool.name === identifier ||
|
||||||
|
createToolSlug(tool.name) === identifier.toLowerCase()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if tool has a valid project URL (hosted on CC24 server)
|
||||||
|
*/
|
||||||
|
function isToolHosted(tool) {
|
||||||
|
return tool.projectUrl !== undefined &&
|
||||||
|
tool.projectUrl !== null &&
|
||||||
|
tool.projectUrl !== "" &&
|
||||||
|
tool.projectUrl.trim() !== "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make functions available globally for existing code compatibility
|
||||||
|
window.createToolSlug = createToolSlug;
|
||||||
|
window.findToolByIdentifier = findToolByIdentifier;
|
||||||
|
window.isToolHosted = isToolHosted;
|
||||||
|
|
||||||
|
// Export for module usage
|
||||||
|
if (typeof module !== 'undefined' && module.exports) {
|
||||||
|
module.exports = { createToolSlug, findToolByIdentifier, isToolHosted };
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Tool utilities loaded');
|
68
src/utils/toolHelpers.ts
Normal file
68
src/utils/toolHelpers.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* Tool utility functions for consistent tool operations across the app
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface Tool {
|
||||||
|
name: string;
|
||||||
|
type?: 'software' | 'method' | 'concept';
|
||||||
|
projectUrl?: string | null;
|
||||||
|
license?: string;
|
||||||
|
knowledgebase?: boolean;
|
||||||
|
domains?: string[];
|
||||||
|
phases?: string[];
|
||||||
|
platforms?: string[];
|
||||||
|
skillLevel?: string;
|
||||||
|
description?: string;
|
||||||
|
tags?: string[];
|
||||||
|
related_concepts?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a URL-safe slug from a tool name
|
||||||
|
* Used for URLs, IDs, and file names consistently across the app
|
||||||
|
*/
|
||||||
|
export function createToolSlug(toolName: string): string {
|
||||||
|
if (!toolName || typeof toolName !== 'string') {
|
||||||
|
console.warn('[toolHelpers] Invalid toolName provided to createToolSlug:', toolName);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return toolName.toLowerCase()
|
||||||
|
.replace(/[^a-z0-9\s-]/g, '') // Remove special characters
|
||||||
|
.replace(/\s+/g, '-') // Replace spaces with hyphens
|
||||||
|
.replace(/-+/g, '-') // Remove duplicate hyphens
|
||||||
|
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a tool by name or slug from tools array
|
||||||
|
*/
|
||||||
|
export function findToolByIdentifier(tools: Tool[], identifier: string): Tool | undefined {
|
||||||
|
if (!identifier || !Array.isArray(tools)) return undefined;
|
||||||
|
|
||||||
|
return tools.find(tool =>
|
||||||
|
tool.name === identifier ||
|
||||||
|
createToolSlug(tool.name) === identifier.toLowerCase()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if tool has a valid project URL (hosted on CC24 server)
|
||||||
|
*/
|
||||||
|
export function isToolHosted(tool: Tool): boolean {
|
||||||
|
return tool.projectUrl !== undefined &&
|
||||||
|
tool.projectUrl !== null &&
|
||||||
|
tool.projectUrl !== "" &&
|
||||||
|
tool.projectUrl.trim() !== "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines tool category for styling/logic
|
||||||
|
*/
|
||||||
|
export function getToolCategory(tool: Tool): 'concept' | 'method' | 'hosted' | 'oss' | 'proprietary' {
|
||||||
|
if (tool.type === 'concept') return 'concept';
|
||||||
|
if (tool.type === 'method') return 'method';
|
||||||
|
if (isToolHosted(tool)) return 'hosted';
|
||||||
|
if (tool.license && tool.license !== 'Proprietary') return 'oss';
|
||||||
|
return 'proprietary';
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user