Created
August 5, 2025 16:06
-
-
Save RageshAntonyHM/ad14c0fa58588b4d180f83ed155a7ba0 to your computer and use it in GitHub Desktop.
Patent Search
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React, { useState, useEffect, useMemo } from 'react'; | |
| import { Search, FileText, Lightbulb, AlertCircle, Clock, Tag } from 'lucide-react'; | |
| const PatentSearchSystem = () => { | |
| const [query, setQuery] = useState(''); | |
| const [suggestions, setSuggestions] = useState([]); | |
| const [corrections, setCorrections] = useState([]); | |
| const [expansions, setExpansions] = useState([]); | |
| const [results, setResults] = useState([]); | |
| const [isSearching, setIsSearching] = useState(false); | |
| const [selectedPartitions, setSelectedPartitions] = useState([]); | |
| // Mock patent data with topics and classifications | |
| const mockPatents = useMemo(() => [ | |
| { | |
| id: 'US001', | |
| title: 'Autonomous Vehicle Navigation System', | |
| abstract: 'A system for autonomous vehicle navigation using machine learning algorithms and sensor fusion technology.', | |
| topics: ['autonomous', 'vehicle', 'navigation', 'machine learning', 'sensor'], | |
| class: 'Transportation', | |
| citations: 15, | |
| importance: 0.9 | |
| }, | |
| { | |
| id: 'US002', | |
| title: 'Electric Car Battery Management', | |
| abstract: 'Battery management system for electric vehicles with improved charging efficiency and thermal control.', | |
| topics: ['electric', 'car', 'battery', 'charging', 'thermal'], | |
| class: 'Transportation', | |
| citations: 8, | |
| importance: 0.7 | |
| }, | |
| { | |
| id: 'US003', | |
| title: 'Automobile Safety Enhancement', | |
| abstract: 'Safety system for automobiles including collision detection and automatic braking mechanisms.', | |
| topics: ['automobile', 'safety', 'collision', 'braking', 'detection'], | |
| class: 'Transportation', | |
| citations: 12, | |
| importance: 0.8 | |
| }, | |
| { | |
| id: 'US004', | |
| title: 'Medical Device Monitoring System', | |
| abstract: 'IoT-based monitoring system for medical devices in healthcare facilities.', | |
| topics: ['medical', 'device', 'monitoring', 'iot', 'healthcare'], | |
| class: 'Medical', | |
| citations: 20, | |
| importance: 0.95 | |
| }, | |
| { | |
| id: 'US005', | |
| title: 'Wireless Communication Protocol', | |
| abstract: 'Enhanced wireless communication protocol for 5G networks with improved latency and bandwidth.', | |
| topics: ['wireless', 'communication', 'protocol', '5g', 'network'], | |
| class: 'Communications', | |
| citations: 25, | |
| importance: 1.0 | |
| }, | |
| { | |
| id: 'US006', | |
| title: 'Smart Home Automation System', | |
| abstract: 'Intelligent home automation system using AI for energy optimization and user comfort.', | |
| topics: ['smart', 'home', 'automation', 'ai', 'energy'], | |
| class: 'Technology', | |
| citations: 10, | |
| importance: 0.75 | |
| } | |
| ], []); | |
| // Topic model for suggestions | |
| const topicModel = useMemo(() => ({ | |
| 'Transportation': ['vehicle', 'car', 'automobile', 'navigation', 'autonomous', 'electric', 'battery', 'safety'], | |
| 'Medical': ['medical', 'device', 'healthcare', 'monitoring', 'patient', 'diagnosis', 'treatment'], | |
| 'Communications': ['wireless', 'communication', 'network', '5g', 'protocol', 'signal', 'transmission'], | |
| 'Technology': ['smart', 'ai', 'automation', 'iot', 'system', 'algorithm', 'software'] | |
| }), []); | |
| // Synonyms for query expansion | |
| const synonyms = useMemo(() => ({ | |
| 'car': ['automobile', 'vehicle', 'auto'], | |
| 'vehicle': ['car', 'automobile', 'auto'], | |
| 'automobile': ['car', 'vehicle', 'auto'], | |
| 'smart': ['intelligent', 'automated', 'advanced'], | |
| 'ai': ['artificial intelligence', 'machine learning', 'intelligent'], | |
| 'wireless': ['radio', 'cellular', 'mobile'], | |
| 'battery': ['cell', 'power source', 'energy storage'] | |
| }), []); | |
| // Calculate edit distance for error correction | |
| const editDistance = (str1, str2) => { | |
| const matrix = Array(str2.length + 1).fill(null).map(() => Array(str1.length + 1).fill(null)); | |
| for (let i = 0; i <= str1.length; i++) matrix[0][i] = i; | |
| for (let j = 0; j <= str2.length; j++) matrix[j][0] = j; | |
| for (let j = 1; j <= str2.length; j++) { | |
| for (let i = 1; i <= str1.length; i++) { | |
| const indicator = str1[i - 1] === str2[j - 1] ? 0 : 1; | |
| matrix[j][i] = Math.min( | |
| matrix[j][i - 1] + 1, | |
| matrix[j - 1][i] + 1, | |
| matrix[j - 1][i - 1] + indicator | |
| ); | |
| } | |
| } | |
| return matrix[str2.length][str1.length]; | |
| }; | |
| // Error correction function | |
| const findCorrections = (word) => { | |
| const allWords = new Set(); | |
| mockPatents.forEach(patent => { | |
| patent.topics.forEach(topic => allWords.add(topic)); | |
| patent.title.toLowerCase().split(' ').forEach(w => allWords.add(w)); | |
| }); | |
| return Array.from(allWords) | |
| .filter(w => editDistance(word.toLowerCase(), w.toLowerCase()) <= 2 && w !== word.toLowerCase()) | |
| .slice(0, 3); | |
| }; | |
| // Topic-based suggestion function | |
| const findTopicSuggestions = (queryWords) => { | |
| const topicScores = {}; | |
| Object.entries(topicModel).forEach(([topic, words]) => { | |
| topicScores[topic] = queryWords.reduce((score, word) => { | |
| return score + (words.includes(word.toLowerCase()) ? 1 : 0); | |
| }, 0); | |
| }); | |
| const bestTopic = Object.entries(topicScores).reduce((a, b) => | |
| topicScores[a[0]] > topicScores[b[0]] ? a : b | |
| )[0]; | |
| return topicModel[bestTopic]?.filter(word => | |
| !queryWords.map(w => w.toLowerCase()).includes(word) | |
| ).slice(0, 5) || []; | |
| }; | |
| // Query expansion function | |
| const findExpansions = (queryWords) => { | |
| const expanded = new Set(); | |
| queryWords.forEach(word => { | |
| const syns = synonyms[word.toLowerCase()] || []; | |
| syns.forEach(syn => expanded.add(syn)); | |
| }); | |
| return Array.from(expanded).slice(0, 5); | |
| }; | |
| // Patent ranking function | |
| const rankPatents = (patents, queryWords) => { | |
| return patents.map(patent => { | |
| const queryLower = queryWords.map(w => w.toLowerCase()); | |
| // Keyword relevancy (TF-IDF simplified) | |
| const titleWords = patent.title.toLowerCase().split(' '); | |
| const abstractWords = patent.abstract.toLowerCase().split(' '); | |
| const allWords = [...titleWords, ...abstractWords]; | |
| const keywordScore = queryLower.reduce((score, word) => { | |
| const tf = allWords.filter(w => w.includes(word)).length; | |
| return score + (tf > 0 ? Math.log(1 + tf) : 0); | |
| }, 0); | |
| // Topic relevancy | |
| const topicScore = queryLower.reduce((score, word) => { | |
| return score + (patent.topics.includes(word) ? 1 : 0); | |
| }, 0); | |
| // Combined score | |
| const totalScore = 0.3 * patent.importance + 0.4 * keywordScore + 0.3 * topicScore; | |
| return { ...patent, score: totalScore }; | |
| }).sort((a, b) => b.score - a.score); | |
| }; | |
| // Partition selection | |
| const selectPartitions = (queryWords) => { | |
| const partitionScores = {}; | |
| Object.keys(topicModel).forEach(partition => { | |
| partitionScores[partition] = queryWords.reduce((score, word) => { | |
| return score + (topicModel[partition].includes(word.toLowerCase()) ? 1 : 0); | |
| }, 0); | |
| }); | |
| return Object.entries(partitionScores) | |
| .sort(([,a], [,b]) => b - a) | |
| .slice(0, 3) | |
| .map(([partition]) => partition); | |
| }; | |
| // Handle query changes | |
| useEffect(() => { | |
| if (query.length > 0) { | |
| const words = query.split(' ').filter(w => w.length > 0); | |
| const lastWord = words[words.length - 1]; | |
| // Error correction | |
| if (lastWord.length > 2) { | |
| setCorrections(findCorrections(lastWord)); | |
| } | |
| // Topic suggestions | |
| setSuggestions(findTopicSuggestions(words)); | |
| // Query expansion | |
| setExpansions(findExpansions(words)); | |
| // Partition selection | |
| setSelectedPartitions(selectPartitions(words)); | |
| } else { | |
| setSuggestions([]); | |
| setCorrections([]); | |
| setExpansions([]); | |
| setSelectedPartitions([]); | |
| } | |
| }, [query]); | |
| // Handle search | |
| const handleSearch = () => { | |
| if (!query.trim()) return; | |
| setIsSearching(true); | |
| // Simulate search delay | |
| setTimeout(() => { | |
| const queryWords = query.split(' ').filter(w => w.length > 0); | |
| // Filter patents by selected partitions | |
| const relevantPatents = mockPatents.filter(patent => | |
| selectedPartitions.length === 0 || selectedPartitions.includes(patent.class) | |
| ); | |
| const rankedResults = rankPatents(relevantPatents, queryWords); | |
| setResults(rankedResults.slice(0, 10)); | |
| setIsSearching(false); | |
| }, 1000); | |
| }; | |
| const handleSuggestionClick = (suggestion) => { | |
| const words = query.split(' '); | |
| words.push(suggestion); | |
| setQuery(words.join(' ')); | |
| }; | |
| return ( | |
| <div className="max-w-6xl mx-auto p-6 bg-gray-50 min-h-screen"> | |
| <div className="bg-white rounded-lg shadow-lg p-8 mb-8"> | |
| <h1 className="text-3xl font-bold text-gray-800 mb-2 flex items-center"> | |
| <FileText className="mr-3 text-blue-600" /> | |
| User-Friendly Patent Search System | |
| </h1> | |
| <p className="text-gray-600 mb-6"> | |
| Advanced patent search with error correction, topic suggestions, and query expansion | |
| </p> | |
| {/* Search Interface */} | |
| <div className="relative mb-6"> | |
| <div className="flex"> | |
| <input | |
| type="text" | |
| value={query} | |
| onChange={(e) => setQuery(e.target.value)} | |
| placeholder="Enter patent search keywords..." | |
| className="flex-1 px-4 py-3 border border-gray-300 rounded-l-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" | |
| onKeyPress={(e) => e.key === 'Enter' && handleSearch()} | |
| /> | |
| <button | |
| onClick={handleSearch} | |
| disabled={isSearching || !query.trim()} | |
| className="bg-blue-600 text-white px-6 py-3 rounded-r-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center" | |
| > | |
| {isSearching ? <Clock className="animate-spin mr-2" size={20} /> : <Search className="mr-2" size={20} />} | |
| Search | |
| </button> | |
| </div> | |
| {/* Selected Partitions */} | |
| {selectedPartitions.length > 0 && ( | |
| <div className="mt-2 flex flex-wrap gap-2"> | |
| <span className="text-sm text-gray-600">Selected partitions:</span> | |
| {selectedPartitions.map(partition => ( | |
| <span key={partition} className="bg-blue-100 text-blue-800 px-2 py-1 rounded text-sm"> | |
| {partition} | |
| </span> | |
| ))} | |
| </div> | |
| )} | |
| </div> | |
| {/* Suggestions Panel */} | |
| {(suggestions.length > 0 || corrections.length > 0 || expansions.length > 0) && ( | |
| <div className="grid md:grid-cols-3 gap-4 mb-6"> | |
| {/* Error Corrections */} | |
| {corrections.length > 0 && ( | |
| <div className="bg-red-50 p-4 rounded-lg"> | |
| <h3 className="font-semibold text-red-800 mb-2 flex items-center"> | |
| <AlertCircle size={16} className="mr-2" /> | |
| Corrections | |
| </h3> | |
| <div className="flex flex-wrap gap-2"> | |
| {corrections.map(correction => ( | |
| <button | |
| key={correction} | |
| onClick={() => handleSuggestionClick(correction)} | |
| className="bg-red-100 text-red-800 px-2 py-1 rounded text-sm hover:bg-red-200 transition-colors" | |
| > | |
| {correction} | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| )} | |
| {/* Topic Suggestions */} | |
| {suggestions.length > 0 && ( | |
| <div className="bg-blue-50 p-4 rounded-lg"> | |
| <h3 className="font-semibold text-blue-800 mb-2 flex items-center"> | |
| <Tag size={16} className="mr-2" /> | |
| Topic Suggestions | |
| </h3> | |
| <div className="flex flex-wrap gap-2"> | |
| {suggestions.map(suggestion => ( | |
| <button | |
| key={suggestion} | |
| onClick={() => handleSuggestionClick(suggestion)} | |
| className="bg-blue-100 text-blue-800 px-2 py-1 rounded text-sm hover:bg-blue-200 transition-colors" | |
| > | |
| {suggestion} | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| )} | |
| {/* Query Expansions */} | |
| {expansions.length > 0 && ( | |
| <div className="bg-green-50 p-4 rounded-lg"> | |
| <h3 className="font-semibold text-green-800 mb-2 flex items-center"> | |
| <Lightbulb size={16} className="mr-2" /> | |
| Expansions | |
| </h3> | |
| <div className="flex flex-wrap gap-2"> | |
| {expansions.map(expansion => ( | |
| <button | |
| key={expansion} | |
| onClick={() => handleSuggestionClick(expansion)} | |
| className="bg-green-100 text-green-800 px-2 py-1 rounded text-sm hover:bg-green-200 transition-colors" | |
| > | |
| {expansion} | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| )} | |
| </div> | |
| {/* Search Results */} | |
| {results.length > 0 && ( | |
| <div className="bg-white rounded-lg shadow-lg p-6"> | |
| <h2 className="text-2xl font-bold text-gray-800 mb-4"> | |
| Search Results ({results.length} patents found) | |
| </h2> | |
| <div className="space-y-4"> | |
| {results.map(patent => ( | |
| <div key={patent.id} className="border border-gray-200 rounded-lg p-4 hover:shadow-md transition-shadow"> | |
| <div className="flex justify-between items-start mb-2"> | |
| <h3 className="text-lg font-semibold text-blue-800 hover:text-blue-600 cursor-pointer"> | |
| {patent.title} | |
| </h3> | |
| <div className="text-right text-sm text-gray-500"> | |
| <div>Patent ID: {patent.id}</div> | |
| <div>Score: {patent.score.toFixed(3)}</div> | |
| </div> | |
| </div> | |
| <p className="text-gray-700 mb-3">{patent.abstract}</p> | |
| <div className="flex flex-wrap items-center gap-4 text-sm text-gray-600"> | |
| <span className="bg-gray-100 px-2 py-1 rounded"> | |
| Class: {patent.class} | |
| </span> | |
| <span>Citations: {patent.citations}</span> | |
| <span>Importance: {patent.importance}</span> | |
| </div> | |
| <div className="mt-2 flex flex-wrap gap-1"> | |
| {patent.topics.map(topic => ( | |
| <span key={topic} className="bg-blue-100 text-blue-800 px-2 py-1 rounded-full text-xs"> | |
| {topic} | |
| </span> | |
| ))} | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| )} | |
| {/* No Results */} | |
| {query && results.length === 0 && !isSearching && ( | |
| <div className="bg-white rounded-lg shadow-lg p-8 text-center"> | |
| <FileText size={48} className="mx-auto text-gray-400 mb-4" /> | |
| <h3 className="text-xl font-semibold text-gray-700 mb-2">No patents found</h3> | |
| <p className="text-gray-500">Try using the suggested corrections, topics, or expansions above.</p> | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| }; | |
| export default PatentSearchSystem; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment