From 836850d82ca219438a9b11da00eed1a70766ba62 Mon Sep 17 00:00:00 2001 From: trivedikavya Date: Sun, 15 Feb 2026 12:04:18 +0530 Subject: [PATCH 1/3] refactor: remove AI integration and project section/form (Pivot Implementation) --- package-lock.json | 36 - package.json | 1 - src/App.tsx | 8 - src/components/AIFeatureIntro.tsx | 35 - src/components/AISettingsDialog.tsx | 392 ----------- src/components/AssistantLauncher.tsx | 83 --- src/components/ElementEditor.tsx | 44 +- src/components/ProjectCard.tsx | 345 ---------- src/components/ProjectsSection.tsx | 157 ----- src/components/QuickStartGuide.tsx | 7 +- src/components/SubmitSection.tsx | 351 ---------- .../readme-editor/APIKeySettings.tsx | 252 ------- src/components/readme-editor/ChatPanel.tsx | 361 ---------- src/components/readme-editor/ReadmeEditor.tsx | 425 ++---------- src/components/ui/ai-textarea.tsx | 162 ----- src/pages/AIEditorIntro.tsx | 16 - src/pages/DragDropEditor.tsx | 76 --- src/pages/Home.tsx | 113 ++- src/services/geminiService.ts | 285 -------- src/services/readmeAIService.ts | 291 -------- src/services/webSearchService.ts | 643 ------------------ src/types/FeatureRequest.ts | 15 - 22 files changed, 117 insertions(+), 3981 deletions(-) delete mode 100644 src/components/AIFeatureIntro.tsx delete mode 100644 src/components/AISettingsDialog.tsx delete mode 100644 src/components/AssistantLauncher.tsx delete mode 100644 src/components/ProjectCard.tsx delete mode 100644 src/components/ProjectsSection.tsx delete mode 100644 src/components/SubmitSection.tsx delete mode 100644 src/components/readme-editor/APIKeySettings.tsx delete mode 100644 src/components/readme-editor/ChatPanel.tsx delete mode 100644 src/components/ui/ai-textarea.tsx delete mode 100644 src/pages/AIEditorIntro.tsx delete mode 100644 src/services/geminiService.ts delete mode 100644 src/services/readmeAIService.ts delete mode 100644 src/services/webSearchService.ts delete mode 100644 src/types/FeatureRequest.ts diff --git a/package-lock.json b/package-lock.json index d3e20ed..fa963fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,6 @@ "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", - "@google/generative-ai": "^0.24.1", "@hookform/resolvers": "^5.1.0", "@monaco-editor/react": "^4.7.0", "@octokit/rest": "^22.0.1", @@ -831,7 +830,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1110,15 +1108,6 @@ "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", "license": "MIT" }, - "node_modules/@google/generative-ai": { - "version": "0.24.1", - "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz", - "integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@hookform/resolvers": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.1.1.tgz", @@ -8311,7 +8300,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8328,7 +8316,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8345,7 +8332,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8362,7 +8348,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8379,7 +8364,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8396,7 +8380,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8413,7 +8396,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8430,7 +8412,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8447,7 +8428,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8464,7 +8444,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8481,7 +8460,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8498,7 +8476,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8515,7 +8492,6 @@ "cpu": [ "mips64el" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8532,7 +8508,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8549,7 +8524,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8566,7 +8540,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8583,7 +8556,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8600,7 +8572,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8617,7 +8588,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8634,7 +8604,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8651,7 +8620,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8668,7 +8636,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8685,7 +8652,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8702,7 +8668,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -8719,7 +8684,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ diff --git a/package.json b/package.json index 8b4baf7..3d26a5a 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,6 @@ "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", - "@google/generative-ai": "^0.24.1", "@hookform/resolvers": "^5.1.0", "@monaco-editor/react": "^4.7.0", "@octokit/rest": "^22.0.1", diff --git a/src/App.tsx b/src/App.tsx index ae83053..b3e16ab 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,8 +7,6 @@ import ScrollToTop from "./components/ScrollToTop"; import ScrollRestoration from "./components/ScrollRestoration"; import Elements from "./pages/Elements"; -import ProjectsSection from "./components/ProjectsSection"; -import SubmitSection from "./components/SubmitSection"; import DragDropEditor from "./pages/DragDropEditor"; import TemplateLibraryPage from "./pages/TemplateLibraryPage"; import ComingSoon from "./pages/ComingSoon"; @@ -19,10 +17,8 @@ import TermsOfService from "./pages/TermsOfService"; import AboutUs from "./components/_components/about"; import { ThemeProvider } from "./components/theme-provider"; import { Toaster } from "./components/ui/sonner"; -import ReadmeGenerator from "./components/generator/Readme-generator"; import ReadmeEditor from "./components/readme-editor/ReadmeEditor"; import MarkdownEditor from "./pages/MarkdownEditor"; -import AIEditorIntro from "./pages/AIEditorIntro"; import Cursortrail from "./Cursortrail"; const queryClient = new QueryClient(); @@ -52,18 +48,14 @@ export default function App() { } /> } /> - } /> - } /> } /> } /> } /> } /> } /> - } /> } /> } /> - } /> } /> diff --git a/src/components/AIFeatureIntro.tsx b/src/components/AIFeatureIntro.tsx deleted file mode 100644 index 8cbd691..0000000 --- a/src/components/AIFeatureIntro.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { Alert, AlertDescription } from '@/components/ui/alert'; -import { Button } from '@/components/ui/button'; -import { Sparkles, Settings, ArrowRight } from 'lucide-react'; - -interface AIFeatureIntroProps { - onOpenSettings: () => void; - isVisible: boolean; -} - -export function AIFeatureIntro({ onOpenSettings, isVisible }: AIFeatureIntroProps) { - if (!isVisible) return null; - - return ( - - - -
- AI Enhancement Available! -

- Configure your Gemini API key to enable AI-powered text enhancement and generation in text fields. -

-
- -
-
- ); -} diff --git a/src/components/AISettingsDialog.tsx b/src/components/AISettingsDialog.tsx deleted file mode 100644 index f4984df..0000000 --- a/src/components/AISettingsDialog.tsx +++ /dev/null @@ -1,392 +0,0 @@ -import { useState, useEffect } from 'react'; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, -} from '@/components/ui/dialog'; -import { Button } from '@/components/ui/button'; -import { Input } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; -import { Badge } from '@/components/ui/badge'; -import { Alert, AlertDescription } from '@/components/ui/alert'; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; -import { Eye, EyeOff, ExternalLink, Key, Sparkles, Trash2, Github } from 'lucide-react'; -import { geminiService } from '@/services/geminiService'; -import { toast } from 'sonner'; - -interface AISettingsDialogProps { - isOpen: boolean; - onClose: () => void; -} - -export function AISettingsDialog({ isOpen, onClose }: AISettingsDialogProps) { - const [apiKey, setApiKey] = useState(''); - const [showApiKey, setShowApiKey] = useState(false); - const [isTestingConnection, setIsTestingConnection] = useState(false); - const [hasExistingKey, setHasExistingKey] = useState(false); - const [creativity, setCreativity] = useState<'concise' | 'balanced' | 'detailed'>('balanced'); - const [style, setStyle] = useState<'professional' | 'casual' | 'technical' | 'creative' | 'recruiter' | 'maintainer'>('professional'); - const [githubToken, setGithubToken] = useState(''); - const [showGithubToken, setShowGithubToken] = useState(false); - - useEffect(() => { - if (isOpen) { - const existingKey = geminiService.getApiKey(); - setHasExistingKey(!!existingKey); - setApiKey(existingKey || ''); - - const settings = geminiService.getSettings(); - setCreativity(settings.creativity); - setStyle(settings.style); - - const storedToken = localStorage.getItem('github-token'); - setGithubToken(storedToken || ''); - } - }, [isOpen]); - - const handleSave = async () => { - if (!apiKey.trim() && !githubToken.trim()) { - toast.error('Please enter either a Gemini API key or a GitHub token'); - return; - } - - try { - setIsTestingConnection(true); - - // Save Gemini Key if provided - if (apiKey.trim()) { - geminiService.setApiKey(apiKey.trim()); - } else { - geminiService.clearApiKey(); - } - - // Save the AI settings - geminiService.setSettings({ creativity, style }); - - // Save GitHub Token - if (githubToken.trim()) { - localStorage.setItem('github-token', githubToken.trim()); - } else { - localStorage.removeItem('github-token'); - } - - // Test Gemini with a simple request ONLY if a key was provided - if (apiKey.trim()) { - await geminiService.enhanceText('Hello world', 'test'); - } - - toast.success('Settings saved successfully!'); - onClose(); - } catch (error) { - toast.error('Invalid API key. Please check your key and try again.'); - console.error('API key validation failed:', error); - } finally { - setIsTestingConnection(false); - } - }; - - const handleClearKey = () => { - geminiService.clearApiKey(); - setApiKey(''); - setHasExistingKey(false); - toast.success('API key cleared successfully'); - }; - - const openGeminiConsole = () => { - window.open('https://aistudio.google.com/apikey', '_blank'); - }; - - return ( - - - - - - AI Settings - - - Configure your Gemini API key and AI preferences to enable intelligent text enhancement and generation. - - - -
- - - - - API Key - - - - Preferences - - - - GitHub - - - - - - - - Get your free API key from Google AI Studio. The key is stored locally in your browser and never sent to our servers. - - - -
-
- - -
- -
- setApiKey(e.target.value)} - placeholder="Enter your Gemini API key..." - className="pr-16" - /> -
- - {hasExistingKey && ( - - )} -
-
-
- -
-

• API usage follows Google's terms of service

-

• Free tier includes generous usage limits

-

• Your data is processed by Google's AI services

-
-
- - -
-
- -

How detailed should AI responses be?

- -
- -
- -

What tone should the AI use?

- -
- -
-

Preview Example:

-

- {creativity === 'concise' && style === 'professional' && "I'm a passionate developer focused on creating efficient solutions."} - {creativity === 'concise' && style === 'casual' && "Hey! I'm a developer who loves building cool stuff."} - {creativity === 'concise' && style === 'technical' && "Software engineer specializing in full-stack development."} - {creativity === 'concise' && style === 'creative' && "Code artist crafting digital experiences."} - - {creativity === 'balanced' && style === 'professional' && "I'm a passionate software developer with expertise in modern web technologies. I focus on creating efficient, scalable solutions that deliver real value to users."} - {creativity === 'balanced' && style === 'casual' && "Hey there! I'm a developer who loves building awesome apps and learning new tech. I enjoy solving problems and creating things that people actually want to use."} - {creativity === 'balanced' && style === 'technical' && "Software engineer with expertise in React, Node.js, and cloud architecture. I specialize in building scalable applications with focus on performance optimization."} - {creativity === 'balanced' && style === 'creative' && "Digital architect weaving code into experiences. I transform ideas into interactive realities using cutting-edge technologies and creative problem-solving."} - {creativity === 'balanced' && style === 'recruiter' && "Led a team of 5 developers to ship critical features, resulting in a 30% increase in user retention. Implemented CI/CD pipelines that reduced deployment time by 50%."} - {creativity === 'balanced' && style === 'maintainer' && "A lightweight, flexible library for managing global state in React applications. We welcome contributions of all kinds, from bug fixes to documentation improvements."} - {creativity === 'concise' && style === 'recruiter' && "Delivered 30% performance boost and reduced build times by 50%."} - {creativity === 'concise' && style === 'maintainer' && "Open source library for easy React state management. PRs welcome!"} - - - {creativity === 'detailed' && style === 'professional' && "I'm a passionate software developer with extensive experience in modern web technologies and full-stack development. I specialize in creating efficient, scalable solutions that deliver measurable value to businesses and users. My approach combines technical expertise with strategic thinking to build applications that not only function flawlessly but also drive real results."} - {creativity === 'detailed' && style === 'casual' && "Hey there! I'm a developer who absolutely loves building awesome applications and diving deep into new technologies. I get excited about solving complex problems and creating things that people genuinely enjoy using. Whether it's a sleek frontend or robust backend, I pour my heart into every project and love collaborating with teams to bring ideas to life."} - {creativity === 'detailed' && style === 'technical' && "Software engineer with comprehensive expertise in React, Node.js, TypeScript, and cloud architecture patterns. I specialize in building high-performance, scalable applications with emphasis on code quality, testing strategies, and deployment automation. My experience spans microservices architecture, database optimization, and implementing CI/CD pipelines for enterprise-level applications."} - {creativity === 'detailed' && style === 'creative' && "Digital architect and code poet, weaving elegant solutions from the threads of imagination and logic. I transform abstract concepts into tangible, interactive experiences using cutting-edge technologies as my palette. My journey involves crafting not just applications, but digital stories that resonate with users and push the boundaries of what's possible in the digital realm."} - {creativity === 'detailed' && style === 'recruiter' && "Spearheaded the migration to microservices architecture, managing a budget of $50k and a team of 5. This initiative improved system reliability by 99.9% and increased user engagement metrics by 30% quarter-over-quarter. My focus is on delivering scalable, high-impact technical solutions that drive business growth."} - {creativity === 'detailed' && style === 'maintainer' && "Empower your React applications with this battle-tested state management solution used by over 10k developers. We represent a diverse community of contributors and maintainers committed to high-quality code. Detailed contribution guidelines are provided to help you get started quickly with your first Pull Request."} -

-
-
-
- - - - - - Configure your GitHub Personal Access Token to enable "Export to Gist" and other GitHub features. - Make sure the token has the gist scope. - - - -
-
- - -
- -
- setGithubToken(e.target.value)} - placeholder="ghp_xxxxxxxxxxxx" - className="pr-10" - /> - -
-
- -
-

• Tokens are stored only in your local browser storage

-

• Used for "Export to Gist" and GitHub elements

-
-
-
- -
- -
- - Text Enhancement - - - Content Generation - - - Smart Suggestions - -
-
-
- - - - - -
-
- ); -} diff --git a/src/components/AssistantLauncher.tsx b/src/components/AssistantLauncher.tsx deleted file mode 100644 index 9f67477..0000000 --- a/src/components/AssistantLauncher.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { useState, useRef, useEffect } from "react"; -import { Sparkles } from "lucide-react"; -import { ReadmeAnalysis } from "@/components/ReadmeAnalysis"; -import type { ElementType } from "@/types/elements"; -import type { SuggestionAction } from "@/types/branding"; - -interface AssistantLauncherProps { - elements: ElementType[]; - isEditorActive: boolean; - onApplySuggestion: (elementId: string, newContent: string) => void; - onApplyAction?: (action: SuggestionAction) => void; - onAddElement?: (element: ElementType) => void; - onRemoveElement?: (elementId: string) => void; - onReorderElement?: (elementId: string, direction: 'up' | 'down') => void; - backToTopVisible?: boolean; -} - -export function AssistantLauncher({ - elements, - isEditorActive, - onApplySuggestion, - onApplyAction, - onAddElement, - onRemoveElement, - onReorderElement, - backToTopVisible = false, -}: AssistantLauncherProps) { - const [open, setOpen] = useState(false); - -const panelRef = useRef(null); -useEffect(() => { - if (!open) return; - - const handleClickOutside = (event: MouseEvent) => { - const target = event.target as HTMLElement | null; - if (!target) return; - - if (panelRef.current?.contains(target)) return; - if (target.closest('.radix-portal')) return; - if (target.closest('[role="listbox"]')) return; - - setOpen(false); - }; - - document.addEventListener("mousedown", handleClickOutside); - return () => { - document.removeEventListener("mousedown", handleClickOutside); - }; -}, [open]); - - - return ( - <> - {/* Floating button */} - - - {/* Assistant panel */} - {open && ( -
- -
- )} - - ); -} diff --git a/src/components/ElementEditor.tsx b/src/components/ElementEditor.tsx index 1cc09b0..9226d55 100644 --- a/src/components/ElementEditor.tsx +++ b/src/components/ElementEditor.tsx @@ -9,7 +9,7 @@ import { } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { Label } from '@/components/ui/label'; -import { AITextarea } from '@/components/ui/ai-textarea'; +import { Textarea } from '@/components/ui/textarea'; // Changed from AITextarea to standard Textarea import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import type { ElementType } from '@/types/elements'; @@ -22,7 +22,7 @@ interface ElementEditorProps { export function ElementEditor({ element, isOpen, onClose, onSave }: ElementEditorProps) { const [editedElement, setEditedElement] = useState(null); - // FIX: Local state for the technologies string to allow typing spaces and commas + // Local state for the technologies string to allow typing spaces and commas const [techString, setTechString] = useState(''); useEffect(() => { @@ -46,14 +46,14 @@ export function ElementEditor({ element, isOpen, onClose, onSave }: ElementEdito setEditedElement(prev => prev ? { ...prev, ...updates } as ElementType : null); }; - const shouldShowAITextarea = (elementType: string) => { + // Logic to determine if a content input should be shown + const shouldShowContentInput = (elementType: string) => { const excludedTypes = ['git-contribution', 'divider', 'image']; return !excludedTypes.includes(elementType); }; return ( - {/* z-[200] ensures it is above the DialogOverlay (z-150) */} Edit {editedElement.type} Element @@ -62,28 +62,17 @@ export function ElementEditor({ element, isOpen, onClose, onSave }: ElementEdito - {/* Inner scroll container prevents portaled Select menus from being clipped */}
{/* Common Fields */} - {editedElement.type !== 'divider' && editedElement.type !== 'git-contribution' && editedElement.type !== 'image' && ( + {shouldShowContentInput(editedElement.type) && (
- {shouldShowAITextarea(editedElement.type) && ( - updateElement({ content: value })} - placeholder="Enter content..." - aiContext={`${editedElement.type} element`} - showGenerateOption={['text', 'description', 'title', 'header', 'banner'].includes(editedElement.type)} - generationType={ - editedElement.type === 'description' ? 'about' : - editedElement.type === 'title' ? 'summary' : - editedElement.type === 'text' ? 'custom' : - 'project' - } - /> - )} +