Spaces:
Running
Running
Upload 85 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- assets/@google-4tyssLU_.js +0 -0
- assets/@google-4tyssLU_.js.map +0 -0
- assets/AiCodeExplainer-C0HS8Khr.js +11 -0
- assets/AiCodeExplainer-C0HS8Khr.js.map +1 -0
- assets/AiCodeMigrator-D1DuZhlC.js +8 -0
- assets/AiCodeMigrator-D1DuZhlC.js.map +1 -0
- assets/AiCodingChallenge-BQSkuis0.js +2 -0
- assets/AiCodingChallenge-BQSkuis0.js.map +1 -0
- assets/AiCommandCenter-BVcknEjZ.js +3 -0
- assets/AiCommandCenter-BVcknEjZ.js.map +1 -0
- assets/AiCommitGenerator-CtJxujtN.js +14 -0
- assets/AiCommitGenerator-CtJxujtN.js.map +1 -0
- assets/AiFeatureBuilder-P_ujuQBI.js +6 -0
- assets/AiFeatureBuilder-P_ujuQBI.js.map +1 -0
- assets/AiStyleTransfer-C0syujQ9.js +4 -0
- assets/AiStyleTransfer-C0syujQ9.js.map +1 -0
- assets/AiUnitTestGenerator-DnqoljB0.js +5 -0
- assets/AiUnitTestGenerator-DnqoljB0.js.map +1 -0
- assets/ChangelogGenerator-tkGkQ38b.js +13 -0
- assets/ChangelogGenerator-tkGkQ38b.js.map +1 -0
- assets/CodeFormatter-CMsj5Hyg.js +8 -0
- assets/CodeFormatter-CMsj5Hyg.js.map +1 -0
- assets/CodeReviewBot-BgQ3GFY_.js +12 -0
- assets/CodeReviewBot-BgQ3GFY_.js.map +1 -0
- assets/CronJobBuilder-CPbxJxRA.js +2 -0
- assets/CronJobBuilder-CPbxJxRA.js.map +1 -0
- assets/CssGridEditor-Ct_gd1L2.js +7 -0
- assets/CssGridEditor-Ct_gd1L2.js.map +1 -0
- assets/DevNotesStickyPanel-C-lefFL-.js +3 -0
- assets/DevNotesStickyPanel-C-lefFL-.js.map +1 -0
- assets/FontPairingTool-B69d5r3k.js +2 -0
- assets/FontPairingTool-B69d5r3k.js.map +1 -0
- assets/FontPreviewPicker-Z5SOKfoJ.js +2 -0
- assets/FontPreviewPicker-Z5SOKfoJ.js.map +1 -0
- assets/JsonTreeNavigator-BT2AXqig.js +13 -0
- assets/JsonTreeNavigator-BT2AXqig.js.map +1 -0
- assets/MarkdownRenderer-BDaVxTSW.js +2 -0
- assets/MarkdownRenderer-BDaVxTSW.js.map +1 -0
- assets/MarkdownSlides-BMRDMVTS.js +24 -0
- assets/MarkdownSlides-BMRDMVTS.js.map +1 -0
- assets/Placeholder-D_7djokD.js +2 -0
- assets/Placeholder-D_7djokD.js.map +1 -0
- assets/PrSummaryGenerator-CCRA0dN-.js +7 -0
- assets/PrSummaryGenerator-CCRA0dN-.js.map +1 -0
- assets/ProjectMoodboard-Cq8q--8L.js +2 -0
- assets/ProjectMoodboard-Cq8q--8L.js.map +1 -0
- assets/PromptCraftPad-Bsdu3BUV.js +2 -0
- assets/PromptCraftPad-Bsdu3BUV.js.map +1 -0
- assets/PwaManifestEditor-CI-u9z3y.js +2 -0
- assets/PwaManifestEditor-CI-u9z3y.js.map +1 -0
assets/@google-4tyssLU_.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/@google-4tyssLU_.js.map
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/AiCodeExplainer-C0HS8Khr.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r,j as e}from"./react-D_B_5QVd.js";import{e as g,a as b}from"./index-QBya0NjG.js";import{M as N}from"./MarkdownRenderer-BDaVxTSW.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";import"./marked-CesSW9Du.js";const f=({text:l="AI is analyzing..."})=>e.jsxs("div",{className:"flex items-center justify-center space-x-2",children:[e.jsx("div",{className:"w-2 h-2 rounded-full bg-cyan-400 animate-pulse",style:{animationDelay:"0s"}}),e.jsx("div",{className:"w-2 h-2 rounded-full bg-cyan-400 animate-pulse",style:{animationDelay:"0.2s"}}),e.jsx("div",{className:"w-2 h-2 rounded-full bg-cyan-400 animate-pulse",style:{animationDelay:"0.4s"}}),e.jsx("span",{className:"text-slate-400 ml-2",children:l})]}),v=`const bubbleSort = (arr) => {
|
| 2 |
+
for (let i = 0; i < arr.length; i++) {
|
| 3 |
+
for (let j = 0; j < arr.length - i - 1; j++) {
|
| 4 |
+
if (arr[j] > arr[j + 1]) {
|
| 5 |
+
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
|
| 6 |
+
}
|
| 7 |
+
}
|
| 8 |
+
}
|
| 9 |
+
return arr;
|
| 10 |
+
};`,T=({initialCode:l})=>{const[d,m]=r.useState(l||v),[a,x]=r.useState(null),[n,u]=r.useState(!1),[i,c]=r.useState(""),[p,h]=r.useState("summary"),o=r.useCallback(async s=>{if(!s.trim()){c("Please enter some code to explain.");return}u(!0),c(""),x(null),h("summary");try{const t=await g(s);x(t)}catch(t){const y=t instanceof Error?t.message:"An unknown error occurred.";c(`Failed to get explanation: ${y}`)}finally{u(!1)}},[]);r.useEffect(()=>{l&&(m(l),o(l))},[l,o]);const j=()=>{if(!a)return null;switch(p){case"summary":return e.jsx(N,{content:a.summary});case"lineByLine":return e.jsx("div",{className:"space-y-3",children:a.lineByLine.map((s,t)=>e.jsxs("div",{className:"p-3 bg-slate-900/50 rounded-md",children:[e.jsxs("p",{className:"font-mono text-xs text-cyan-400 mb-1",children:["Lines: ",s.lines]}),e.jsx("p",{className:"text-sm",children:s.explanation})]},t))});case"complexity":return e.jsxs("div",{children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Time Complexity:"})," ",e.jsx("span",{className:"font-mono text-amber-400",children:a.complexity.time})]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Space Complexity:"})," ",e.jsx("span",{className:"font-mono text-amber-400",children:a.complexity.space})]})]});case"suggestions":return e.jsx("ul",{className:"list-disc list-inside space-y-2",children:a.suggestions.map((s,t)=>e.jsx("li",{children:s},t))})}};return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8 text-slate-300",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(b,{}),e.jsx("span",{className:"ml-3",children:"AI Code Explainer"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Get a detailed, structured analysis of any code snippet."})]}),e.jsxs("div",{className:"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 min-h-0",children:[e.jsxs("div",{className:"flex flex-col min-h-0",children:[e.jsx("label",{htmlFor:"code-input",className:"text-sm font-medium text-slate-400 mb-2",children:"Your Code"}),e.jsx("textarea",{id:"code-input",value:d,onChange:s=>m(s.target.value),placeholder:"Paste your code here...",className:"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-cyan-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none"}),e.jsx("div",{className:"mt-4",children:e.jsx("button",{onClick:()=>o(d),disabled:n,className:"w-full flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 transition-colors disabled:bg-slate-600 disabled:cursor-not-allowed",children:n?e.jsx(f,{text:"Analyzing..."}):"Analyze Code"})})]}),e.jsxs("div",{className:"flex flex-col min-h-0",children:[e.jsx("label",{className:"text-sm font-medium text-slate-400 mb-2",children:"AI Analysis"}),e.jsxs("div",{className:"relative flex-grow flex flex-col bg-slate-800/50 border border-slate-700/50 rounded-md overflow-hidden",children:[e.jsx("div",{className:"flex-shrink-0 flex border-b border-slate-700",children:["summary","lineByLine","complexity","suggestions"].map(s=>e.jsx("button",{onClick:()=>h(s),disabled:!a,className:`px-4 py-2 text-sm font-medium capitalize transition-colors ${p===s?"bg-slate-700/50 text-cyan-300":"text-slate-400 hover:bg-slate-700/30 disabled:text-slate-600"}`,children:s.replace(/([A-Z])/g," $1")},s))}),e.jsxs("div",{className:"p-4 flex-grow overflow-y-auto",children:[n&&e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsx(f,{})}),i&&e.jsx("p",{className:"text-red-400",children:i}),a&&!n&&j(),!n&&!a&&!i&&e.jsx("div",{className:"text-slate-500 h-full flex items-center justify-center",children:"The analysis will appear here."})]})]})]})]})]})};export{T as AiCodeExplainer};
|
| 11 |
+
//# sourceMappingURL=AiCodeExplainer-C0HS8Khr.js.map
|
assets/AiCodeExplainer-C0HS8Khr.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"AiCodeExplainer-C0HS8Khr.js","sources":["../../components/AiCodeExplainer.tsx"],"sourcesContent":["\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport { explainCodeStructured, StructuredExplanation } from '../services/geminiService.ts';\nimport { CpuChipIcon } from './icons/InterfaceIcons.tsx';\nimport { MarkdownRenderer } from './shared/MarkdownRenderer.tsx';\n\nconst LoadingSpinner: React.FC<{text?: string}> = ({ text = 'AI is analyzing...'}) => (\n <div className=\"flex items-center justify-center space-x-2\">\n <div className=\"w-2 h-2 rounded-full bg-cyan-400 animate-pulse\" style={{ animationDelay: '0s' }}></div>\n <div className=\"w-2 h-2 rounded-full bg-cyan-400 animate-pulse\" style={{ animationDelay: '0.2s' }}></div>\n <div className=\"w-2 h-2 rounded-full bg-cyan-400 animate-pulse\" style={{ animationDelay: '0.4s' }}></div>\n <span className=\"text-slate-400 ml-2\">{text}</span>\n </div>\n);\n\nconst exampleCode = `const bubbleSort = (arr) => {\n for (let i = 0; i < arr.length; i++) {\n for (let j = 0; j < arr.length - i - 1; j++) {\n if (arr[j] > arr[j + 1]) {\n [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];\n }\n }\n }\n return arr;\n};`;\n\ntype ExplanationTab = 'summary' | 'lineByLine' | 'complexity' | 'suggestions';\n\nexport const AiCodeExplainer: React.FC<{ initialCode?: string }> = ({ initialCode }) => {\n const [code, setCode] = useState<string>(initialCode || exampleCode);\n const [explanation, setExplanation] = useState<StructuredExplanation | null>(null);\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<string>('');\n const [activeTab, setActiveTab] = useState<ExplanationTab>('summary');\n\n const handleExplain = useCallback(async (codeToExplain: string) => {\n if (!codeToExplain.trim()) {\n setError('Please enter some code to explain.');\n return;\n }\n setIsLoading(true);\n setError('');\n setExplanation(null);\n setActiveTab('summary');\n try {\n const result = await explainCodeStructured(codeToExplain);\n setExplanation(result);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';\n setError(`Failed to get explanation: ${errorMessage}`);\n } finally {\n setIsLoading(false);\n }\n }, []);\n \n useEffect(() => {\n if (initialCode) {\n setCode(initialCode);\n handleExplain(initialCode);\n }\n }, [initialCode, handleExplain]);\n\n const renderTabContent = () => {\n if (!explanation) return null;\n switch(activeTab) {\n case 'summary':\n return <MarkdownRenderer content={explanation.summary} />;\n case 'lineByLine':\n return (\n <div className=\"space-y-3\">\n {explanation.lineByLine.map((item, index) => (\n <div key={index} className=\"p-3 bg-slate-900/50 rounded-md\">\n <p className=\"font-mono text-xs text-cyan-400 mb-1\">Lines: {item.lines}</p>\n <p className=\"text-sm\">{item.explanation}</p>\n </div>\n ))}\n </div>\n );\n case 'complexity':\n return (\n <div>\n <p><strong>Time Complexity:</strong> <span className=\"font-mono text-amber-400\">{explanation.complexity.time}</span></p>\n <p><strong>Space Complexity:</strong> <span className=\"font-mono text-amber-400\">{explanation.complexity.space}</span></p>\n </div>\n );\n case 'suggestions':\n return (\n <ul className=\"list-disc list-inside space-y-2\">\n {explanation.suggestions.map((item, index) => <li key={index}>{item}</li>)}\n </ul>\n );\n }\n }\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8 text-slate-300\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <CpuChipIcon />\n <span className=\"ml-3\">AI Code Explainer</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Get a detailed, structured analysis of any code snippet.</p>\n </header>\n <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 min-h-0\">\n <div className=\"flex flex-col min-h-0\">\n <label htmlFor=\"code-input\" className=\"text-sm font-medium text-slate-400 mb-2\">Your Code</label>\n <textarea\n id=\"code-input\"\n value={code}\n onChange={(e) => setCode(e.target.value)}\n placeholder=\"Paste your code here...\"\n className=\"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-cyan-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none\"\n />\n <div className=\"mt-4\">\n <button\n onClick={() => handleExplain(code)}\n disabled={isLoading}\n className=\"w-full flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 transition-colors disabled:bg-slate-600 disabled:cursor-not-allowed\"\n >\n {isLoading ? <LoadingSpinner text=\"Analyzing...\"/> : 'Analyze Code'}\n </button>\n </div>\n </div>\n <div className=\"flex flex-col min-h-0\">\n <label className=\"text-sm font-medium text-slate-400 mb-2\">AI Analysis</label>\n <div className=\"relative flex-grow flex flex-col bg-slate-800/50 border border-slate-700/50 rounded-md overflow-hidden\">\n <div className=\"flex-shrink-0 flex border-b border-slate-700\">\n {(['summary', 'lineByLine', 'complexity', 'suggestions'] as ExplanationTab[]).map(tab => (\n <button key={tab} onClick={() => setActiveTab(tab)} disabled={!explanation}\n className={`px-4 py-2 text-sm font-medium capitalize transition-colors ${activeTab === tab ? 'bg-slate-700/50 text-cyan-300' : 'text-slate-400 hover:bg-slate-700/30 disabled:text-slate-600'}`}>\n {tab.replace(/([A-Z])/g, ' $1')}\n </button>\n ))}\n </div>\n <div className=\"p-4 flex-grow overflow-y-auto\">\n {isLoading && <div className=\"flex items-center justify-center h-full\"><LoadingSpinner /></div>}\n {error && <p className=\"text-red-400\">{error}</p>}\n {explanation && !isLoading && renderTabContent()}\n {!isLoading && !explanation && !error && <div className=\"text-slate-500 h-full flex items-center justify-center\">The analysis will appear here.</div>}\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};"],"names":["LoadingSpinner","text","jsxs","jsx","exampleCode","AiCodeExplainer","initialCode","code","setCode","useState","explanation","setExplanation","isLoading","setIsLoading","error","setError","activeTab","setActiveTab","handleExplain","useCallback","codeToExplain","result","explainCodeStructured","err","errorMessage","useEffect","renderTabContent","MarkdownRenderer","item","index","CpuChipIcon","e","tab"],"mappings":"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"}
|
assets/AiCodeMigrator-D1DuZhlC.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as a,j as e}from"./react-D_B_5QVd.js";import{H as b,I as y,L as g}from"./index-QBya0NjG.js";import{M as N}from"./MarkdownRenderer-BDaVxTSW.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";import"./marked-CesSW9Du.js";const v=["SASS","CSS","JavaScript","TypeScript","Python","Go","React","Vue","Angular","Tailwind CSS"],C=`// SASS
|
| 2 |
+
$primary-color: #333;
|
| 3 |
+
|
| 4 |
+
body {
|
| 5 |
+
color: $primary-color;
|
| 6 |
+
font-family: sans-serif;
|
| 7 |
+
}`,R=()=>{const[o,p]=a.useState(C),[n,x]=a.useState(""),[c,h]=a.useState("SASS"),[i,j]=a.useState("CSS"),[l,u]=a.useState(!1),[d,m]=a.useState(""),S=a.useCallback(async()=>{if(!o.trim()){m("Please enter some code to migrate.");return}u(!0),m(""),x("");try{const s=b(o,c,i);let r="";for await(const t of s)r+=t,x(r)}catch(s){const r=s instanceof Error?s.message:"An unknown error occurred.";m(`Failed to migrate code: ${r}`)}finally{u(!1)}},[o,c,i]),f=({value:s,onChange:r})=>e.jsx("select",{value:s,onChange:t=>r(t.target.value),className:"w-full px-3 py-2 rounded-md bg-slate-800 border border-slate-700",children:v.map(t=>e.jsx("option",{value:t,children:t},t))});return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(y,{}),e.jsx("span",{className:"ml-3",children:"AI Code Migrator"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Translate code between languages, frameworks, and syntax styles."})]}),e.jsxs("div",{className:"flex-grow flex flex-col min-h-0",children:[e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6 flex-grow min-h-0",children:[e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("div",{className:"mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-slate-400",children:"From:"}),e.jsx(f,{value:c,onChange:h})]}),e.jsx("textarea",{value:o,onChange:s=>p(s.target.value),placeholder:"Paste your source code here...",className:"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm"})]}),e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("div",{className:"mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-slate-400",children:"To:"}),e.jsx(f,{value:i,onChange:j})]}),e.jsxs("div",{className:"flex-grow p-1 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto",children:[l&&e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsx(g,{})}),d&&e.jsx("p",{className:"p-4 text-red-400",children:d}),n&&!l&&e.jsx(N,{content:n}),!l&&!n&&!d&&e.jsx("div",{className:"text-slate-500 h-full flex items-center justify-center",children:"Migrated code will appear here."})]})]})]}),e.jsx("button",{onClick:S,disabled:l,className:"mt-4 w-full max-w-sm mx-auto flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600",children:l?e.jsx(g,{}):"Migrate Code"})]})]})};export{R as AiCodeMigrator};
|
| 8 |
+
//# sourceMappingURL=AiCodeMigrator-D1DuZhlC.js.map
|
assets/AiCodeMigrator-D1DuZhlC.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"AiCodeMigrator-D1DuZhlC.js","sources":["../../components/features/AiCodeMigrator.tsx"],"sourcesContent":["\nimport React, { useState, useCallback } from 'react';\nimport { migrateCodeStream } from '../../services/geminiService.ts';\nimport { ArrowPathIcon } from '../icons/FeatureIcons.tsx';\nimport { LoadingSpinner } from '../shared/LoadingSpinner.tsx';\nimport { MarkdownRenderer } from '../shared/MarkdownRenderer.tsx';\n\nconst languages = ['SASS', 'CSS', 'JavaScript', 'TypeScript', 'Python', 'Go', 'React', 'Vue', 'Angular', 'Tailwind CSS'];\n\nconst exampleCode = `// SASS\n$primary-color: #333;\n\nbody {\n color: $primary-color;\n font-family: sans-serif;\n}`;\n\nexport const AiCodeMigrator: React.FC = () => {\n const [inputCode, setInputCode] = useState<string>(exampleCode);\n const [outputCode, setOutputCode] = useState<string>('');\n const [fromLang, setFromLang] = useState('SASS');\n const [toLang, setToLang] = useState('CSS');\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<string>('');\n\n const handleMigrate = useCallback(async () => {\n if (!inputCode.trim()) {\n setError('Please enter some code to migrate.');\n return;\n }\n setIsLoading(true);\n setError('');\n setOutputCode('');\n try {\n const stream = migrateCodeStream(inputCode, fromLang, toLang);\n let fullResponse = '';\n for await (const chunk of stream) {\n fullResponse += chunk;\n setOutputCode(fullResponse);\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';\n setError(`Failed to migrate code: ${errorMessage}`);\n } finally {\n setIsLoading(false);\n }\n }, [inputCode, fromLang, toLang]);\n\n const LanguageSelector: React.FC<{ value: string, onChange: (val: string) => void }> = ({ value, onChange }) => (\n <select value={value} onChange={e => onChange(e.target.value)} className=\"w-full px-3 py-2 rounded-md bg-slate-800 border border-slate-700\">\n {languages.map(lang => <option key={lang} value={lang}>{lang}</option>)}\n </select>\n );\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\"><ArrowPathIcon /><span className=\"ml-3\">AI Code Migrator</span></h1>\n <p className=\"text-slate-400 mt-1\">Translate code between languages, frameworks, and syntax styles.</p>\n </header>\n <div className=\"flex-grow flex flex-col min-h-0\">\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6 flex-grow min-h-0\">\n <div className=\"flex flex-col h-full\">\n <div className=\"mb-2\">\n <label className=\"text-sm font-medium text-slate-400\">From:</label>\n <LanguageSelector value={fromLang} onChange={setFromLang} />\n </div>\n <textarea\n value={inputCode}\n onChange={(e) => setInputCode(e.target.value)}\n placeholder=\"Paste your source code here...\"\n className=\"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm\"\n />\n </div>\n <div className=\"flex flex-col h-full\">\n <div className=\"mb-2\">\n <label className=\"text-sm font-medium text-slate-400\">To:</label>\n <LanguageSelector value={toLang} onChange={setToLang} />\n </div>\n <div className=\"flex-grow p-1 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto\">\n {isLoading && <div className=\"flex items-center justify-center h-full\"><LoadingSpinner /></div>}\n {error && <p className=\"p-4 text-red-400\">{error}</p>}\n {outputCode && !isLoading && <MarkdownRenderer content={outputCode} />}\n {!isLoading && !outputCode && !error && <div className=\"text-slate-500 h-full flex items-center justify-center\">Migrated code will appear here.</div>}\n </div>\n </div>\n </div>\n <button\n onClick={handleMigrate}\n disabled={isLoading}\n className=\"mt-4 w-full max-w-sm mx-auto flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600\"\n >\n {isLoading ? <LoadingSpinner /> : 'Migrate Code'}\n </button>\n </div>\n </div>\n );\n};"],"names":["languages","exampleCode","AiCodeMigrator","inputCode","setInputCode","useState","outputCode","setOutputCode","fromLang","setFromLang","toLang","setToLang","isLoading","setIsLoading","error","setError","handleMigrate","useCallback","stream","migrateCodeStream","fullResponse","chunk","err","errorMessage","LanguageSelector","value","onChange","jsx","e","lang","jsxs","ArrowPathIcon","LoadingSpinner","MarkdownRenderer"],"mappings":"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"}
|
assets/AiCodingChallenge-BQSkuis0.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as t,j as e}from"./react-D_B_5QVd.js";import{v as h,B as g,L as m}from"./index-QBya0NjG.js";import{m as u}from"./marked-CesSW9Du.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const S=()=>{const[r,o]=t.useState(""),[a,c]=t.useState(!1),[n,i]=t.useState(""),[p,d]=t.useState("");t.useEffect(()=>{(async()=>{if(r){const s=await u.parse(r);d(s)}else d("")})()},[r]);const x=t.useCallback(async()=>{c(!0),i(""),o("");try{const l=h(null);let s="";for await(const f of l)s+=f,o(s)}catch(l){const s=l instanceof Error?l.message:"An unknown error occurred.";i(`Failed to generate challenge: ${s}`)}finally{c(!1)}},[]);return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6 flex justify-between items-center",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(g,{}),e.jsx("span",{className:"ml-3",children:"AI Coding Challenge Generator"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Generate a unique coding problem to test your skills."})]}),e.jsx("button",{onClick:x,disabled:a,className:"flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 transition-colors disabled:bg-slate-600 disabled:cursor-not-allowed",children:a?e.jsx(m,{}):"Generate New Challenge"})]}),e.jsxs("div",{className:"flex-grow p-4 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto",children:[a&&e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsx(m,{})}),n&&e.jsx("p",{className:"text-red-400",children:n}),r&&!a&&e.jsx("div",{className:"prose prose-sm prose-invert max-w-none prose-headings:text-slate-200 prose-p:text-slate-300 prose-strong:text-slate-100 prose-code:text-cyan-300 prose-code:before:content-none prose-code:after:content-none prose-pre:bg-slate-900/50 prose-pre:border prose-pre:border-slate-700",dangerouslySetInnerHTML:{__html:p}}),!a&&!r&&!n&&e.jsx("div",{className:"text-slate-500 h-full flex items-center justify-center",children:'Click "Generate New Challenge" to start.'})]})]})};export{S as AiCodingChallenge};
|
| 2 |
+
//# sourceMappingURL=AiCodingChallenge-BQSkuis0.js.map
|
assets/AiCodingChallenge-BQSkuis0.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"AiCodingChallenge-BQSkuis0.js","sources":["../../components/features/AiCodingChallenge.tsx"],"sourcesContent":["\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport { generateCodingChallengeStream } from '../../services/geminiService.ts';\nimport { BeakerIcon } from '../icons/FeatureIcons.tsx';\nimport { LoadingSpinner } from '../shared/LoadingSpinner.tsx';\nimport { marked } from 'marked';\n\nexport const AiCodingChallenge: React.FC = () => {\n const [challenge, setChallenge] = useState<string>('');\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<string>('');\n const [challengeHtml, setChallengeHtml] = useState<string | TrustedHTML>('');\n\n useEffect(() => {\n const parse = async () => {\n if (challenge) {\n const html = await marked.parse(challenge);\n setChallengeHtml(html);\n } else {\n setChallengeHtml('');\n }\n };\n parse();\n }, [challenge]);\n\n const handleGenerate = useCallback(async () => {\n setIsLoading(true);\n setError('');\n setChallenge('');\n try {\n const stream = generateCodingChallengeStream(null);\n let fullResponse = '';\n for await (const chunk of stream) {\n fullResponse += chunk;\n setChallenge(fullResponse);\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';\n setError(`Failed to generate challenge: ${errorMessage}`);\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6 flex justify-between items-center\">\n <div>\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <BeakerIcon />\n <span className=\"ml-3\">AI Coding Challenge Generator</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Generate a unique coding problem to test your skills.</p>\n </div>\n <button\n onClick={handleGenerate}\n disabled={isLoading}\n className=\"flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 transition-colors disabled:bg-slate-600 disabled:cursor-not-allowed\"\n >\n {isLoading ? <LoadingSpinner /> : 'Generate New Challenge'}\n </button>\n </header>\n <div className=\"flex-grow p-4 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto\">\n {isLoading && (\n <div className=\"flex items-center justify-center h-full\">\n <LoadingSpinner />\n </div>\n )}\n {error && <p className=\"text-red-400\">{error}</p>}\n {challenge && !isLoading && (\n <div\n className=\"prose prose-sm prose-invert max-w-none prose-headings:text-slate-200 prose-p:text-slate-300 prose-strong:text-slate-100 prose-code:text-cyan-300 prose-code:before:content-none prose-code:after:content-none prose-pre:bg-slate-900/50 prose-pre:border prose-pre:border-slate-700\"\n dangerouslySetInnerHTML={{ __html: challengeHtml }}\n />\n )}\n {!isLoading && !challenge && !error && (\n <div className=\"text-slate-500 h-full flex items-center justify-center\">\n Click \"Generate New Challenge\" to start.\n </div>\n )}\n </div>\n </div>\n );\n};"],"names":["AiCodingChallenge","challenge","setChallenge","useState","isLoading","setIsLoading","error","setError","challengeHtml","setChallengeHtml","useEffect","html","marked","handleGenerate","useCallback","stream","generateCodingChallengeStream","fullResponse","chunk","err","errorMessage","jsxs","jsx","BeakerIcon","LoadingSpinner"],"mappings":"kSAQO,MAAMA,EAA8B,IAAM,CAC7C,KAAM,CAACC,EAAWC,CAAY,EAAIC,EAAAA,SAAiB,EAAE,EAC/C,CAACC,EAAWC,CAAY,EAAIF,EAAAA,SAAkB,EAAK,EACnD,CAACG,EAAOC,CAAQ,EAAIJ,EAAAA,SAAiB,EAAE,EACvC,CAACK,EAAeC,CAAgB,EAAIN,EAAAA,SAA+B,EAAE,EAE3EO,EAAAA,UAAU,IAAM,EACE,SAAY,CACtB,GAAIT,EAAW,CACX,MAAMU,EAAO,MAAMC,EAAO,MAAMX,CAAS,EACzCQ,EAAiBE,CAAI,CACzB,MACIF,EAAiB,EAAE,CAE3B,GACA,CACJ,EAAG,CAACR,CAAS,CAAC,EAEd,MAAMY,EAAiBC,EAAAA,YAAY,SAAY,CAC3CT,EAAa,EAAI,EACjBE,EAAS,EAAE,EACXL,EAAa,EAAE,EACf,GAAI,CACA,MAAMa,EAASC,EAA8B,IAAI,EACjD,IAAIC,EAAe,GACnB,gBAAiBC,KAASH,EACtBE,GAAgBC,EAChBhB,EAAae,CAAY,CAEjC,OAASE,EAAK,CACV,MAAMC,EAAeD,aAAe,MAAQA,EAAI,QAAU,6BAC1DZ,EAAS,iCAAiCa,CAAY,EAAE,CAC5D,QAAA,CACIf,EAAa,EAAK,CACtB,CACJ,EAAG,CAAA,CAAE,EAEL,OACIgB,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACX,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,yCACd,SAAA,CAAAA,OAAC,MAAA,CACG,SAAA,CAAAA,EAAAA,KAAC,KAAA,CAAG,UAAU,sDACV,SAAA,CAAAC,EAAAA,IAACC,EAAA,EAAW,EACZD,EAAAA,IAAC,OAAA,CAAK,UAAU,OAAO,SAAA,+BAAA,CAA6B,CAAA,EACxD,EACAA,EAAAA,IAAC,IAAA,CAAE,UAAU,sBAAsB,SAAA,uDAAA,CAAqD,CAAA,EAC5F,EACAA,EAAAA,IAAC,SAAA,CACG,QAAST,EACT,SAAUT,EACV,UAAU,mLAET,SAAAA,EAAYkB,EAAAA,IAACE,EAAA,CAAA,CAAe,EAAK,wBAAA,CAAA,CACtC,EACJ,EACAH,EAAAA,KAAC,MAAA,CAAI,UAAU,sFACV,SAAA,CAAAjB,SACK,MAAA,CAAI,UAAU,0CACZ,SAAAkB,MAACE,IAAe,EACnB,EAEJlB,GAASgB,EAAAA,IAAC,IAAA,CAAE,UAAU,eAAgB,SAAAhB,EAAM,EAC5CL,GAAa,CAACG,GACXkB,EAAAA,IAAC,MAAA,CACG,UAAU,sRACV,wBAAyB,CAAE,OAAQd,CAAA,CAAc,CAAA,EAGvD,CAACJ,GAAa,CAACH,GAAa,CAACK,GAC3BgB,EAAAA,IAAC,MAAA,CAAI,UAAU,yDAAyD,SAAA,0CAAA,CAExE,CAAA,CAAA,CAER,CAAA,EACJ,CAER"}
|
assets/AiCommandCenter-BVcknEjZ.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as i,j as e}from"./react-D_B_5QVd.js";import{T as n}from"./@google-4tyssLU_.js";import{u as f,g as y,l as b,C as T,L as v}from"./index-QBya0NjG.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./idb-Dob3nYDb.js";const E=[{id:"ai-command-center",name:"AI Command Center",description:"The main entry point. Use natural language to navigate and control the entire toolkit. Can call other tools.",category:"Core",inputs:"A natural language prompt describing what the user wants to do. Examples: 'explain this code: ...', 'design a theme with space vibes'."},{id:"ai-code-explainer",name:"AI Code Explainer",description:"Accepts a code snippet and provides a detailed, structured analysis including summary, line-by-line breakdown, time/space complexity, and suggestions for improvement.",category:"AI Tools",inputs:"A string containing a code snippet."},{id:"theme-designer",name:"AI Theme Designer",description:"Generates a complete UI color theme (primary, background, text colors) from a simple text description.",category:"AI Tools",inputs:"A string describing the desired aesthetic. Example: 'a calm, minimalist theme for a blog'."},{id:"regex-sandbox",name:"RegEx Sandbox",description:"Generates a regular expression from a natural language description. Also allows testing expressions against a string.",category:"Testing",inputs:"A string describing the pattern to match. Example: 'find all email addresses'."},{id:"pr-summary-generator",name:"AI PR Summary Generator",description:"Takes 'before' and 'after' code snippets, calculates the diff, and generates a structured pull request summary including a title, a prose description, and a bulleted list of changes.",category:"AI Tools",inputs:"Two strings: 'beforeCode' and 'afterCode'."},{id:"changelog-generator",name:"AI Changelog Generator",description:"Intelligently parses a raw 'git log' output to create a categorized and well-formatted changelog, separating new features from bug fixes.",category:"Git",inputs:"A string containing the raw output of a 'git log' command."},{id:"cron-job-builder",name:"AI Cron Job Builder",description:"Generates a valid cron expression from a natural language description of a schedule.",category:"Deployment",inputs:"A string describing a schedule. Example: 'every weekday at 5pm'."}],C=[{name:"navigateToCodeExplainer",description:"Navigates to the AI Code Explainer and explains a given piece of code.",parameters:{type:n.OBJECT,properties:{code:{type:n.STRING,description:"The code snippet to be explained."}},required:["code"]}},{name:"navigateToThemeDesigner",description:"Navigates to the AI Theme Designer and generates a theme from a description.",parameters:{type:n.OBJECT,properties:{description:{type:n.STRING,description:'A text description of the desired theme, e.g., "a dark cyberpunk theme".'}},required:["description"]}},{name:"navigateToRegexSandbox",description:"Navigates to the RegEx Sandbox and generates a regex from a description.",parameters:{type:n.OBJECT,properties:{description:{type:n.STRING,description:"A text description of the regex pattern to generate."}},required:["description"]}}],A=E.map(a=>`- ${a.name} (${a.id}): ${a.description} Inputs: ${a.inputs}`).join(`
|
| 2 |
+
`),G=()=>{const{dispatch:a}=f(),[s,p]=i.useState(""),[o,m]=i.useState(!1),[g,r]=i.useState(""),u=i.useCallback(async()=>{if(s.trim()){m(!0),r("");try{const t=await y(s,C,A),d=t.functionCalls;if(d&&d.length>0){const h=d[0],{name:l,args:c}=h;switch(r(`Understood! Executing command: ${l}`),l){case"navigateToCodeExplainer":a({type:"SET_VIEW",payload:{view:"ai-code-explainer",props:{initialCode:c.code}}});break;case"navigateToThemeDesigner":a({type:"SET_VIEW",payload:{view:"theme-designer",props:{initialPrompt:c.description}}});break;case"navigateToRegexSandbox":a({type:"SET_VIEW",payload:{view:"regex-sandbox",props:{initialPrompt:c.description}}});break;default:r(`Unknown command: ${l}`)}p("")}else r(t.text)}catch(t){b(t,{prompt:s}),r(t instanceof Error?t.message:"An unknown error occurred.")}finally{m(!1)}}},[s,a]),x=t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),u())};return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6 text-center",children:[e.jsxs("h1",{className:"text-4xl font-extrabold text-slate-100 tracking-tight flex items-center justify-center",children:[e.jsx(T,{}),e.jsx("span",{className:"ml-3",children:"AI Command Center"})]}),e.jsx("p",{className:"mt-2 text-lg text-slate-400",children:"What would you like to do?"})]}),e.jsxs("div",{className:"flex-grow flex flex-col justify-end",children:[g&&e.jsx("div",{className:"mb-4 p-4 bg-slate-800/50 rounded-lg text-slate-300",children:e.jsxs("p",{children:[e.jsx("strong",{children:"AI:"})," ",g]})}),e.jsxs("div",{className:"relative",children:[e.jsx("textarea",{value:s,onChange:t=>p(t.target.value),onKeyPress:x,disabled:o,placeholder:'Try "explain this code: const a = 1;" or "design a theme with ocean vibes"',className:"w-full p-4 pr-28 rounded-lg bg-slate-800 border border-slate-700 focus:ring-2 focus:ring-cyan-500 focus:outline-none resize-none",rows:2}),e.jsx("button",{onClick:u,disabled:o,className:"absolute right-3 top-1/2 -translate-y-1/2 px-4 py-2 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600",children:o?e.jsx(v,{}):"Send"})]}),e.jsx("p",{className:"text-xs text-slate-500 text-center mt-2",children:"Press Enter to send, Shift+Enter for new line."})]})]})};export{G as AiCommandCenter};
|
| 3 |
+
//# sourceMappingURL=AiCommandCenter-BVcknEjZ.js.map
|
assets/AiCommandCenter-BVcknEjZ.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"AiCommandCenter-BVcknEjZ.js","sources":["../../services/taxonomyService.ts","../../components/features/AiCommandCenter.tsx"],"sourcesContent":["export interface FeatureTaxonomy {\n id: string;\n name: string;\n description: string;\n category: string;\n inputs: string;\n}\n\nexport const FEATURE_TAXONOMY: FeatureTaxonomy[] = [\n {\n id: \"ai-command-center\",\n name: \"AI Command Center\",\n description: \"The main entry point. Use natural language to navigate and control the entire toolkit. Can call other tools.\",\n category: \"Core\",\n inputs: \"A natural language prompt describing what the user wants to do. Examples: 'explain this code: ...', 'design a theme with space vibes'.\"\n },\n {\n id: \"ai-code-explainer\",\n name: \"AI Code Explainer\",\n description: \"Accepts a code snippet and provides a detailed, structured analysis including summary, line-by-line breakdown, time/space complexity, and suggestions for improvement.\",\n category: \"AI Tools\",\n inputs: \"A string containing a code snippet.\"\n },\n {\n id: \"theme-designer\",\n name: \"AI Theme Designer\",\n description: \"Generates a complete UI color theme (primary, background, text colors) from a simple text description.\",\n category: \"AI Tools\",\n inputs: \"A string describing the desired aesthetic. Example: 'a calm, minimalist theme for a blog'.\"\n },\n {\n id: \"regex-sandbox\",\n name: \"RegEx Sandbox\",\n description: \"Generates a regular expression from a natural language description. Also allows testing expressions against a string.\",\n category: \"Testing\",\n inputs: \"A string describing the pattern to match. Example: 'find all email addresses'.\"\n },\n {\n id: \"pr-summary-generator\",\n name: \"AI PR Summary Generator\",\n description: \"Takes 'before' and 'after' code snippets, calculates the diff, and generates a structured pull request summary including a title, a prose description, and a bulleted list of changes.\",\n category: \"AI Tools\",\n inputs: \"Two strings: 'beforeCode' and 'afterCode'.\"\n },\n {\n id: \"changelog-generator\",\n name: \"AI Changelog Generator\",\n description: \"Intelligently parses a raw 'git log' output to create a categorized and well-formatted changelog, separating new features from bug fixes.\",\n category: \"Git\",\n inputs: \"A string containing the raw output of a 'git log' command.\"\n },\n {\n id: \"cron-job-builder\",\n name: \"AI Cron Job Builder\",\n description: \"Generates a valid cron expression from a natural language description of a schedule.\",\n category: \"Deployment\",\n inputs: \"A string describing a schedule. Example: 'every weekday at 5pm'.\"\n },\n];\n","\n\n\nimport React, { useState, useCallback } from 'react';\nimport { Type, FunctionDeclaration } from \"@google/genai\";\nimport { getInferenceFunction } from '../../services/geminiService.ts';\nimport { FEATURE_TAXONOMY } from '../../services/taxonomyService.ts';\nimport { useGlobalState } from '../../contexts/GlobalStateContext.tsx';\nimport { CommandLineIcon } from '../icons/FeatureIcons.tsx';\nimport { LoadingSpinner } from '../shared/LoadingSpinner.tsx';\nimport { logError } from '../../services/telemetryService.ts';\n\nconst functionDeclarations: FunctionDeclaration[] = [\n {\n name: 'navigateToCodeExplainer',\n description: 'Navigates to the AI Code Explainer and explains a given piece of code.',\n parameters: {\n type: Type.OBJECT,\n properties: {\n code: { type: Type.STRING, description: 'The code snippet to be explained.' },\n },\n required: ['code'],\n },\n },\n {\n name: 'navigateToThemeDesigner',\n description: 'Navigates to the AI Theme Designer and generates a theme from a description.',\n parameters: {\n type: Type.OBJECT,\n properties: {\n description: { type: Type.STRING, description: 'A text description of the desired theme, e.g., \"a dark cyberpunk theme\".' },\n },\n required: ['description'],\n },\n },\n {\n name: 'navigateToRegexSandbox',\n description: 'Navigates to the RegEx Sandbox and generates a regex from a description.',\n parameters: {\n type: Type.OBJECT,\n properties: {\n description: { type: Type.STRING, description: 'A text description of the regex pattern to generate.' },\n },\n required: ['description'],\n },\n }\n];\n\nconst knowledgeBase = FEATURE_TAXONOMY.map(f => `- ${f.name} (${f.id}): ${f.description} Inputs: ${f.inputs}`).join('\\n');\n\nexport const AiCommandCenter: React.FC = () => {\n const { dispatch } = useGlobalState();\n const [prompt, setPrompt] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const [lastResponse, setLastResponse] = useState('');\n\n const handleCommand = useCallback(async () => {\n if (!prompt.trim()) return;\n\n setIsLoading(true);\n setLastResponse('');\n\n try {\n const response = await getInferenceFunction(prompt, functionDeclarations, knowledgeBase);\n \n const functionCalls = response.functionCalls;\n\n if (functionCalls && functionCalls.length > 0) {\n const call = functionCalls[0];\n const { name, args } = call;\n\n setLastResponse(`Understood! Executing command: ${name}`);\n\n switch (name) {\n case 'navigateToCodeExplainer':\n dispatch({ type: 'SET_VIEW', payload: { view: 'ai-code-explainer', props: { initialCode: args.code } } });\n break;\n case 'navigateToThemeDesigner':\n dispatch({ type: 'SET_VIEW', payload: { view: 'theme-designer', props: { initialPrompt: args.description } } });\n break;\n case 'navigateToRegexSandbox':\n dispatch({ type: 'SET_VIEW', payload: { view: 'regex-sandbox', props: { initialPrompt: args.description } } });\n break;\n default:\n setLastResponse(`Unknown command: ${name}`);\n }\n setPrompt(''); // Clear prompt on successful command\n } else {\n setLastResponse(response.text);\n }\n\n } catch (err) {\n logError(err as Error, { prompt });\n setLastResponse(err instanceof Error ? err.message : 'An unknown error occurred.');\n } finally {\n setIsLoading(false);\n }\n }, [prompt, dispatch]);\n\n const handleKeyPress = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleCommand();\n }\n };\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6 text-center\">\n <h1 className=\"text-4xl font-extrabold text-slate-100 tracking-tight flex items-center justify-center\">\n <CommandLineIcon />\n <span className=\"ml-3\">AI Command Center</span>\n </h1>\n <p className=\"mt-2 text-lg text-slate-400\">What would you like to do?</p>\n </header>\n \n <div className=\"flex-grow flex flex-col justify-end\">\n {lastResponse && (\n <div className=\"mb-4 p-4 bg-slate-800/50 rounded-lg text-slate-300\">\n <p><strong>AI:</strong> {lastResponse}</p>\n </div>\n )}\n <div className=\"relative\">\n <textarea\n value={prompt}\n onChange={e => setPrompt(e.target.value)}\n onKeyPress={handleKeyPress}\n disabled={isLoading}\n placeholder='Try \"explain this code: const a = 1;\" or \"design a theme with ocean vibes\"'\n className=\"w-full p-4 pr-28 rounded-lg bg-slate-800 border border-slate-700 focus:ring-2 focus:ring-cyan-500 focus:outline-none resize-none\"\n rows={2}\n />\n <button\n onClick={handleCommand}\n disabled={isLoading}\n className=\"absolute right-3 top-1/2 -translate-y-1/2 px-4 py-2 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600\"\n >\n {isLoading ? <LoadingSpinner/> : 'Send'}\n </button>\n </div>\n <p className=\"text-xs text-slate-500 text-center mt-2\">Press Enter to send, Shift+Enter for new line.</p>\n </div>\n </div>\n );\n};"],"names":["FEATURE_TAXONOMY","functionDeclarations","Type","knowledgeBase","f","AiCommandCenter","dispatch","useGlobalState","prompt","setPrompt","useState","isLoading","setIsLoading","lastResponse","setLastResponse","handleCommand","useCallback","response","getInferenceFunction","functionCalls","call","name","args","err","logError","handleKeyPress","e","jsxs","jsx","CommandLineIcon","LoadingSpinner"],"mappings":"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"}
|
assets/AiCommitGenerator-CtJxujtN.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as a,j as e}from"./react-D_B_5QVd.js";import{m as g,G as h,L as d}from"./index-QBya0NjG.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const b=`diff --git a/src/components/Button.tsx b/src/components/Button.tsx
|
| 2 |
+
index 1b2c3d4..5e6f7g8 100644
|
| 3 |
+
--- a/src/components/Button.tsx
|
| 4 |
+
+++ b/src/components/Button.tsx
|
| 5 |
+
@@ -1,7 +1,7 @@
|
| 6 |
+
import React from 'react';
|
| 7 |
+
|
| 8 |
+
interface ButtonProps {
|
| 9 |
+
- text: string;
|
| 10 |
+
+ label: string;
|
| 11 |
+
onClick: () => void;
|
| 12 |
+
}
|
| 13 |
+
`,k=()=>{const[r,f]=a.useState(b),[l,c]=a.useState(""),[t,m]=a.useState(!1),[n,i]=a.useState(""),x=a.useCallback(async()=>{if(!r.trim()){i("Please paste a diff to generate a message.");return}m(!0),i(""),c("");try{const s=g(r);let o="";for await(const p of s)o+=p,c(o)}catch(s){const o=s instanceof Error?s.message:"An unknown error occurred.";i(`Failed to generate message: ${o}`)}finally{m(!1)}},[r]),u=()=>{navigator.clipboard.writeText(l)};return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(h,{}),e.jsx("span",{className:"ml-3",children:"AI Commit Message Generator"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Paste your diff and let Gemini craft the perfect commit message."})]}),e.jsxs("div",{className:"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden",children:[e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{htmlFor:"diff-input",className:"text-sm font-medium text-slate-400 mb-2",children:"Git Diff"}),e.jsx("textarea",{id:"diff-input",value:r,onChange:s=>f(s.target.value),placeholder:"Paste your git diff here...",className:"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-slate-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none"}),e.jsx("button",{onClick:x,disabled:t,className:"mt-4 w-full flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 transition-colors disabled:bg-slate-600 disabled:cursor-not-allowed",children:t?e.jsx(d,{}):"Generate Commit Message"})]}),e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{className:"text-sm font-medium text-slate-400 mb-2",children:"Generated Message"}),e.jsxs("div",{className:"relative flex-grow p-4 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto",children:[t&&e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsx(d,{})}),n&&e.jsx("p",{className:"text-red-400",children:n}),l&&!t&&e.jsxs(e.Fragment,{children:[e.jsx("button",{onClick:u,className:"absolute top-2 right-2 px-2 py-1 bg-slate-700 hover:bg-slate-600 rounded-md text-xs",children:"Copy"}),e.jsx("pre",{className:"whitespace-pre-wrap font-sans text-slate-200",children:l})]}),!t&&!l&&!n&&e.jsx("div",{className:"text-slate-500 h-full flex items-center justify-center",children:"The commit message will appear here."})]})]})]})]})};export{k as AiCommitGenerator};
|
| 14 |
+
//# sourceMappingURL=AiCommitGenerator-CtJxujtN.js.map
|
assets/AiCommitGenerator-CtJxujtN.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"AiCommitGenerator-CtJxujtN.js","sources":["../../components/AiCommitGenerator.tsx"],"sourcesContent":["\n\nimport React, { useState, useCallback } from 'react';\nimport { generateCommitMessageStream } from '../services/geminiService.ts';\nimport { GitBranchIcon } from './icons/FeatureIcons.tsx';\nimport { LoadingSpinner } from './shared/LoadingSpinner.tsx';\n\nconst exampleDiff = `diff --git a/src/components/Button.tsx b/src/components/Button.tsx\nindex 1b2c3d4..5e6f7g8 100644\n--- a/src/components/Button.tsx\n+++ b/src/components/Button.tsx\n@@ -1,7 +1,7 @@\n import React from 'react';\n\n interface ButtonProps {\n- text: string;\n+ label: string;\n onClick: () => void;\n }\n`;\n\nexport const AiCommitGenerator: React.FC = () => {\n const [diff, setDiff] = useState<string>(exampleDiff);\n const [message, setMessage] = useState<string>('');\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<string>('');\n\n const handleGenerate = useCallback(async () => {\n if (!diff.trim()) {\n setError('Please paste a diff to generate a message.');\n return;\n }\n setIsLoading(true);\n setError('');\n setMessage('');\n try {\n const stream = generateCommitMessageStream(diff);\n let fullResponse = '';\n for await (const chunk of stream) {\n fullResponse += chunk;\n setMessage(fullResponse);\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';\n setError(`Failed to generate message: ${errorMessage}`);\n } finally {\n setIsLoading(false);\n }\n }, [diff]);\n \n const handleCopy = () => {\n navigator.clipboard.writeText(message);\n };\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <GitBranchIcon />\n <span className=\"ml-3\">AI Commit Message Generator</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Paste your diff and let Gemini craft the perfect commit message.</p>\n </header>\n <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden\">\n <div className=\"flex flex-col h-full\">\n <label htmlFor=\"diff-input\" className=\"text-sm font-medium text-slate-400 mb-2\">Git Diff</label>\n <textarea\n id=\"diff-input\"\n value={diff}\n onChange={(e) => setDiff(e.target.value)}\n placeholder=\"Paste your git diff here...\"\n className=\"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-slate-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none\"\n />\n <button\n onClick={handleGenerate}\n disabled={isLoading}\n className=\"mt-4 w-full flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 transition-colors disabled:bg-slate-600 disabled:cursor-not-allowed\"\n >\n {isLoading ? <LoadingSpinner /> : 'Generate Commit Message'}\n </button>\n </div>\n <div className=\"flex flex-col h-full\">\n <label className=\"text-sm font-medium text-slate-400 mb-2\">Generated Message</label>\n <div className=\"relative flex-grow p-4 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto\">\n {isLoading && (\n <div className=\"flex items-center justify-center h-full\">\n <LoadingSpinner />\n </div>\n )}\n {error && <p className=\"text-red-400\">{error}</p>}\n {message && !isLoading && (\n <>\n <button onClick={handleCopy} className=\"absolute top-2 right-2 px-2 py-1 bg-slate-700 hover:bg-slate-600 rounded-md text-xs\">Copy</button>\n <pre className=\"whitespace-pre-wrap font-sans text-slate-200\">{message}</pre>\n </>\n )}\n {!isLoading && !message && !error && (\n <div className=\"text-slate-500 h-full flex items-center justify-center\">\n The commit message will appear here.\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n};"],"names":["exampleDiff","AiCommitGenerator","diff","setDiff","useState","message","setMessage","isLoading","setIsLoading","error","setError","handleGenerate","useCallback","stream","generateCommitMessageStream","fullResponse","chunk","err","errorMessage","handleCopy","jsxs","jsx","GitBranchIcon","e","LoadingSpinner","Fragment"],"mappings":"yPAOA,MAAMA,EAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcPC,EAA8B,IAAM,CAC7C,KAAM,CAACC,EAAMC,CAAO,EAAIC,EAAAA,SAAiBJ,CAAW,EAC9C,CAACK,EAASC,CAAU,EAAIF,EAAAA,SAAiB,EAAE,EAC3C,CAACG,EAAWC,CAAY,EAAIJ,EAAAA,SAAkB,EAAK,EACnD,CAACK,EAAOC,CAAQ,EAAIN,EAAAA,SAAiB,EAAE,EAEvCO,EAAiBC,EAAAA,YAAY,SAAY,CAC3C,GAAI,CAACV,EAAK,OAAQ,CACdQ,EAAS,4CAA4C,EACrD,MACJ,CACAF,EAAa,EAAI,EACjBE,EAAS,EAAE,EACXJ,EAAW,EAAE,EACb,GAAI,CACA,MAAMO,EAASC,EAA4BZ,CAAI,EAC/C,IAAIa,EAAe,GACnB,gBAAiBC,KAASH,EACtBE,GAAgBC,EAChBV,EAAWS,CAAY,CAE/B,OAASE,EAAK,CACV,MAAMC,EAAeD,aAAe,MAAQA,EAAI,QAAU,6BAC1DP,EAAS,+BAA+BQ,CAAY,EAAE,CAC1D,QAAA,CACIV,EAAa,EAAK,CACtB,CACJ,EAAG,CAACN,CAAI,CAAC,EAEHiB,EAAa,IAAM,CACrB,UAAU,UAAU,UAAUd,CAAO,CACzC,EAEA,OACIe,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACX,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,OACd,SAAA,CAAAA,EAAAA,KAAC,KAAA,CAAG,UAAU,sDACV,SAAA,CAAAC,EAAAA,IAACC,EAAA,EAAc,EACfD,EAAAA,IAAC,OAAA,CAAK,UAAU,OAAO,SAAA,6BAAA,CAA2B,CAAA,EACtD,EACAA,EAAAA,IAAC,IAAA,CAAE,UAAU,sBAAsB,SAAA,kEAAA,CAAgE,CAAA,EACvG,EACAD,EAAAA,KAAC,MAAA,CAAI,UAAU,yEACX,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACX,SAAA,CAAAC,MAAC,QAAA,CAAM,QAAQ,aAAa,UAAU,0CAA0C,SAAA,WAAQ,EACxFA,EAAAA,IAAC,WAAA,CACG,GAAG,aACH,MAAOnB,EACP,SAAWqB,GAAMpB,EAAQoB,EAAE,OAAO,KAAK,EACvC,YAAY,8BACZ,UAAU,gKAAA,CAAA,EAEbF,EAAAA,IAAC,SAAA,CACE,QAASV,EACT,SAAUJ,EACV,UAAU,+LAET,SAAAA,EAAYc,EAAAA,IAACG,EAAA,CAAA,CAAe,EAAK,yBAAA,CAAA,CACtC,EACJ,EACAJ,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACX,SAAA,CAAAC,EAAAA,IAAC,QAAA,CAAM,UAAU,0CAA0C,SAAA,oBAAiB,EAC5ED,EAAAA,KAAC,MAAA,CAAI,UAAU,+FACV,SAAA,CAAAb,SACK,MAAA,CAAI,UAAU,0CACZ,SAAAc,MAACG,IAAe,EACnB,EAEJf,GAASY,EAAAA,IAAC,IAAA,CAAE,UAAU,eAAgB,SAAAZ,EAAM,EAC5CJ,GAAW,CAACE,GACTa,EAAAA,KAAAK,EAAAA,SAAA,CACG,SAAA,CAAAJ,MAAC,SAAA,CAAO,QAASF,EAAY,UAAU,sFAAsF,SAAA,OAAI,EACjIE,EAAAA,IAAC,MAAA,CAAI,UAAU,+CAAgD,SAAAhB,CAAA,CAAQ,CAAA,EAC1E,EAEF,CAACE,GAAa,CAACF,GAAW,CAACI,GACzBY,EAAAA,IAAC,MAAA,CAAI,UAAU,yDAAyD,SAAA,sCAAA,CAExE,CAAA,CAAA,CAER,CAAA,CAAA,CACJ,CAAA,CAAA,CACJ,CAAA,EACJ,CAER"}
|
assets/AiFeatureBuilder-P_ujuQBI.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as s,j as e}from"./react-D_B_5QVd.js";import{b as F,s as S,c as E,d as T,a as D,D as O,f as M}from"./index-QBya0NjG.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const P=()=>e.jsxs("div",{className:"flex items-center justify-center space-x-2",children:[e.jsx("div",{className:"w-2 h-2 rounded-full bg-cyan-400 animate-pulse",style:{animationDelay:"0s"}}),e.jsx("div",{className:"w-2 h-2 rounded-full bg-cyan-400 animate-pulse",style:{animationDelay:"0.2s"}}),e.jsx("div",{className:"w-2 h-2 rounded-full bg-cyan-400 animate-pulse",style:{animationDelay:"0.4s"}})]}),R=()=>{const[r,w]=s.useState('A simple "Hello World" React component with a button that shows an alert.'),[u,c]=s.useState([]),[f,p]=s.useState(""),[h,g]=s.useState(""),[n,i]=s.useState(null),[m,b]=s.useState(!1),[j,d]=s.useState(""),[o,x]=s.useState("CODE");s.useEffect(()=>{(async()=>{const a=await M();c(a),a.length>0&&i(a[0])})()},[]);const N=s.useCallback(async()=>{if(!r.trim()){d("Please enter a feature description.");return}b(!0),d(""),c([]),p(""),g(""),i(null),x("CODE");try{const t=await F(r);c(t);for(const l of t)await S(l);t.length>0&&i(t[0]);const a=t.find(l=>l.filePath.endsWith(".tsx"));if(a){const l=await E(a.content);p(l)}const v=t.map(l=>`File: ${l.filePath}
|
| 2 |
+
|
| 3 |
+
${l.content}`).join(`
|
| 4 |
+
---
|
| 5 |
+
`),C=await T(v);g(C)}catch(t){const a=t instanceof Error?t.message:"An unknown error occurred.";d(`Failed to generate feature: ${a}`),console.error(a)}finally{b(!1)}},[r]),y=()=>{switch(o){case"TESTS":return e.jsx("pre",{className:"w-full h-full p-4 bg-transparent resize-none font-mono text-sm text-cyan-300 whitespace-pre-wrap",children:f});case"COMMIT":return e.jsx("pre",{className:"w-full h-full p-4 bg-transparent resize-none font-sans text-sm text-slate-200 whitespace-pre-wrap",children:h});case"CODE":default:return n?e.jsx("textarea",{readOnly:!0,value:n.content,className:"w-full h-full p-4 bg-transparent resize-none font-mono text-sm text-cyan-300 focus:outline-none"}):e.jsx("div",{className:"flex items-center justify-center h-full text-slate-500",children:m?"Generating files...":"Generated files will appear here."})}};return e.jsxs("div",{className:"h-full flex flex-col text-slate-300",children:[e.jsxs("header",{className:"p-4 border-b border-slate-800 flex-shrink-0",children:[e.jsxs("h1",{className:"text-xl font-bold text-slate-100 flex items-center",children:[e.jsx(D,{}),e.jsx("span",{className:"ml-3",children:"AI Feature Builder"})]}),e.jsx("p",{className:"text-slate-400 mt-1 text-sm",children:"Describe a new feature, and watch Gemini build the code, tests, and commit message."})]}),e.jsxs("div",{className:"flex-grow flex min-h-0",children:[e.jsxs("aside",{className:"w-64 bg-slate-900/70 border-r border-slate-800 p-4 flex flex-col space-y-2 overflow-y-auto",children:[e.jsx("h2",{className:"text-sm font-semibold text-slate-400 mb-2",children:"Generated Files"}),u.map(t=>e.jsxs("div",{onClick:()=>{i(t),x("CODE")},className:`flex items-center space-x-2 p-2 rounded-md cursor-pointer text-sm ${(n==null?void 0:n.filePath)===t.filePath&&o==="CODE"?"bg-cyan-500/20 text-cyan-300":"hover:bg-slate-800"}`,children:[e.jsx(O,{}),e.jsx("span",{children:t.filePath.split("/").pop()})]},t.filePath))]}),e.jsxs("main",{className:"flex-1 flex flex-col min-w-0",children:[e.jsxs("div",{className:"flex-grow flex flex-col bg-slate-900",children:[e.jsxs("div",{className:"border-b border-slate-800 flex items-center justify-between",children:[e.jsx("div",{className:"flex",children:u.length>0&&["CODE","TESTS","COMMIT"].map(t=>t==="TESTS"&&!f||t==="COMMIT"&&!h?null:e.jsx("button",{onClick:()=>x(t),className:`px-4 py-2 text-sm ${o===t?"bg-slate-800 text-slate-100":"text-slate-400"}`,children:t},t))}),n&&o==="CODE"&&e.jsx("h3",{className:"font-mono text-sm text-slate-400 pr-4",children:n.filePath})]}),y()]}),e.jsx("div",{className:"flex-shrink-0 p-4 border-t border-slate-800",children:e.jsxs("div",{className:"flex flex-col",children:[e.jsx("label",{htmlFor:"prompt-input",className:"text-sm font-medium text-slate-400 mb-2",children:"Feature Request"}),e.jsx("textarea",{id:"prompt-input",value:r,onChange:t=>w(t.target.value),placeholder:"e.g., A user profile card with an avatar, name, and bio.",className:"p-2 bg-slate-800 border border-slate-700 rounded-md resize-none text-sm text-slate-300 h-24"}),e.jsx("button",{onClick:N,disabled:m,className:"mt-2 w-full flex items-center justify-center gap-2 px-4 py-2 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600",children:m?e.jsxs(e.Fragment,{children:[e.jsx(P,{})," Generating..."]}):"Generate Feature"}),j&&e.jsx("p",{className:"text-red-400 text-xs mt-2 text-center",children:j})]})})]})]})]})};export{R as AiFeatureBuilder};
|
| 6 |
+
//# sourceMappingURL=AiFeatureBuilder-P_ujuQBI.js.map
|
assets/AiFeatureBuilder-P_ujuQBI.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"AiFeatureBuilder-P_ujuQBI.js","sources":["../../components/features/AiFeatureBuilder.tsx"],"sourcesContent":["\n\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport type { GeneratedFile } from '../../types.ts';\nimport { generateFeature, generateUnitTests, generateCommitMessage } from '../../services/geminiService.ts';\nimport { saveFile, getAllFiles } from '../../services/dbService.ts';\nimport { CpuChipIcon, DocumentIcon } from '../icons/InterfaceIcons.tsx';\n\nconst LoadingSpinner: React.FC = () => (\n <div className=\"flex items-center justify-center space-x-2\">\n <div className=\"w-2 h-2 rounded-full bg-cyan-400 animate-pulse\" style={{ animationDelay: '0s' }}></div>\n <div className=\"w-2 h-2 rounded-full bg-cyan-400 animate-pulse\" style={{ animationDelay: '0.2s' }}></div>\n <div className=\"w-2 h-2 rounded-full bg-cyan-400 animate-pulse\" style={{ animationDelay: '0.4s' }}></div>\n </div>\n);\n\ntype ActiveTab = 'CODE' | 'TESTS' | 'COMMIT';\n\nexport const AiFeatureBuilder: React.FC = () => {\n const [prompt, setPrompt] = useState<string>('A simple \"Hello World\" React component with a button that shows an alert.');\n const [generatedFiles, setGeneratedFiles] = useState<GeneratedFile[]>([]);\n const [unitTests, setUnitTests] = useState<string>('');\n const [commitMessage, setCommitMessage] = useState<string>('');\n const [selectedFile, setSelectedFile] = useState<GeneratedFile | null>(null);\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<string>('');\n const [activeTab, setActiveTab] = useState<ActiveTab>('CODE');\n \n useEffect(() => {\n const loadFiles = async () => {\n const files = await getAllFiles();\n setGeneratedFiles(files);\n if (files.length > 0) {\n setSelectedFile(files[0]);\n }\n };\n loadFiles();\n }, []);\n\n const handleGenerate = useCallback(async () => {\n if (!prompt.trim()) {\n setError('Please enter a feature description.');\n return;\n }\n setIsLoading(true);\n setError('');\n setGeneratedFiles([]);\n setUnitTests('');\n setCommitMessage('');\n setSelectedFile(null);\n setActiveTab('CODE');\n\n try {\n // 1. Generate feature files\n const resultFiles = await generateFeature(prompt);\n setGeneratedFiles(resultFiles);\n\n for (const file of resultFiles) {\n await saveFile(file);\n }\n\n if (resultFiles.length > 0) {\n setSelectedFile(resultFiles[0]);\n }\n\n // 2. Generate Unit Tests\n const componentFile = resultFiles.find(f => f.filePath.endsWith('.tsx'));\n if (componentFile) {\n const tests = await generateUnitTests(componentFile.content);\n setUnitTests(tests);\n }\n\n // 3. Generate Commit Message\n const diffContext = resultFiles.map(f => `File: ${f.filePath}\\n\\n${f.content}`).join('\\n---\\n');\n const commit = await generateCommitMessage(diffContext);\n setCommitMessage(commit);\n\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';\n setError(`Failed to generate feature: ${errorMessage}`);\n console.error(errorMessage);\n } finally {\n setIsLoading(false);\n }\n }, [prompt]);\n\n const renderContent = () => {\n switch (activeTab) {\n case 'TESTS':\n return <pre className=\"w-full h-full p-4 bg-transparent resize-none font-mono text-sm text-cyan-300 whitespace-pre-wrap\">{unitTests}</pre>\n case 'COMMIT':\n return <pre className=\"w-full h-full p-4 bg-transparent resize-none font-sans text-sm text-slate-200 whitespace-pre-wrap\">{commitMessage}</pre>\n case 'CODE':\n default:\n return selectedFile ? (\n <textarea\n readOnly\n value={selectedFile.content}\n className=\"w-full h-full p-4 bg-transparent resize-none font-mono text-sm text-cyan-300 focus:outline-none\"\n />\n ) : (\n <div className=\"flex items-center justify-center h-full text-slate-500\">\n {isLoading ? 'Generating files...' : 'Generated files will appear here.'}\n </div>\n )\n }\n }\n\n return (\n <div className=\"h-full flex flex-col text-slate-300\">\n <header className=\"p-4 border-b border-slate-800 flex-shrink-0\">\n <h1 className=\"text-xl font-bold text-slate-100 flex items-center\"><CpuChipIcon /><span className=\"ml-3\">AI Feature Builder</span></h1>\n <p className=\"text-slate-400 mt-1 text-sm\">Describe a new feature, and watch Gemini build the code, tests, and commit message.</p>\n </header>\n\n <div className=\"flex-grow flex min-h-0\">\n <aside className=\"w-64 bg-slate-900/70 border-r border-slate-800 p-4 flex flex-col space-y-2 overflow-y-auto\">\n <h2 className=\"text-sm font-semibold text-slate-400 mb-2\">Generated Files</h2>\n {generatedFiles.map(file => (\n <div key={file.filePath} onClick={() => { setSelectedFile(file); setActiveTab('CODE'); }} className={`flex items-center space-x-2 p-2 rounded-md cursor-pointer text-sm ${selectedFile?.filePath === file.filePath && activeTab === 'CODE' ? 'bg-cyan-500/20 text-cyan-300' : 'hover:bg-slate-800'}`}>\n <DocumentIcon /><span>{file.filePath.split('/').pop()}</span>\n </div>\n ))}\n </aside>\n\n <main className=\"flex-1 flex flex-col min-w-0\">\n <div className=\"flex-grow flex flex-col bg-slate-900\">\n <div className=\"border-b border-slate-800 flex items-center justify-between\">\n <div className=\"flex\">\n {generatedFiles.length > 0 && ['CODE', 'TESTS', 'COMMIT'].map(tab => {\n if (tab === 'TESTS' && !unitTests) return null;\n if (tab === 'COMMIT' && !commitMessage) return null;\n return <button key={tab} onClick={() => setActiveTab(tab as ActiveTab)} className={`px-4 py-2 text-sm ${activeTab === tab ? 'bg-slate-800 text-slate-100' : 'text-slate-400'}`}>{tab}</button>\n })}\n </div>\n {selectedFile && activeTab==='CODE' && <h3 className=\"font-mono text-sm text-slate-400 pr-4\">{selectedFile.filePath}</h3>}\n </div>\n {renderContent()}\n </div>\n \n <div className=\"flex-shrink-0 p-4 border-t border-slate-800\">\n <div className=\"flex flex-col\">\n <label htmlFor=\"prompt-input\" className=\"text-sm font-medium text-slate-400 mb-2\">Feature Request</label>\n <textarea id=\"prompt-input\" value={prompt} onChange={(e) => setPrompt(e.target.value)} placeholder=\"e.g., A user profile card with an avatar, name, and bio.\" className=\"p-2 bg-slate-800 border border-slate-700 rounded-md resize-none text-sm text-slate-300 h-24\"/>\n <button onClick={handleGenerate} disabled={isLoading} className=\"mt-2 w-full flex items-center justify-center gap-2 px-4 py-2 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600\">\n {isLoading ? <><LoadingSpinner /> Generating...</> : 'Generate Feature'}\n </button>\n {error && <p className=\"text-red-400 text-xs mt-2 text-center\">{error}</p>}\n </div>\n </div>\n </main>\n </div>\n </div>\n );\n};"],"names":["LoadingSpinner","jsxs","jsx","AiFeatureBuilder","prompt","setPrompt","useState","generatedFiles","setGeneratedFiles","unitTests","setUnitTests","commitMessage","setCommitMessage","selectedFile","setSelectedFile","isLoading","setIsLoading","error","setError","activeTab","setActiveTab","useEffect","files","getAllFiles","handleGenerate","useCallback","resultFiles","generateFeature","file","saveFile","componentFile","f","tests","generateUnitTests","diffContext","commit","generateCommitMessage","err","errorMessage","renderContent","CpuChipIcon","DocumentIcon","tab","e","Fragment"],"mappings":"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"}
|
assets/AiStyleTransfer-C0syujQ9.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as t,j as e}from"./react-D_B_5QVd.js";import{t as b,S as y,L as u}from"./index-QBya0NjG.js";import{m as N}from"./marked-CesSW9Du.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const v="function my_func(x,y){return x+y;}",w=`- Use camelCase for function names.
|
| 2 |
+
- Add a space after commas in argument lists.
|
| 3 |
+
- Use semicolons at the end of statements.`,L=()=>{const[o,f]=t.useState(v),[n,p]=t.useState(w),[a,c]=t.useState(""),[r,m]=t.useState(!1),[d,i]=t.useState(""),[h,x]=t.useState("");t.useEffect(()=>{(async()=>{if(a){const l=await N.parse(a);x(l)}else x("")})()},[a]);const g=t.useCallback(async()=>{if(!o.trim()||!n.trim()){i("Please provide both code and a style guide.");return}m(!0),i(""),c("");try{const s=b({code:o,styleGuide:n});let l="";for await(const j of s)l+=j,c(l)}catch(s){const l=s instanceof Error?s.message:"An unknown error occurred.";i(`Failed to transfer style: ${l}`)}finally{m(!1)}},[o,n]);return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(y,{}),e.jsx("span",{className:"ml-3",children:"AI Code Style Transfer"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Rewrite code to match a specific style guide using AI."})]}),e.jsxs("div",{className:"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden",children:[e.jsxs("div",{className:"flex flex-col h-full gap-4",children:[e.jsxs("div",{className:"flex flex-col flex-1",children:[e.jsx("label",{htmlFor:"input-code",className:"text-sm font-medium text-slate-400 mb-2",children:"Original Code"}),e.jsx("textarea",{id:"input-code",value:o,onChange:s=>f(s.target.value),className:"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm"})]}),e.jsxs("div",{className:"flex flex-col flex-1",children:[e.jsx("label",{htmlFor:"style-guide",className:"text-sm font-medium text-slate-400 mb-2",children:"Style Guide"}),e.jsx("textarea",{id:"style-guide",value:n,onChange:s=>p(s.target.value),className:"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm"})]})]}),e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{className:"text-sm font-medium text-slate-400 mb-2",children:"Rewritten Code"}),e.jsxs("div",{className:"flex-grow p-1 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto",children:[r&&e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsx(u,{})}),d&&e.jsx("p",{className:"p-4 text-red-400",children:d}),a&&!r&&e.jsx("div",{className:"prose prose-sm prose-invert max-w-none prose-pre:bg-transparent prose-pre:p-4 prose-pre:m-0",dangerouslySetInnerHTML:{__html:h}}),!r&&!a&&!d&&e.jsx("div",{className:"text-slate-500 h-full flex items-center justify-center",children:"Rewritten code will appear here."})]})]})]}),e.jsx("div",{className:"flex-shrink-0 pt-4",children:e.jsx("button",{onClick:g,disabled:r,className:"w-full max-w-md mx-auto flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600",children:r?e.jsx(u,{}):"Rewrite Code"})})]})};export{L as AiStyleTransfer};
|
| 4 |
+
//# sourceMappingURL=AiStyleTransfer-C0syujQ9.js.map
|
assets/AiStyleTransfer-C0syujQ9.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"AiStyleTransfer-C0syujQ9.js","sources":["../../components/features/AiStyleTransfer.tsx"],"sourcesContent":["\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport { transferCodeStyleStream } from '../../services/geminiService.ts';\nimport { SparklesIcon } from '../icons/FeatureIcons.tsx';\nimport { LoadingSpinner } from '../shared/LoadingSpinner.tsx';\nimport { marked } from 'marked';\n\nconst exampleCode = `function my_func(x,y){return x+y;}`;\nconst exampleStyleGuide = `- Use camelCase for function names.\n- Add a space after commas in argument lists.\n- Use semicolons at the end of statements.`;\n\nexport const AiStyleTransfer: React.FC = () => {\n const [inputCode, setInputCode] = useState<string>(exampleCode);\n const [styleGuide, setStyleGuide] = useState<string>(exampleStyleGuide);\n const [outputCode, setOutputCode] = useState<string>('');\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<string>('');\n const [outputCodeHtml, setOutputCodeHtml] = useState<string | TrustedHTML>('');\n\n useEffect(() => {\n const parse = async () => {\n if (outputCode) {\n const html = await marked.parse(outputCode);\n setOutputCodeHtml(html);\n } else {\n setOutputCodeHtml('');\n }\n };\n parse();\n }, [outputCode]);\n\n const handleGenerate = useCallback(async () => {\n if (!inputCode.trim() || !styleGuide.trim()) {\n setError('Please provide both code and a style guide.');\n return;\n }\n setIsLoading(true);\n setError('');\n setOutputCode('');\n try {\n const stream = transferCodeStyleStream({ code: inputCode, styleGuide });\n let fullResponse = '';\n for await (const chunk of stream) {\n fullResponse += chunk;\n setOutputCode(fullResponse);\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';\n setError(`Failed to transfer style: ${errorMessage}`);\n } finally {\n setIsLoading(false);\n }\n }, [inputCode, styleGuide]);\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <SparklesIcon />\n <span className=\"ml-3\">AI Code Style Transfer</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Rewrite code to match a specific style guide using AI.</p>\n </header>\n <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden\">\n <div className=\"flex flex-col h-full gap-4\">\n <div className=\"flex flex-col flex-1\">\n <label htmlFor=\"input-code\" className=\"text-sm font-medium text-slate-400 mb-2\">Original Code</label>\n <textarea\n id=\"input-code\"\n value={inputCode}\n onChange={(e) => setInputCode(e.target.value)}\n className=\"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm\"\n />\n </div>\n <div className=\"flex flex-col flex-1\">\n <label htmlFor=\"style-guide\" className=\"text-sm font-medium text-slate-400 mb-2\">Style Guide</label>\n <textarea\n id=\"style-guide\"\n value={styleGuide}\n onChange={(e) => setStyleGuide(e.target.value)}\n className=\"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm\"\n />\n </div>\n </div>\n <div className=\"flex flex-col h-full\">\n <label className=\"text-sm font-medium text-slate-400 mb-2\">Rewritten Code</label>\n <div className=\"flex-grow p-1 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto\">\n {isLoading && <div className=\"flex items-center justify-center h-full\"><LoadingSpinner /></div>}\n {error && <p className=\"p-4 text-red-400\">{error}</p>}\n {outputCode && !isLoading && (\n <div\n className=\"prose prose-sm prose-invert max-w-none prose-pre:bg-transparent prose-pre:p-4 prose-pre:m-0\"\n dangerouslySetInnerHTML={{ __html: outputCodeHtml }}\n />\n )}\n {!isLoading && !outputCode && !error && <div className=\"text-slate-500 h-full flex items-center justify-center\">Rewritten code will appear here.</div>}\n </div>\n </div>\n </div>\n <div className=\"flex-shrink-0 pt-4\">\n <button\n onClick={handleGenerate}\n disabled={isLoading}\n className=\"w-full max-w-md mx-auto flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600\"\n >\n {isLoading ? <LoadingSpinner /> : 'Rewrite Code'}\n </button>\n </div>\n </div>\n );\n};"],"names":["exampleCode","exampleStyleGuide","AiStyleTransfer","inputCode","setInputCode","useState","styleGuide","setStyleGuide","outputCode","setOutputCode","isLoading","setIsLoading","error","setError","outputCodeHtml","setOutputCodeHtml","useEffect","html","marked","handleGenerate","useCallback","stream","transferCodeStyleStream","fullResponse","chunk","err","errorMessage","jsxs","jsx","SparklesIcon","e","LoadingSpinner"],"mappings":"kSAQA,MAAMA,EAAc,qCACdC,EAAoB;AAAA;AAAA,4CAIbC,EAA4B,IAAM,CAC3C,KAAM,CAACC,EAAWC,CAAY,EAAIC,EAAAA,SAAiBL,CAAW,EACxD,CAACM,EAAYC,CAAa,EAAIF,EAAAA,SAAiBJ,CAAiB,EAChE,CAACO,EAAYC,CAAa,EAAIJ,EAAAA,SAAiB,EAAE,EACjD,CAACK,EAAWC,CAAY,EAAIN,EAAAA,SAAkB,EAAK,EACnD,CAACO,EAAOC,CAAQ,EAAIR,EAAAA,SAAiB,EAAE,EACvC,CAACS,EAAgBC,CAAiB,EAAIV,EAAAA,SAA+B,EAAE,EAE7EW,EAAAA,UAAU,IAAM,EACE,SAAY,CACtB,GAAIR,EAAY,CACZ,MAAMS,EAAO,MAAMC,EAAO,MAAMV,CAAU,EAC1CO,EAAkBE,CAAI,CAC1B,MACIF,EAAkB,EAAE,CAE5B,GACA,CACJ,EAAG,CAACP,CAAU,CAAC,EAEf,MAAMW,EAAiBC,EAAAA,YAAY,SAAY,CAC3C,GAAI,CAACjB,EAAU,KAAA,GAAU,CAACG,EAAW,OAAQ,CACzCO,EAAS,6CAA6C,EACtD,MACJ,CACAF,EAAa,EAAI,EACjBE,EAAS,EAAE,EACXJ,EAAc,EAAE,EAChB,GAAI,CACA,MAAMY,EAASC,EAAwB,CAAE,KAAMnB,EAAW,WAAAG,EAAY,EACtE,IAAIiB,EAAe,GACnB,gBAAiBC,KAASH,EACtBE,GAAgBC,EAChBf,EAAcc,CAAY,CAElC,OAASE,EAAK,CACV,MAAMC,EAAeD,aAAe,MAAQA,EAAI,QAAU,6BAC1DZ,EAAS,6BAA6Ba,CAAY,EAAE,CACxD,QAAA,CACIf,EAAa,EAAK,CACtB,CACJ,EAAG,CAACR,EAAWG,CAAU,CAAC,EAE1B,OACIqB,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACX,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,OACd,SAAA,CAAAA,EAAAA,KAAC,KAAA,CAAG,UAAU,sDACV,SAAA,CAAAC,EAAAA,IAACC,EAAA,EAAa,EACdD,EAAAA,IAAC,OAAA,CAAK,UAAU,OAAO,SAAA,wBAAA,CAAsB,CAAA,EACjD,EACAA,EAAAA,IAAC,IAAA,CAAE,UAAU,sBAAsB,SAAA,wDAAA,CAAsD,CAAA,EAC7F,EACAD,EAAAA,KAAC,MAAA,CAAI,UAAU,yEACX,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,6BACX,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACX,SAAA,CAAAC,MAAC,QAAA,CAAM,QAAQ,aAAa,UAAU,0CAA0C,SAAA,gBAAa,EAC7FA,EAAAA,IAAC,WAAA,CACG,GAAG,aACH,MAAOzB,EACP,SAAW2B,GAAM1B,EAAa0B,EAAE,OAAO,KAAK,EAC5C,UAAU,6FAAA,CAAA,CACd,EACJ,EACAH,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACX,SAAA,CAAAC,MAAC,QAAA,CAAM,QAAQ,cAAc,UAAU,0CAA0C,SAAA,cAAW,EAC5FA,EAAAA,IAAC,WAAA,CACG,GAAG,cACH,MAAOtB,EACP,SAAWwB,GAAMvB,EAAcuB,EAAE,OAAO,KAAK,EAC7C,UAAU,6FAAA,CAAA,CACd,CAAA,CACJ,CAAA,EACJ,EACAH,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACX,SAAA,CAAAC,EAAAA,IAAC,QAAA,CAAM,UAAU,0CAA0C,SAAA,iBAAc,EACzED,EAAAA,KAAC,MAAA,CAAI,UAAU,sFACV,SAAA,CAAAjB,SAAc,MAAA,CAAI,UAAU,0CAA0C,SAAAkB,MAACG,IAAe,EAAE,EACxFnB,GAASgB,EAAAA,IAAC,IAAA,CAAE,UAAU,mBAAoB,SAAAhB,EAAM,EAChDJ,GAAc,CAACE,GACZkB,EAAAA,IAAC,MAAA,CACG,UAAU,8FACV,wBAAyB,CAAE,OAAQd,CAAA,CAAe,CAAA,EAGxD,CAACJ,GAAa,CAACF,GAAc,CAACI,GAASgB,EAAAA,IAAC,MAAA,CAAI,UAAU,yDAAyD,SAAA,kCAAA,CAAgC,CAAA,CAAA,CACrJ,CAAA,CAAA,CACJ,CAAA,EACJ,EACAA,EAAAA,IAAC,MAAA,CAAI,UAAU,qBACX,SAAAA,EAAAA,IAAC,SAAA,CACG,QAAST,EACT,SAAUT,EACV,UAAU,6JAET,SAAAA,EAAYkB,EAAAA,IAACG,EAAA,CAAA,CAAe,EAAK,cAAA,CAAA,CACtC,CACJ,CAAA,EACJ,CAER"}
|
assets/AiUnitTestGenerator-DnqoljB0.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as s,j as e}from"./react-D_B_5QVd.js";import{n as g,B as j,L as x}from"./index-QBya0NjG.js";import{m as b}from"./marked-CesSW9Du.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const y=`export function calculateTotalPrice(items, taxRate) {
|
| 2 |
+
const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
| 3 |
+
return subtotal * (1 + taxRate);
|
| 4 |
+
}`,G=()=>{const[o,u]=s.useState(y),[a,i]=s.useState(""),[l,d]=s.useState(!1),[n,c]=s.useState(""),[f,m]=s.useState("");s.useEffect(()=>{(async()=>{if(a){const r=await b.parse(a);m(r)}else m("")})()},[a]);const p=s.useCallback(async()=>{if(!o.trim()){c("Please enter some code to generate tests for.");return}d(!0),c(""),i("");try{const t=g(o);let r="";for await(const h of t)r+=h,i(r)}catch(t){const r=t instanceof Error?t.message:"An unknown error occurred.";c(`Failed to generate tests: ${r}`)}finally{d(!1)}},[o]);return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(j,{}),e.jsx("span",{className:"ml-3",children:"AI Unit Test Generator"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Provide a function or component and let AI write the tests."})]}),e.jsxs("div",{className:"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden",children:[e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{htmlFor:"code-input",className:"text-sm font-medium text-slate-400 mb-2",children:"Source Code"}),e.jsx("textarea",{id:"code-input",value:o,onChange:t=>u(t.target.value),placeholder:"Paste your source code here...",className:"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-cyan-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none"}),e.jsx("button",{onClick:p,disabled:l,className:"mt-4 w-full flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 transition-colors disabled:bg-slate-600 disabled:cursor-not-allowed",children:l?e.jsx(x,{}):"Generate Unit Tests"})]}),e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{className:"text-sm font-medium text-slate-400 mb-2",children:"Generated Tests"}),e.jsxs("div",{className:"flex-grow p-1 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto",children:[l&&e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsx(x,{})}),n&&e.jsx("p",{className:"p-4 text-red-400",children:n}),a&&!l&&e.jsx("div",{className:"prose prose-sm prose-invert max-w-none prose-pre:bg-transparent prose-pre:p-4 prose-pre:m-0 prose-code:text-cyan-300",dangerouslySetInnerHTML:{__html:f}}),!l&&!a&&!n&&e.jsx("div",{className:"text-slate-500 h-full flex items-center justify-center",children:"The generated tests will appear here."})]})]})]})]})};export{G as AiUnitTestGenerator};
|
| 5 |
+
//# sourceMappingURL=AiUnitTestGenerator-DnqoljB0.js.map
|
assets/AiUnitTestGenerator-DnqoljB0.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"AiUnitTestGenerator-DnqoljB0.js","sources":["../../components/features/AiUnitTestGenerator.tsx"],"sourcesContent":["\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport { generateUnitTestsStream } from '../../services/geminiService.ts';\nimport { BeakerIcon } from '../icons/FeatureIcons.tsx';\nimport { LoadingSpinner } from '../shared/LoadingSpinner.tsx';\nimport { marked } from 'marked';\n\nconst exampleCode = `export function calculateTotalPrice(items, taxRate) {\n const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);\n return subtotal * (1 + taxRate);\n}`;\n\nexport const AiUnitTestGenerator: React.FC = () => {\n const [code, setCode] = useState<string>(exampleCode);\n const [tests, setTests] = useState<string>('');\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<string>('');\n const [testsHtml, setTestsHtml] = useState<string | TrustedHTML>('');\n\n useEffect(() => {\n const parse = async () => {\n if (tests) {\n const html = await marked.parse(tests);\n setTestsHtml(html);\n } else {\n setTestsHtml('');\n }\n };\n parse();\n }, [tests]);\n\n const handleGenerate = useCallback(async () => {\n if (!code.trim()) {\n setError('Please enter some code to generate tests for.');\n return;\n }\n setIsLoading(true);\n setError('');\n setTests('');\n try {\n const stream = generateUnitTestsStream(code);\n let fullResponse = '';\n for await (const chunk of stream) {\n fullResponse += chunk;\n setTests(fullResponse);\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';\n setError(`Failed to generate tests: ${errorMessage}`);\n } finally {\n setIsLoading(false);\n }\n }, [code]);\n\n const cleanMarkdown = (md: string) => md.replace(/^```(?:\\w+\\n)?/, '').replace(/```$/, '');\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <BeakerIcon />\n <span className=\"ml-3\">AI Unit Test Generator</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Provide a function or component and let AI write the tests.</p>\n </header>\n <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden\">\n <div className=\"flex flex-col h-full\">\n <label htmlFor=\"code-input\" className=\"text-sm font-medium text-slate-400 mb-2\">Source Code</label>\n <textarea\n id=\"code-input\"\n value={code}\n onChange={(e) => setCode(e.target.value)}\n placeholder=\"Paste your source code here...\"\n className=\"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-cyan-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none\"\n />\n <button\n onClick={handleGenerate}\n disabled={isLoading}\n className=\"mt-4 w-full flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 transition-colors disabled:bg-slate-600 disabled:cursor-not-allowed\"\n >\n {isLoading ? <LoadingSpinner /> : 'Generate Unit Tests'}\n </button>\n </div>\n <div className=\"flex flex-col h-full\">\n <label className=\"text-sm font-medium text-slate-400 mb-2\">Generated Tests</label>\n <div className=\"flex-grow p-1 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto\">\n {isLoading && (\n <div className=\"flex items-center justify-center h-full\">\n <LoadingSpinner />\n </div>\n )}\n {error && <p className=\"p-4 text-red-400\">{error}</p>}\n {tests && !isLoading && (\n <div\n className=\"prose prose-sm prose-invert max-w-none prose-pre:bg-transparent prose-pre:p-4 prose-pre:m-0 prose-code:text-cyan-300\"\n dangerouslySetInnerHTML={{ __html: testsHtml }}\n />\n )}\n {!isLoading && !tests && !error && (\n <div className=\"text-slate-500 h-full flex items-center justify-center\">\n The generated tests will appear here.\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n};"],"names":["exampleCode","AiUnitTestGenerator","code","setCode","useState","tests","setTests","isLoading","setIsLoading","error","setError","testsHtml","setTestsHtml","useEffect","html","marked","handleGenerate","useCallback","stream","generateUnitTestsStream","fullResponse","chunk","err","errorMessage","jsxs","jsx","BeakerIcon","e","LoadingSpinner"],"mappings":"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"}
|
assets/ChangelogGenerator-tkGkQ38b.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as s,j as e}from"./react-D_B_5QVd.js";import{z as h,G as f,L as d}from"./index-QBya0NjG.js";import{M as p}from"./MarkdownRenderer-BDaVxTSW.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";import"./marked-CesSW9Du.js";const b=`commit 3a4b5c...
|
| 2 |
+
Author: Dev One <dev.one@example.com>
|
| 3 |
+
Date: Mon Jul 15 11:30:00 2024 -0400
|
| 4 |
+
|
| 5 |
+
feat: add user login page
|
| 6 |
+
|
| 7 |
+
commit 1a2b3c...
|
| 8 |
+
Author: Dev Two <dev.two@example.com>
|
| 9 |
+
Date: Mon Jul 15 10:00:00 2024 -0400
|
| 10 |
+
|
| 11 |
+
fix: correct typo in header
|
| 12 |
+
`,S=()=>{const[a,x]=s.useState(b),[o,n]=s.useState(""),[l,c]=s.useState(!1),[i,r]=s.useState(""),g=s.useCallback(async()=>{if(!a.trim()){r("Please paste your git log output.");return}c(!0),r(""),n("");try{const t=h(a);let m="";for await(const u of t)m+=u,n(m)}catch(t){r(t instanceof Error?t.message:"An unknown error occurred.")}finally{c(!1)}},[a]);return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(f,{}),e.jsx("span",{className:"ml-3",children:"AI Changelog Generator"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Generate a markdown changelog from your raw git log."})]}),e.jsxs("div",{className:"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden",children:[e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{htmlFor:"commit-input",className:"text-sm font-medium text-slate-400 mb-2",children:"Raw Git Log"}),e.jsx("textarea",{id:"commit-input",value:a,onChange:t=>x(t.target.value),className:"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm"}),e.jsx("button",{onClick:g,disabled:l,className:"mt-4 w-full flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600",children:l?e.jsx(d,{}):"Generate Changelog"})]}),e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{className:"text-sm font-medium text-slate-400 mb-2",children:"Generated Changelog.md"}),e.jsxs("div",{className:"relative flex-grow p-4 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto",children:[l&&!o&&e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsx(d,{})}),i&&e.jsx("p",{className:"text-red-400",children:i}),o&&e.jsx(p,{content:o}),e.jsx("button",{onClick:()=>navigator.clipboard.writeText(o),className:"absolute top-2 right-2 px-2 py-1 bg-slate-700 hover:bg-slate-600 rounded-md text-xs",children:"Copy"})]})]})]})]})};export{S as ChangelogGenerator};
|
| 13 |
+
//# sourceMappingURL=ChangelogGenerator-tkGkQ38b.js.map
|
assets/ChangelogGenerator-tkGkQ38b.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"ChangelogGenerator-tkGkQ38b.js","sources":["../../components/features/ChangelogGenerator.tsx"],"sourcesContent":["\n\nimport React, { useState, useCallback } from 'react';\nimport { generateChangelogFromLogStream } from '../../services/geminiService.ts';\nimport { GitBranchIcon } from '../icons/FeatureIcons.tsx';\nimport { LoadingSpinner } from '../shared/LoadingSpinner.tsx';\nimport { MarkdownRenderer } from '../shared/MarkdownRenderer.tsx';\n\nconst exampleLog = `commit 3a4b5c...\nAuthor: Dev One <dev.one@example.com>\nDate: Mon Jul 15 11:30:00 2024 -0400\n\n feat: add user login page\n\ncommit 1a2b3c...\nAuthor: Dev Two <dev.two@example.com>\nDate: Mon Jul 15 10:00:00 2024 -0400\n\n fix: correct typo in header\n`;\n\nexport const ChangelogGenerator: React.FC = () => {\n const [log, setLog] = useState(exampleLog);\n const [changelog, setChangelog] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState('');\n\n const handleGenerate = useCallback(async () => {\n if (!log.trim()) {\n setError('Please paste your git log output.');\n return;\n }\n setIsLoading(true);\n setError('');\n setChangelog('');\n try {\n const stream = generateChangelogFromLogStream(log);\n let fullResponse = '';\n for await (const chunk of stream) {\n fullResponse += chunk;\n setChangelog(fullResponse);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'An unknown error occurred.');\n } finally {\n setIsLoading(false);\n }\n }, [log]);\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <GitBranchIcon />\n <span className=\"ml-3\">AI Changelog Generator</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Generate a markdown changelog from your raw git log.</p>\n </header>\n <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden\">\n <div className=\"flex flex-col h-full\">\n <label htmlFor=\"commit-input\" className=\"text-sm font-medium text-slate-400 mb-2\">Raw Git Log</label>\n <textarea\n id=\"commit-input\"\n value={log}\n onChange={(e) => setLog(e.target.value)}\n className=\"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm\"\n />\n <button onClick={handleGenerate} disabled={isLoading} className=\"mt-4 w-full flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600\">\n {isLoading ? <LoadingSpinner /> : 'Generate Changelog'}\n </button>\n </div>\n <div className=\"flex flex-col h-full\">\n <label className=\"text-sm font-medium text-slate-400 mb-2\">Generated Changelog.md</label>\n <div className=\"relative flex-grow p-4 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto\">\n {isLoading && !changelog && <div className=\"flex items-center justify-center h-full\"><LoadingSpinner /></div>}\n {error && <p className=\"text-red-400\">{error}</p>}\n {changelog && <MarkdownRenderer content={changelog} />}\n <button onClick={() => navigator.clipboard.writeText(changelog)} className=\"absolute top-2 right-2 px-2 py-1 bg-slate-700 hover:bg-slate-600 rounded-md text-xs\">Copy</button>\n </div>\n </div>\n </div>\n </div>\n );\n};\n"],"names":["exampleLog","ChangelogGenerator","log","setLog","useState","changelog","setChangelog","isLoading","setIsLoading","error","setError","handleGenerate","useCallback","stream","generateChangelogFromLogStream","fullResponse","chunk","err","jsxs","jsx","GitBranchIcon","e","LoadingSpinner","MarkdownRenderer"],"mappings":"yUAQA,MAAMA,EAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaNC,EAA+B,IAAM,CAC9C,KAAM,CAACC,EAAKC,CAAM,EAAIC,EAAAA,SAASJ,CAAU,EACnC,CAACK,EAAWC,CAAY,EAAIF,EAAAA,SAAS,EAAE,EACvC,CAACG,EAAWC,CAAY,EAAIJ,EAAAA,SAAS,EAAK,EAC1C,CAACK,EAAOC,CAAQ,EAAIN,EAAAA,SAAS,EAAE,EAE/BO,EAAiBC,EAAAA,YAAY,SAAY,CAC3C,GAAI,CAACV,EAAI,OAAQ,CACbQ,EAAS,mCAAmC,EAC5C,MACJ,CACAF,EAAa,EAAI,EACjBE,EAAS,EAAE,EACXJ,EAAa,EAAE,EACf,GAAI,CACA,MAAMO,EAASC,EAA+BZ,CAAG,EACjD,IAAIa,EAAe,GACnB,gBAAiBC,KAASH,EACtBE,GAAgBC,EAChBV,EAAaS,CAAY,CAEjC,OAASE,EAAK,CACVP,EAASO,aAAe,MAAQA,EAAI,QAAU,4BAA4B,CAC9E,QAAA,CACIT,EAAa,EAAK,CACtB,CACJ,EAAG,CAACN,CAAG,CAAC,EAER,OACIgB,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACX,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,OACd,SAAA,CAAAA,EAAAA,KAAC,KAAA,CAAG,UAAU,sDACV,SAAA,CAAAC,EAAAA,IAACC,EAAA,EAAc,EACfD,EAAAA,IAAC,OAAA,CAAK,UAAU,OAAO,SAAA,wBAAA,CAAsB,CAAA,EACjD,EACAA,EAAAA,IAAC,IAAA,CAAE,UAAU,sBAAsB,SAAA,sDAAA,CAAoD,CAAA,EAC3F,EACAD,EAAAA,KAAC,MAAA,CAAI,UAAU,yEACX,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACX,SAAA,CAAAC,MAAC,QAAA,CAAM,QAAQ,eAAe,UAAU,0CAA0C,SAAA,cAAW,EAC7FA,EAAAA,IAAC,WAAA,CACG,GAAG,eACH,MAAOjB,EACP,SAAWmB,GAAMlB,EAAOkB,EAAE,OAAO,KAAK,EACtC,UAAU,6FAAA,CAAA,EAEbF,EAAAA,IAAC,SAAA,CAAO,QAASR,EAAgB,SAAUJ,EAAW,UAAU,iJAC5D,SAAAA,EAAYY,EAAAA,IAACG,EAAA,CAAA,CAAe,EAAK,oBAAA,CACtC,CAAA,EACJ,EACAJ,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACX,SAAA,CAAAC,EAAAA,IAAC,QAAA,CAAM,UAAU,0CAA0C,SAAA,yBAAsB,EACjFD,EAAAA,KAAC,MAAA,CAAI,UAAU,+FACV,SAAA,CAAAX,GAAa,CAACF,GAAac,EAAAA,IAAC,MAAA,CAAI,UAAU,0CAA0C,SAAAA,EAAAA,IAACG,IAAe,CAAA,CAAE,EACtGb,GAASU,EAAAA,IAAC,IAAA,CAAE,UAAU,eAAgB,SAAAV,EAAM,EAC5CJ,GAAac,EAAAA,IAACI,EAAA,CAAiB,QAASlB,CAAA,CAAW,EACpDc,EAAAA,IAAC,SAAA,CAAO,QAAS,IAAM,UAAU,UAAU,UAAUd,CAAS,EAAG,UAAU,sFAAsF,SAAA,MAAA,CAAI,CAAA,CAAA,CACzK,CAAA,CAAA,CACJ,CAAA,CAAA,CACJ,CAAA,EACJ,CAER"}
|
assets/CodeFormatter-CMsj5Hyg.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as s,j as e}from"./react-D_B_5QVd.js";import{o as g,k as j,L as x}from"./index-QBya0NjG.js";import{m as b}from"./marked-CesSW9Du.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const y=`const MyComponent = (props) => {
|
| 2 |
+
const {name, items}=props
|
| 3 |
+
if(!items || items.length === 0){
|
| 4 |
+
return <p>No items found for {name}</p>;
|
| 5 |
+
}
|
| 6 |
+
return <ul>{items.map(item=> <li key={item.id}>{item.name}</li>)}</ul>
|
| 7 |
+
}`,E=()=>{const[l,p]=s.useState(y),[o,c]=s.useState(""),[a,d]=s.useState(!1),[n,m]=s.useState(""),[f,i]=s.useState("");s.useEffect(()=>{(async()=>{if(o){const r=await b.parse(o);i(r)}else i("")})()},[o]);const u=s.useCallback(async()=>{if(!l.trim()){m("Please enter some code to format.");return}d(!0),m(""),c("");try{const t=g(l);let r="";for await(const h of t)r+=h,c(r)}catch(t){const r=t instanceof Error?t.message:"An unknown error occurred.";m(`Failed to format code: ${r}`)}finally{d(!1)}},[l]);return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(j,{}),e.jsx("span",{className:"ml-3",children:"AI Code Formatter"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Clean up your code with AI-powered formatting, like a smart Prettier."})]}),e.jsxs("div",{className:"flex-grow flex flex-col min-h-0",children:[e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6 flex-grow min-h-0",children:[e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{htmlFor:"code-input",className:"text-sm font-medium text-slate-400 mb-2",children:"Input"}),e.jsx("textarea",{id:"code-input",value:l,onChange:t=>p(t.target.value),placeholder:"Paste your unformatted code here...",className:"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-cyan-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none"})]}),e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{className:"text-sm font-medium text-slate-400 mb-2",children:"Output"}),e.jsxs("div",{className:"flex-grow p-1 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto",children:[a&&e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsx(x,{})}),n&&e.jsx("p",{className:"p-4 text-red-400",children:n}),o&&!a&&e.jsx("div",{className:"prose prose-sm prose-invert max-w-none prose-pre:bg-transparent prose-pre:p-4 prose-pre:m-0 prose-code:text-cyan-300",dangerouslySetInnerHTML:{__html:f}}),!a&&!o&&!n&&e.jsx("div",{className:"text-slate-500 h-full flex items-center justify-center",children:"Formatted code will appear here."})]})]})]}),e.jsx("button",{onClick:u,disabled:a,className:"mt-4 w-full max-w-sm mx-auto flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 transition-colors disabled:bg-slate-600 disabled:cursor-not-allowed",children:a?e.jsx(x,{}):"Format Code"})]})]})};export{E as CodeFormatter};
|
| 8 |
+
//# sourceMappingURL=CodeFormatter-CMsj5Hyg.js.map
|
assets/CodeFormatter-CMsj5Hyg.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"CodeFormatter-CMsj5Hyg.js","sources":["../../components/features/CodeFormatter.tsx"],"sourcesContent":["\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport { formatCodeStream } from '../../services/geminiService.ts';\nimport { CodeBracketSquareIcon } from '../icons/FeatureIcons.tsx';\nimport { LoadingSpinner } from '../shared/LoadingSpinner.tsx';\nimport { marked } from 'marked';\n\nconst exampleCode = `const MyComponent = (props) => {\n const {name, items}=props\n if(!items || items.length === 0){\n return <p>No items found for {name}</p>;\n }\n return <ul>{items.map(item=> <li key={item.id}>{item.name}</li>)}</ul>\n}`;\n\nexport const CodeFormatter: React.FC = () => {\n const [inputCode, setInputCode] = useState<string>(exampleCode);\n const [formattedCode, setFormattedCode] = useState<string>('');\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<string>('');\n const [formattedCodeHtml, setFormattedCodeHtml] = useState<string | TrustedHTML>('');\n\n useEffect(() => {\n const parse = async () => {\n if (formattedCode) {\n const html = await marked.parse(formattedCode);\n setFormattedCodeHtml(html);\n } else {\n setFormattedCodeHtml('');\n }\n };\n parse();\n }, [formattedCode]);\n\n const handleFormat = useCallback(async () => {\n if (!inputCode.trim()) {\n setError('Please enter some code to format.');\n return;\n }\n setIsLoading(true);\n setError('');\n setFormattedCode('');\n try {\n const stream = formatCodeStream(inputCode);\n let fullResponse = '';\n for await (const chunk of stream) {\n fullResponse += chunk;\n setFormattedCode(fullResponse);\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';\n setError(`Failed to format code: ${errorMessage}`);\n } finally {\n setIsLoading(false);\n }\n }, [inputCode]);\n \n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <CodeBracketSquareIcon />\n <span className=\"ml-3\">AI Code Formatter</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Clean up your code with AI-powered formatting, like a smart Prettier.</p>\n </header>\n <div className=\"flex-grow flex flex-col min-h-0\">\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6 flex-grow min-h-0\">\n <div className=\"flex flex-col h-full\">\n <label htmlFor=\"code-input\" className=\"text-sm font-medium text-slate-400 mb-2\">Input</label>\n <textarea\n id=\"code-input\"\n value={inputCode}\n onChange={(e) => setInputCode(e.target.value)}\n placeholder=\"Paste your unformatted code here...\"\n className=\"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-cyan-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none\"\n />\n </div>\n <div className=\"flex flex-col h-full\">\n <label className=\"text-sm font-medium text-slate-400 mb-2\">Output</label>\n <div className=\"flex-grow p-1 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto\">\n {isLoading && (\n <div className=\"flex items-center justify-center h-full\">\n <LoadingSpinner />\n </div>\n )}\n {error && <p className=\"p-4 text-red-400\">{error}</p>}\n {formattedCode && !isLoading && (\n <div\n className=\"prose prose-sm prose-invert max-w-none prose-pre:bg-transparent prose-pre:p-4 prose-pre:m-0 prose-code:text-cyan-300\"\n dangerouslySetInnerHTML={{ __html: formattedCodeHtml }}\n />\n )}\n {!isLoading && !formattedCode && !error && (\n <div className=\"text-slate-500 h-full flex items-center justify-center\">\n Formatted code will appear here.\n </div>\n )}\n </div>\n </div>\n </div>\n <button\n onClick={handleFormat}\n disabled={isLoading}\n className=\"mt-4 w-full max-w-sm mx-auto flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 transition-colors disabled:bg-slate-600 disabled:cursor-not-allowed\"\n >\n {isLoading ? <LoadingSpinner /> : 'Format Code'}\n </button>\n </div>\n </div>\n );\n};"],"names":["exampleCode","CodeFormatter","inputCode","setInputCode","useState","formattedCode","setFormattedCode","isLoading","setIsLoading","error","setError","formattedCodeHtml","setFormattedCodeHtml","useEffect","html","marked","handleFormat","useCallback","stream","formatCodeStream","fullResponse","chunk","err","errorMessage","jsxs","jsx","CodeBracketSquareIcon","e","LoadingSpinner"],"mappings":"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"}
|
assets/CodeReviewBot-BgQ3GFY_.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as t,j as e}from"./react-D_B_5QVd.js";import{w as v,x as j,L as x}from"./index-QBya0NjG.js";import{m as w}from"./marked-CesSW9Du.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const g=`function UserList(users) {
|
| 2 |
+
if (users.length = 0) {
|
| 3 |
+
return "no users";
|
| 4 |
+
} else {
|
| 5 |
+
return (
|
| 6 |
+
users.map(u => {
|
| 7 |
+
return <li>{u.name}</li>
|
| 8 |
+
})
|
| 9 |
+
)
|
| 10 |
+
}
|
| 11 |
+
}`,E=()=>{const[o,u]=t.useState(g),[l,c]=t.useState(""),[a,d]=t.useState(!1),[n,i]=t.useState(""),[f,m]=t.useState("");t.useEffect(()=>{(async()=>{if(l){const r=await w.parse(l);m(r)}else m("")})()},[l]);const p=t.useCallback(async()=>{if(!o.trim()){i("Please enter some code to review.");return}d(!0),i(""),c("");try{const s=v(o);let r="";for await(const h of s)r+=h,c(r)}catch(s){const r=s instanceof Error?s.message:"An unknown error occurred.";i(`Failed to get review: ${r}`)}finally{d(!1)}},[o]);return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(j,{}),e.jsx("span",{className:"ml-3",children:"AI Code Review Bot"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Get an automated code review from Gemini."})]}),e.jsxs("div",{className:"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden",children:[e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{htmlFor:"code-input",className:"text-sm font-medium text-slate-400 mb-2",children:"Code to Review"}),e.jsx("textarea",{id:"code-input",value:o,onChange:s=>u(s.target.value),placeholder:"Paste your code here...",className:"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-cyan-300"}),e.jsx("button",{onClick:p,disabled:a,className:"mt-4 w-full flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600",children:a?e.jsx(x,{}):"Request Review"})]}),e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{className:"text-sm font-medium text-slate-400 mb-2",children:"AI Feedback"}),e.jsxs("div",{className:"flex-grow p-4 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto",children:[a&&e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsx(x,{})}),n&&e.jsx("p",{className:"text-red-400",children:n}),l&&!a&&e.jsx("div",{className:"prose prose-sm prose-invert max-w-none",dangerouslySetInnerHTML:{__html:f}}),!a&&!l&&!n&&e.jsx("div",{className:"text-slate-500 h-full flex items-center justify-center",children:"Review will appear here."})]})]})]})]})};export{E as CodeReviewBot};
|
| 12 |
+
//# sourceMappingURL=CodeReviewBot-BgQ3GFY_.js.map
|
assets/CodeReviewBot-BgQ3GFY_.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"CodeReviewBot-BgQ3GFY_.js","sources":["../../components/features/CodeReviewBot.tsx"],"sourcesContent":["\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport { reviewCodeStream } from '../../services/geminiService.ts';\nimport { CpuChipIcon } from '../icons/FeatureIcons.tsx';\nimport { LoadingSpinner } from '../shared/LoadingSpinner.tsx';\nimport { marked } from 'marked';\n\nconst exampleCode = `function UserList(users) {\n if (users.length = 0) {\n return \"no users\";\n } else {\n return (\n users.map(u => {\n return <li>{u.name}</li>\n })\n )\n }\n}`;\n\nexport const CodeReviewBot: React.FC = () => {\n const [code, setCode] = useState<string>(exampleCode);\n const [review, setReview] = useState<string>('');\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<string>('');\n const [reviewHtml, setReviewHtml] = useState<string | TrustedHTML>('');\n\n useEffect(() => {\n const parse = async () => {\n if (review) {\n const html = await marked.parse(review);\n setReviewHtml(html);\n } else {\n setReviewHtml('');\n }\n };\n parse();\n }, [review]);\n\n const handleGenerate = useCallback(async () => {\n if (!code.trim()) {\n setError('Please enter some code to review.');\n return;\n }\n setIsLoading(true);\n setError('');\n setReview('');\n try {\n const stream = reviewCodeStream(code);\n let fullResponse = '';\n for await (const chunk of stream) {\n fullResponse += chunk;\n setReview(fullResponse);\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';\n setError(`Failed to get review: ${errorMessage}`);\n } finally {\n setIsLoading(false);\n }\n }, [code]);\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <CpuChipIcon />\n <span className=\"ml-3\">AI Code Review Bot</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Get an automated code review from Gemini.</p>\n </header>\n <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden\">\n <div className=\"flex flex-col h-full\">\n <label htmlFor=\"code-input\" className=\"text-sm font-medium text-slate-400 mb-2\">Code to Review</label>\n <textarea\n id=\"code-input\"\n value={code}\n onChange={(e) => setCode(e.target.value)}\n placeholder=\"Paste your code here...\"\n className=\"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-cyan-300\"\n />\n <button\n onClick={handleGenerate}\n disabled={isLoading}\n className=\"mt-4 w-full flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600\"\n >\n {isLoading ? <LoadingSpinner /> : 'Request Review'}\n </button>\n </div>\n <div className=\"flex flex-col h-full\">\n <label className=\"text-sm font-medium text-slate-400 mb-2\">AI Feedback</label>\n <div className=\"flex-grow p-4 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto\">\n {isLoading && <div className=\"flex items-center justify-center h-full\"><LoadingSpinner /></div>}\n {error && <p className=\"text-red-400\">{error}</p>}\n {review && !isLoading && (\n <div\n className=\"prose prose-sm prose-invert max-w-none\"\n dangerouslySetInnerHTML={{ __html: reviewHtml }}\n />\n )}\n {!isLoading && !review && !error && <div className=\"text-slate-500 h-full flex items-center justify-center\">Review will appear here.</div>}\n </div>\n </div>\n </div>\n </div>\n );\n};"],"names":["exampleCode","CodeReviewBot","code","setCode","useState","review","setReview","isLoading","setIsLoading","error","setError","reviewHtml","setReviewHtml","useEffect","html","marked","handleGenerate","useCallback","stream","reviewCodeStream","fullResponse","chunk","err","errorMessage","jsxs","jsx","CpuChipIcon","e","LoadingSpinner"],"mappings":"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"}
|
assets/CronJobBuilder-CPbxJxRA.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as n,j as e}from"./react-D_B_5QVd.js";import{A as v,C,L as N,S}from"./index-QBya0NjG.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const l=({label:r,value:i,onChange:o,options:c})=>e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-slate-400",children:r}),e.jsxs("select",{value:i,onChange:s=>o(s.target.value),className:"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700",children:[e.jsx("option",{value:"*",children:"* (every)"}),c.map(s=>e.jsx("option",{value:s,children:s},s))]})]}),I=()=>{const[r,i]=n.useState("0"),[o,c]=n.useState("0"),[s,p]=n.useState("*"),[m,u]=n.useState("*"),[x,h]=n.useState("*"),[d,j]=n.useState("every weekday at 5pm"),[g,b]=n.useState(!1),f=n.useMemo(()=>`${r} ${o} ${s} ${m} ${x}`,[r,o,s,m,x]),y=n.useCallback(async()=>{if(d){b(!0);try{const t=await v(d);i(t.minute),c(t.hour),p(t.dayOfMonth),u(t.month),h(t.dayOfWeek)}catch(t){console.error(t)}finally{b(!1)}}},[d]);return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(C,{}),e.jsx("span",{className:"ml-3",children:"AI Cron Job Builder"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Visually construct a cron expression or describe it in plain English."})]}),e.jsxs("div",{className:"flex gap-2 mb-6",children:[e.jsx("input",{type:"text",value:d,onChange:t=>j(t.target.value),placeholder:"Describe a schedule...",className:"flex-grow px-3 py-1.5 rounded-md bg-slate-800 border border-slate-700 text-sm"}),e.jsxs("button",{onClick:y,disabled:g,className:"px-4 py-1.5 bg-purple-500 text-slate-900 font-bold rounded-md flex items-center gap-2",children:[g?e.jsx(N,{}):e.jsx(S,{})," AI Generate"]})]}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-5 gap-4 mb-6",children:[e.jsx(l,{label:"Minute",value:r,onChange:i,options:Array.from({length:60},(t,a)=>a)}),e.jsx(l,{label:"Hour",value:o,onChange:c,options:Array.from({length:24},(t,a)=>a)}),e.jsx(l,{label:"Day (Month)",value:s,onChange:p,options:Array.from({length:31},(t,a)=>a+1)}),e.jsx(l,{label:"Month",value:m,onChange:u,options:Array.from({length:12},(t,a)=>a+1)}),e.jsx(l,{label:"Day (Week)",value:x,onChange:h,options:Array.from({length:7},(t,a)=>a)})]}),e.jsxs("div",{className:"bg-slate-900 p-4 rounded-lg text-center",children:[e.jsx("p",{className:"text-slate-400 text-sm",children:"Generated Expression"}),e.jsx("p",{className:"font-mono text-cyan-400 text-2xl mt-1",children:f}),e.jsx("button",{onClick:()=>navigator.clipboard.writeText(f),className:"mt-4 px-3 py-1 bg-slate-700 hover:bg-slate-600 rounded-md text-xs",children:"Copy"})]})]})};export{I as CronJobBuilder};
|
| 2 |
+
//# sourceMappingURL=CronJobBuilder-CPbxJxRA.js.map
|
assets/CronJobBuilder-CPbxJxRA.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"CronJobBuilder-CPbxJxRA.js","sources":["../../components/features/CronJobBuilder.tsx"],"sourcesContent":["\n\nimport React, { useState, useMemo, useCallback } from 'react';\nimport { CommandLineIcon, SparklesIcon } from '../icons/FeatureIcons';\nimport { generateCronFromDescription, CronParts } from '../../services/geminiService.ts';\nimport { LoadingSpinner } from '../shared/LoadingSpinner.tsx';\n\nconst CronPartSelector: React.FC<{ label: string, value: string, onChange: (value: string) => void, options: (string|number)[] }> = ({ label, value, onChange, options }) => {\n return (\n <div>\n <label className=\"block text-sm font-medium text-slate-400\">{label}</label>\n <select value={value} onChange={e => onChange(e.target.value)} className=\"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700\">\n <option value=\"*\">* (every)</option>\n {options.map(o => <option key={o} value={o}>{o}</option>)}\n </select>\n </div>\n );\n};\n\nexport const CronJobBuilder: React.FC = () => {\n const [minute, setMinute] = useState('0');\n const [hour, setHour] = useState('0');\n const [dayOfMonth, setDayOfMonth] = useState('*');\n const [month, setMonth] = useState('*');\n const [dayOfWeek, setDayOfWeek] = useState('*');\n const [aiPrompt, setAiPrompt] = useState('every weekday at 5pm');\n const [isLoading, setIsLoading] = useState(false);\n \n const cronExpression = useMemo(() => {\n return `${minute} ${hour} ${dayOfMonth} ${month} ${dayOfWeek}`;\n }, [minute, hour, dayOfMonth, month, dayOfWeek]);\n\n const handleAiGenerate = useCallback(async () => {\n if (!aiPrompt) return;\n setIsLoading(true);\n try {\n const result: CronParts = await generateCronFromDescription(aiPrompt);\n setMinute(result.minute);\n setHour(result.hour);\n setDayOfMonth(result.dayOfMonth);\n setMonth(result.month);\n setDayOfWeek(result.dayOfWeek);\n } catch (e) {\n console.error(e);\n // You might want to show an error to the user here\n } finally {\n setIsLoading(false);\n }\n }, [aiPrompt]);\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <CommandLineIcon />\n <span className=\"ml-3\">AI Cron Job Builder</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Visually construct a cron expression or describe it in plain English.</p>\n </header>\n <div className=\"flex gap-2 mb-6\">\n <input type=\"text\" value={aiPrompt} onChange={e => setAiPrompt(e.target.value)} placeholder=\"Describe a schedule...\" className=\"flex-grow px-3 py-1.5 rounded-md bg-slate-800 border border-slate-700 text-sm\"/>\n <button onClick={handleAiGenerate} disabled={isLoading} className=\"px-4 py-1.5 bg-purple-500 text-slate-900 font-bold rounded-md flex items-center gap-2\">\n {isLoading ? <LoadingSpinner /> : <SparklesIcon />} AI Generate\n </button>\n </div>\n <div className=\"grid grid-cols-2 md:grid-cols-5 gap-4 mb-6\">\n <CronPartSelector label=\"Minute\" value={minute} onChange={setMinute} options={Array.from({length: 60}, (_, i) => i)} />\n <CronPartSelector label=\"Hour\" value={hour} onChange={setHour} options={Array.from({length: 24}, (_, i) => i)} />\n <CronPartSelector label=\"Day (Month)\" value={dayOfMonth} onChange={setDayOfMonth} options={Array.from({length: 31}, (_, i) => i + 1)} />\n <CronPartSelector label=\"Month\" value={month} onChange={setMonth} options={Array.from({length: 12}, (_, i) => i + 1)} />\n <CronPartSelector label=\"Day (Week)\" value={dayOfWeek} onChange={setDayOfWeek} options={Array.from({length: 7}, (_, i) => i)} />\n </div>\n <div className=\"bg-slate-900 p-4 rounded-lg text-center\">\n <p className=\"text-slate-400 text-sm\">Generated Expression</p>\n <p className=\"font-mono text-cyan-400 text-2xl mt-1\">{cronExpression}</p>\n <button onClick={() => navigator.clipboard.writeText(cronExpression)} className=\"mt-4 px-3 py-1 bg-slate-700 hover:bg-slate-600 rounded-md text-xs\">Copy</button>\n </div>\n </div>\n );\n};"],"names":["CronPartSelector","label","value","onChange","options","jsx","jsxs","e","o","CronJobBuilder","minute","setMinute","useState","hour","setHour","dayOfMonth","setDayOfMonth","month","setMonth","dayOfWeek","setDayOfWeek","aiPrompt","setAiPrompt","isLoading","setIsLoading","cronExpression","useMemo","handleAiGenerate","useCallback","result","generateCronFromDescription","CommandLineIcon","LoadingSpinner","SparklesIcon","_","i"],"mappings":"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"}
|
assets/CssGridEditor-Ct_gd1L2.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as o,j as e}from"./react-D_B_5QVd.js";import{k as g}from"./index-QBya0NjG.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const w=()=>{const[a,d]=o.useState(3),[l,i]=o.useState(4),[t,m]=o.useState(1),[r,p]=o.useState(1),x={display:"grid",gridTemplateColumns:`repeat(${l}, 1fr)`,gridTemplateRows:`repeat(${a}, 1fr)`,gap:`${t}rem ${r}rem`,height:"100%",width:"100%"},n=o.useMemo(()=>`.grid-container {
|
| 2 |
+
display: grid;
|
| 3 |
+
grid-template-columns: repeat(${l}, 1fr);
|
| 4 |
+
grid-template-rows: repeat(${a}, 1fr);
|
| 5 |
+
gap: ${t}rem ${r}rem;
|
| 6 |
+
}`,[a,l,t,r]),u=()=>{navigator.clipboard.writeText(n)};return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(g,{}),e.jsx("span",{className:"ml-3",children:"CSS Grid Visual Editor"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Configure your grid layout and copy the generated CSS."})]}),e.jsxs("div",{className:"flex-grow grid grid-cols-1 lg:grid-cols-3 gap-6 min-h-0",children:[e.jsxs("div",{className:"lg:col-span-1 flex flex-col gap-4 bg-slate-800/50 p-6 rounded-lg",children:[e.jsx("h3",{className:"text-xl font-bold",children:"Controls"}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsxs("label",{htmlFor:"rows",className:"block text-sm font-medium text-slate-400",children:["Rows (",a,")"]}),e.jsx("input",{id:"rows",type:"range",min:"1",max:"12",value:a,onChange:s=>d(Number(s.target.value)),className:"w-full h-2 bg-slate-700 rounded-lg appearance-none cursor-pointer"})]}),e.jsxs("div",{children:[e.jsxs("label",{htmlFor:"cols",className:"block text-sm font-medium text-slate-400",children:["Columns (",l,")"]}),e.jsx("input",{id:"cols",type:"range",min:"1",max:"12",value:l,onChange:s=>i(Number(s.target.value)),className:"w-full h-2 bg-slate-700 rounded-lg appearance-none cursor-pointer"})]}),e.jsxs("div",{children:[e.jsxs("label",{htmlFor:"rowGap",className:"block text-sm font-medium text-slate-400",children:["Row Gap (",t,"rem)"]}),e.jsx("input",{id:"rowGap",type:"range",min:"0",max:"8",step:"0.25",value:t,onChange:s=>m(Number(s.target.value)),className:"w-full h-2 bg-slate-700 rounded-lg appearance-none cursor-pointer"})]}),e.jsxs("div",{children:[e.jsxs("label",{htmlFor:"colGap",className:"block text-sm font-medium text-slate-400",children:["Column Gap (",r,"rem)"]}),e.jsx("input",{id:"colGap",type:"range",min:"0",max:"8",step:"0.25",value:r,onChange:s=>p(Number(s.target.value)),className:"w-full h-2 bg-slate-700 rounded-lg appearance-none cursor-pointer"})]})]}),e.jsxs("div",{className:"flex-grow mt-4",children:[e.jsx("label",{className:"block text-sm font-medium text-slate-400 mb-2",children:"Generated CSS"}),e.jsxs("div",{className:"relative h-full",children:[e.jsx("pre",{className:"bg-slate-900 p-4 rounded-md text-cyan-300 text-sm overflow-auto h-full",children:n}),e.jsx("button",{onClick:u,className:"absolute top-2 right-2 px-2 py-1 bg-slate-700 hover:bg-slate-600 rounded-md text-xs",children:"Copy"})]})]})]}),e.jsx("div",{className:"lg:col-span-2 bg-slate-900 rounded-lg p-4",children:e.jsx("div",{style:x,children:Array.from({length:a*l}).map((s,c)=>e.jsx("div",{className:"bg-cyan-500/20 rounded-lg border-2 border-dashed border-cyan-400/50 flex items-center justify-center text-cyan-300",children:e.jsx("span",{className:"text-xs opacity-70",children:c+1})},c))})})]})]})};export{w as CssGridEditor};
|
| 7 |
+
//# sourceMappingURL=CssGridEditor-Ct_gd1L2.js.map
|
assets/CssGridEditor-Ct_gd1L2.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"CssGridEditor-Ct_gd1L2.js","sources":["../../components/features/CssGridEditor.tsx"],"sourcesContent":["\nimport React, { useState, useMemo } from 'react';\nimport { CodeBracketSquareIcon } from '../icons/FeatureIcons.tsx';\n\nexport const CssGridEditor: React.FC = () => {\n const [rows, setRows] = useState(3);\n const [cols, setCols] = useState(4);\n const [rowGap, setRowGap] = useState(1); // in rem\n const [colGap, setColGap] = useState(1); // in rem\n\n const gridStyle = {\n display: 'grid',\n gridTemplateColumns: `repeat(${cols}, 1fr)`,\n gridTemplateRows: `repeat(${rows}, 1fr)`,\n gap: `${rowGap}rem ${colGap}rem`,\n height: '100%',\n width: '100%'\n };\n\n const cssCode = useMemo(() => {\n return `.grid-container {\n display: grid;\n grid-template-columns: repeat(${cols}, 1fr);\n grid-template-rows: repeat(${rows}, 1fr);\n gap: ${rowGap}rem ${colGap}rem;\n}`;\n }, [rows, cols, rowGap, colGap]);\n \n const handleCopy = () => {\n navigator.clipboard.writeText(cssCode);\n };\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <CodeBracketSquareIcon />\n <span className=\"ml-3\">CSS Grid Visual Editor</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Configure your grid layout and copy the generated CSS.</p>\n </header>\n <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-3 gap-6 min-h-0\">\n <div className=\"lg:col-span-1 flex flex-col gap-4 bg-slate-800/50 p-6 rounded-lg\">\n <h3 className=\"text-xl font-bold\">Controls</h3>\n <div className=\"space-y-4\">\n <div>\n <label htmlFor=\"rows\" className=\"block text-sm font-medium text-slate-400\">Rows ({rows})</label>\n <input id=\"rows\" type=\"range\" min=\"1\" max=\"12\" value={rows} onChange={e => setRows(Number(e.target.value))} className=\"w-full h-2 bg-slate-700 rounded-lg appearance-none cursor-pointer\" />\n </div>\n <div>\n <label htmlFor=\"cols\" className=\"block text-sm font-medium text-slate-400\">Columns ({cols})</label>\n <input id=\"cols\" type=\"range\" min=\"1\" max=\"12\" value={cols} onChange={e => setCols(Number(e.target.value))} className=\"w-full h-2 bg-slate-700 rounded-lg appearance-none cursor-pointer\" />\n </div>\n <div>\n <label htmlFor=\"rowGap\" className=\"block text-sm font-medium text-slate-400\">Row Gap ({rowGap}rem)</label>\n <input id=\"rowGap\" type=\"range\" min=\"0\" max=\"8\" step=\"0.25\" value={rowGap} onChange={e => setRowGap(Number(e.target.value))} className=\"w-full h-2 bg-slate-700 rounded-lg appearance-none cursor-pointer\" />\n </div>\n <div>\n <label htmlFor=\"colGap\" className=\"block text-sm font-medium text-slate-400\">Column Gap ({colGap}rem)</label>\n <input id=\"colGap\" type=\"range\" min=\"0\" max=\"8\" step=\"0.25\" value={colGap} onChange={e => setColGap(Number(e.target.value))} className=\"w-full h-2 bg-slate-700 rounded-lg appearance-none cursor-pointer\" />\n </div>\n </div>\n <div className=\"flex-grow mt-4\">\n <label className=\"block text-sm font-medium text-slate-400 mb-2\">Generated CSS</label>\n <div className=\"relative h-full\">\n <pre className=\"bg-slate-900 p-4 rounded-md text-cyan-300 text-sm overflow-auto h-full\">{cssCode}</pre>\n <button onClick={handleCopy} className=\"absolute top-2 right-2 px-2 py-1 bg-slate-700 hover:bg-slate-600 rounded-md text-xs\">Copy</button>\n </div>\n </div>\n </div>\n <div className=\"lg:col-span-2 bg-slate-900 rounded-lg p-4\">\n <div style={gridStyle}>\n {Array.from({ length: rows * cols }).map((_, i) => (\n <div key={i} className=\"bg-cyan-500/20 rounded-lg border-2 border-dashed border-cyan-400/50 flex items-center justify-center text-cyan-300\">\n <span className=\"text-xs opacity-70\">{i + 1}</span>\n </div>\n ))}\n </div>\n </div>\n </div>\n </div>\n );\n};"],"names":["CssGridEditor","rows","setRows","useState","cols","setCols","rowGap","setRowGap","colGap","setColGap","gridStyle","cssCode","useMemo","handleCopy","jsxs","jsx","CodeBracketSquareIcon","e","_","i"],"mappings":"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"}
|
assets/DevNotesStickyPanel-C-lefFL-.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as d,j as t}from"./react-D_B_5QVd.js";import{q as w,F as v,S,L as k}from"./index-QBya0NjG.js";import{u as C}from"./useLocalStorage-WuAvJp3F.js";import{M as z}from"./MarkdownRenderer-BDaVxTSW.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";import"./marked-CesSW9Du.js";const g=["bg-yellow-300","bg-green-300","bg-blue-300","bg-pink-300","bg-purple-300"],B=()=>{const[o,n]=C("devcore_notes",[]),[r,u]=d.useState(null),[i,x]=d.useState(!1),[m,c]=d.useState(""),p=d.useCallback(async()=>{if(o.length!==0){x(!0),c("");try{const e=o.map(a=>`- ${a.text}`).join(`
|
| 2 |
+
`),s=w(e);let l="";for await(const a of s)l+=a,c(l)}catch(e){console.error(e),c("Sorry, an error occurred while summarizing.")}finally{x(!1)}}},[o]),b=()=>{const e={id:Date.now(),text:"New note...",x:50+o.length%10*20,y:50+o.length%10*20,color:g[o.length%g.length]};n([...o,e])},h=(e,s)=>{n(o.map(l=>l.id===e?{...l,text:s}:l))},N=e=>{n(o.filter(s=>s.id!==e))},j=(e,s)=>{if(e.target.tagName==="TEXTAREA"||e.target.tagName==="BUTTON")return;const a=e.currentTarget.getBoundingClientRect();u({id:s,offsetX:e.clientX-a.left,offsetY:e.clientY-a.top})},y=e=>{if(!r)return;const s=e.currentTarget.getBoundingClientRect();n(o.map(l=>l.id===r.id?{...l,x:e.clientX-r.offsetX-s.left,y:e.clientY-r.offsetY-s.top}:l))},f=()=>u(null);return t.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[t.jsxs("header",{className:"mb-6 flex justify-between items-center",children:[t.jsxs("div",{children:[t.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[t.jsx(v,{}),t.jsx("span",{className:"ml-3",children:"Dev Notes Sticky Panel"})]}),t.jsx("p",{className:"text-slate-400 mt-1",children:"A place for your thoughts, todos, and random ideas."})]}),t.jsxs("div",{className:"flex gap-2",children:[t.jsxs("button",{onClick:p,disabled:i||o.length===0,className:"flex items-center gap-2 px-4 py-2 bg-purple-500 text-slate-900 font-bold rounded-md disabled:bg-slate-600",children:[t.jsx(S,{})," ",i?"Summarizing...":"AI Summarize"]}),t.jsx("button",{onClick:b,className:"px-6 py-2 bg-cyan-500 text-slate-900 font-bold rounded-md",children:"Add Note"})]})]}),t.jsx("div",{className:"relative flex-grow bg-slate-900/50 border-2 border-dashed border-slate-700 rounded-lg overflow-hidden",onMouseMove:y,onMouseUp:f,onMouseLeave:f,children:o.map(e=>t.jsxs("div",{className:`absolute w-48 h-48 p-2 flex flex-col shadow-lg cursor-grab active:cursor-grabbing ${e.color}`,style:{top:e.y,left:e.x,transform:(r==null?void 0:r.id)===e.id?"scale(1.05) rotate(3deg)":"scale(1)"},onMouseDown:s=>j(s,e.id),children:[t.jsx("button",{onClick:()=>N(e.id),className:"absolute -top-2 -right-2 w-6 h-6 rounded-full bg-red-500 text-white font-bold text-xs flex items-center justify-center opacity-0 hover:opacity-100",children:"×"}),t.jsx("textarea",{value:e.text,onChange:s=>h(e.id,s.target.value),className:"w-full h-full bg-transparent text-black resize-none focus:outline-none font-medium p-1"})]},e.id))}),(i||m)&&t.jsx("div",{className:"fixed inset-0 bg-slate-900/80 backdrop-blur-sm z-50 flex items-center justify-center",onClick:()=>c(""),children:t.jsxs("div",{className:"w-full max-w-2xl bg-slate-800 border border-slate-700 rounded-lg shadow-2xl p-6",onClick:e=>e.stopPropagation(),children:[t.jsx("h2",{className:"text-xl font-bold mb-4",children:"AI Summary of Notes"}),i&&!m?t.jsx(k,{}):t.jsx(z,{content:m})]})})]})};export{B as DevNotesStickyPanel};
|
| 3 |
+
//# sourceMappingURL=DevNotesStickyPanel-C-lefFL-.js.map
|
assets/DevNotesStickyPanel-C-lefFL-.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"DevNotesStickyPanel-C-lefFL-.js","sources":["../../components/features/DevNotesStickyPanel.tsx"],"sourcesContent":["import React, { useState, useCallback } from 'react';\nimport { FileCodeIcon, SparklesIcon } from '../icons/FeatureIcons.tsx';\nimport { useLocalStorage } from '../../hooks/useLocalStorage.ts';\nimport { summarizeNotesStream } from '../../services/geminiService.ts';\nimport { LoadingSpinner } from '../shared/LoadingSpinner.tsx';\nimport { MarkdownRenderer } from '../shared/MarkdownRenderer.tsx';\n\ninterface Note {\n id: number;\n text: string;\n x: number;\n y: number;\n color: string;\n}\n\nconst colors = ['bg-yellow-300', 'bg-green-300', 'bg-blue-300', 'bg-pink-300', 'bg-purple-300'];\n\nexport const DevNotesStickyPanel: React.FC = () => {\n const [notes, setNotes] = useLocalStorage('devcore_notes', []);\n const [dragging, setDragging] = useState<{ id: number; offsetX: number; offsetY: number } | null>(null);\n const [isSummarizing, setIsSummarizing] = useState(false);\n const [summary, setSummary] = useState('');\n\n const handleSummarize = useCallback(async () => {\n if (notes.length === 0) return;\n setIsSummarizing(true);\n setSummary('');\n try {\n const allNotesText = notes.map((n: Note) => `- ${n.text}`).join('\\n');\n const stream = summarizeNotesStream(allNotesText);\n let fullResponse = '';\n for await (const chunk of stream) {\n fullResponse += chunk;\n setSummary(fullResponse);\n }\n } catch (error) {\n console.error(error);\n setSummary('Sorry, an error occurred while summarizing.');\n } finally {\n setIsSummarizing(false);\n }\n }, [notes]);\n\n\n const addNote = () => {\n const newNote: Note = {\n id: Date.now(),\n text: 'New note...',\n x: 50 + (notes.length % 10) * 20,\n y: 50 + (notes.length % 10) * 20,\n color: colors[notes.length % colors.length],\n };\n setNotes([...notes, newNote]);\n };\n\n const updateText = (id: number, text: string) => {\n setNotes(notes.map((n: Note) => n.id === id ? { ...n, text } : n));\n };\n \n const deleteNote = (id: number) => {\n setNotes(notes.filter((n: Note) => n.id !== id));\n };\n\n const onMouseDown = (e: React.MouseEvent<HTMLDivElement>, id: number) => {\n if((e.target as HTMLElement).tagName === 'TEXTAREA' || (e.target as HTMLElement).tagName === 'BUTTON') return;\n const noteElement = e.currentTarget;\n const rect = noteElement.getBoundingClientRect();\n setDragging({ id, offsetX: e.clientX - rect.left, offsetY: e.clientY - rect.top });\n };\n\n const onMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {\n if (!dragging) return;\n const boardRect = e.currentTarget.getBoundingClientRect();\n setNotes(\n notes.map((n: Note) =>\n n.id === dragging.id\n ? { ...n, x: e.clientX - dragging.offsetX - boardRect.left, y: e.clientY - dragging.offsetY - boardRect.top }\n : n\n )\n );\n };\n\n const onMouseUp = () => setDragging(null);\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6 flex justify-between items-center\">\n <div>\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\"><FileCodeIcon /><span className=\"ml-3\">Dev Notes Sticky Panel</span></h1>\n <p className=\"text-slate-400 mt-1\">A place for your thoughts, todos, and random ideas.</p>\n </div>\n <div className=\"flex gap-2\">\n <button onClick={handleSummarize} disabled={isSummarizing || notes.length === 0} className=\"flex items-center gap-2 px-4 py-2 bg-purple-500 text-slate-900 font-bold rounded-md disabled:bg-slate-600\">\n <SparklesIcon/> {isSummarizing ? 'Summarizing...' : 'AI Summarize'}\n </button>\n <button onClick={addNote} className=\"px-6 py-2 bg-cyan-500 text-slate-900 font-bold rounded-md\">Add Note</button>\n </div>\n </header>\n <div\n className=\"relative flex-grow bg-slate-900/50 border-2 border-dashed border-slate-700 rounded-lg overflow-hidden\"\n onMouseMove={onMouseMove}\n onMouseUp={onMouseUp}\n onMouseLeave={onMouseUp}\n >\n {notes.map((note: Note) => (\n <div\n key={note.id}\n className={`absolute w-48 h-48 p-2 flex flex-col shadow-lg cursor-grab active:cursor-grabbing ${note.color}`}\n style={{ top: note.y, left: note.x, transform: dragging?.id === note.id ? 'scale(1.05) rotate(3deg)' : 'scale(1)' }}\n onMouseDown={e => onMouseDown(e, note.id)}\n >\n <button onClick={() => deleteNote(note.id)} className=\"absolute -top-2 -right-2 w-6 h-6 rounded-full bg-red-500 text-white font-bold text-xs flex items-center justify-center opacity-0 hover:opacity-100\">×</button>\n <textarea\n value={note.text}\n onChange={(e) => updateText(note.id, e.target.value)}\n className=\"w-full h-full bg-transparent text-black resize-none focus:outline-none font-medium p-1\"\n />\n </div>\n ))}\n </div>\n {(isSummarizing || summary) && (\n <div className=\"fixed inset-0 bg-slate-900/80 backdrop-blur-sm z-50 flex items-center justify-center\" onClick={() => setSummary('')}>\n <div className=\"w-full max-w-2xl bg-slate-800 border border-slate-700 rounded-lg shadow-2xl p-6\" onClick={e => e.stopPropagation()}>\n <h2 className=\"text-xl font-bold mb-4\">AI Summary of Notes</h2>\n {isSummarizing && !summary ? <LoadingSpinner /> : <MarkdownRenderer content={summary} />}\n </div>\n </div>\n )}\n </div>\n );\n};"],"names":["colors","DevNotesStickyPanel","notes","setNotes","useLocalStorage","dragging","setDragging","useState","isSummarizing","setIsSummarizing","summary","setSummary","handleSummarize","useCallback","allNotesText","n","stream","summarizeNotesStream","fullResponse","chunk","error","addNote","newNote","updateText","id","text","deleteNote","onMouseDown","rect","onMouseMove","boardRect","onMouseUp","jsxs","jsx","FileCodeIcon","SparklesIcon","note","e","LoadingSpinner","MarkdownRenderer"],"mappings":"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"}
|
assets/FontPairingTool-B69d5r3k.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as a,j as e}from"./react-D_B_5QVd.js";import{E as d}from"./index-QBya0NjG.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const p=["Roboto","Open Sans","Lato","Montserrat","Oswald","Source Sans Pro","Raleway","Poppins","Nunito","Merriweather"],y=()=>{const[t,r]=a.useState("Oswald"),[l,c]=a.useState("Roboto");a.useEffect(()=>{const n=[t,l].filter(s=>s).join("|");if(n){const s=document.createElement("link");return s.href=`https://fonts.googleapis.com/css?family=${n.replace(/ /g,"+")}:400,700&display=swap`,s.rel="stylesheet",document.head.appendChild(s),()=>{document.head.removeChild(s)}}},[t,l]);const i=({label:n,value:s,onChange:m})=>e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-slate-400",children:n}),e.jsx("select",{value:s,onChange:o=>m(o.target.value),className:"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700",children:p.map(o=>e.jsx("option",{value:o,children:o},o))})]});return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(d,{}),e.jsx("span",{className:"ml-3",children:"Font Pairing Tool"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Preview Google Font combinations for your projects."})]}),e.jsxs("div",{className:"flex-grow grid grid-cols-1 lg:grid-cols-3 gap-6 min-h-0",children:[e.jsxs("div",{className:"lg:col-span-1 flex flex-col gap-4 bg-slate-800/50 p-6 rounded-lg",children:[e.jsx("h3",{className:"text-xl font-bold",children:"Controls"}),e.jsx(i,{label:"Heading Font",value:t,onChange:r}),e.jsx(i,{label:"Body Font",value:l,onChange:c})]}),e.jsxs("div",{className:"lg:col-span-2 bg-slate-900 rounded-lg p-8 overflow-y-auto",children:[e.jsx("h2",{className:"text-4xl font-bold mb-4",style:{fontFamily:t},children:"The Quick Brown Fox Jumps Over the Lazy Dog"}),e.jsx("p",{className:"text-lg",style:{fontFamily:l},children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat."})]})]})]})};export{y as FontPairingTool};
|
| 2 |
+
//# sourceMappingURL=FontPairingTool-B69d5r3k.js.map
|
assets/FontPairingTool-B69d5r3k.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"FontPairingTool-B69d5r3k.js","sources":["../../components/features/FontPairingTool.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react';\nimport { EyeIcon } from '../icons/FeatureIcons.tsx';\n\nconst popularFonts = [\n 'Roboto', 'Open Sans', 'Lato', 'Montserrat', 'Oswald', 'Source Sans Pro', 'Raleway', 'Poppins', 'Nunito', 'Merriweather'\n];\n\nexport const FontPairingTool: React.FC = () => {\n const [headingFont, setHeadingFont] = useState('Oswald');\n const [bodyFont, setBodyFont] = useState('Roboto');\n\n useEffect(() => {\n const fontsToLoad = [headingFont, bodyFont].filter(f => f).join('|');\n if (fontsToLoad) {\n const link = document.createElement('link');\n link.href = `https://fonts.googleapis.com/css?family=${fontsToLoad.replace(/ /g, '+')}:400,700&display=swap`;\n link.rel = 'stylesheet';\n document.head.appendChild(link);\n return () => {\n document.head.removeChild(link);\n };\n }\n }, [headingFont, bodyFont]);\n \n const FontSelector: React.FC<{ label: string, value: string, onChange: (font: string) => void }> = ({ label, value, onChange }) => (\n <div>\n <label className=\"block text-sm font-medium text-slate-400\">{label}</label>\n <select value={value} onChange={e => onChange(e.target.value)} className=\"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700\">\n {popularFonts.map(font => <option key={font} value={font}>{font}</option>)}\n </select>\n </div>\n );\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <EyeIcon />\n <span className=\"ml-3\">Font Pairing Tool</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Preview Google Font combinations for your projects.</p>\n </header>\n <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-3 gap-6 min-h-0\">\n <div className=\"lg:col-span-1 flex flex-col gap-4 bg-slate-800/50 p-6 rounded-lg\">\n <h3 className=\"text-xl font-bold\">Controls</h3>\n <FontSelector label=\"Heading Font\" value={headingFont} onChange={setHeadingFont} />\n <FontSelector label=\"Body Font\" value={bodyFont} onChange={setBodyFont} />\n </div>\n <div className=\"lg:col-span-2 bg-slate-900 rounded-lg p-8 overflow-y-auto\">\n <h2 className=\"text-4xl font-bold mb-4\" style={{ fontFamily: headingFont }}>\n The Quick Brown Fox Jumps Over the Lazy Dog\n </h2>\n <p className=\"text-lg\" style={{ fontFamily: bodyFont }}>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat.\n </p>\n </div>\n </div>\n </div>\n );\n};"],"names":["popularFonts","FontPairingTool","headingFont","setHeadingFont","useState","bodyFont","setBodyFont","useEffect","fontsToLoad","f","link","FontSelector","label","value","onChange","jsx","e","font","jsxs","EyeIcon"],"mappings":"2OAGA,MAAMA,EAAe,CACjB,SAAU,YAAa,OAAQ,aAAc,SAAU,kBAAmB,UAAW,UAAW,SAAU,cAC9G,EAEaC,EAA4B,IAAM,CAC3C,KAAM,CAACC,EAAaC,CAAc,EAAIC,EAAAA,SAAS,QAAQ,EACjD,CAACC,EAAUC,CAAW,EAAIF,EAAAA,SAAS,QAAQ,EAEjDG,EAAAA,UAAU,IAAM,CACZ,MAAMC,EAAc,CAACN,EAAaG,CAAQ,EAAE,OAAOI,GAAKA,CAAC,EAAE,KAAK,GAAG,EACnE,GAAID,EAAa,CACb,MAAME,EAAO,SAAS,cAAc,MAAM,EAC1C,OAAAA,EAAK,KAAO,2CAA2CF,EAAY,QAAQ,KAAM,GAAG,CAAC,wBACrFE,EAAK,IAAM,aACX,SAAS,KAAK,YAAYA,CAAI,EACvB,IAAM,CACT,SAAS,KAAK,YAAYA,CAAI,CAClC,CACJ,CACJ,EAAG,CAACR,EAAaG,CAAQ,CAAC,EAE1B,MAAMM,EAA6F,CAAC,CAAE,MAAAC,EAAO,MAAAC,EAAO,SAAAC,CAAA,WAC/G,MAAA,CACG,SAAA,CAAAC,EAAAA,IAAC,QAAA,CAAM,UAAU,2CAA4C,SAAAH,EAAM,EACnEG,EAAAA,IAAC,UAAO,MAAAF,EAAc,YAAeC,EAASE,EAAE,OAAO,KAAK,EAAG,UAAU,wEACpE,SAAAhB,EAAa,OAAYe,EAAAA,IAAC,SAAA,CAAkB,MAAOE,EAAO,SAAAA,GAApBA,CAAyB,CAAS,CAAA,CAC7E,CAAA,EACJ,EAGJ,OACIC,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACX,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,OACd,SAAA,CAAAA,EAAAA,KAAC,KAAA,CAAG,UAAU,sDACV,SAAA,CAAAH,EAAAA,IAACI,EAAA,EAAQ,EACTJ,EAAAA,IAAC,OAAA,CAAK,UAAU,OAAO,SAAA,mBAAA,CAAiB,CAAA,EAC5C,EACAA,EAAAA,IAAC,IAAA,CAAE,UAAU,sBAAsB,SAAA,qDAAA,CAAmD,CAAA,EAC1F,EACAG,EAAAA,KAAC,MAAA,CAAI,UAAU,0DACX,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,mEACX,SAAA,CAAAH,EAAAA,IAAC,KAAA,CAAG,UAAU,oBAAoB,SAAA,WAAQ,QACzCJ,EAAA,CAAa,MAAM,eAAe,MAAOT,EAAa,SAAUC,EAAgB,QAChFQ,EAAA,CAAa,MAAM,YAAY,MAAON,EAAU,SAAUC,CAAA,CAAa,CAAA,EAC5E,EACAY,EAAAA,KAAC,MAAA,CAAI,UAAU,4DACX,SAAA,CAAAH,EAAAA,IAAC,KAAA,CAAG,UAAU,0BAA0B,MAAO,CAAE,WAAYb,CAAA,EAAe,SAAA,6CAAA,CAE5E,EACAa,EAAAA,IAAC,KAAE,UAAU,UAAU,MAAO,CAAE,WAAYV,CAAA,EAAY,SAAA,sWAAA,CAExD,CAAA,CAAA,CACJ,CAAA,CAAA,CACJ,CAAA,EACJ,CAER"}
|
assets/FontPreviewPicker-Z5SOKfoJ.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as l,j as e}from"./react-D_B_5QVd.js";import{E as n}from"./index-QBya0NjG.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const c=["Roboto","Open Sans","Lato","Montserrat","Oswald","Source Sans Pro","Raleway","Poppins","Nunito","Merriweather"],f=()=>{const[s,r]=l.useState("Roboto"),[a,i]=l.useState("The quick brown fox jumps over the lazy dog.");l.useEffect(()=>{if(s){const t=document.createElement("link");return t.href=`https://fonts.googleapis.com/css?family=${s.replace(/ /g,"+")}&display=swap`,t.rel="stylesheet",document.head.appendChild(t),()=>{document.head.removeChild(t)}}},[s]);const o=`@import url('https://fonts.googleapis.com/css?family=${s.replace(/ /g,"+")}&display=swap');`;return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(n,{}),e.jsx("span",{className:"ml-3",children:"Font Preview & Picker"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Preview Google Fonts and get the CSS import rule."})]}),e.jsxs("div",{className:"flex-grow grid grid-cols-1 lg:grid-cols-3 gap-6 min-h-0",children:[e.jsxs("div",{className:"lg:col-span-1 flex flex-col gap-4 bg-slate-800/50 p-6 rounded-lg",children:[e.jsx("h3",{className:"text-xl font-bold",children:"Controls"}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"font-select",className:"block text-sm font-medium text-slate-400",children:"Select Font"}),e.jsx("select",{id:"font-select",value:s,onChange:t=>r(t.target.value),className:"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700",children:c.map(t=>e.jsx("option",{value:t,children:t},t))})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"preview-text",className:"block text-sm font-medium text-slate-400",children:"Preview Text"}),e.jsx("textarea",{id:"preview-text",value:a,onChange:t=>i(t.target.value),className:"w-full mt-1 p-2 rounded-md bg-slate-800 border border-slate-700 h-24 resize-none"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-slate-400",children:"CSS Import Rule"}),e.jsxs("div",{className:"relative mt-1",children:[e.jsx("pre",{className:"bg-slate-900 p-2 rounded-md text-cyan-300 text-xs overflow-x-auto",children:o}),e.jsx("button",{onClick:()=>navigator.clipboard.writeText(o),className:"absolute top-1 right-1 px-2 py-0.5 bg-slate-700 hover:bg-slate-600 rounded-md text-xs",children:"Copy"})]})]})]}),e.jsx("div",{className:"lg:col-span-2 bg-slate-900 rounded-lg p-8 flex items-center justify-center",children:e.jsx("p",{className:"text-4xl",style:{fontFamily:s},children:a})})]})]})};export{f as FontPreviewPicker};
|
| 2 |
+
//# sourceMappingURL=FontPreviewPicker-Z5SOKfoJ.js.map
|
assets/FontPreviewPicker-Z5SOKfoJ.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"FontPreviewPicker-Z5SOKfoJ.js","sources":["../../components/features/FontPreviewPicker.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react';\nimport { EyeIcon } from '../icons/FeatureIcons.tsx';\n\nconst popularFonts = [\n 'Roboto', 'Open Sans', 'Lato', 'Montserrat', 'Oswald', 'Source Sans Pro', 'Raleway', 'Poppins', 'Nunito', 'Merriweather'\n];\n\nexport const FontPreviewPicker: React.FC = () => {\n const [selectedFont, setSelectedFont] = useState('Roboto');\n const [previewText, setPreviewText] = useState('The quick brown fox jumps over the lazy dog.');\n\n useEffect(() => {\n if (selectedFont) {\n const link = document.createElement('link');\n link.href = `https://fonts.googleapis.com/css?family=${selectedFont.replace(/ /g, '+')}&display=swap`;\n link.rel = 'stylesheet';\n document.head.appendChild(link);\n return () => {\n document.head.removeChild(link);\n };\n }\n }, [selectedFont]);\n \n const importRule = `@import url('https://fonts.googleapis.com/css?family=${selectedFont.replace(/ /g, '+')}&display=swap');`;\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <EyeIcon />\n <span className=\"ml-3\">Font Preview & Picker</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Preview Google Fonts and get the CSS import rule.</p>\n </header>\n <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-3 gap-6 min-h-0\">\n <div className=\"lg:col-span-1 flex flex-col gap-4 bg-slate-800/50 p-6 rounded-lg\">\n <h3 className=\"text-xl font-bold\">Controls</h3>\n <div>\n <label htmlFor=\"font-select\" className=\"block text-sm font-medium text-slate-400\">Select Font</label>\n <select id=\"font-select\" value={selectedFont} onChange={e => setSelectedFont(e.target.value)} className=\"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700\">\n {popularFonts.map(font => <option key={font} value={font}>{font}</option>)}\n </select>\n </div>\n <div>\n <label htmlFor=\"preview-text\" className=\"block text-sm font-medium text-slate-400\">Preview Text</label>\n <textarea id=\"preview-text\" value={previewText} onChange={e => setPreviewText(e.target.value)} className=\"w-full mt-1 p-2 rounded-md bg-slate-800 border border-slate-700 h-24 resize-none\"></textarea>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-slate-400\">CSS Import Rule</label>\n <div className=\"relative mt-1\">\n <pre className=\"bg-slate-900 p-2 rounded-md text-cyan-300 text-xs overflow-x-auto\">{importRule}</pre>\n <button onClick={() => navigator.clipboard.writeText(importRule)} className=\"absolute top-1 right-1 px-2 py-0.5 bg-slate-700 hover:bg-slate-600 rounded-md text-xs\">Copy</button>\n </div>\n </div>\n </div>\n <div className=\"lg:col-span-2 bg-slate-900 rounded-lg p-8 flex items-center justify-center\">\n <p className=\"text-4xl\" style={{ fontFamily: selectedFont }}>\n {previewText}\n </p>\n </div>\n </div>\n </div>\n );\n};"],"names":["popularFonts","FontPreviewPicker","selectedFont","setSelectedFont","useState","previewText","setPreviewText","useEffect","link","importRule","jsxs","jsx","EyeIcon","e","font"],"mappings":"2OAGA,MAAMA,EAAe,CACjB,SAAU,YAAa,OAAQ,aAAc,SAAU,kBAAmB,UAAW,UAAW,SAAU,cAC9G,EAEaC,EAA8B,IAAM,CAC7C,KAAM,CAACC,EAAcC,CAAe,EAAIC,EAAAA,SAAS,QAAQ,EACnD,CAACC,EAAaC,CAAc,EAAIF,EAAAA,SAAS,8CAA8C,EAE7FG,EAAAA,UAAU,IAAM,CACZ,GAAIL,EAAc,CACd,MAAMM,EAAO,SAAS,cAAc,MAAM,EAC1C,OAAAA,EAAK,KAAO,2CAA2CN,EAAa,QAAQ,KAAM,GAAG,CAAC,gBACtFM,EAAK,IAAM,aACX,SAAS,KAAK,YAAYA,CAAI,EACvB,IAAM,CACT,SAAS,KAAK,YAAYA,CAAI,CAClC,CACJ,CACJ,EAAG,CAACN,CAAY,CAAC,EAEjB,MAAMO,EAAa,wDAAwDP,EAAa,QAAQ,KAAM,GAAG,CAAC,mBAE1G,OACIQ,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACX,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,OACd,SAAA,CAAAA,EAAAA,KAAC,KAAA,CAAG,UAAU,sDACV,SAAA,CAAAC,EAAAA,IAACC,EAAA,EAAQ,EACTD,EAAAA,IAAC,OAAA,CAAK,UAAU,OAAO,SAAA,uBAAA,CAAqB,CAAA,EAChD,EACAA,EAAAA,IAAC,IAAA,CAAE,UAAU,sBAAsB,SAAA,mDAAA,CAAiD,CAAA,EACxF,EACAD,EAAAA,KAAC,MAAA,CAAI,UAAU,0DACX,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,mEACX,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAG,UAAU,oBAAoB,SAAA,WAAQ,SACzC,MAAA,CACG,SAAA,CAAAA,MAAC,QAAA,CAAM,QAAQ,cAAc,UAAU,2CAA2C,SAAA,cAAW,EAC7FA,EAAAA,IAAC,SAAA,CAAO,GAAG,cAAc,MAAOT,EAAc,SAAUW,GAAKV,EAAgBU,EAAE,OAAO,KAAK,EAAG,UAAU,wEACnG,SAAAb,EAAa,IAAIc,GAAQH,EAAAA,IAAC,SAAA,CAAkB,MAAOG,EAAO,SAAAA,CAAA,EAApBA,CAAyB,CAAS,CAAA,CAC7E,CAAA,EACJ,SACC,MAAA,CACG,SAAA,CAAAH,MAAC,QAAA,CAAM,QAAQ,eAAe,UAAU,2CAA2C,SAAA,eAAY,EAC/FA,EAAAA,IAAC,WAAA,CAAS,GAAG,eAAe,MAAON,EAAa,SAAUQ,GAAKP,EAAeO,EAAE,OAAO,KAAK,EAAG,UAAU,kFAAA,CAAmF,CAAA,EAChM,SACC,MAAA,CACG,SAAA,CAAAF,EAAAA,IAAC,QAAA,CAAM,UAAU,2CAA2C,SAAA,kBAAe,EAC3ED,EAAAA,KAAC,MAAA,CAAI,UAAU,gBACX,SAAA,CAAAC,EAAAA,IAAC,MAAA,CAAI,UAAU,oEAAqE,SAAAF,EAAW,EAC/FE,EAAAA,IAAC,SAAA,CAAO,QAAS,IAAM,UAAU,UAAU,UAAUF,CAAU,EAAG,UAAU,wFAAwF,SAAA,MAAA,CAAI,CAAA,CAAA,CAC5K,CAAA,CAAA,CACJ,CAAA,EACJ,EACAE,EAAAA,IAAC,MAAA,CAAI,UAAU,6EACX,eAAC,IAAA,CAAE,UAAU,WAAW,MAAO,CAAE,WAAYT,CAAA,EACxC,WACL,CAAA,CACJ,CAAA,CAAA,CACJ,CAAA,EACJ,CAER"}
|
assets/JsonTreeNavigator-BT2AXqig.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as i,j as e}from"./react-D_B_5QVd.js";import{F as u}from"./index-QBya0NjG.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const m=({data:s,nodeKey:l,isRoot:a=!1})=>{const[r,o]=i.useState(a),n=typeof s=="object"&&s!==null,c=()=>o(!r);if(!n)return e.jsxs("div",{className:"ml-4 pl-4 border-l border-slate-700",children:[e.jsxs("span",{className:"text-purple-400",children:[l,": "]}),e.jsx("span",{className:typeof s=="string"?"text-green-400":"text-orange-400",children:typeof s=="string"?`"${s}"`:String(s)})]});const d=Object.entries(s),t=Array.isArray(s)?"[]":"{}";return e.jsxs("div",{className:`ml-4 ${a?"":"pl-4 border-l border-slate-700"}`,children:[e.jsxs("button",{onClick:c,className:"flex items-center cursor-pointer",children:[e.jsx("span",{className:`transform transition-transform ${r?"rotate-90":"rotate-0"}`,children:"▶"}),e.jsxs("span",{className:"ml-1 text-purple-400",children:[l,":"]}),e.jsx("span",{className:"ml-2 text-slate-500",children:t[0]}),!r&&e.jsxs("span",{className:"text-slate-500",children:["...",t[1]]})]}),r&&e.jsxs("div",{children:[d.map(([x,p])=>e.jsx(m,{nodeKey:x,data:p},x)),e.jsx("div",{className:"text-slate-500 ml-4",children:t[1]})]})]})},f=({data:s})=>{const[l,a]=i.useState(`{
|
| 2 |
+
"id": "devcore-001",
|
| 3 |
+
"active": true,
|
| 4 |
+
"features": [
|
| 5 |
+
"ai-explainer",
|
| 6 |
+
"api-tester"
|
| 7 |
+
],
|
| 8 |
+
"config": {
|
| 9 |
+
"theme": "dark",
|
| 10 |
+
"version": 1
|
| 11 |
+
}
|
| 12 |
+
}`),[r,o]=i.useState(null),[n,c]=i.useState(""),d=()=>{try{const t=JSON.parse(l);o(t),c("")}catch(t){t instanceof Error&&c(t.message),o(null)}};return s?e.jsx("div",{className:"font-mono text-sm",children:e.jsx(m,{data:s,nodeKey:"root",isRoot:!0})}):e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(u,{}),e.jsx("span",{className:"ml-3",children:"JSON Tree Navigator"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Paste your JSON data to visualize it as a collapsible tree."})]}),e.jsxs("div",{className:"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden",children:[e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{htmlFor:"json-input",className:"text-sm font-medium text-slate-400 mb-2",children:"JSON Input"}),e.jsx("textarea",{id:"json-input",value:l,onChange:t=>a(t.target.value),className:`flex-grow p-4 bg-slate-900 border ${n?"border-red-500":"border-slate-700"} rounded-md resize-none font-mono text-sm text-cyan-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none`}),n&&e.jsx("p",{className:"text-red-400 text-xs mt-1",children:n}),e.jsx("button",{onClick:d,className:"mt-4 w-full px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400",children:"Render Tree"})]}),e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{className:"text-sm font-medium text-slate-400 mb-2",children:"Tree View"}),e.jsx("div",{className:"flex-grow p-4 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto",children:r?e.jsx(f,{data:r}):e.jsx("div",{className:"text-slate-500",children:'Click "Render Tree" to view'})})]})]})]})};export{f as JsonTreeNavigator};
|
| 13 |
+
//# sourceMappingURL=JsonTreeNavigator-BT2AXqig.js.map
|
assets/JsonTreeNavigator-BT2AXqig.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"JsonTreeNavigator-BT2AXqig.js","sources":["../../components/features/JsonTreeNavigator.tsx"],"sourcesContent":["\nimport React, { useState } from 'react';\nimport { FileCodeIcon } from '../icons/FeatureIcons.tsx';\n\ninterface JsonNodeProps {\n data: any;\n nodeKey: string;\n isRoot?: boolean;\n}\n\nconst JsonNode: React.FC<JsonNodeProps> = ({ data, nodeKey, isRoot = false }) => {\n const [isOpen, setIsOpen] = useState(isRoot);\n const isObject = typeof data === 'object' && data !== null;\n\n const toggleOpen = () => setIsOpen(!isOpen);\n\n if (!isObject) {\n return (\n <div className=\"ml-4 pl-4 border-l border-slate-700\">\n <span className=\"text-purple-400\">{nodeKey}: </span>\n <span className={typeof data === 'string' ? 'text-green-400' : 'text-orange-400'}>\n {typeof data === 'string' ? `\"${data}\"` : String(data)}\n </span>\n </div>\n );\n }\n\n const entries = Object.entries(data);\n const bracket = Array.isArray(data) ? '[]' : '{}';\n\n return (\n <div className={`ml-4 ${!isRoot ? 'pl-4 border-l border-slate-700' : ''}`}>\n <button onClick={toggleOpen} className=\"flex items-center cursor-pointer\">\n <span className={`transform transition-transform ${isOpen ? 'rotate-90' : 'rotate-0'}`}>▶</span>\n <span className=\"ml-1 text-purple-400\">{nodeKey}:</span>\n <span className=\"ml-2 text-slate-500\">{bracket[0]}</span>\n {!isOpen && <span className=\"text-slate-500\">...{bracket[1]}</span>}\n </button>\n {isOpen && (\n <div>\n {entries.map(([key, value]) => (\n <JsonNode key={key} nodeKey={key} data={value} />\n ))}\n <div className=\"text-slate-500 ml-4\">{bracket[1]}</div>\n </div>\n )}\n </div>\n );\n};\n\ninterface JsonTreeNavigatorProps {\n data?: any;\n}\n\nexport const JsonTreeNavigator: React.FC<JsonTreeNavigatorProps> = ({ data }) => {\n const [jsonInput, setJsonInput] = useState('{\\n \"id\": \"devcore-001\",\\n \"active\": true,\\n \"features\": [\\n \"ai-explainer\",\\n \"api-tester\"\\n ],\\n \"config\": {\\n \"theme\": \"dark\",\\n \"version\": 1\\n }\\n}');\n const [parsedData, setParsedData] = useState<any>(null);\n const [error, setError] = useState('');\n\n const parseJson = () => {\n try {\n const parsed = JSON.parse(jsonInput);\n setParsedData(parsed);\n setError('');\n } catch (e) {\n if (e instanceof Error) setError(e.message);\n setParsedData(null);\n }\n };\n \n // If data is passed as a prop, use it directly\n if (data) {\n return (\n <div className=\"font-mono text-sm\">\n <JsonNode data={data} nodeKey=\"root\" isRoot />\n </div>\n );\n }\n \n // Standalone mode with textarea\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <FileCodeIcon />\n <span className=\"ml-3\">JSON Tree Navigator</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Paste your JSON data to visualize it as a collapsible tree.</p>\n </header>\n <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden\">\n <div className=\"flex flex-col h-full\">\n <label htmlFor=\"json-input\" className=\"text-sm font-medium text-slate-400 mb-2\">JSON Input</label>\n <textarea\n id=\"json-input\"\n value={jsonInput}\n onChange={(e) => setJsonInput(e.target.value)}\n className={`flex-grow p-4 bg-slate-900 border ${error ? 'border-red-500' : 'border-slate-700'} rounded-md resize-none font-mono text-sm text-cyan-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none`}\n />\n {error && <p className=\"text-red-400 text-xs mt-1\">{error}</p>}\n <button onClick={parseJson} className=\"mt-4 w-full px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400\">\n Render Tree\n </button>\n </div>\n <div className=\"flex flex-col h-full\">\n <label className=\"text-sm font-medium text-slate-400 mb-2\">Tree View</label>\n <div className=\"flex-grow p-4 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto\">\n {parsedData ? <JsonTreeNavigator data={parsedData} /> : <div className=\"text-slate-500\">Click \"Render Tree\" to view</div>}\n </div>\n </div>\n </div>\n </div>\n );\n};"],"names":["JsonNode","data","nodeKey","isRoot","isOpen","setIsOpen","useState","isObject","toggleOpen","jsxs","entries","bracket","jsx","key","value","JsonTreeNavigator","jsonInput","setJsonInput","parsedData","setParsedData","error","setError","parseJson","parsed","e","FileCodeIcon"],"mappings":"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"}
|
assets/MarkdownRenderer-BDaVxTSW.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as s,j as p}from"./react-D_B_5QVd.js";import{m as a}from"./marked-CesSW9Du.js";const c=({content:e})=>{const[t,r]=s.useState("");return s.useEffect(()=>{(async()=>{if(e){const o=await a.parse(e);r(o)}else r("")})()},[e]),p.jsx("div",{className:"prose prose-sm prose-invert max-w-none prose-headings:text-slate-200 prose-p:text-slate-300 prose-strong:text-slate-100 prose-code:text-cyan-300 prose-code:before:content-none prose-code:after:content-none prose-pre:bg-slate-900/50 prose-pre:border prose-pre:border-slate-700 prose-pre:p-4 prose-pre:m-0",dangerouslySetInnerHTML:{__html:t}})};export{c as M};
|
| 2 |
+
//# sourceMappingURL=MarkdownRenderer-BDaVxTSW.js.map
|
assets/MarkdownRenderer-BDaVxTSW.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"MarkdownRenderer-BDaVxTSW.js","sources":["../../components/shared/MarkdownRenderer.tsx"],"sourcesContent":["\n\nimport React, { useState, useEffect } from 'react';\nimport { marked } from 'marked';\n\ninterface MarkdownRendererProps {\n content: string;\n}\n\nexport const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({ content }) => {\n const [sanitizedHtml, setSanitizedHtml] = useState<string | TrustedHTML>('');\n\n useEffect(() => {\n const parse = async () => {\n if (content) {\n const html = await marked.parse(content);\n setSanitizedHtml(html);\n } else {\n setSanitizedHtml('');\n }\n };\n parse();\n }, [content]);\n\n return (\n <div\n className=\"prose prose-sm prose-invert max-w-none prose-headings:text-slate-200 prose-p:text-slate-300 prose-strong:text-slate-100 prose-code:text-cyan-300 prose-code:before:content-none prose-code:after:content-none prose-pre:bg-slate-900/50 prose-pre:border prose-pre:border-slate-700 prose-pre:p-4 prose-pre:m-0\"\n dangerouslySetInnerHTML={{ __html: sanitizedHtml }}\n />\n );\n};"],"names":["MarkdownRenderer","content","sanitizedHtml","setSanitizedHtml","useState","useEffect","html","marked","jsx"],"mappings":"wFASO,MAAMA,EAAoD,CAAC,CAAE,QAAAC,KAAc,CAC9E,KAAM,CAACC,EAAeC,CAAgB,EAAIC,EAAAA,SAA+B,EAAE,EAE3EC,OAAAA,EAAAA,UAAU,IAAM,EACE,SAAY,CACtB,GAAIJ,EAAS,CACT,MAAMK,EAAO,MAAMC,EAAO,MAAMN,CAAO,EACvCE,EAAiBG,CAAI,CACzB,MACIH,EAAiB,EAAE,CAE3B,GACA,CACJ,EAAG,CAACF,CAAO,CAAC,EAGRO,EAAAA,IAAC,MAAA,CACG,UAAU,kTACV,wBAAyB,CAAE,OAAQN,CAAA,CAAc,CAAA,CAG7D"}
|
assets/MarkdownSlides-BMRDMVTS.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as a,j as e}from"./react-D_B_5QVd.js";import{m as u}from"./marked-CesSW9Du.js";import{P as h}from"./index-QBya0NjG.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const f=`# Slide 1: Welcome
|
| 2 |
+
|
| 3 |
+
This is a slide deck generated from Markdown.
|
| 4 |
+
|
| 5 |
+
- Use standard markdown syntax
|
| 6 |
+
- Like lists, headers, and **bold** text.
|
| 7 |
+
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
# Slide 2: Features
|
| 11 |
+
|
| 12 |
+
Navigate using the buttons below.
|
| 13 |
+
|
| 14 |
+
\`\`\`javascript
|
| 15 |
+
console.log("Code blocks work too!");
|
| 16 |
+
\`\`\`
|
| 17 |
+
|
| 18 |
+
---
|
| 19 |
+
|
| 20 |
+
# Slide 3: The End
|
| 21 |
+
|
| 22 |
+
Easy to create and present.
|
| 23 |
+
`,S=()=>{const[o,i]=a.useState(f),[t,r]=a.useState(0),[c,n]=a.useState(""),l=a.useMemo(()=>o.split(/^-{3,}\s*$/m),[o]);a.useEffect(()=>{(async()=>{const d=l[t]||"";if(d){const p=await u.parse(d);n(p)}else n("")})()},[l,t]);const m=()=>r(s=>Math.min(s+1,l.length-1)),x=()=>r(s=>Math.max(s-1,0));return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(h,{}),e.jsx("span",{className:"ml-3",children:"Markdown to Slides"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Write markdown, present it as a slideshow. Use '---' to separate slides."})]}),e.jsxs("div",{className:"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden",children:[e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{htmlFor:"md-input",className:"text-sm font-medium text-slate-400 mb-2",children:"Markdown Editor"}),e.jsx("textarea",{id:"md-input",value:o,onChange:s=>i(s.target.value),className:"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-cyan-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none"})]}),e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsx("label",{className:"text-sm font-medium text-slate-400 mb-2",children:"Presentation View"}),e.jsxs("div",{className:"relative flex-grow flex flex-col justify-center items-center p-8 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto",children:[e.jsx("div",{className:"prose prose-lg prose-invert max-w-none w-full",dangerouslySetInnerHTML:{__html:c}}),e.jsxs("div",{className:"absolute bottom-4 left-4 right-4 flex justify-between items-center",children:[e.jsx("button",{onClick:x,disabled:t===0,className:"px-4 py-2 bg-slate-700 rounded-md disabled:opacity-50",children:"Prev"}),e.jsxs("span",{className:"text-sm text-slate-400",children:[t+1," / ",l.length]}),e.jsx("button",{onClick:m,disabled:t===l.length-1,className:"px-4 py-2 bg-slate-700 rounded-md disabled:opacity-50",children:"Next"})]})]})]})]})]})};export{S as MarkdownSlides};
|
| 24 |
+
//# sourceMappingURL=MarkdownSlides-BMRDMVTS.js.map
|
assets/MarkdownSlides-BMRDMVTS.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"MarkdownSlides-BMRDMVTS.js","sources":["../../components/features/MarkdownSlides.tsx"],"sourcesContent":["\n\nimport React, { useState, useMemo, useEffect } from 'react';\nimport { marked } from 'marked';\nimport { PhotoIcon } from '../icons/FeatureIcons.tsx';\n\nconst exampleMarkdown = `# Slide 1: Welcome\n\nThis is a slide deck generated from Markdown.\n\n- Use standard markdown syntax\n- Like lists, headers, and **bold** text.\n\n---\n\n# Slide 2: Features\n\nNavigate using the buttons below.\n\n\\`\\`\\`javascript\nconsole.log(\"Code blocks work too!\");\n\\`\\`\\`\n\n---\n\n# Slide 3: The End\n\nEasy to create and present.\n`;\n\nexport const MarkdownSlides: React.FC = () => {\n const [markdown, setMarkdown] = useState(exampleMarkdown);\n const [currentSlide, setCurrentSlide] = useState(0);\n const [slideHtml, setSlideHtml] = useState<string | TrustedHTML>('');\n\n const slides = useMemo(() => markdown.split(/^-{3,}\\s*$/m), [markdown]);\n\n useEffect(() => {\n const parse = async () => {\n const currentSlideContent = slides[currentSlide] || '';\n if (currentSlideContent) {\n const html = await marked.parse(currentSlideContent);\n setSlideHtml(html);\n } else {\n setSlideHtml('');\n }\n };\n parse();\n }, [slides, currentSlide]);\n\n const goToNext = () => setCurrentSlide(s => Math.min(s + 1, slides.length - 1));\n const goToPrev = () => setCurrentSlide(s => Math.max(s - 1, 0));\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <PhotoIcon />\n <span className=\"ml-3\">Markdown to Slides</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Write markdown, present it as a slideshow. Use '---' to separate slides.</p>\n </header>\n <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 h-full overflow-hidden\">\n <div className=\"flex flex-col h-full\">\n <label htmlFor=\"md-input\" className=\"text-sm font-medium text-slate-400 mb-2\">Markdown Editor</label>\n <textarea\n id=\"md-input\"\n value={markdown}\n onChange={e => setMarkdown(e.target.value)}\n className=\"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-cyan-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none\"\n />\n </div>\n <div className=\"flex flex-col h-full\">\n <label className=\"text-sm font-medium text-slate-400 mb-2\">Presentation View</label>\n <div className=\"relative flex-grow flex flex-col justify-center items-center p-8 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto\">\n <div\n className=\"prose prose-lg prose-invert max-w-none w-full\"\n dangerouslySetInnerHTML={{ __html: slideHtml }}\n />\n <div className=\"absolute bottom-4 left-4 right-4 flex justify-between items-center\">\n <button onClick={goToPrev} disabled={currentSlide === 0} className=\"px-4 py-2 bg-slate-700 rounded-md disabled:opacity-50\">Prev</button>\n <span className=\"text-sm text-slate-400\">{currentSlide + 1} / {slides.length}</span>\n <button onClick={goToNext} disabled={currentSlide === slides.length - 1} className=\"px-4 py-2 bg-slate-700 rounded-md disabled:opacity-50\">Next</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};"],"names":["exampleMarkdown","MarkdownSlides","markdown","setMarkdown","useState","currentSlide","setCurrentSlide","slideHtml","setSlideHtml","slides","useMemo","useEffect","currentSlideContent","html","marked","goToNext","goToPrev","jsxs","jsx","PhotoIcon","e"],"mappings":"oRAMA,MAAMA,EAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBXC,EAA2B,IAAM,CAC1C,KAAM,CAACC,EAAUC,CAAW,EAAIC,EAAAA,SAASJ,CAAe,EAClD,CAACK,EAAcC,CAAe,EAAIF,EAAAA,SAAS,CAAC,EAC5C,CAACG,EAAWC,CAAY,EAAIJ,EAAAA,SAA+B,EAAE,EAE7DK,EAASC,EAAAA,QAAQ,IAAMR,EAAS,MAAM,aAAa,EAAG,CAACA,CAAQ,CAAC,EAEtES,EAAAA,UAAU,IAAM,EACE,SAAY,CACtB,MAAMC,EAAsBH,EAAOJ,CAAY,GAAK,GACpD,GAAIO,EAAqB,CACrB,MAAMC,EAAO,MAAMC,EAAO,MAAMF,CAAmB,EACnDJ,EAAaK,CAAI,CACrB,MACIL,EAAa,EAAE,CAEvB,GACA,CACJ,EAAG,CAACC,EAAQJ,CAAY,CAAC,EAEzB,MAAMU,EAAW,IAAMT,EAAgB,GAAK,KAAK,IAAI,EAAI,EAAGG,EAAO,OAAS,CAAC,CAAC,EACxEO,EAAW,IAAMV,EAAgB,GAAK,KAAK,IAAI,EAAI,EAAG,CAAC,CAAC,EAE9D,OACIW,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACX,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,OACd,SAAA,CAAAA,EAAAA,KAAC,KAAA,CAAG,UAAU,sDACV,SAAA,CAAAC,EAAAA,IAACC,EAAA,EAAU,EACXD,EAAAA,IAAC,OAAA,CAAK,UAAU,OAAO,SAAA,oBAAA,CAAkB,CAAA,EAC7C,EACAA,EAAAA,IAAC,IAAA,CAAE,UAAU,sBAAsB,SAAA,0EAAA,CAAwE,CAAA,EAC/G,EACAD,EAAAA,KAAC,MAAA,CAAI,UAAU,yEACX,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACV,SAAA,CAAAC,MAAC,QAAA,CAAM,QAAQ,WAAW,UAAU,0CAA0C,SAAA,kBAAe,EAC7FA,EAAAA,IAAC,WAAA,CACE,GAAG,WACH,MAAOhB,EACP,SAAUkB,GAAKjB,EAAYiB,EAAE,OAAO,KAAK,EACzC,UAAU,+JAAA,CAAA,CACd,EACJ,EACCH,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACZ,SAAA,CAAAC,EAAAA,IAAC,QAAA,CAAM,UAAU,0CAA0C,SAAA,oBAAiB,EAC5ED,EAAAA,KAAC,MAAA,CAAI,UAAU,yIACX,SAAA,CAAAC,EAAAA,IAAC,MAAA,CACG,UAAU,gDACV,wBAAyB,CAAE,OAAQX,CAAA,CAAU,CAAA,EAEhDU,EAAAA,KAAC,MAAA,CAAI,UAAU,qEACZ,SAAA,CAAAC,EAAAA,IAAC,SAAA,CAAO,QAASF,EAAU,SAAUX,IAAiB,EAAG,UAAU,wDAAwD,SAAA,MAAA,CAAI,EAC/HY,EAAAA,KAAC,OAAA,CAAK,UAAU,yBAA0B,SAAA,CAAAZ,EAAe,EAAE,MAAII,EAAO,MAAA,EAAO,EAC7ES,EAAAA,IAAC,SAAA,CAAO,QAASH,EAAU,SAAUV,IAAiBI,EAAO,OAAS,EAAG,UAAU,wDAAwD,SAAA,MAAA,CAAI,CAAA,CAAA,CACnJ,CAAA,CAAA,CACJ,CAAA,CAAA,CACJ,CAAA,CAAA,CACJ,CAAA,EACJ,CAER"}
|
assets/Placeholder-D_7djokD.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{j as l}from"./react-D_B_5QVd.js";import"./jszip-C9ownNzX.js";const i=({feature:s})=>l.jsxs("div",{className:"flex flex-col items-center justify-center h-full p-8 text-center text-slate-400",children:[l.jsx("div",{className:"text-6xl mb-4","aria-hidden":"true",children:s==null?void 0:s.icon}),l.jsx("h1",{className:"text-3xl font-bold text-slate-200 mb-2",children:(s==null?void 0:s.name)||"Feature"}),l.jsx("p",{className:"text-lg mb-4 max-w-md",children:(s==null?void 0:s.description)||"Feature description."}),l.jsxs("div",{className:"bg-yellow-900/50 text-yellow-300 border border-yellow-800/80 rounded-lg px-6 py-3",children:[l.jsx("p",{className:"font-semibold",children:"Under Construction"}),l.jsx("p",{className:"text-sm",children:"This feature is not yet available."})]})]});export{i as Placeholder};
|
| 2 |
+
//# sourceMappingURL=Placeholder-D_7djokD.js.map
|
assets/Placeholder-D_7djokD.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"Placeholder-D_7djokD.js","sources":["../../components/features/Placeholder.tsx"],"sourcesContent":["\nimport React from 'react';\nimport type { Feature } from '../types.ts';\n\nexport const Placeholder: React.FC<{ feature?: Feature }> = ({ feature }) => {\n return (\n <div className=\"flex flex-col items-center justify-center h-full p-8 text-center text-slate-400\">\n <div className=\"text-6xl mb-4\" aria-hidden=\"true\">\n {feature?.icon}\n </div>\n <h1 className=\"text-3xl font-bold text-slate-200 mb-2\">\n {feature?.name || 'Feature'}\n </h1>\n <p className=\"text-lg mb-4 max-w-md\">\n {feature?.description || 'Feature description.'}\n </p>\n <div className=\"bg-yellow-900/50 text-yellow-300 border border-yellow-800/80 rounded-lg px-6 py-3\">\n <p className=\"font-semibold\">Under Construction</p>\n <p className=\"text-sm\">This feature is not yet available.</p>\n </div>\n </div>\n );\n};"],"names":["Placeholder","feature","jsxs","jsx"],"mappings":"oEAIO,MAAMA,EAA+C,CAAC,CAAE,QAAAC,KAEvDC,EAAAA,KAAC,MAAA,CAAI,UAAU,kFACX,SAAA,CAAAC,MAAC,OAAI,UAAU,gBAAgB,cAAY,OACtC,0BAAS,KACd,QACC,KAAA,CAAG,UAAU,yCACT,UAAAF,GAAA,YAAAA,EAAS,OAAQ,UACtB,QACC,IAAA,CAAE,UAAU,wBACR,UAAAA,GAAA,YAAAA,EAAS,cAAe,uBAC7B,EACAC,EAAAA,KAAC,MAAA,CAAI,UAAU,oFACX,SAAA,CAAAC,EAAAA,IAAC,IAAA,CAAE,UAAU,gBAAgB,SAAA,qBAAkB,EAC/CA,EAAAA,IAAC,IAAA,CAAE,UAAU,UAAU,SAAA,oCAAA,CAAkC,CAAA,CAAA,CAC7D,CAAA,EACJ"}
|
assets/PrSummaryGenerator-CCRA0dN-.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r,j as e}from"./react-D_B_5QVd.js";import{c as p}from"./diff-DcU-ljqw.js";import{y as j,G as g,L as x}from"./index-QBya0NjG.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const b=`function Greeter(props) {
|
| 2 |
+
return <h1>Hello, {props.name}!</h1>;
|
| 3 |
+
}`,y=`function Greeter({ name, enthusiasmLevel = 1 }) {
|
| 4 |
+
const punctuation = '!'.repeat(enthusiasmLevel);
|
| 5 |
+
return <h1>Hello, {name}{punctuation}</h1>;
|
| 6 |
+
}`,A=()=>{const[n,f]=r.useState(b),[o,u]=r.useState(y),[t,i]=r.useState(null),[a,d]=r.useState(!1),[m,c]=r.useState(""),h=r.useCallback(async()=>{if(!n.trim()&&!o.trim()){c("Please provide code to generate a summary.");return}d(!0),c(""),i(null);try{const s=p("component.tsx",n,o),l=await j(s);i(l)}catch(s){const l=s instanceof Error?s.message:"An unknown error occurred.";c(`Failed to generate summary: ${l}`)}finally{d(!1)}},[n,o]);return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(g,{}),e.jsx("span",{className:"ml-3",children:"AI PR Summary Generator"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Paste 'before' and 'after' code snippets to generate a comprehensive PR summary."})]}),e.jsxs("div",{className:"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 min-h-0",children:[e.jsxs("div",{className:"flex flex-col gap-4 min-h-0",children:[e.jsxs("div",{className:"flex flex-col flex-1 min-h-0",children:[e.jsx("label",{htmlFor:"before-code",className:"text-sm font-medium text-slate-400 mb-2",children:"Before"}),e.jsx("textarea",{id:"before-code",value:n,onChange:s=>f(s.target.value),className:"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm"})]}),e.jsxs("div",{className:"flex flex-col flex-1 min-h-0",children:[e.jsx("label",{htmlFor:"after-code",className:"text-sm font-medium text-slate-400 mb-2",children:"After"}),e.jsx("textarea",{id:"after-code",value:o,onChange:s=>u(s.target.value),className:"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm"})]}),e.jsx("button",{onClick:h,disabled:a,className:"w-full flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600",children:a?e.jsx(x,{}):"Generate Summary"})]}),e.jsxs("div",{className:"flex flex-col min-h-0",children:[e.jsx("label",{className:"text-sm font-medium text-slate-400 mb-2",children:"Generated Summary"}),e.jsxs("div",{className:"flex-grow p-4 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto",children:[a&&e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsx(x,{})}),m&&e.jsx("p",{className:"text-red-400",children:m}),t&&!a&&e.jsxs("div",{className:"prose prose-sm prose-invert max-w-none",children:[e.jsx("h3",{children:t.title}),e.jsx("p",{children:t.summary}),e.jsx("h4",{children:"Changes:"}),e.jsx("ul",{children:t.changes.map((s,l)=>e.jsx("li",{children:s},l))})]}),!a&&!t&&!m&&e.jsx("div",{className:"text-slate-500 h-full flex items-center justify-center",children:"The summary will appear here."})]})]})]})]})};export{A as PrSummaryGenerator};
|
| 7 |
+
//# sourceMappingURL=PrSummaryGenerator-CCRA0dN-.js.map
|
assets/PrSummaryGenerator-CCRA0dN-.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"PrSummaryGenerator-CCRA0dN-.js","sources":["../../components/features/PrSummaryGenerator.tsx"],"sourcesContent":["\n\n\nimport React, { useState, useCallback } from 'react';\nimport * as Diff from 'diff';\nimport { generatePrSummaryStructured } from '../../services/geminiService.ts';\nimport type { StructuredPrSummary } from '../../types.ts';\nimport { GitBranchIcon } from '../icons/FeatureIcons.tsx';\nimport { LoadingSpinner } from '../shared/LoadingSpinner.tsx';\n\nconst exampleBefore = `function Greeter(props) {\n return <h1>Hello, {props.name}!</h1>;\n}`;\nconst exampleAfter = `function Greeter({ name, enthusiasmLevel = 1 }) {\n const punctuation = '!'.repeat(enthusiasmLevel);\n return <h1>Hello, {name}{punctuation}</h1>;\n}`;\n\nexport const PrSummaryGenerator: React.FC = () => {\n const [beforeCode, setBeforeCode] = useState<string>(exampleBefore);\n const [afterCode, setAfterCode] = useState<string>(exampleAfter);\n const [summary, setSummary] = useState<StructuredPrSummary | null>(null);\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<string>('');\n\n const handleGenerate = useCallback(async () => {\n if (!beforeCode.trim() && !afterCode.trim()) {\n setError('Please provide code to generate a summary.');\n return;\n }\n setIsLoading(true);\n setError('');\n setSummary(null);\n\n try {\n const diff = Diff.createPatch('component.tsx', beforeCode, afterCode);\n const result = await generatePrSummaryStructured(diff);\n setSummary(result);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';\n setError(`Failed to generate summary: ${errorMessage}`);\n } finally {\n setIsLoading(false);\n }\n }, [beforeCode, afterCode]);\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <GitBranchIcon />\n <span className=\"ml-3\">AI PR Summary Generator</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Paste 'before' and 'after' code snippets to generate a comprehensive PR summary.</p>\n </header>\n <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 min-h-0\">\n <div className=\"flex flex-col gap-4 min-h-0\">\n <div className=\"flex flex-col flex-1 min-h-0\">\n <label htmlFor=\"before-code\" className=\"text-sm font-medium text-slate-400 mb-2\">Before</label>\n <textarea id=\"before-code\" value={beforeCode} onChange={e => setBeforeCode(e.target.value)} className=\"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm\" />\n </div>\n <div className=\"flex flex-col flex-1 min-h-0\">\n <label htmlFor=\"after-code\" className=\"text-sm font-medium text-slate-400 mb-2\">After</label>\n <textarea id=\"after-code\" value={afterCode} onChange={e => setAfterCode(e.target.value)} className=\"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm\" />\n </div>\n <button onClick={handleGenerate} disabled={isLoading} className=\"w-full flex items-center justify-center px-6 py-3 bg-cyan-500 text-slate-900 font-bold rounded-md hover:bg-cyan-400 disabled:bg-slate-600\">\n {isLoading ? <LoadingSpinner /> : 'Generate Summary'}\n </button>\n </div>\n <div className=\"flex flex-col min-h-0\">\n <label className=\"text-sm font-medium text-slate-400 mb-2\">Generated Summary</label>\n <div className=\"flex-grow p-4 bg-slate-800/50 border border-slate-700/50 rounded-md overflow-y-auto\">\n {isLoading && <div className=\"flex items-center justify-center h-full\"><LoadingSpinner /></div>}\n {error && <p className=\"text-red-400\">{error}</p>}\n {summary && !isLoading && (\n <div className=\"prose prose-sm prose-invert max-w-none\">\n <h3>{summary.title}</h3>\n <p>{summary.summary}</p>\n <h4>Changes:</h4>\n <ul>\n {summary.changes.map((change, i) => <li key={i}>{change}</li>)}\n </ul>\n </div>\n )}\n {!isLoading && !summary && !error && <div className=\"text-slate-500 h-full flex items-center justify-center\">The summary will appear here.</div>}\n </div>\n </div>\n </div>\n </div>\n );\n};"],"names":["exampleBefore","exampleAfter","PrSummaryGenerator","beforeCode","setBeforeCode","useState","afterCode","setAfterCode","summary","setSummary","isLoading","setIsLoading","error","setError","handleGenerate","useCallback","diff","Diff.createPatch","result","generatePrSummaryStructured","err","errorMessage","jsxs","jsx","GitBranchIcon","e","LoadingSpinner","change","i"],"mappings":"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"}
|
assets/ProjectMoodboard-Cq8q--8L.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as g,j as o}from"./react-D_B_5QVd.js";import{P as p}from"./index-QBya0NjG.js";import{u as b}from"./useLocalStorage-WuAvJp3F.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const d=["bg-yellow-300","bg-green-300","bg-blue-300","bg-pink-300"],D=()=>{const[r,n]=b("devcore_moodboard",[]),[s,a]=g.useState(null),m=()=>{const e={id:Date.now(),text:"New idea...",x:50,y:50,color:d[Math.floor(Math.random()*d.length)]};n([...r,e])},u=(e,t)=>{n(r.map(l=>l.id===e?{...l,text:t}:l))},x=(e,t)=>{const i=e.currentTarget.getBoundingClientRect();a({id:t,offsetX:e.clientX-i.left,offsetY:e.clientY-i.top})},f=e=>{s&&n(r.map(t=>t.id===s.id?{...t,x:e.clientX-s.offsetX-e.currentTarget.getBoundingClientRect().left,y:e.clientY-s.offsetY-e.currentTarget.getBoundingClientRect().top}:t))},c=()=>{a(null)};return o.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[o.jsxs("header",{className:"mb-6 flex justify-between items-center",children:[o.jsxs("div",{children:[o.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[o.jsx(p,{}),o.jsx("span",{className:"ml-3",children:"Project Moodboard"})]}),o.jsx("p",{className:"text-slate-400 mt-1",children:"Organize your ideas with draggable sticky notes."})]}),o.jsx("button",{onClick:m,className:"px-6 py-2 bg-cyan-500 text-slate-900 font-bold rounded-md",children:"Add Note"})]}),o.jsx("div",{className:"relative flex-grow bg-slate-900/50 border-2 border-dashed border-slate-700 rounded-lg overflow-hidden",onMouseMove:f,onMouseUp:c,onMouseLeave:c,children:r.map(e=>o.jsx("div",{className:`absolute w-48 h-48 p-2 flex flex-col shadow-lg cursor-grab active:cursor-grabbing ${e.color}`,style:{top:e.y,left:e.x,transform:(s==null?void 0:s.id)===e.id?"scale(1.05)":"scale(1)"},onMouseDown:t=>x(t,e.id),children:o.jsx("textarea",{value:e.text,onChange:t=>u(e.id,t.target.value),onMouseDown:t=>t.stopPropagation(),className:"w-full h-full bg-transparent text-black resize-none focus:outline-none font-medium"})},e.id))})]})};export{D as ProjectMoodboard};
|
| 2 |
+
//# sourceMappingURL=ProjectMoodboard-Cq8q--8L.js.map
|
assets/ProjectMoodboard-Cq8q--8L.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"ProjectMoodboard-Cq8q--8L.js","sources":["../../components/features/ProjectMoodboard.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { PhotoIcon } from '../icons/FeatureIcons.tsx';\nimport { useLocalStorage } from '../../hooks/useLocalStorage.ts';\n\ninterface Note {\n id: number;\n text: string;\n x: number;\n y: number;\n color: string;\n}\n\nconst colors = ['bg-yellow-300', 'bg-green-300', 'bg-blue-300', 'bg-pink-300'];\n\nexport const ProjectMoodboard: React.FC = () => {\n const [notes, setNotes] = useLocalStorage('devcore_moodboard', []);\n const [dragging, setDragging] = useState<{ id: number; offsetX: number; offsetY: number } | null>(null);\n\n const addNote = () => {\n const newNote: Note = {\n id: Date.now(),\n text: 'New idea...',\n x: 50,\n y: 50,\n color: colors[Math.floor(Math.random() * colors.length)],\n };\n setNotes([...notes, newNote]);\n };\n\n const updateText = (id: number, text: string) => {\n setNotes(notes.map((n: Note) => n.id === id ? { ...n, text } : n));\n };\n\n const onMouseDown = (e: React.MouseEvent<HTMLDivElement>, id: number) => {\n const noteElement = e.currentTarget;\n const rect = noteElement.getBoundingClientRect();\n setDragging({\n id,\n offsetX: e.clientX - rect.left,\n offsetY: e.clientY - rect.top,\n });\n };\n\n const onMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {\n if (!dragging) return;\n setNotes(\n notes.map((n: Note) =>\n n.id === dragging.id\n ? { ...n, x: e.clientX - dragging.offsetX - e.currentTarget.getBoundingClientRect().left, y: e.clientY - dragging.offsetY - e.currentTarget.getBoundingClientRect().top }\n : n\n )\n );\n };\n\n const onMouseUp = () => {\n setDragging(null);\n };\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6 flex justify-between items-center\">\n <div>\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <PhotoIcon />\n <span className=\"ml-3\">Project Moodboard</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Organize your ideas with draggable sticky notes.</p>\n </div>\n <button onClick={addNote} className=\"px-6 py-2 bg-cyan-500 text-slate-900 font-bold rounded-md\">Add Note</button>\n </header>\n <div\n className=\"relative flex-grow bg-slate-900/50 border-2 border-dashed border-slate-700 rounded-lg overflow-hidden\"\n onMouseMove={onMouseMove}\n onMouseUp={onMouseUp}\n onMouseLeave={onMouseUp}\n >\n {notes.map((note: Note) => (\n <div\n key={note.id}\n className={`absolute w-48 h-48 p-2 flex flex-col shadow-lg cursor-grab active:cursor-grabbing ${note.color}`}\n style={{ top: note.y, left: note.x, transform: dragging?.id === note.id ? 'scale(1.05)' : 'scale(1)' }}\n onMouseDown={e => onMouseDown(e, note.id)}\n >\n <textarea\n value={note.text}\n onChange={(e) => updateText(note.id, e.target.value)}\n onMouseDown={(e) => e.stopPropagation()}\n className=\"w-full h-full bg-transparent text-black resize-none focus:outline-none font-medium\"\n />\n </div>\n ))}\n </div>\n </div>\n );\n};"],"names":["colors","ProjectMoodboard","notes","setNotes","useLocalStorage","dragging","setDragging","useState","addNote","newNote","updateText","id","text","n","onMouseDown","rect","onMouseMove","onMouseUp","jsxs","jsx","PhotoIcon","note","e"],"mappings":"6RAYA,MAAMA,EAAS,CAAC,gBAAiB,eAAgB,cAAe,aAAa,EAEhEC,EAA6B,IAAM,CAC5C,KAAM,CAACC,EAAOC,CAAQ,EAAIC,EAAgB,oBAAqB,CAAA,CAAE,EAC3D,CAACC,EAAUC,CAAW,EAAIC,EAAAA,SAAkE,IAAI,EAEhGC,EAAU,IAAM,CAClB,MAAMC,EAAgB,CAClB,GAAI,KAAK,IAAA,EACT,KAAM,cACN,EAAG,GACH,EAAG,GACH,MAAOT,EAAO,KAAK,MAAM,KAAK,OAAA,EAAWA,EAAO,MAAM,CAAC,CAAA,EAE3DG,EAAS,CAAC,GAAGD,EAAOO,CAAO,CAAC,CAChC,EAEMC,EAAa,CAACC,EAAYC,IAAiB,CAC7CT,EAASD,EAAM,IAAKW,GAAYA,EAAE,KAAOF,EAAK,CAAE,GAAGE,EAAG,KAAAD,CAAA,EAASC,CAAC,CAAC,CACrE,EAEMC,EAAc,CAAC,EAAqCH,IAAe,CAErE,MAAMI,EADc,EAAE,cACG,sBAAA,EACzBT,EAAY,CACR,GAAAK,EACA,QAAS,EAAE,QAAUI,EAAK,KAC1B,QAAS,EAAE,QAAUA,EAAK,GAAA,CAC7B,CACL,EAEMC,EAAe,GAAwC,CACpDX,GACLF,EACID,EAAM,IAAKW,GACPA,EAAE,KAAOR,EAAS,GACZ,CAAE,GAAGQ,EAAG,EAAG,EAAE,QAAUR,EAAS,QAAU,EAAE,cAAc,sBAAA,EAAwB,KAAM,EAAG,EAAE,QAAUA,EAAS,QAAU,EAAE,cAAc,sBAAA,EAAwB,KAClKQ,CAAA,CACV,CAER,EAEMI,EAAY,IAAM,CACpBX,EAAY,IAAI,CACpB,EAEA,OACIY,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACX,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,yCACb,SAAA,CAAAA,OAAC,MAAA,CACE,SAAA,CAAAA,EAAAA,KAAC,KAAA,CAAG,UAAU,sDACV,SAAA,CAAAC,EAAAA,IAACC,EAAA,EAAU,EACXD,EAAAA,IAAC,OAAA,CAAK,UAAU,OAAO,SAAA,mBAAA,CAAiB,CAAA,EAC5C,EACAA,EAAAA,IAAC,IAAA,CAAE,UAAU,sBAAsB,SAAA,kDAAA,CAAgD,CAAA,EACvF,QACC,SAAA,CAAO,QAASX,EAAS,UAAU,4DAA4D,SAAA,UAAA,CAAQ,CAAA,EAC5G,EACAW,EAAAA,IAAC,MAAA,CACG,UAAU,wGACV,YAAAH,EACA,UAAAC,EACA,aAAcA,EAEb,SAAAf,EAAM,IAAKmB,GACRF,EAAAA,IAAC,MAAA,CAEG,UAAW,qFAAqFE,EAAK,KAAK,GAC1G,MAAO,CAAE,IAAKA,EAAK,EAAG,KAAMA,EAAK,EAAG,WAAWhB,GAAA,YAAAA,EAAU,MAAOgB,EAAK,GAAK,cAAgB,UAAA,EAC1F,YAAaC,GAAKR,EAAYQ,EAAGD,EAAK,EAAE,EAExC,SAAAF,EAAAA,IAAC,WAAA,CACG,MAAOE,EAAK,KACZ,SAAWC,GAAMZ,EAAWW,EAAK,GAAIC,EAAE,OAAO,KAAK,EAClD,YAAcA,GAAMA,EAAE,gBAAA,EACvB,UAAU,oFAAA,CAAA,CACd,EAVKD,EAAK,EAAA,CAYjB,CAAA,CAAA,CACL,EACJ,CAER"}
|
assets/PromptCraftPad-Bsdu3BUV.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as d,j as e}from"./react-D_B_5QVd.js";import{S as p}from"./index-QBya0NjG.js";import{u as f}from"./useLocalStorage-WuAvJp3F.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const v=()=>{const[l,r]=f("devcore_prompts",[{id:1,name:"React Component Generator",text:"Generate a React component named {name} that {description}. Style it with Tailwind CSS."}]),[s,n]=d.useState(l[0]||null);d.useEffect(()=>{if(!s&&l.length>0&&n(l[0]),s){const t=l.find(a=>a.id===s.id);n(t||null)}},[l,s]);const c=t=>{n(t)},i=t=>{if(!s)return;const a={...s,text:t.target.value};n(a),r(l.map(o=>o.id===a.id?a:o))},m=()=>{const t={id:Date.now(),name:"New Untitled Prompt",text:""};r([...l,t]),n(t)},x=t=>{r(l.filter(a=>a.id!==t)),(s==null?void 0:s.id)===t&&n(null)};return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(p,{}),e.jsx("span",{className:"ml-3",children:"Prompt Craft Pad"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Create, save, and manage your favorite AI prompts."})]}),e.jsxs("div",{className:"flex-grow flex gap-6 min-h-0",children:[e.jsxs("aside",{className:"w-1/3 bg-slate-800/50 p-4 rounded-lg flex flex-col",children:[e.jsx("h3",{className:"font-bold mb-2",children:"My Prompts"}),e.jsx("ul",{className:"space-y-2 flex-grow overflow-y-auto",children:l.map(t=>e.jsxs("li",{className:"group flex items-center justify-between",children:[e.jsx("button",{onClick:()=>c(t),className:`w-full text-left px-3 py-2 rounded-md ${(s==null?void 0:s.id)===t.id?"bg-cyan-500/20 text-cyan-300":"hover:bg-slate-700/50"}`,children:t.name}),e.jsx("button",{onClick:()=>x(t.id),className:"ml-2 p-1 text-slate-500 hover:text-red-400 opacity-0 group-hover:opacity-100",children:"×"})]},t.id))}),e.jsx("div",{className:"mt-4 pt-4 border-t border-slate-700",children:e.jsx("button",{onClick:m,className:"w-full text-sm py-2 bg-cyan-500/80 text-white rounded-md",children:"Add New Prompt"})})]}),e.jsx("main",{className:"w-2/3 flex flex-col",children:s?e.jsxs(e.Fragment,{children:[e.jsx("label",{htmlFor:"prompt-editor",className:"text-sm font-medium text-slate-400 mb-2",children:s.name}),e.jsx("textarea",{id:"prompt-editor",value:s.text,onChange:i,className:"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-cyan-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none"})]}):e.jsx("div",{className:"flex-grow flex items-center justify-center bg-slate-900 rounded-lg text-slate-500",children:"Select a prompt or create a new one."})})]})]})};export{v as PromptCraftPad};
|
| 2 |
+
//# sourceMappingURL=PromptCraftPad-Bsdu3BUV.js.map
|
assets/PromptCraftPad-Bsdu3BUV.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"PromptCraftPad-Bsdu3BUV.js","sources":["../../components/features/PromptCraftPad.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react';\nimport { SparklesIcon } from '../icons/FeatureIcons.tsx';\nimport { useLocalStorage } from '../../hooks/useLocalStorage.ts';\n\ninterface Prompt {\n id: number;\n name: string;\n text: string;\n}\n\nexport const PromptCraftPad: React.FC = () => {\n const [prompts, setPrompts] = useLocalStorage('devcore_prompts', [\n { id: 1, name: 'React Component Generator', text: 'Generate a React component named {name} that {description}. Style it with Tailwind CSS.'}\n ]);\n const [activePrompt, setActivePrompt] = useState<Prompt | null>(prompts[0] || null);\n \n useEffect(() => {\n if(!activePrompt && prompts.length > 0) {\n setActivePrompt(prompts[0]);\n }\n if (activePrompt) {\n const freshPrompt = prompts.find((p: Prompt) => p.id === activePrompt.id);\n setActivePrompt(freshPrompt || null);\n }\n }, [prompts, activePrompt]);\n\n const handleSelectPrompt = (prompt: Prompt) => {\n setActivePrompt(prompt);\n };\n\n const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (!activePrompt) return;\n const updatedPrompt = { ...activePrompt, text: e.target.value };\n setActivePrompt(updatedPrompt);\n setPrompts(prompts.map((p: Prompt) => p.id === updatedPrompt.id ? updatedPrompt : p));\n };\n\n const handleAddNew = () => {\n const newPrompt = { id: Date.now(), name: 'New Untitled Prompt', text: '' };\n setPrompts([...prompts, newPrompt]);\n setActivePrompt(newPrompt);\n };\n \n const handleDelete = (id: number) => {\n setPrompts(prompts.filter((p: Prompt) => p.id !== id));\n if(activePrompt?.id === id) setActivePrompt(null);\n }\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <SparklesIcon />\n <span className=\"ml-3\">Prompt Craft Pad</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Create, save, and manage your favorite AI prompts.</p>\n </header>\n <div className=\"flex-grow flex gap-6 min-h-0\">\n <aside className=\"w-1/3 bg-slate-800/50 p-4 rounded-lg flex flex-col\">\n <h3 className=\"font-bold mb-2\">My Prompts</h3>\n <ul className=\"space-y-2 flex-grow overflow-y-auto\">\n {prompts.map((prompt: Prompt) => (\n <li key={prompt.id} className=\"group flex items-center justify-between\">\n <button onClick={() => handleSelectPrompt(prompt)} className={`w-full text-left px-3 py-2 rounded-md ${activePrompt?.id === prompt.id ? 'bg-cyan-500/20 text-cyan-300' : 'hover:bg-slate-700/50'}`}>\n {prompt.name}\n </button>\n <button onClick={() => handleDelete(prompt.id)} className=\"ml-2 p-1 text-slate-500 hover:text-red-400 opacity-0 group-hover:opacity-100\">×</button>\n </li>\n ))}\n </ul>\n <div className=\"mt-4 pt-4 border-t border-slate-700\">\n <button onClick={handleAddNew} className=\"w-full text-sm py-2 bg-cyan-500/80 text-white rounded-md\">Add New Prompt</button>\n </div>\n </aside>\n <main className=\"w-2/3 flex flex-col\">\n {activePrompt ? (\n <>\n <label htmlFor=\"prompt-editor\" className=\"text-sm font-medium text-slate-400 mb-2\">{activePrompt.name}</label>\n <textarea\n id=\"prompt-editor\"\n value={activePrompt.text}\n onChange={handleTextChange}\n className=\"flex-grow p-4 bg-slate-900 border border-slate-700 rounded-md resize-none font-mono text-sm text-cyan-300 focus:ring-2 focus:ring-cyan-500 focus:outline-none\"\n />\n </>\n ) : (\n <div className=\"flex-grow flex items-center justify-center bg-slate-900 rounded-lg text-slate-500\">\n Select a prompt or create a new one.\n </div>\n )}\n </main>\n </div>\n </div>\n );\n};"],"names":["PromptCraftPad","prompts","setPrompts","useLocalStorage","activePrompt","setActivePrompt","useState","useEffect","freshPrompt","p","handleSelectPrompt","prompt","handleTextChange","e","updatedPrompt","handleAddNew","newPrompt","handleDelete","id","jsxs","jsx","SparklesIcon","Fragment"],"mappings":"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"}
|
assets/PwaManifestEditor-CI-u9z3y.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r,j as e}from"./react-D_B_5QVd.js";import{k as m}from"./index-QBya0NjG.js";import"./jszip-C9ownNzX.js";import"./react-dom-EAO2-NBm.js";import"./scheduler-DYLXRpC5.js";import"./@google-4tyssLU_.js";import"./idb-Dob3nYDb.js";const b=()=>{const[s,o]=r.useState({name:"DevCore 100 Progressive Web App",short_name:"DevCore100",start_url:"/",display:"standalone",background_color:"#1e293b",theme_color:"#06b6d4"}),l=t=>{o({...s,[t.target.name]:t.target.value})},a=r.useMemo(()=>{const t={...s,icons:[{src:"icon-192.png",type:"image/png",sizes:"192x192"},{src:"icon-512.png",type:"image/png",sizes:"512x512"}]};return JSON.stringify(t,null,2)},[s]),n=()=>{navigator.clipboard.writeText(a)};return e.jsxs("div",{className:"h-full flex flex-col p-4 sm:p-6 lg:p-8",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("h1",{className:"text-3xl font-bold text-slate-100 flex items-center",children:[e.jsx(m,{}),e.jsx("span",{className:"ml-3",children:"PWA Manifest Editor"})]}),e.jsx("p",{className:"text-slate-400 mt-1",children:"Configure and generate the `manifest.json` file for your PWA."})]}),e.jsxs("div",{className:"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 min-h-0",children:[e.jsxs("div",{className:"flex flex-col gap-4 bg-slate-800/50 p-6 rounded-lg overflow-y-auto",children:[e.jsx("h3",{className:"text-xl font-bold",children:"Configuration"}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"name",className:"block text-sm font-medium text-slate-400",children:"App Name"}),e.jsx("input",{type:"text",name:"name",value:s.name,onChange:l,className:"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"short_name",className:"block text-sm font-medium text-slate-400",children:"Short Name"}),e.jsx("input",{type:"text",name:"short_name",value:s.short_name,onChange:l,className:"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"start_url",className:"block text-sm font-medium text-slate-400",children:"Start URL"}),e.jsx("input",{type:"text",name:"start_url",value:s.start_url,onChange:l,className:"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"display",className:"block text-sm font-medium text-slate-400",children:"Display Mode"}),e.jsxs("select",{name:"display",value:s.display,onChange:l,className:"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700",children:[e.jsx("option",{children:"standalone"}),e.jsx("option",{children:"fullscreen"}),e.jsx("option",{children:"minimal-ui"})]})]}),e.jsxs("div",{className:"flex gap-4",children:[e.jsxs("div",{className:"w-1/2",children:[e.jsx("label",{htmlFor:"background_color",className:"block text-sm font-medium text-slate-400",children:"Background Color"}),e.jsx("input",{type:"color",name:"background_color",value:s.background_color,onChange:l,className:"w-full mt-1 h-10 rounded-md bg-slate-800 border border-slate-700"})]}),e.jsxs("div",{className:"w-1/2",children:[e.jsx("label",{htmlFor:"theme_color",className:"block text-sm font-medium text-slate-400",children:"Theme Color"}),e.jsx("input",{type:"color",name:"theme_color",value:s.theme_color,onChange:l,className:"w-full mt-1 h-10 rounded-md bg-slate-800 border border-slate-700"})]})]})]}),e.jsxs("div",{className:"flex flex-col",children:[e.jsx("label",{className:"text-sm font-medium text-slate-400 mb-2",children:"Generated manifest.json"}),e.jsxs("div",{className:"relative flex-grow",children:[e.jsx("pre",{className:"w-full h-full bg-slate-900 p-4 rounded-md text-cyan-300 text-sm overflow-auto",children:a}),e.jsx("button",{onClick:n,className:"absolute top-2 right-2 px-2 py-1 bg-slate-700 hover:bg-slate-600 rounded-md text-xs",children:"Copy"})]})]})]})]})};export{b as PwaManifestEditor};
|
| 2 |
+
//# sourceMappingURL=PwaManifestEditor-CI-u9z3y.js.map
|
assets/PwaManifestEditor-CI-u9z3y.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"version":3,"file":"PwaManifestEditor-CI-u9z3y.js","sources":["../../components/features/PwaManifestEditor.tsx"],"sourcesContent":["\nimport React, { useState, useMemo } from 'react';\nimport { CodeBracketSquareIcon } from '../icons/FeatureIcons.tsx';\n\ninterface ManifestData {\n name: string;\n short_name: string;\n start_url: string;\n display: 'standalone' | 'fullscreen' | 'minimal-ui';\n background_color: string;\n theme_color: string;\n}\n\nexport const PwaManifestEditor: React.FC = () => {\n const [manifest, setManifest] = useState<ManifestData>({\n name: 'DevCore 100 Progressive Web App',\n short_name: 'DevCore100',\n start_url: '/',\n display: 'standalone',\n background_color: '#1e293b',\n theme_color: '#06b6d4',\n });\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {\n setManifest({ ...manifest, [e.target.name]: e.target.value });\n };\n\n const generatedJson = useMemo(() => {\n const fullManifest = {\n ...manifest,\n icons: [\n {\n \"src\": \"icon-192.png\",\n \"type\": \"image/png\",\n \"sizes\": \"192x192\"\n },\n {\n \"src\": \"icon-512.png\",\n \"type\": \"image/png\",\n \"sizes\": \"512x512\"\n }\n ]\n }\n return JSON.stringify(fullManifest, null, 2);\n }, [manifest]);\n\n const handleCopy = () => {\n navigator.clipboard.writeText(generatedJson);\n };\n\n return (\n <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8\">\n <header className=\"mb-6\">\n <h1 className=\"text-3xl font-bold text-slate-100 flex items-center\">\n <CodeBracketSquareIcon />\n <span className=\"ml-3\">PWA Manifest Editor</span>\n </h1>\n <p className=\"text-slate-400 mt-1\">Configure and generate the `manifest.json` file for your PWA.</p>\n </header>\n <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 min-h-0\">\n <div className=\"flex flex-col gap-4 bg-slate-800/50 p-6 rounded-lg overflow-y-auto\">\n <h3 className=\"text-xl font-bold\">Configuration</h3>\n <div>\n <label htmlFor=\"name\" className=\"block text-sm font-medium text-slate-400\">App Name</label>\n <input type=\"text\" name=\"name\" value={manifest.name} onChange={handleChange} className=\"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700\"/>\n </div>\n <div>\n <label htmlFor=\"short_name\" className=\"block text-sm font-medium text-slate-400\">Short Name</label>\n <input type=\"text\" name=\"short_name\" value={manifest.short_name} onChange={handleChange} className=\"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700\"/>\n </div>\n <div>\n <label htmlFor=\"start_url\" className=\"block text-sm font-medium text-slate-400\">Start URL</label>\n <input type=\"text\" name=\"start_url\" value={manifest.start_url} onChange={handleChange} className=\"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700\"/>\n </div>\n <div>\n <label htmlFor=\"display\" className=\"block text-sm font-medium text-slate-400\">Display Mode</label>\n <select name=\"display\" value={manifest.display} onChange={handleChange} className=\"w-full mt-1 px-3 py-2 rounded-md bg-slate-800 border border-slate-700\">\n <option>standalone</option>\n <option>fullscreen</option>\n <option>minimal-ui</option>\n </select>\n </div>\n <div className=\"flex gap-4\">\n <div className=\"w-1/2\">\n <label htmlFor=\"background_color\" className=\"block text-sm font-medium text-slate-400\">Background Color</label>\n <input type=\"color\" name=\"background_color\" value={manifest.background_color} onChange={handleChange} className=\"w-full mt-1 h-10 rounded-md bg-slate-800 border border-slate-700\"/>\n </div>\n <div className=\"w-1/2\">\n <label htmlFor=\"theme_color\" className=\"block text-sm font-medium text-slate-400\">Theme Color</label>\n <input type=\"color\" name=\"theme_color\" value={manifest.theme_color} onChange={handleChange} className=\"w-full mt-1 h-10 rounded-md bg-slate-800 border border-slate-700\"/>\n </div>\n </div>\n </div>\n <div className=\"flex flex-col\">\n <label className=\"text-sm font-medium text-slate-400 mb-2\">Generated manifest.json</label>\n <div className=\"relative flex-grow\">\n <pre className=\"w-full h-full bg-slate-900 p-4 rounded-md text-cyan-300 text-sm overflow-auto\">{generatedJson}</pre>\n <button onClick={handleCopy} className=\"absolute top-2 right-2 px-2 py-1 bg-slate-700 hover:bg-slate-600 rounded-md text-xs\">Copy</button>\n </div>\n </div>\n </div>\n </div>\n );\n};"],"names":["PwaManifestEditor","manifest","setManifest","useState","handleChange","e","generatedJson","useMemo","fullManifest","handleCopy","jsxs","jsx","CodeBracketSquareIcon"],"mappings":"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"}
|