turash/bugulma/frontend/components/map/organizationIcons.ts
Damir Mukimov 6347f42e20
Consolidate repositories: Remove nested frontend .git and merge into main repository
- Remove nested git repository from bugulma/frontend/.git
- Add all frontend files to main repository tracking
- Convert from separate frontend/backend repos to unified monorepo
- Preserve all frontend code and development history as tracked files
- Eliminate nested repository complexity for simpler development workflow

This creates a proper monorepo structure with frontend and backend
coexisting in the same repository for easier development and deployment.
2025-11-25 06:02:57 +01:00

152 lines
3.7 KiB
TypeScript

import type { OrganizationSubtype } from '@/schemas/organizationSubtype.ts';
import {
Banknote,
Briefcase,
Building,
Building2,
Car,
Church,
Circle,
Construction,
Cpu,
Factory,
GraduationCap,
Heart,
Hotel,
Scissors,
ShoppingBag,
Theater,
Truck,
UtensilsCrossed,
Zap
} from 'lucide-react';
import React from 'react';
import { renderToString } from 'react-dom/server';
/**
* Database subtypes (actual values from database)
* These are the granular subtypes stored in the database
*/
export type DatabaseSubtype =
| 'retail'
| 'healthcare'
| 'educational'
| 'personal_services'
| 'food_beverage'
| 'automotive'
| 'religious'
| 'professional_services'
| 'energy'
| 'financial'
| 'government'
| 'manufacturing'
| 'cultural'
| 'hospitality'
| 'transportation'
| 'infrastructure'
| 'technology'
| 'other';
/**
* Get the appropriate Lucide icon component for an organization subtype
*/
function getLucideIconForSubtype(subtype: string): React.ComponentType<{ size?: number; color?: string }> {
const subtypeLower = subtype.toLowerCase().trim();
// Map database subtypes to Lucide icons
switch (subtypeLower) {
case 'retail':
return ShoppingBag;
case 'food_beverage':
return UtensilsCrossed;
case 'automotive':
return Car;
case 'personal_services':
return Scissors;
case 'professional_services':
return Briefcase;
case 'financial':
return Banknote;
case 'manufacturing':
return Factory;
case 'hospitality':
return Hotel;
case 'transportation':
return Truck;
case 'energy':
return Zap;
case 'technology':
return Cpu;
case 'commercial':
return Building2;
case 'cultural':
return Theater;
case 'government':
return Building;
case 'religious':
return Church;
case 'educational':
return GraduationCap;
case 'infrastructure':
return Construction;
case 'healthcare':
return Heart;
case 'other':
default:
return Circle;
}
}
/**
* Get organization icon SVG as string (for use in Leaflet DivIcon)
* Uses Lucide icons rendered to HTML strings
*/
export function getOrganizationIconSvg(
subtype: OrganizationSubtype | DatabaseSubtype | string | undefined | null,
size: number,
iconColor: string,
backgroundColor: string
): string {
// Debug logging in development
if (process.env.NODE_ENV === 'development') {
console.log('[organizationIcons] getOrganizationIconSvg called with:', {
subtype,
size,
iconColor,
backgroundColor,
sizeType: typeof size,
iconColorType: typeof iconColor,
backgroundColorType: typeof backgroundColor
});
}
// Ensure all parameters are valid with proper type checking
const safeSize = Math.max(1, Number.isFinite(size) && size > 0 ? size : 24);
const safeIconSize = safeSize * 0.5;
const subtypeValue = (subtype || '').toLowerCase().trim();
// Ensure colors are never undefined and are valid strings
const safeIconColor = (typeof iconColor === 'string' && iconColor.trim()) ? iconColor : '#ffffff';
const safeBackgroundColor = (typeof backgroundColor === 'string' && backgroundColor.trim()) ? backgroundColor : '#000000';
// Get the appropriate Lucide icon component
const IconComponent = getLucideIconForSubtype(subtypeValue);
// Render the icon to HTML string
const iconHtml = renderToString(
React.createElement(IconComponent, {
size: safeIconSize,
color: safeIconColor,
strokeWidth: 1.5
})
);
// Return the icon wrapped in an SVG container
return `
<svg width="${safeIconSize}" height="${safeIconSize}" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
${iconHtml}
</svg>
`;
}