mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
- 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.
284 lines
8.7 KiB
Python
284 lines
8.7 KiB
Python
#!/usr/bin/env python3
|
|
import os
|
|
import re
|
|
from pathlib import Path
|
|
|
|
# Mapping of old icon names to Lucide icon names
|
|
icon_mapping = {
|
|
# MiscIcons
|
|
'SearchIcon': 'Search',
|
|
'GlobeIcon': 'Globe',
|
|
'VerifiedIcon': 'BadgeCheck',
|
|
'ArrowLeftIcon': 'ArrowLeft',
|
|
'ArrowRightIcon': 'ArrowRight',
|
|
'ExternalLinkIcon': 'ExternalLink',
|
|
'FileTextIcon': 'FileText',
|
|
'MessageSquareIcon': 'MessageSquare',
|
|
'BriefcaseIcon': 'Briefcase',
|
|
'CarIcon': 'Car',
|
|
'ChurchIcon': 'Church',
|
|
'CoffeeIcon': 'Coffee',
|
|
'FuelIcon': 'Fuel',
|
|
'HeartIcon': 'Heart',
|
|
'HomeIcon': 'Home',
|
|
'ShoppingCartIcon': 'ShoppingCart',
|
|
'StethoscopeIcon': 'Stethoscope',
|
|
'SwimmingPoolIcon': 'Waves',
|
|
'WrenchIcon': 'Wrench',
|
|
'MapPinIcon': 'MapPin',
|
|
'PhoneIcon': 'Phone',
|
|
'PlusIcon': 'Plus',
|
|
'MailIcon': 'Mail',
|
|
'SortIcon': 'ArrowUpDown',
|
|
'DollarSignIcon': 'DollarSign',
|
|
'MenuIcon': 'Menu',
|
|
'LoginIcon': 'LogIn',
|
|
'NetworkIcon': 'Network',
|
|
'TrendingUpIcon': 'TrendingUp',
|
|
'ChevronDownIcon': 'ChevronDown',
|
|
'AlertTriangleIcon': 'AlertTriangle',
|
|
'ArrowDownIcon': 'ArrowDown',
|
|
'ArrowUpIcon': 'ArrowUp',
|
|
'BarChartIcon': 'BarChart3',
|
|
'CheckCircleIcon': 'CheckCircle',
|
|
'ClockIcon': 'Clock',
|
|
'FilterIcon': 'Filter',
|
|
'MinusIcon': 'Minus',
|
|
'TargetIcon': 'Target',
|
|
'TrendingDownIcon': 'TrendingDown',
|
|
'UsersIcon': 'Users',
|
|
'ZapIcon': 'Zap',
|
|
'AwardIcon': 'Award',
|
|
'GridIcon': 'Grid3X3',
|
|
'ListIcon': 'List',
|
|
'BeakerIcon': 'FlaskConical',
|
|
'ThermometerIcon': 'Thermometer',
|
|
'UserIcon': 'User',
|
|
'XCircleIcon': 'XCircle',
|
|
'XIcon': 'X',
|
|
|
|
# SectorIcons
|
|
'Building2Icon': 'Building2',
|
|
'FactoryIcon': 'Factory',
|
|
'WarehouseIcon': 'Warehouse',
|
|
|
|
# MapIcons
|
|
'ZoomInIcon': 'ZoomIn',
|
|
'ZoomOutIcon': 'ZoomOut',
|
|
'ResetViewIcon': 'RotateCw',
|
|
'HistoryIcon': 'History',
|
|
|
|
# StatusIcons
|
|
'ErrorIcon': 'XCircle',
|
|
|
|
# HeritageIcons
|
|
'BendIcon': 'GitBranch',
|
|
'TradeIcon': 'TrendingUp',
|
|
'QuillIcon': 'PenTool',
|
|
'RailwayIcon': 'Train',
|
|
'WarIcon': 'Swords',
|
|
'OilDerrickIcon': 'Fuel',
|
|
'MedalIcon': 'Medal',
|
|
'ArchitectureIcon': 'Landmark',
|
|
'CompassIcon': 'Compass',
|
|
'PeopleIcon': 'Users',
|
|
|
|
# SymbiosisIcons
|
|
'NeedIcon': 'LogIn',
|
|
'OfferIcon': 'LogOut',
|
|
|
|
# EditIcons
|
|
'EditIcon': 'Pencil',
|
|
'UploadCloudIcon': 'UploadCloud',
|
|
'EditTrashIcon': 'Trash2',
|
|
'EyeIcon': 'Eye',
|
|
|
|
# ChatIcons
|
|
'ChatBubbleIcon': 'MessageSquare',
|
|
'SendIcon': 'Send',
|
|
'CloseIcon': 'X',
|
|
'ChatTrashIcon': 'Trash2',
|
|
'CopyIcon': 'Copy',
|
|
'CheckIcon': 'Check',
|
|
'PaperclipIcon': 'Paperclip',
|
|
'MicIcon': 'Mic',
|
|
|
|
# StepsIcons
|
|
'ProfileIcon': 'User',
|
|
'SearchIconSteps': 'UserSearch',
|
|
'HandshakeIcon': 'Handshake',
|
|
|
|
# ThemeIcons
|
|
'SunIcon': 'Sun',
|
|
'MoonIcon': 'Moon',
|
|
}
|
|
|
|
def find_files_with_icons():
|
|
files = []
|
|
for root, dirs, filenames in os.walk('.'):
|
|
# Skip node_modules and other irrelevant directories
|
|
dirs[:] = [d for d in dirs if not d.startswith('.') and d != 'node_modules']
|
|
for filename in filenames:
|
|
if filename.endswith(('.tsx', '.ts')) and not filename.endswith('.d.ts'):
|
|
filepath = os.path.join(root, filename)
|
|
try:
|
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
if '@/components/icons/' in content:
|
|
files.append(filepath)
|
|
except:
|
|
pass
|
|
return files
|
|
|
|
def analyze_file(filepath):
|
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
changes = []
|
|
|
|
# Find icon imports
|
|
import_pattern = r'import\s*\{\s*([^}]+)\s*\}\s*from\s*[\'\"`][^\'\"`]*@\/components\/icons\/[^\'\"`]*[\'\"`];?'
|
|
import_matches = re.findall(import_pattern, content)
|
|
|
|
if import_matches:
|
|
lucide_icons = set()
|
|
for match in import_matches:
|
|
icons = [icon.strip() for icon in match.split(',') if icon.strip()]
|
|
for icon in icons:
|
|
if icon in icon_mapping:
|
|
lucide_icons.add(icon_mapping[icon])
|
|
|
|
if lucide_icons:
|
|
changes.append(f' Import: {sorted(lucide_icons)} from lucide-react')
|
|
|
|
# Find icon usage
|
|
usage_pattern = r'<(\w+Icon)\s*([^>]*)\/>'
|
|
usage_matches = re.findall(usage_pattern, content)
|
|
|
|
icon_usages = []
|
|
for icon_name, props in usage_matches:
|
|
if icon_name in icon_mapping:
|
|
icon_usages.append(f'{icon_name} -> {icon_mapping[icon_name]}')
|
|
|
|
if icon_usages:
|
|
changes.append(f' Usage: {icon_usages}')
|
|
|
|
return changes
|
|
|
|
def apply_changes(filepath):
|
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
original_content = content
|
|
|
|
# Replace icon imports
|
|
import_pattern = r'import\s*\{\s*([^}]+)\s*\}\s*from\s*[\'\"`][^\'\"`]*@\/components\/icons\/[^\'\"`]*[\'\"`];?'
|
|
def replace_import(match):
|
|
icons_part = match.group(1)
|
|
icons = [icon.strip() for icon in icons_part.split(',') if icon.strip()]
|
|
lucide_icons = [icon_mapping[icon] for icon in icons if icon in icon_mapping]
|
|
|
|
if lucide_icons:
|
|
return f"import {{ {', '.join(sorted(set(lucide_icons)))} }} from 'lucide-react';"
|
|
return match
|
|
|
|
content = re.sub(import_pattern, replace_import, content)
|
|
|
|
# Replace icon usage - convert to className based approach
|
|
def replace_icon_usage(content):
|
|
# Find all icon usages
|
|
pattern = r'<(\w+Icon)(\s[^>]*)?/>'
|
|
def replacer(match):
|
|
icon_name = match.group(1)
|
|
props = match.group(2) or ''
|
|
|
|
if icon_name in icon_mapping:
|
|
lucide_name = icon_mapping[icon_name]
|
|
|
|
# Extract size and variant, default to 'sm' and 'default'
|
|
size = 'sm'
|
|
variant = 'default'
|
|
|
|
# Simple prop extraction
|
|
size_match = re.search(r'size=["\'](\w+)["\']', props)
|
|
if size_match:
|
|
size = size_match.group(1)
|
|
|
|
variant_match = re.search(r'variant=["\'](\w+)["\']', props)
|
|
if variant_match:
|
|
variant = variant_match.group(1)
|
|
|
|
# Size mapping
|
|
size_classes = {
|
|
'xs': 'h-3 w-3',
|
|
'sm': 'h-4 w-4',
|
|
'md': 'h-5 w-5',
|
|
'lg': 'h-6 w-6',
|
|
'xl': 'h-8 w-8',
|
|
'2xl': 'h-10 w-10',
|
|
}
|
|
|
|
# Variant mapping
|
|
variant_classes = {
|
|
'default': 'text-current',
|
|
'muted': 'text-muted-foreground',
|
|
'primary': 'text-primary',
|
|
'destructive': 'text-destructive',
|
|
'success': 'text-green-600',
|
|
'warning': 'text-yellow-600',
|
|
}
|
|
|
|
class_name = f"{size_classes.get(size, size_classes['sm'])} {variant_classes.get(variant, variant_classes['default'])}"
|
|
|
|
# Remove size and variant from props, keep other props
|
|
other_props = re.sub(r'\s*size=["\']\w+["\']', '', props)
|
|
other_props = re.sub(r'\s*variant=["\']\w+["\']', '', other_props).strip()
|
|
|
|
if other_props:
|
|
return f'<{lucide_name} className="{class_name}" {other_props} />'
|
|
else:
|
|
return f'<{lucide_name} className="{class_name}" />'
|
|
|
|
return match.group(0)
|
|
|
|
return re.sub(pattern, replacer, content)
|
|
|
|
content = replace_icon_usage(content)
|
|
|
|
if content != original_content:
|
|
with open(filepath, 'w', encoding='utf-8') as f:
|
|
f.write(content)
|
|
print(f'Updated: {filepath}')
|
|
return True
|
|
|
|
return False
|
|
|
|
def main():
|
|
import sys
|
|
|
|
if len(sys.argv) > 1 and sys.argv[1] == '--apply':
|
|
print('=== APPLYING CHANGES ===')
|
|
files = find_files_with_icons()
|
|
updated_count = 0
|
|
for filepath in sorted(files):
|
|
if apply_changes(filepath):
|
|
updated_count += 1
|
|
|
|
print(f'\n=== SUMMARY ===')
|
|
print(f'Updated {updated_count} out of {len(files)} files')
|
|
else:
|
|
print('=== DRY RUN: Files that would be changed ===')
|
|
files = find_files_with_icons()
|
|
for filepath in sorted(files):
|
|
print(f'\n{filepath}:')
|
|
changes = analyze_file(filepath)
|
|
for change in changes:
|
|
print(change)
|
|
|
|
print(f'\n=== SUMMARY ===')
|
|
print(f'Found {len(files)} files with icon imports that need updating')
|
|
print('Run with --apply to actually make the changes')
|
|
|
|
if __name__ == '__main__':
|
|
main()
|