consolidation
This commit is contained in:
		
							parent
							
								
									1e7c1a2468
								
							
						
					
					
						commit
						b7fea4f31f
					
				@ -1,4 +1,6 @@
 | 
			
		||||
---
 | 
			
		||||
import { createToolSlug } from '../utils/toolHelpers.js';
 | 
			
		||||
 | 
			
		||||
export interface Props {
 | 
			
		||||
  toolName: string;
 | 
			
		||||
  context: 'card' | 'modal-primary' | 'modal-secondary';
 | 
			
		||||
@ -7,12 +9,8 @@ export interface Props {
 | 
			
		||||
 | 
			
		||||
const { toolName, context, size = 'small' } = Astro.props;
 | 
			
		||||
 | 
			
		||||
// Create URL-safe slug from tool name
 | 
			
		||||
const toolSlug = 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
 | 
			
		||||
// AFTER: Single line with centralized function
 | 
			
		||||
const toolSlug = createToolSlug(toolName);
 | 
			
		||||
 | 
			
		||||
const iconSize = size === 'small' ? '14' : '16';
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
@ -286,26 +286,12 @@ domains.forEach((domain: any) => {
 | 
			
		||||
 | 
			
		||||
  // ===== SHARING FUNCTIONALITY =====
 | 
			
		||||
  
 | 
			
		||||
  // Create tool slug from name (same logic as ShareButton.astro)
 | 
			
		||||
  function createToolSlug(toolName) {
 | 
			
		||||
    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()
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  // REMOVED: createToolSlug function - now using window.createToolSlug
 | 
			
		||||
  // REMOVED: findTool function - now using window.findToolByIdentifier
 | 
			
		||||
 | 
			
		||||
  // Generate share URLs
 | 
			
		||||
  function generateShareURL(toolName, view, modal = null) {
 | 
			
		||||
    const toolSlug = createToolSlug(toolName);
 | 
			
		||||
    const toolSlug = window.createToolSlug(toolName);
 | 
			
		||||
    const baseUrl = window.location.origin + window.location.pathname;
 | 
			
		||||
    const params = new URLSearchParams();
 | 
			
		||||
    params.set('tool', toolSlug);
 | 
			
		||||
@ -517,10 +503,7 @@ domains.forEach((domain: any) => {
 | 
			
		||||
    elements.description.textContent = tool.description;
 | 
			
		||||
 | 
			
		||||
    // Badges
 | 
			
		||||
    const hasValidProjectUrl = tool.projectUrl !== undefined && 
 | 
			
		||||
                              tool.projectUrl !== null && 
 | 
			
		||||
                              tool.projectUrl !== "" && 
 | 
			
		||||
                              tool.projectUrl.trim() !== "";
 | 
			
		||||
    const hasValidProjectUrl = window.isToolHosted(tool);
 | 
			
		||||
 | 
			
		||||
    elements.badges.innerHTML = '';
 | 
			
		||||
    if (isConcept) {
 | 
			
		||||
@ -645,7 +628,7 @@ domains.forEach((domain: any) => {
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (tool.knowledgebase === true) {
 | 
			
		||||
      const kbId = tool.name.toLowerCase().replace(/\s+/g, '-');
 | 
			
		||||
      const kbId = window.createToolSlug(tool.name);
 | 
			
		||||
      linksHTML += `
 | 
			
		||||
        <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;">
 | 
			
		||||
@ -665,7 +648,7 @@ domains.forEach((domain: any) => {
 | 
			
		||||
    // ===== POPULATE SHARE BUTTON =====
 | 
			
		||||
    const shareButtonContainer = document.getElementById(`share-button-${modalType}`);
 | 
			
		||||
    if (shareButtonContainer) {
 | 
			
		||||
      const toolSlug = createToolSlug(tool.name);
 | 
			
		||||
      const toolSlug = window.createToolSlug(tool.name);
 | 
			
		||||
      shareButtonContainer.innerHTML = `
 | 
			
		||||
        <button class="share-btn share-btn--medium" 
 | 
			
		||||
                data-tool-name="${tool.name}" 
 | 
			
		||||
@ -822,10 +805,7 @@ domains.forEach((domain: any) => {
 | 
			
		||||
          }
 | 
			
		||||
          
 | 
			
		||||
          const isMethod = tool.type === 'method';
 | 
			
		||||
          const hasValidProjectUrl = tool.projectUrl !== undefined && 
 | 
			
		||||
                                    tool.projectUrl !== null && 
 | 
			
		||||
                                    tool.projectUrl !== "" && 
 | 
			
		||||
                                    tool.projectUrl.trim() !== "";
 | 
			
		||||
          const hasValidProjectUrl = window.isToolHosted(tool);
 | 
			
		||||
          
 | 
			
		||||
          const domains = tool.domains || [];
 | 
			
		||||
          const phases = tool.phases || [];
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,9 @@ const { title, description = 'CC24-Guide - A comprehensive directory of digital
 | 
			
		||||
  <!-- CONSOLIDATED: Load theme 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 -->
 | 
			
		||||
  <script src="/src/scripts/client-auth.js"></script>
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
@ -217,22 +217,8 @@ const tools = data.tools;
 | 
			
		||||
      checkboxWrappers.forEach(wrapper => wrapper.style.display = 'flex');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create tool slug from name
 | 
			
		||||
    function createToolSlug(toolName) {
 | 
			
		||||
      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()
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    // REMOVED: createToolSlug function - now using window.createToolSlug
 | 
			
		||||
    // REMOVED: findTool function - now using window.findToolByIdentifier
 | 
			
		||||
 | 
			
		||||
    // Navigation functions for sharing
 | 
			
		||||
    window.navigateToGrid = function(toolName) {
 | 
			
		||||
@ -337,8 +323,8 @@ const tools = data.tools;
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // Find the tool by name or slug
 | 
			
		||||
      const tool = findTool(toolParam);
 | 
			
		||||
      // Find the tool by name or slug using global function
 | 
			
		||||
      const tool = window.findToolByIdentifier(window.toolsData, toolParam);
 | 
			
		||||
      if (!tool) {
 | 
			
		||||
        console.warn('Shared tool not found:', toolParam);
 | 
			
		||||
        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