diff --git a/app/about/page.tsx b/app/about/page.tsx index 7feb6f5..b690ba8 100644 --- a/app/about/page.tsx +++ b/app/about/page.tsx @@ -1,6 +1,6 @@ export default function About() { return ( -
+

About

@@ -13,13 +13,9 @@ export default function About() { The Source Code is available on GitHub (link below).

-

Features

-
    -
  • Password Generator - Create secure passwords with customizable options
  • -
  • Image Converter - Convert images between different formats
  • -
  • Website Bookmarks - Save and organize your favorite websites
  • -
  • More tools coming soon!
  • -
+
+

Current Version: 0.2.0

+

Privacy

diff --git a/app/api/convert/route.ts b/app/api/convert/route.ts index 8a4a013..6006a20 100644 --- a/app/api/convert/route.ts +++ b/app/api/convert/route.ts @@ -34,6 +34,15 @@ export async function POST(req: NextRequest) { case 'gif': convertedBuffer = await sharpInstance.gif().toBuffer() break + case 'ico': + convertedBuffer = await sharpInstance + .resize(256, 256, { + fit: 'contain', + background: { r: 0, g: 0, b: 0, alpha: 0 } + }) + .png() + .toBuffer() + break default: throw new Error('Unsupported format') } diff --git a/app/calculator/scientific/page.tsx b/app/calculator/scientific/page.tsx new file mode 100644 index 0000000..20b6005 --- /dev/null +++ b/app/calculator/scientific/page.tsx @@ -0,0 +1,186 @@ +'use client' +import { useState } from 'react' + +export default function ScientificCalculator() { + const [display, setDisplay] = useState('0') + const [memory, setMemory] = useState(0) + const [lastOperation, setLastOperation] = useState(null) + const [newNumber, setNewNumber] = useState(true) + + const operations = { + '+': (a: number, b: number) => a + b, + '-': (a: number, b: number) => a - b, + '×': (a: number, b: number) => a * b, + '÷': (a: number, b: number) => a / b, + 'xⁿ': (a: number, b: number) => Math.pow(a, b), + 'ⁿ√x': (a: number, b: number) => Math.pow(a, 1/b), + } + + const handleNumber = (num: string) => { + if (newNumber) { + setDisplay(num) + setNewNumber(false) + } else { + setDisplay(display === '0' ? num : display + num) + } + } + + const handleDecimal = () => { + if (newNumber) { + setDisplay('0.') + setNewNumber(false) + } else if (!display.includes('.')) { + setDisplay(display + '.') + } + } + + const handleOperation = (op: string) => { + setMemory(parseFloat(display)) + setLastOperation(op) + setNewNumber(true) + } + + const handleEquals = () => { + if (lastOperation && !newNumber) { + const current = parseFloat(display) + const operation = operations[lastOperation as keyof typeof operations] + const result = operation(memory, current) + setDisplay(result.toString()) + setNewNumber(true) + setLastOperation(null) + } + } + + const handleFunction = (func: string) => { + const num = parseFloat(display) + let result: number + + switch (func) { + case 'sin': + result = Math.sin(num * Math.PI / 180) + break + case 'cos': + result = Math.cos(num * Math.PI / 180) + break + case 'tan': + result = Math.tan(num * Math.PI / 180) + break + case 'log': + result = Math.log10(num) + break + case 'ln': + result = Math.log(num) + break + case '√': + result = Math.sqrt(num) + break + case 'x²': + result = num * num + break + case '1/x': + result = 1 / num + break + default: + return + } + + setDisplay(result.toString()) + setNewNumber(true) + } + + const handleClear = () => { + setDisplay('0') + setMemory(0) + setLastOperation(null) + setNewNumber(true) + } + + const handleBackspace = () => { + if (display.length > 1) { + setDisplay(display.slice(0, -1)) + } else { + setDisplay('0') + setNewNumber(true) + } + } + + const handlePlusMinus = () => { + setDisplay(display.startsWith('-') ? display.slice(1) : '-' + display) + } + + const Button = ({ children, onClick, className = '' }: { children: React.ReactNode, onClick: () => void, className?: string }) => ( + + ) + + return ( +

+
+

Scientific Calculator

+ +
+
+

+ A scientific calculator with advanced mathematical functions including trigonometry, + logarithms, and exponential operations. +

+
+ +
+
+ +
+ +
+ {/* Scientific Functions */} + + + + + + + + + + + + + + + + {/* Numbers and Basic Operations */} + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ ) +} \ No newline at end of file diff --git a/app/changelog/page.tsx b/app/changelog/page.tsx new file mode 100644 index 0000000..b7fa4c0 --- /dev/null +++ b/app/changelog/page.tsx @@ -0,0 +1,40 @@ +export default function Changelog() { + return ( +
+
+

Changelog

+ +
+
+
+
+

Version 0.2.0

+
    +
  • Added Settings and Changelog pages
  • +
  • Color Converter added
  • +
  • Enhanced QR code generator
  • +
  • Currency converter added
  • +
  • Number Converter added
  • +
  • Scientific Calculator added
  • +
  • Removed bookmarked websites feature
  • +
  • Updated navigation structure
  • +
+
+ +
+

Version 0.1.0

+
    +
  • Initial release
  • +
  • Added basic tools: Password Generator, QR Code Generator
  • +
  • Added converters: Number, Color, Currency
  • +
  • Added Scientific Calculator
  • +
  • Basic website layout and navigation
  • +
+
+
+
+
+
+
+ ) +} \ No newline at end of file diff --git a/app/coming_soon/page.tsx b/app/coming_soon/page.tsx index 472f07a..c293e8d 100644 --- a/app/coming_soon/page.tsx +++ b/app/coming_soon/page.tsx @@ -1,13 +1,13 @@ export default function ComingSoon() { return ( -
+

Coming Soon

- This project is maintained and developed by me as an individual developer. + This project is maintained and developed by me as an individual developer. New functions and tools will be added as time and inspiration allow.

@@ -16,10 +16,42 @@ export default function ComingSoon() { Instead, I add new tools and functions when I have a good idea and the time allows.

-

- If you have suggestions for new tools or features, you can submit them via GitHub - or contact me directly. I welcome any feedback and suggestions! -

+
+
+

Planned Features

+
    +
  • Text Tools +
      +
    • Text Case Converter
    • +
    • Lorem Ipsum Generator
    • +
    • String Hash Generator
    • +
    +
  • +
  • Development Tools +
      +
    • JSON Formatter
    • +
    • Base64 Encoder/Decoder
    • +
    • URL Encoder/Decoder
    • +
    +
  • +
  • Image Tools +
      +
    • Image Resizer
    • +
    • Image Format Converter
    • +
    • Image Compression
    • +
    +
  • +
+
+ +
+

Want to suggest a feature?

+

+ Feel free to suggest new tools or features through the GitHub repository or contact me directly. + I welcome any feedback and suggestions! +

+
+
diff --git a/app/components/AddWebsite.tsx b/app/components/AddWebsite.tsx index 43768dc..0caf873 100644 --- a/app/components/AddWebsite.tsx +++ b/app/components/AddWebsite.tsx @@ -7,12 +7,26 @@ export default function AddWebsite() { const [title, setTitle] = useState('') const [isAdding, setIsAdding] = useState(false) + const formatUrl = (inputUrl: string) => { + // Remove leading/trailing whitespace + let formattedUrl = inputUrl.trim() + + // If URL doesn't start with a protocol, add https:// + if (!formattedUrl.match(/^https?:\/\//i)) { + formattedUrl = 'https://' + formattedUrl + } + + return formattedUrl + } + const handleSubmit = (e: React.FormEvent) => { e.preventDefault() - // Validiere URL + const formattedUrl = formatUrl(url) + + // Validate URL try { - new URL(url) + new URL(formattedUrl) } catch { alert('Please enter a valid URL') return @@ -20,23 +34,23 @@ export default function AddWebsite() { const newWebsite: PinnedWebsite = { id: Date.now().toString(), - title: title || url, - url: url.startsWith('http') ? url : `https://${url}`, + title: title || formattedUrl, + url: formattedUrl, addedAt: Date.now() } - // Lade bestehende Websites + // Load existing websites const existingWebsites = JSON.parse(localStorage.getItem('pinnedWebsites') || '[]') - // Füge neue Website hinzu + // Add new website localStorage.setItem('pinnedWebsites', JSON.stringify([...existingWebsites, newWebsite])) - // Setze Formular zurück + // Reset form setUrl('') setTitle('') setIsAdding(false) - // Lade die Seite neu um die neue Website anzuzeigen + // Reload page to show new website window.location.reload() } @@ -59,10 +73,13 @@ export default function AddWebsite() { type="text" value={url} onChange={(e) => setUrl(e.target.value)} - placeholder="https://example.com" + placeholder="example.com" className="w-full bg-zinc-700 text-white rounded-md border border-gray-600 p-2" required /> +

+ HTTPS will be added automatically if not provided +