diff --git a/README.md b/README.md new file mode 100644 index 0000000..b99ad5c --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# Dev Assistant 🚀 + +A comprehensive suite of developer tools designed to streamline your daily workflow. Built with performance, privacy, and ease of use in mind. + +## ✨ Features + +- **Code Formatter**: Quickly format your code using Prettier. +- **Diff Tool**: Compare two pieces of code or text to find differences. +- **JSON Parser**: Parse, validate, and format JSON data. +- **Unit Conversion**: Convert between various units (Length, Weight, Temp, etc.). +- **Image Converter**: Convert images between different formats directly in your browser. +- **Data Converter**: Convert data between formats like CSV, XML, and JSON. + +## 🛠️ Tech Stack + +- **Monorepo**: Managed with NPM Workspaces. +- **Frontend**: [React](https://reactjs.org/) + [Vite](https://vitejs.dev/) + [TypeScript](https://www.typescriptlang.org/). +- **Styling**: [Tailwind CSS](https://tailwindcss.com/). +- **Editor**: [Monaco Editor](https://microsoft.github.io/monaco-editor/) for a rich coding experience. +- **Utilities**: + - `diff-match-patch` for text comparisons. + - `prettier` for code formatting. + - `lucide-react` for beautiful icons. + +## 📁 Project Structure + +```text +. +├── apps/ +│ └── web/ # The main React application (Vite) +├── packages/ +│ └── core/ # Shared logic and utilities +├── package.json # Root workspace configuration +└── README.md # You are here +``` + +## 🚀 Getting Started + +### Prerequisites + +- [Node.js](https://nodejs.org/) (v18 or higher recommended) +- [NPM](https://www.npmjs.com/) + +### Installation + +1. Clone the repository: + ```bash + git clone https://github.com/madcoderBubt/DevAsistant.git + cd DevAsistant + ``` + +2. Install dependencies: + ```bash + npm install + ``` + +### Development + +To start the development server for the web application: + +```bash +npm run dev +``` + +The application will be available at `http://localhost:5173`. + +### Building for Production + +To build all packages and the web application: + +```bash +npm run build +``` + +## 📄 License + +This project is licensed under the MIT License - see the LICENSE file for details. diff --git a/apps/web/README.md b/apps/web/README.md new file mode 100644 index 0000000..efb75fb --- /dev/null +++ b/apps/web/README.md @@ -0,0 +1,26 @@ +# Dev Assistant - Web Application + +This is the frontend React application for the Dev Assistant project. + +## Tech Stack + +- **Framework**: React 18 +- **Build Tool**: Vite +- **Styling**: Tailwind CSS +- **Code Editor**: Monaco Editor (@monaco-editor/react) +- **Icons**: Lucide React + +## Scripts + +- `npm run dev`: Starts the development server. +- `npm run build`: Builds the application for production. +- `npm run preview`: Previews the production build locally. + +## Features Included + +- Code Formatter +- Diff Tool +- JSON Parser +- Unit Conversion +- Image Converter +- Data Converter diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 045199c..03f5685 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -5,6 +5,7 @@ import DiffPage from './pages/DiffPage'; import JSONParserPage from './pages/JSONParserPage'; import UnitConversionPage from './pages/UnitConversionPage'; import ImageConverterPage from './pages/ImageConverterPage'; +import DataConverterPage from './pages/DataConverterPage'; function App() { return ( @@ -17,6 +18,7 @@ function App() { } /> } /> } /> + } /> diff --git a/apps/web/src/components/Layout.tsx b/apps/web/src/components/Layout.tsx index 7ef9b34..172db17 100644 --- a/apps/web/src/components/Layout.tsx +++ b/apps/web/src/components/Layout.tsx @@ -1,5 +1,5 @@ import { Link, Outlet, useLocation } from 'react-router-dom'; -import { FileJson, ArrowLeftRight, Code2, Braces, Ruler, Image } from 'lucide-react'; +import { FileJson, ArrowLeftRight, Code2, Braces, Ruler, Image, Database } from 'lucide-react'; export default function Layout() { const location = useLocation(); @@ -10,6 +10,7 @@ export default function Layout() { { path: '/diff', label: 'Diff Viewer', icon: ArrowLeftRight }, { path: '/unit-conversion', label: 'Unit Converter', icon: Ruler }, { path: '/image-converter', label: 'Image Converter', icon: Image }, + { path: '/data-converter', label: 'Data Converter', icon: Database }, ]; return ( diff --git a/apps/web/src/pages/DataConverterPage.tsx b/apps/web/src/pages/DataConverterPage.tsx new file mode 100644 index 0000000..f2596c7 --- /dev/null +++ b/apps/web/src/pages/DataConverterPage.tsx @@ -0,0 +1,322 @@ +import { useState, useEffect } from 'react'; +import { RefreshCw, Copy, Trash2, ArrowLeftRight, Download, FileJson, FileCode, Table } from 'lucide-react'; +import { + jsonToXml, + xmlToJson, + jsonToCsv, + csvToJson, + xmlToCsv, + csvToXml, + ConversionResult +} from '@dev-assistant/core'; + +type DataFormat = 'json' | 'xml' | 'csv'; + +const SAMPLE_DATA = { + json: `{ + "users": [ + { + "id": 1, + "name": "John Doe", + "email": "john@example.com", + "active": true + }, + { + "id": 2, + "name": "Jane Smith", + "email": "jane@example.com", + "active": false + } + ] +}`, + xml: ` + + + + 1 + John Doe + john@example.com + true + + + 2 + Jane Smith + jane@example.com + false + + +`, + csv: `id,name,email,active +1,John Doe,john@example.com,true +2,Jane Smith,jane@example.com,false` +}; + +export default function DataConverterPage() { + const [sourceFormat, setSourceFormat] = useState('json'); + const [targetFormat, setTargetFormat] = useState('xml'); + const [inputValue, setInputValue] = useState(''); + const [outputValue, setOutputValue] = useState(''); + const [error, setError] = useState(''); + const [isConverting, setIsConverting] = useState(false); + + const formatIcons = { + json: FileJson, + xml: FileCode, + csv: Table + }; + + const formatLabels = { + json: 'JSON', + xml: 'XML', + csv: 'CSV' + }; + + useEffect(() => { + // Auto-convert when input changes + if (inputValue.trim()) { + handleConvert(); + } else { + setOutputValue(''); + setError(''); + } + }, [inputValue, sourceFormat, targetFormat]); + + const handleConvert = () => { + if (!inputValue.trim()) { + setOutputValue(''); + setError(''); + return; + } + + setIsConverting(true); + setError(''); + + try { + let result: ConversionResult; + + // Perform conversion based on source and target formats + if (sourceFormat === 'json' && targetFormat === 'xml') { + result = jsonToXml(inputValue); + } else if (sourceFormat === 'json' && targetFormat === 'csv') { + result = jsonToCsv(inputValue); + } else if (sourceFormat === 'xml' && targetFormat === 'json') { + result = xmlToJson(inputValue); + } else if (sourceFormat === 'xml' && targetFormat === 'csv') { + result = xmlToCsv(inputValue); + } else if (sourceFormat === 'csv' && targetFormat === 'json') { + result = csvToJson(inputValue); + } else if (sourceFormat === 'csv' && targetFormat === 'xml') { + result = csvToXml(inputValue); + } else { + // Same format - just copy + result = { success: true, data: inputValue }; + } + + if (result.success && result.data) { + setOutputValue(result.data); + setError(''); + } else { + setOutputValue(''); + setError(result.error || 'Conversion failed'); + } + } catch (err) { + setOutputValue(''); + setError(err instanceof Error ? err.message : 'An unexpected error occurred'); + } finally { + setIsConverting(false); + } + }; + + const copyToClipboard = (text: string) => { + navigator.clipboard.writeText(text); + }; + + const clear = () => { + setInputValue(''); + setOutputValue(''); + setError(''); + }; + + const swapFormats = () => { + setSourceFormat(targetFormat); + setTargetFormat(sourceFormat); + setInputValue(outputValue); + }; + + const loadSample = () => { + setInputValue(SAMPLE_DATA[sourceFormat]); + }; + + const downloadOutput = () => { + if (!outputValue) return; + + const blob = new Blob([outputValue], { type: 'text/plain' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = `converted.${targetFormat}`; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + }; + + const FormatIcon = formatIcons[sourceFormat]; + const TargetIcon = formatIcons[targetFormat]; + + return ( +
+
+

Data Format Converter

+

+ Convert between JSON, XML, and CSV formats seamlessly. +

+
+ + {/* Format Selection */} +
+
+
+ + +
+ + + +
+ + +
+
+
+ + {/* Conversion Area */} +
+ {/* Input Section */} +
+
+

+ + Input ({formatLabels[sourceFormat]}) +

+
+ + +
+
+