diff mrjunejune/src/tools/file_converter/index.html @ 92:655ea0b661fd

[Seobeo] Added few endpoints for handling files. [Dowa] Added few functions for random number and generating uuids
author June Park <parkjune1995@gmail.com>
date Fri, 02 Jan 2026 17:47:10 -0800
parents
children be91a73d801a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mrjunejune/src/tools/file_converter/index.html	Fri Jan 02 17:47:10 2026 -0800
@@ -0,0 +1,267 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>File Format Converter</title>
+    {{/parts/base_head.html}}
+    <style>
+        .container {
+            max-width: 800px;
+            margin: 2rem auto;
+            padding: 2rem;
+        }
+
+        .converter-section {
+            border-radius: 8px;
+            border: 2px solid var(--lightgray);
+            padding: 2rem;
+            margin-bottom: 2rem;
+        }
+
+        .converter-section h2 {
+            margin-top: 0;
+            color: var(--black);
+        }
+
+        .file-input-wrapper {
+            margin: 1rem 0;
+        }
+
+        .file-input-wrapper label {
+            display: block;
+            margin-bottom: 0.5rem;
+            font-weight: 600;
+        }
+
+        input[type="file"] {
+            width: 50%;
+            padding: 0.5rem;
+            border: 2px dashed #ccc;
+            border-radius: 4px;
+            background: white;
+        }
+
+        button {
+            background: var(--purple);
+            font-family: "More Thin", sans-serif;
+            color: var(--gray-gradient);
+            border: none;
+            padding: 0.75rem 1.5rem;
+            border-radius: 4px;
+            cursor: pointer;
+            font-size: 1rem;
+            margin-top: 1rem;
+        }
+
+        button:hover {
+            background: var(--orange);
+        }
+
+        button:disabled {
+            background: var(--gray);
+            cursor: not-allowed;
+        }
+
+        .result {
+            margin-top: 1rem;
+            padding: 1rem;
+            background: white;
+            border-radius: 4px;
+            display: none;
+        }
+
+        .result.show {
+            display: block;
+        }
+
+        .result.success {
+            border-left: 4px solid var(--blue);
+        }
+
+        .result.error {
+            border-left: 4px solid var(--red);
+        }
+
+        .download-link {
+            display: inline-block;
+            margin-top: 0.5rem;
+            color: var(--awesome);
+            text-decoration: none;
+        }
+
+        .download-link:hover {
+            text-decoration: underline;
+        }
+
+        .loading {
+            display: none;
+            margin-top: 1rem;
+        }
+
+        .loading.show {
+            display: block;
+        }
+    </style>
+</head>
+<body>
+    {{/parts/header.html}}
+
+    <div class="container">
+        <h1>File Format Converter</h1>
+        <p>Convert your images and videos to different formats using FFmpeg</p>
+
+        <div class="converter-section">
+            <h2>Image to WebP Converter</h2>
+            <p>Upload an image file (PNG, JPG, GIF, etc.) to convert it to WebP format</p>
+
+            <div class="file-input-wrapper">
+                <label for="imageInput">Choose an image file:</label>
+                <input type="file" id="imageInput" accept="image/*">
+            </div>
+
+            <button id="convertImageBtn" onclick="convertImageToWebP()">Convert to WebP</button>
+
+            <div class="loading" id="imageLoading">Converting... Please wait.</div>
+
+            <div class="result" id="imageResult">
+                <p id="imageMessage"></p>
+                <a id="imageDownload" class="download-link" style="display: none;">Download WebP Image</a>
+            </div>
+        </div>
+
+        <div class="converter-section">
+            <h2>Video to MP4 Converter</h2>
+            <p>Upload a video file (AVI, MOV, MKV, etc.) to convert it to MP4 format</p>
+
+            <div class="file-input-wrapper">
+                <label for="videoInput">Choose a video file:</label>
+                <input type="file" id="videoInput" accept="video/*">
+            </div>
+
+            <button id="convertVideoBtn" onclick="convertVideoToMP4()">Convert to MP4</button>
+
+            <div class="loading" id="videoLoading">Converting... Please wait.</div>
+
+            <div class="result" id="videoResult">
+                <p id="videoMessage"></p>
+                <a id="videoDownload" class="download-link" style="display: none;">Download MP4 Video</a>
+            </div>
+        </div>
+    </div>
+
+    <script>
+        async function convertImageToWebP() {
+            const input = document.getElementById('imageInput');
+            const btn = document.getElementById('convertImageBtn');
+            const loading = document.getElementById('imageLoading');
+            const result = document.getElementById('imageResult');
+            const message = document.getElementById('imageMessage');
+            const download = document.getElementById('imageDownload');
+
+            if (!input.files || !input.files[0]) {
+                alert('Please select an image file first');
+                return;
+            }
+
+            const file = input.files[0];
+
+            // Show loading state
+            btn.disabled = true;
+            loading.classList.add('show');
+            result.classList.remove('show', 'success', 'error');
+            download.style.display = 'none';
+
+            try {
+                const response = await fetch('/api/convert/image-to-webp', {
+                    method: 'POST',
+                    body: file,
+                    headers: {
+                        'Content-Type': file.type
+                    }
+                });
+
+                loading.classList.remove('show');
+                result.classList.add('show');
+
+                if (response.ok) {
+                    const data = await response.json();
+
+                    download.href = data.download_url;
+                    download.download = file.name.replace(/\.[^/.]+$/, '') + '.webp';
+                    download.style.display = 'inline-block';
+
+                    message.textContent = 'Conversion successful! Link expires in ' + data.expires + '.';
+                    result.classList.add('success');
+                } else {
+                    const text = await response.text();
+                    message.textContent = 'Conversion failed: ' + text;
+                    result.classList.add('error');
+                }
+            } catch (error) {
+                loading.classList.remove('show');
+                result.classList.add('show', 'error');
+                message.textContent = 'Error: ' + error.message;
+            } finally {
+                btn.disabled = false;
+            }
+        }
+
+        async function convertVideoToMP4() {
+            const input = document.getElementById('videoInput');
+            const btn = document.getElementById('convertVideoBtn');
+            const loading = document.getElementById('videoLoading');
+            const result = document.getElementById('videoResult');
+            const message = document.getElementById('videoMessage');
+            const download = document.getElementById('videoDownload');
+
+            if (!input.files || !input.files[0]) {
+                alert('Please select a video file first');
+                return;
+            }
+
+            const file = input.files[0];
+
+            // Show loading state
+            btn.disabled = true;
+            loading.classList.add('show');
+            result.classList.remove('show', 'success', 'error');
+            download.style.display = 'none';
+
+            try {
+                const response = await fetch('/api/convert/video-to-mp4', {
+                    method: 'POST',
+                    body: file,
+                    headers: {
+                        'Content-Type': file.type
+                    }
+                });
+
+                loading.classList.remove('show');
+                result.classList.add('show');
+
+                if (response.ok) {
+                    const data = await response.json();
+
+                    download.href = data.download_url;
+                    download.download = file.name.replace(/\.[^/.]+$/, '') + '.mp4';
+                    download.style.display = 'inline-block';
+
+                    message.textContent = 'Conversion successful! Link expires in ' + data.expires + '.';
+                    result.classList.add('success');
+                } else {
+                    const text = await response.text();
+                    message.textContent = 'Conversion failed: ' + text;
+                    result.classList.add('error');
+                }
+            } catch (error) {
+                loading.classList.remove('show');
+                result.classList.add('show', 'error');
+                message.textContent = 'Error: ' + error.message;
+            } finally {
+                btn.disabled = false;
+            }
+        }
+    </script>
+</body>
+</html>